Skip to content

Streamline first-time setup with recommended defaults - #660

Open
robzolkos wants to merge 1 commit into
mainfrom
fast-default-setup
Open

Streamline first-time setup with recommended defaults#660
robzolkos wants to merge 1 commit into
mainfrom
fast-default-setup

Conversation

@robzolkos

@robzolkos robzolkos commented Aug 26, 2026

Copy link
Copy Markdown
Collaborator

Summary

This aligns Basecamp CLI onboarding with the streamlined setup experience in the HEY CLI: approve browser OAuth once, apply sensible defaults, configure detected integrations, and get started. The existing question-by-question flow remains available for people who want to choose each setting.

  • On an unauthenticated first interactive run, make bare basecamp and basecamp setup open browser OAuth, select the OAuth-bound or first available account, save it globally, and leave the default project unset
  • Automatically configure every detected coding agent, showing progress while installation runs and a durable status when it finishes
  • Detect Omarchy and install and enable the 37signals.basecamp plugin when absent, or update the existing installation
  • Preserve the guided setup flow as basecamp setup --customize
  • Add basecamp setup --minimal, intended for Omarchy plugin-driven CLI installs, to end with SETUP COMPLETE instead of showing starter commands
  • Refresh the default setup presentation with the current Basecamp snowglobe, concise browser-authentication output, integration status, and account-wide starter commands
  • Run interactive setup from the installers, including routing piped Bash installs through the controlling terminal so OAuth can complete
  • Document mise installation and direct mise-managed upgrades back through mise

CLI setup

image

Setup run if Omarchy plugin installs the CLI (opens in a modal)

image

Copilot AI balanced review requested due to automatic review settings August 26, 2026 20:38
@github-actions github-actions Bot added commands CLI command implementations tui Terminal UI tests Tests (unit and e2e) skills Agent skills docs labels Aug 26, 2026

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Streamlines onboarding with OAuth-based recommended defaults while preserving customizable setup.

Changes:

  • Adds fast setup with automatic account and agent configuration.
  • Improves installer TTY handling and mise upgrades.
  • Adds concise branding, output, documentation, and tests.

Tip

If you aren't ready for review, convert to a draft PR.
Click "Convert to draft" or run gh pr ready --undo.
Click "Ready for review" or run gh pr ready to reengage.

Reviewed changes

Copilot reviewed 21 out of 21 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
.surface Adds the customize flag.
README.md Documents setup and mise.
e2e/installer.bats Tests installer TTY routing.
e2e/setup.bats Updates setup safety documentation.
install.md Updates installation guidance.
internal/appctx/context.go Adds notice suppression state.
internal/cli/root.go Suppresses post-setup notices.
internal/cli/root_test.go Tests notice suppression.
internal/commands/commands.go Updates setup catalog text.
internal/commands/quickstart.go Routes first runs to fast setup.
internal/commands/upgrade_selfupdate.go Detects mise installations.
internal/commands/upgrade_selfupdate_test.go Tests mise detection.
internal/commands/wizard.go Implements recommended setup.
internal/commands/wizard_agents.go Configures detected agents.
internal/commands/wizard_test.go Tests streamlined setup.
internal/tui/brand.go Adds logo-only rendering.
internal/tui/brand_anim.go Adds logo-only animation.
internal/tui/brand_test.go Tests logo rendering.
scripts/install.ps1 Updates Windows setup behavior.
scripts/install.sh Routes setup through /dev/tty.
skills/basecamp-doctor/SKILL.md Updates setup remediation guidance.
Suppressed comments (2)

internal/commands/wizard.go:94

  • The recommended flow never clears an existing global project_id: PersistValue merges only account_id into the existing file, while app.Config.ProjectID also remains populated. Re-running default setup after a customized or pre-seeded configuration therefore keeps a default project, contrary to this flow’s advertised defaults. Remove the global project_id and clear the in-memory value (with coverage for an existing project setting); also define how any higher-precedence local/repo value should be handled.
	if err := resolve.PersistValue("account_id", accountID, "global"); err != nil {
		return fmt.Errorf("saving the default account: %w", err)
	}

README.md:108

  • This list promises the first account unconditionally, but account-bound OAuth uses its bound account instead. Reflect that precedence in the documented recommended defaults.
