fix(update): give post-upgrade and skill nudges breathing room

Summary

The post-upgrade banner and the bundled-skill-updates check were jamming their lines into the preceding command output and into each other. The skill line crammed a header, the skill list, and the action onto a single sentence ending with glab. Run: glab skills update glab — visually noisy and confusing.

Reported by a user who ran glab -v and got a one-line version answer trailed by the full "what's new" + skills pitch.

Changes

  • Skip the post-command nudges for version / -v / --version. Asking "what version do I have?" should get a one-line answer. Also avoids polluting glab -v 2>&1-style automation.
  • Leading blank line on the version-available block and the post-upgrade banner so nudges don't cram against the user's actual command output.
  • Restructure the skill-update notice as its own multi-line block (yellow header + indented body + indented Run: line) matching the version-available shape, separated from any prior block by a blank line.

Before

➜  gitlab git:(fr/bump-labkit-version) glab -v
glab 1.102.0 (b5a548b3)
What's new in glab v1.102.0
  Run: glab whatsnew
  1 installed agent skill has updates: glab. Run: glab skills update glab

After

glab -v now just answers the question:

➜  gitlab git:(fr/bump-labkit-version) glab -v
glab 1.102.0 (b5a548b3)

When both nudges fire after another command (e.g. glab mr list):

…mr list output…

A new version of glab is available
  v1.101.0 → v1.102.0
  Run: brew upgrade glab
  Release notes: https://gitlab.com/gitlab-org/cli/-/releases/v1.102.0

What's new in glab v1.102.0
  Run: glab whatsnew

Agent skill updates available
  glab
  Run: glab skills update glab

For the multi-skill case the body line collapses to a comma list and the action becomes --all:

Agent skill updates available
  glab, glab-stack
  Run: glab skills update --all

Test plan

  • go test ./internal/commands/update/... passes
  • go test ./... passes
  • go build ./... clean
  • Manually verify glab -v no longer trails nudges
  • Manually verify glab version no longer trails nudges
  • Manually verify glab --version no longer trails nudges
  • Manually verify post-upgrade banner now leads with a blank line
  • Manually verify skill block renders as its own multi-line section (single- and multi-skill)

How the manual tests were run

Built with an injected version (-ldflags "-X main.version=v1.50.0") and an isolated GLAB_CONFIG_DIR seeded with last_seen_version: v1.0.0 so the post-upgrade banner and skill blocks reliably fire. Skill blocks were triggered by installing a bundled skill into a throwaway repo and editing its SKILL.md to force a content-hash mismatch.

Important

The nudges must be verified in a non-agent environment. Under a coding agent (e.g. Claude Code sets CLAUDECODE=1), DetectCodingAgent() returns non-empty, which short-circuits the post-upgrade banner and routes the version notice to the single-line agent path — masking these blocks entirely. Tests below stripped CLAUDECODE/AI_AGENT/etc. and set TERM_PROGRAM=.

Version forms skip everything (clean stderr):

Command stderr
glab version (empty)
glab -v (empty)
glab --version (empty)
glab config get editor (control) full banner — confirms the nudges would have fired

The control proves the empty output for the version forms is a genuine skip, not a non-firing nudge.

Resolves @GitLabDuo's review note: the -v / --version guards do match in practice. cmd/glab/main.go passes argCommand := expandedArgs[0] — the raw first arg from os.Args[1:] / alias expansion, not a parsed cobra.Command.Name() — so flag forms arrive verbatim (-v, --version) and are matched directly. Confirmed end-to-end above.

Post-upgrade banner + skill block rendering (cat -e, $ marks line ends):

$
What's new in glab v1.50.0$
  Run: glab whatsnew$
$
Agent skill updates available$
  glab$
  Run: glab skills update glab$

Multi-skill:

$
Agent skill updates available$
  glab, glab-stack$
  Run: glab skills update --all$
Edited by Jay McCure

Merge request reports

Loading