Skip to content

Adapt spinner output for invoking agents - #14191

Merged
babakks merged 3 commits into
trunkfrom
niik-agent-spinner-output
Aug 21, 2026
Merged

babakks merged 3 commits into
trunkfrom
niik-agent-spinner-output

Conversation

@niik

@niik niik commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

Closes #12839
Related to #12522

Description

gh already detects when it is invoked by an AI coding agent, but detection happened after IOStreams initialization and was repeated for telemetry and HTTP setup.

This change detects the invoking agent once during startup and shares that result with IOStreams, telemetry, and the command factory. When an agent is detected, animated braille spinners use the existing text-only progress indicator instead.

GH_SPINNER_DISABLED remains the highest-precedence override, including falsey values that explicitly restore animated spinners.

How did you test this change?

Manually exercised a spinner-producing command under a real PTY:

  • Without an agent environment variable, the animated braille spinner appeared.
  • With AI_AGENT or CLAUDECODE, Working... appeared without braille animation.
  • With an agent and GH_SPINNER_DISABLED=false, animated braille was restored.
  • With piped or non-TTY output, no progress indicator appeared.

Key points

  • Spinner precedence is environment override, detected agent, then configuration.
  • The existing agent detector remains the single source of truth.
  • The detected value is stored on the existing command factory for downstream output adaptations.
  • No-agent and non-TTY behavior remains unchanged.

Notes for reviewers

Start with internal/ghcmd/cmd.go, where detection moves ahead of IOStreams initialization and spinner precedence is applied.

internal/ghcmd/cmd_test.go covers precedence and environment isolation. acceptance/testdata/telemetry/agent-dimensions.txtar verifies the complete startup path.

Authorship and follow-up

Who wrote this:

  • A human wrote it.
  • An agent wrote it under close human direction.
  • An agent wrote it independently, and no human has guided the implementation beyond the initial prompt.

Who answers review comments:

  • @username will read and reply directly. Name the account.
  • An agent will draft replies and @niik will read them before they are posted.
  • Nobody has explicitly committed to replying.

niik added 2 commits August 18, 2026 14:09
Detect the invoking agent once during startup and reuse the result for IOStreams, telemetry, and command factory initialization. Prefer text progress indicators for agents while preserving GH_SPINNER_DISABLED as the explicit override.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: edd6fa49-4788-4882-93f6-ca7caca4b7ed
Isolate spinner precedence tests from inherited environment overrides and verify startup propagation of agent detection through telemetry in the acceptance suite.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: edd6fa49-4788-4882-93f6-ca7caca4b7ed
Copilot AI balanced review requested due to automatic review settings August 18, 2026 12:42

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Detects the invoking agent once and adapts spinner output for agent-driven sessions.

Changes:

  • Reuses agent detection across IOStreams, telemetry, and command setup.
  • Applies environment, agent, then configuration spinner precedence.
  • Adds unit and acceptance coverage.
Show a summary per file
File Description
internal/ghcmd/cmd.go Integrates agent-aware spinner initialization.
internal/ghcmd/cmd_test.go Tests spinner precedence and environment isolation.
acceptance/testdata/telemetry/agent-dimensions.txtar Verifies startup telemetry dimensions.

Review details

💡 Configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

  • Files reviewed: 3/3 changed files
  • Comments generated: 0
  • Review effort level: Balanced

@niik
niik marked this pull request as ready for review August 18, 2026 12:58
@niik
niik requested a review from a team as a code owner August 18, 2026 12:58
@niik
niik requested a review from BagToad August 18, 2026 12:58

@babakks babakks left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks for tackling this, @niik! ✨

Really nice, focused change. Collapsing agent detection down to a single Detect() call at startup and threading that one value through IOStreams, telemetry, and the factory is a clean improvement over the previous repeated detection. The spinner precedence (env override, then detected agent, then config) reads well, and I appreciate the acceptance test covering the full startup path.

I only have a couple of minor comments inline, nothing blocking.

Comment on lines +282 to +283
t.Setenv("GH_SPINNER_DISABLED", "")
require.NoError(t, os.Unsetenv("GH_SPINNER_DISABLED"))

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

question: why do we need both of these? The os.Unsetenv call should be enough on its own to clear the variable, right? If the goal is just to guarantee a clean slate before each case, the t.Setenv("GH_SPINNER_DISABLED", "") line looks redundant. Or is t.Setenv there to register the var with the testing framework so it gets restored after the test, while Unsetenv actually clears it for the run? If so, a short comment explaining the intent would help.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

is t.Setenv there to register the var with the testing framework so it gets restored after the test, while Unsetenv actually clears it for the run? If so, a short comment explaining the intent would help.

Yeah, that's it. I've pushed a comment, please take a look and see if you think it's explanatory enough

@babakks
babakks merged commit 7fff140 into trunk Aug 21, 2026
11 checks passed
@babakks
babakks deleted the niik-agent-spinner-output branch August 21, 2026 11:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

COPILOT_CLI=1 could trigger text spinners

3 participants