- First available account, saved globally

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread scripts/install.sh
echo ""
elif [[ -t 0 ]] && [[ -t 1 ]]; then
"$BIN_DIR/$binary_name" setup
elif [[ "${BASECAMP_NONINTERACTIVE:-}" != "1" ]] && [[ -t 1 ]] && [[ -t 2 ]] && [[ -c /dev/tty ]]; then
Comment thread internal/commands/wizard.go Outdated
Comment on lines +45 to +46
Long: "Authenticate with Basecamp, select the first available account, save it globally, " +
"and connect detected coding agents. Use --customize to choose each setting.",
Comment thread README.md
On Windows 11 with Smart App Control, see [Troubleshooting](#windows-smart-app-control-and-smartscreen) if the install is blocked.

That's it. You now have full access to Basecamp from your terminal.
On an interactive terminal, the installer opens Basecamp setup: approve OAuth in your browser and the CLI selects the first available account, saves it globally, skips a default project, and connects every detected coding agent. Use `basecamp setup --customize` to choose those settings instead.
Comment thread install.md
Install the Basecamp CLI and connect it to your AI agent. Execute all steps autonomously.

The piped installer (Step 1) already installs the baseline agent skill and, on a best-effort basis, attempts to connect a single detected coding agent. The optional "Connect Your Agent" section below is for forcing a specific agent, handling multiple detected agents, or verifying the connection.
On an interactive terminal, the installer runs the recommended setup after download: browser authentication, the first available account saved globally, no default project, and every detected coding agent connected. Use `basecamp setup --customize` when you want to choose those settings. In non-interactive environments, the installer installs the baseline agent skill and, on a best-effort basis, attempts to connect a single detected coding agent.
Copilot AI review requested due to automatic review settings August 26, 2026 20:44

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 20 out of 20 changed files in this pull request and generated no new comments.

Suppressed comments (5)

scripts/install.sh:528

  • BASECAMP_NONINTERACTIVE is parsed by the CLI as a case-insensitive boolean (1 or true), but this installer gate only recognizes 1. On a TTY, BASECAMP_NONINTERACTIVE=true therefore launches setup; setup rejects the session and set -e aborts the installer instead of taking the noninteractive fallback. Match the CLI's truthy values here.
  elif [[ "${BASECAMP_NONINTERACTIVE:-}" != "1" ]] && [[ -t 1 ]] && [[ -t 2 ]] && [[ -c /dev/tty ]]; then

internal/commands/wizard.go:46

  • This help text does not match automaticAccount: account-bound OAuth credentials win before account discovery, and only unbound credentials fall back to the first authorized account. Describe that precedence so users are not told the CLI chose an arbitrary first account.
		Long: "Authenticate with Basecamp, select the first available account, save it globally, " +
			"and connect detected coding agents. Use --customize to choose each setting.",

README.md:26

  • The setup implementation prefers the account bound to the OAuth token and only lists accounts as a fallback. Saying it always selects the first available account misdocuments the normal account-bound OAuth path.
On an interactive terminal, the installer opens Basecamp setup: approve OAuth in your browser and the CLI selects the first available account, saves it globally, skips a default project, and connects every detected coding agent. Use `basecamp setup --customize` to choose those settings instead.

README.md:108

  • This recommended-default list conflicts with the implemented precedence: the OAuth-bound account is selected first, with the first available account used only as a fallback. Update the bullet so the documented setup result is accurate.
- First available account, saved globally

install.md:5

  • The installer does not always choose the first available account: automaticAccount prefers the account bound to the OAuth token. Document the bound-account-first behavior here, consistent with the PR description and implementation.
On an interactive terminal, the installer runs the recommended setup after download: browser authentication, the first available account saved globally, no default project, and every detected coding agent connected. Use `basecamp setup --customize` when you want to choose those settings. In non-interactive environments, the installer installs the baseline agent skill and, on a best-effort basis, attempts to connect a single detected coding agent.

Copilot AI review requested due to automatic review settings August 26, 2026 20:52

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 20 out of 20 changed files in this pull request and generated 1 comment.

Suppressed comments (2)

Previously missed (1) — in code that hasn't changed since the last review.

internal/commands/wizard.go:94

  • PersistValue preserves every existing JSON key, so this only changes account_id; an existing global project_id survives recommended setup. The advertised account-wide starter commands will then remain project-scoped (and the retained project may belong to the previous account), despite this path rejecting --project and promising no default project. Clear project_id from the global config as part of applying these defaults, and clear the in-memory value too.
	if err := resolve.PersistValue("account_id", accountID, "global"); err != nil {
		return fmt.Errorf("saving the default account: %w", err)
	}

scripts/install.sh:528

  • The CLI treats BASECAMP_NONINTERACTIVE=true case-insensitively as enabled (internal/config/config.go:468-470), but this installer only recognizes 1. On a TTY, BASECAMP_NONINTERACTIVE=true curl … | bash therefore enters this branch, and basecamp setup immediately refuses under set -e, making an otherwise successful install exit as a failure instead of using post_install_setup. Match both truthy spellings here.
  elif [[ "${BASECAMP_NONINTERACTIVE:-}" != "1" ]] && [[ -t 1 ]] && [[ -t 2 ]] && [[ -c /dev/tty ]]; then

Comment thread install.md
```

> **Note:** The install scripts auto-detect non-interactive environments (CI, piped input, coding agents) and skip the interactive setup wizard. In that case they still run `basecamp setup agents`, which installs the baseline agent skill and **attempts to connect** a single detected coding agent (best effort). If several agents are detected, or none is, only the baseline skill is installed and the per-agent commands are surfaced. Explicitly skipping the wizard with `BASECAMP_SKIP_SETUP=1` still runs `setup agents`.
> **Note:** On an interactive terminal, the install scripts run `basecamp setup` with the recommended defaults. In non-interactive environments (CI, piped input, coding agents), they skip authentication and run `basecamp setup agents`, which installs the baseline agent skill and **attempts to connect** a single detected coding agent (best effort). If several agents are detected, or none is, only the baseline skill is installed and the per-agent commands are surfaced. Explicitly skipping first-time setup with `BASECAMP_SKIP_SETUP=1` still runs `setup agents`.
Copilot AI review requested due to automatic review settings August 26, 2026 21:01

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 20 out of 20 changed files in this pull request and generated no new comments.

Suppressed comments (2)

Previously missed (1) — in code that hasn't changed since the last review.

scripts/install.ps1:428

  • The PowerShell installer does not honor the same BASECAMP_NONINTERACTIVE escape hatch as the Bash installer and CLI. When an agent runs under an interactive-looking PowerShell host with this variable set, it still invokes human setup; setup then refuses, and the noninteractive Invoke-PostInstallSetup fallback is skipped. Include the environment gate in this branch.
    } elseif ($isInteractive) {
      & $installedBinary setup

scripts/install.sh:528

  • BASECAMP_NONINTERACTIVE is parsed as a truthy boolean by the CLI (true/TRUE as well as 1), but this installer gate recognizes only 1. On an interactive terminal with BASECAMP_NONINTERACTIVE=true, the installer enters this branch, and the installed CLI immediately refuses setup instead of running the noninteractive fallback. Match the CLI's accepted truthy forms here.
  elif [[ "${BASECAMP_NONINTERACTIVE:-}" != "1" ]] && [[ -t 1 ]] && [[ -t 2 ]] && [[ -c /dev/tty ]]; then

Copilot AI review requested due to automatic review settings August 26, 2026 21:12

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 22 out of 22 changed files in this pull request and generated no new comments.

Suppressed comments (1)

scripts/install.sh:528

  • BASECAMP_NONINTERACTIVE is case-insensitively truthy for both 1 and true in the CLI, but this gate skips setup only for 1. With BASECAMP_NONINTERACTIVE=true in a TTY, the installer invokes setup; setup rejects the interactive flow and set -e aborts the installer instead of taking the noninteractive fallback. Match the CLI's boolean semantics here.
  elif [[ "${BASECAMP_NONINTERACTIVE:-}" != "1" ]] && [[ -t 1 ]] && [[ -t 2 ]] && [[ -c /dev/tty ]]; then

Copilot AI review requested due to automatic review settings August 26, 2026 21:36

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 22 out of 22 changed files in this pull request and generated no new comments.

Suppressed comments (1)

Previously missed (1) — in code that hasn't changed since the last review.

internal/commands/wizard.go:361

  • When browser OAuth returns a BC5 resource-bound account, an explicit --account still wins here. If the user passes a different ID, setup persists an account that the newly issued token is guaranteed not to access, yet reports success because RequireAccount only checks that the ID is numeric. Reject a mismatch between explicitAccountID and boundAccountID (and update the precedence test) rather than saving an unusable default.
	if explicitAccountID != "" {
		return explicitAccountID, "", nil
	}
	if boundAccountID != "" {
		return boundAccountID, "", nil

Copilot AI review requested due to automatic review settings August 26, 2026 21:48

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 22 out of 22 changed files in this pull request and generated no new comments.

Suppressed comments (6)

Previously missed (2) — in code that hasn't changed since the last review.

internal/commands/wizard.go:95

  • Recommended setup preserves any existing global project_id: PersistValue loads the current config and only changes account_id. Therefore rerunning basecamp setup can finish with a project default still active, contradicting the advertised “No default project” behavior. Remove project_id from the global config as part of this transaction (and update the in-memory project state) before reporting completion.
	if err := resolve.PersistValue("account_id", accountID, "global"); err != nil {

internal/commands/wizard.go:47

  • The help text says setup always selects the first account, but automaticAccount prefers an OAuth-bound account. Describe that precedence so users with account-bound credentials are not told the wrong default.
		Long: "Authenticate with Basecamp, select the first available account, save it globally, " +
			"and connect detected coding agents. Use --customize to choose each setting or --minimal for a concise completion message.",

README.md:26

  • This onboarding description omits the higher-priority OAuth-bound account selection and can promise the wrong account. Match the actual OAuth-bound-then-first-available behavior.
On an interactive terminal, the installer opens Basecamp setup: approve OAuth in your browser and the CLI selects the first available account, saves it globally, skips a default project, and connects every detected coding agent. Use `basecamp setup --customize` to choose those settings instead.

README.md:108

  • This bullet says the first account is always selected, but account-bound OAuth credentials take precedence. Document the actual selection order.
- First available account, saved globally

install.md:5

  • The setup description says the first account is always selected, while the implementation first uses an OAuth-bound account. Update the guide to reflect the actual precedence.
On an interactive terminal, the installer runs the recommended setup after download: browser authentication, the first available account saved globally, no default project, and every detected coding agent connected. Use `basecamp setup --customize` when you want to choose those settings. In non-interactive environments, the installer installs the baseline agent skill and, on a best-effort basis, attempts to connect a single detected coding agent.

install.md:33

  • Piped input is no longer a reason for the Bash installer to skip setup: the new /dev/tty redirection specifically makes the documented curl | bash path interactive when stdout and stderr are terminals. Listing “piped input” here incorrectly tells users that the standard install command skips authentication.
> **Note:** On an interactive terminal, the install scripts run `basecamp setup` with the recommended defaults. In non-interactive environments (CI, piped input, coding agents), they skip authentication and run `basecamp setup agents`, which installs the baseline agent skill and **attempts to connect** a single detected coding agent (best effort). If several agents are detected, or none is, only the baseline skill is installed and the per-agent commands are surfaced. Explicitly skipping first-time setup with `BASECAMP_SKIP_SETUP=1` still runs `setup agents`.

Copilot AI review requested due to automatic review settings August 26, 2026 21:53

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 22 out of 22 changed files in this pull request and generated no new comments.

Suppressed comments (2)

Previously missed (1) — in code that hasn't changed since the last review.

scripts/install.ps1:430

  • The PowerShell installer does not account for BASECAMP_NONINTERACTIVE before invoking interactive setup. With that variable enabled in an otherwise interactive console, setupCanRun rejects the invocation, and the installer neither authenticates nor runs the intended noninteractive agent setup fallback. Include the environment escape hatch in this branch, as the Bash installer does.
      Info 'Skipping first-time setup because PowerShell is running non-interactively.'

scripts/install.sh:528

  • BASECAMP_NONINTERACTIVE=true (including case variants) is treated as enabled by the CLI, but this check excludes only the literal 1. In an interactive terminal the installer therefore launches setup, which immediately refuses to run instead of taking the noninteractive setup agents path. Match the same true values accepted by config.NonInteractiveEnv.
  elif [[ "${BASECAMP_NONINTERACTIVE:-}" != "1" ]] && [[ -t 1 ]] && [[ -t 2 ]] && [[ -c /dev/tty ]]; then

Copilot AI review requested due to automatic review settings August 26, 2026 22:12

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 24 out of 24 changed files in this pull request and generated no new comments.

Suppressed comments (3)

Previously missed (2) — in code that hasn't changed since the last review.

scripts/install.sh:528

  • -c /dev/tty only proves that the device node exists; it does not prove this process has a controlling terminal. For example, a setsid session can retain TTY stdout/stderr while opening /dev/tty fails with ENXIO, so this branch would abort an otherwise successful install at the redirection. Probe that /dev/tty can actually be opened in the condition.
  elif [[ "${BASECAMP_NONINTERACTIVE:-}" != "1" ]] && [[ -t 1 ]] && [[ -t 2 ]] && [[ -c /dev/tty ]]; then

internal/commands/wizard.go:97

  • The recommended path persists account_id into the existing global config map but leaves any prior global project_id untouched. Therefore, rerunning default basecamp setup can continue to resolve a default project, contrary to this flow's account-wide/no-default-project contract. Clear the global project value and the in-memory resolved value when applying these defaults.
	if err := resolve.PersistValue("account_id", accountID, "global"); err != nil {
		return fmt.Errorf("saving the default account: %w", err)
	}

install.md:33

  • This note still lists piped input as a case that skips authentication, but the new canonical curl | bash path deliberately runs setup via /dev/tty when a controlling terminal is available. Qualify the example so the documentation matches the installer behavior.
> **Note:** On an interactive terminal, the install scripts run `basecamp setup` with the recommended defaults. In non-interactive environments (CI, piped input, coding agents), they skip authentication and run `basecamp setup agents`, which installs the baseline agent skill and **attempts to connect** a single detected coding agent (best effort). If several agents are detected, or none is, only the baseline skill is installed and the per-agent commands are surfaced. Explicitly skipping first-time setup with `BASECAMP_SKIP_SETUP=1` still runs `setup agents`.

Copilot AI review requested due to automatic review settings August 27, 2026 00:53

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 24 out of 24 changed files in this pull request and generated no new comments.

Suppressed comments (8)

Previously missed (5) — in code that hasn't changed since the last review.

internal/commands/wizard.go:96

  • The recommended path writes the account but never clears an existing project_id from app.Config or persisted configuration. Therefore, running basecamp setup with an existing local/global project keeps that project as the effective default, contrary to the promised intentionally project-free setup. Clear the relevant project setting(s), or explicitly define and document that existing project defaults are preserved.
	if err := resolve.PersistValue("account_id", accountID, "global"); err != nil {
		return fmt.Errorf("saving the default account: %w", err)

internal/commands/wizard.go:552

  • This success headline is unconditional even when the preceding agent status reports issues or omarchy.failed() is true. In --minimal mode that produces contradictory output such as “needs attention” followed by “SETUP COMPLETE.” Propagate the overall outcome into this renderer and use a needs-attention headline when any setup step failed.
	if minimal {
		fmt.Fprintln(w, fastSetupTitleStyle(styles).Render("SETUP COMPLETE"))

scripts/install.sh:528

  • /dev/tty exists as a character device even when this process has no controlling terminal (for example, under setsid). In that case stdout/stderr can still satisfy -t, this branch is taken, and the redirection on the next line aborts the installer under set -e instead of using the non-interactive fallback. Probe that /dev/tty can actually be opened as part of the condition.
  elif [[ "${BASECAMP_NONINTERACTIVE:-}" != "1" ]] && [[ -t 1 ]] && [[ -t 2 ]] && [[ -c /dev/tty ]]; then

internal/tui/spinner.go:46

  • Hiding the cursor here can leave the user's terminal cursor permanently hidden: Go's default SIGINT/SIGTERM termination does not run deferred functions, so Ctrl-C after the spinner appears skips the restore sequence. Either add process-level signal cleanup or avoid hiding the cursor for this transient spinner.
	fmt.Fprint(w, "\033[?25l")
	defer fmt.Fprint(w, "\r\033[2K\033[?25h")

internal/commands/wizard.go:47

  • The help text says the first account is always selected, but automaticAccount prefers app.Auth.AccountID() and only falls back to the first authorized account. Describe that precedence so users know which account setup will save.
		Long: "Authenticate with Basecamp, select the first available account, save it globally, " +
			"and connect detected coding agents. Use --customize to choose each setting or --minimal for a concise completion message.",

README.md:26

  • This onboarding description is inaccurate when OAuth is bound to an account: setup prefers that bound account rather than the first account returned by authorization. Document the bound-account precedence to match the implemented behavior.
On an interactive terminal, the installer opens Basecamp setup: approve OAuth in your browser and the CLI selects the first available account, saves it globally, skips a default project, and connects every detected coding agent. Use `basecamp setup --customize` to choose those settings instead.

README.md:108

  • The recommended account default is not always the first available account; automaticAccount first uses the OAuth-bound account. This list should state the actual precedence.
- First available account, saved globally

install.md:5

  • This says setup always saves the first available account, but the implementation prefers the OAuth-bound account and only falls back to the first account. Update the installation guidance to reflect the actual selection rule.
On an interactive terminal, the installer runs the recommended setup after download: browser authentication, the first available account saved globally, no default project, and every detected coding agent connected. Use `basecamp setup --customize` when you want to choose those settings. In non-interactive environments, the installer installs the baseline agent skill and, on a best-effort basis, attempts to connect a single detected coding agent.

Copilot AI review requested due to automatic review settings August 27, 2026 01:12

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 24 out of 24 changed files in this pull request and generated no new comments.

Suppressed comments (7)

Previously missed (3) — in code that hasn't changed since the last review.

internal/commands/wizard.go:552

  • --minimal always ends with SETUP COMPLETE, even when the preceding agent status reports unresolved issues or Omarchy reports a failure. That makes the final summary contradict the actual setup result. Pass the combined agent/Omarchy outcome here and render a needs-attention result whenever either has unresolved failures.
	if minimal {
		fmt.Fprintln(w, fastSetupTitleStyle(styles).Render("SETUP COMPLETE"))

internal/commands/wizard.go:47

  • This help text does not match automaticAccount: an explicit --account wins, then an OAuth-bound account wins, and only then is the first authorized account selected. Describe that order so users with account-bound OAuth credentials are not told setup chose the first account.
		Long: "Authenticate with Basecamp, select the first available account, save it globally, " +
			"and connect detected coding agents. Use --customize to choose each setting or --minimal for a concise completion message.",

scripts/install.ps1:430

  • The PowerShell installer does not honor BASECAMP_NONINTERACTIVE. On an interactive host with that variable enabled, it invokes setup; the command rejects interactive setup, and the baseline post-install path is skipped. Include the environment setting in this branch, matching the CLI's accepted true/1 values.
      Info 'Skipping first-time setup because PowerShell is running non-interactively.'

scripts/install.sh:528

  • The CLI treats both 1 and case-insensitive true as enabling BASECAMP_NONINTERACTIVE, but this installer gate recognizes only 1. With BASECAMP_NONINTERACTIVE=true on a TTY, the installer launches setup, which immediately rejects the session and aborts the set -e script. Match every true form accepted by config.NonInteractiveEnv.
  elif [[ "${BASECAMP_NONINTERACTIVE:-}" != "1" ]] && [[ -t 1 ]] && [[ -t 2 ]] && [[ -c /dev/tty ]]; then

README.md:26

  • This onboarding description says setup always selects the first account, but the implementation prefers the OAuth-bound account (and an explicit --account) before consulting the account list. Update the description to match the actual selection behavior.
On an interactive terminal, the installer opens Basecamp setup: approve OAuth in your browser and the CLI selects the first available account, saves it globally, skips a default project, and connects every detected coding agent. Use `basecamp setup --customize` to choose those settings instead.

README.md:108

  • The recommended account is not always the first available one: setup prefers an explicit or OAuth-bound account. This bullet should reflect the implemented default so the setup documentation is accurate.
- First available account, saved globally

install.md:5

  • This says interactive setup saves the first account, but automaticAccount first uses an explicit or OAuth-bound account. Align this installation guide with the actual account-selection order.
On an interactive terminal, the installer runs the recommended setup after download: browser authentication, the first available account saved globally, no default project, and every detected coding agent connected. Use `basecamp setup --customize` when you want to choose those settings. In non-interactive environments, the installer installs the baseline agent skill and, on a best-effort basis, attempts to connect a single detected coding agent.

Copilot AI review requested due to automatic review settings August 27, 2026 01:20

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 24 out of 24 changed files in this pull request and generated no new comments.

Suppressed comments (3)

Previously missed (1) — in code that hasn't changed since the last review.

internal/tui/spinner.go:24

  • The new tests use only bytes.Buffer, so isWriterTTY always takes the non-terminal branch. The core terminal path—including delayed rendering and restoring the cursor after success or error—remains untested. Add a PTY-backed test with a task lasting beyond spinnerDelay and verify both spinner output and the final clear/show-cursor sequence.
func RunWithSpinner(w io.Writer, theme Theme, message string, task func() error) error {
	if !isWriterTTY(w) {
		return task()
	}

install.md:33

  • This note now contradicts the installer behavior above: piped Bash input is explicitly supported when stdout/stderr and /dev/tty are terminals, so curl | bash does not by itself skip authentication. Describe the lack of a controlling terminal—not piped input—as the non-interactive case.
> **Note:** On an interactive terminal, the install scripts run `basecamp setup` with the recommended defaults. In non-interactive environments (CI, piped input, coding agents), they skip authentication and run `basecamp setup agents`, which installs the baseline agent skill and **attempts to connect** a single detected coding agent (best effort). If several agents are detected, or none is, only the baseline skill is installed and the per-agent commands are surfaced. Explicitly skipping first-time setup with `BASECAMP_SKIP_SETUP=1` still runs `setup agents`.

scripts/install.sh:533

  • This branch also runs when BASECAMP_NONINTERACTIVE=1, even if a terminal is present, so reporting “no terminal detected” is misleading. Mention both reasons in the status message.
    info "Skipping first-time setup (no terminal detected)."

Copilot AI review requested due to automatic review settings August 27, 2026 01:28

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 24 out of 24 changed files in this pull request and generated no new comments.

Suppressed comments (6)

Previously missed (2) — in code that hasn't changed since the last review.

internal/commands/wizard.go:47

  • The help text does not match the implemented precedence: automaticAccount chooses an OAuth-bound account before the first account returned by authorization. This matters for users authorized for multiple accounts; describe the bound-account preference rather than promising the first account.
		Long: "Authenticate with Basecamp, select the first available account, save it globally, " +
			"and connect detected coding agents. Use --customize to choose each setting or --minimal for a concise completion message.",

skills/basecamp-doctor/SKILL.md:31

  • The setup gate also requires terminal stdout through app.IsInteractive; terminal stdin and stderr alone are insufficient. This remediation guidance should name all three streams so agents do not suggest a setup invocation that will still be refused when stdout is redirected.
refuses with a usage error in machine-output modes or when stdin and stderr are
not both terminals. `basecamp setup --customize` additionally asks the user to

scripts/install.sh:528

  • BASECAMP_NONINTERACTIVE=true is a supported truthy value (config.NonInteractiveEnv accepts true case-insensitively), but this installer only recognizes 1. In an interactive shell it will invoke setup; the CLI then rejects the run as noninteractive, and set -e aborts the installation instead of taking the post-install fallback. Match the CLI's truthy-value handling here.
  elif [[ "${BASECAMP_NONINTERACTIVE:-}" != "1" ]] && [[ -t 1 ]] && [[ -t 2 ]] && [[ -c /dev/tty ]]; then

README.md:26

  • Recommended setup prefers the OAuth-bound account and only falls back to the first available account. This installation summary currently promises the fallback behavior unconditionally, which can misdescribe the selected account for multi-account users.
On an interactive terminal, the installer opens Basecamp setup: approve OAuth in your browser and the CLI selects the first available account, saves it globally, skips a default project, and connects every detected coding agent. Use `basecamp setup --customize` to choose those settings instead.

README.md:108

  • This default is inaccurate for OAuth credentials carrying an account resource: the implementation selects that bound account before considering the first available account. Document both branches so this section agrees with setup behavior.
- First available account, saved globally

install.md:5

  • The recommended flow uses the OAuth-bound account when one exists and only otherwise chooses the first available account. Calling it always the first account can set the wrong expectation for multi-account installations.
On an interactive terminal, the installer runs the recommended setup after download: browser authentication, the first available account saved globally, no default project, and every detected coding agent connected. Use `basecamp setup --customize` when you want to choose those settings. In non-interactive environments, the installer installs the baseline agent skill and, on a best-effort basis, attempts to connect a single detected coding agent.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

commands CLI command implementations docs skills Agent skills tests Tests (unit and e2e) tui Terminal UI

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants