Skip to content

Show one tip on first start, document completion setup in the CLI - #495

Open
joe4dev wants to merge 8 commits into
mainfrom
devx-821-enforce-max-one-tip
Open

Show one tip on first start, document completion setup in the CLI#495
joe4dev wants to merge 8 commits into
mainfrom
devx-821-enforce-max-one-tip

Conversation

@joe4dev

@joe4dev joe4dev commented Sep 8, 2026

Copy link
Copy Markdown
Member

Motivation

#484 introduced a UX regression by rendering two tips on the first lstk startup (shell completion + rotation tip). Furthermore, the review also flagged the long docs URL as poor terminal UX.

Solution

One tip per run, enforced structurally rather than by convention.

  • selectTip (new internal/container/tips.go) is the only place that decides which tip to show, and it returns one string, not a list. The first-run completion tip outranks the rotating per-emulator tips: first run happens once per install, while the rotating tips come back on every later start.
  • container.Start is the only place that emits it. Its body moved to an unexported start, leaving the public entry point a thin wrapper around the single emit. emitPostStartPointers no longer emits a tip, and internal/ui no longer emits one either — RunOptions.CompletionTip is replaced by StartOptions.FirstRun.

Adding a tip now means ranking it inside selectTip; there is nowhere else to put it. The rule is written up under "Post-start tips" in CLAUDE.md.

The tip names a command instead of linking to docs.

> Tip: Set up tab completion: lstk completion

A URL in terminal output can't be clicked, rots, and drifts from an already-shipped binary. So lstk completion now carries the setup instructions itself; the per-shell subcommands forward to it, and lstk docs renders it, which makes the CLI the source and the docs site the follower.

User-visible change: a first interactive start shows the completion tip and nothing else. Every other run is unchanged, rotation included.

Shell completion

Bare lstk completion (and lstk completion --help) now prints:

Generate shell completion scripts for lstk.

To load completions:

Bash:

  # Load in current session
  eval "$(lstk completion bash)"

  # Load in new sessions (Linux)
  echo 'eval "$(lstk completion bash)"' >> ~/.bashrc

  # Load in new sessions (macOS)
  echo 'eval "$(lstk completion bash)"' >> ~/.bash_profile

Zsh:

  # Load in current session
  autoload -Uz compinit && compinit
  source <(lstk completion zsh)

  # Load in new sessions (Linux, macOS)
  echo 'autoload -Uz compinit && compinit' >> ~/.zshrc
  echo 'source <(lstk completion zsh)' >> ~/.zshrc

Fish:

  # Load in current session
  lstk completion fish | source

  # Load in new sessions (Linux, macOS)
  lstk completion fish > ~/.config/fish/completions/lstk.fish

PowerShell:

  # Load in current session
  lstk completion powershell | Out-String | Invoke-Expression

  # Load in new sessions (Windows, Linux, macOS)
  if (!(Test-Path $PROFILE)) { New-Item -ItemType File -Path $PROFILE -Force }
  lstk completion powershell | Out-File -Append -Encoding utf8 $PROFILE

Every recipe is the same shape: the current-session command, or that same command appended to the shell's startup file.

Optional alternatives considered and dropped

Verified on macOS 15 / Apple Silicon.

Dropped option Why
Zsh: lstk completion zsh > "${fpath[1]}/_lstk" fpath[1] is root-owned on stock macOS (/usr/local/share/zsh/site-functions), so a normal user gets permission denied. It doesn't exist on stock macOS yielding zsh: no such file or directory. Under oh-my-zsh it is a plugin directory. On my private mac, it points to ~/.docker/completions
Zsh: lstk completion zsh > $(brew --prefix)/share/zsh/site-functions/_lstk Silently does nothing on macOS's built-in zsh — that directory is not on the default $fpath (default fpath[1] is the Intel prefix while Homebrew sits at /opt/homebrew). It needs Homebrew's own zsh, or FPATH="$(brew --prefix)/share/zsh/site-functions:${FPATH}" before compinit.
Bash: lstk completion bash > /etc/bash_completion.d/lstk and the $(brew --prefix)/etc/bash_completion.d/lstk variant Both need the bash-completion package, which the eval form does not — lstk's script ships its own _get_comp_words_by_ref fallback (DEVX-950). They only buy lazy loading on first Tab instead of sourcing at every shell start.
Guarding the startup-file lines, e.g. [[ $commands[lstk] ]] && source <(lstk completion zsh) Would avoid command not found: lstk in every new shell after an uninstall, but roughly doubles the length of each line. Happy to add it to bash and zsh if reviewers prefer.

Two things that look optional but are not:

  • The zsh compinit line is required. Cobra's generated script calls compdef on line 2, and compdef does not exist until compinit has run — without it you get compdef: command not found and nothing registers. A duplicate compinit (oh-my-zsh already runs one) is harmless. Sourcing costs ~8 ms per shell start.
  • PowerShell uses Out-File -Encoding utf8 rather than >>, which writes UTF-16LE on PowerShell 5.1 and leaves a profile the shell cannot parse.
Docs

The CLI is now the source of truth for shell-completion setup, and the docs site should follow it rather than the reverse.

Handled in localstack/localstack-docs#937, which rewrites the Shell completions section to match lstk completion — the page currently recommends ${fpath[1]} and the Homebrew site-functions path for zsh (neither works on stock macOS — see the table above), omits the required compinit step, and has no PowerShell instructions. The same section is duplicated on the Azure page; that PR updates both.

No new command, flag, or env var. The first-start tip no longer links to the docs, so the #shell-completions anchor is no longer referenced from the CLI.

Manual Testing

First startup tip

No more docs link and adjusted message:
Screenshot 2026-09-10 at 19 00 11

Shell Completions

  • @joe4dev I tested Bash, Zsh, Fish, PowerShell on macOS and PowerShell on Windows
  • @dfangl Bash and Zsh on Linux (Fish and PS should be the same as macOS)

Review

Human review advised — it changes user-facing output and help text on the shared start path, and @gtsiolis raised the original concern on #484, so it's worth confirming this is the resolution he had in mind.

Related

Towards DEVX-821

Docs PR with synchronized shell completion changes: localstack/localstack-docs#937

@joe4dev joe4dev added semver: patch docs: skip Pull request does not require documentation changes labels Sep 8, 2026
@joe4dev
joe4dev force-pushed the devx-821-enforce-max-one-tip branch 2 times, most recently from 55008c9 to 2f6fbbe Compare September 8, 2026 14:33
@joe4dev
joe4dev force-pushed the devx-821-enforce-max-one-tip branch from 2f6fbbe to 2360c8a Compare September 9, 2026 12:44
@joe4dev
joe4dev marked this pull request as ready for review September 9, 2026 12:51
@joe4dev
joe4dev requested review from a team and peter-smith-phd as code owners September 9, 2026 12:51
@joe4dev
joe4dev requested a review from gtsiolis September 9, 2026 12:51

@gtsiolis gtsiolis 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, @joe4dev! Left some comments, let me know what you think!

Comment thread internal/container/tips.go Outdated
Comment thread internal/container/tips.go
Comment thread internal/container/tips.go Outdated
@joe4dev joe4dev changed the title Show only one tip on first start Show one tip on first start, document completion setup in the CLI Sep 10, 2026
@joe4dev joe4dev added docs: needed Pull request requires documentation updates and removed docs: skip Pull request does not require documentation changes labels Sep 10, 2026
@joe4dev
joe4dev marked this pull request as draft September 10, 2026 19:03
joe4dev and others added 5 commits September 11, 2026 13:44
Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Claude <noreply@anthropic.com>
@joe4dev
joe4dev force-pushed the devx-821-enforce-max-one-tip branch from 4f82c9d to 8f02787 Compare September 11, 2026 13:44
@joe4dev
joe4dev marked this pull request as ready for review September 11, 2026 13:45
@joe4dev
joe4dev requested a review from gtsiolis September 11, 2026 13:45

@gtsiolis gtsiolis 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.

Nearly perfect, adding a latest screenshot of the current state for reference. 🏁

Image

Comment thread cmd/completion.go Outdated
Comment thread cmd/completion.go Outdated
Comment thread cmd/completion.go
joe4dev and others added 3 commits September 11, 2026 16:23
Co-authored-by: George Tsiolis <tsiolis.g@gmail.com>
Co-authored-by: George Tsiolis <tsiolis.g@gmail.com>
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

docs: needed Pull request requires documentation updates semver: patch

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants