Skip to content

feat: add --theme flag to preselect TUI theme#2933

Merged
dgageot merged 2 commits into
docker:mainfrom
dgageot:board/e4da0297f5bfa48b
May 29, 2026
Merged

feat: add --theme flag to preselect TUI theme#2933
dgageot merged 2 commits into
docker:mainfrom
dgageot:board/e4da0297f5bfa48b

Conversation

@dgageot
Copy link
Copy Markdown
Member

@dgageot dgageot commented May 29, 2026

Users often prefer a consistent visual theme across all agents and environments. Rather than repeatedly selecting a theme from the TUI menu, a --theme flag on docker agent run lets them preselect a theme by name at launch.

The implementation maintains a clear precedence: explicit --theme flag wins, falling back to any theme configured in the agent config, then to the built-in default. An invalid theme name is caught early with a helpful "unknown theme; available themes: ..." error instead of silently falling back. The flag is registered with shell completion via a new completeTheme function backed by styles.ListThemeRefs(), and its help text clarifies that it only applies in interactive TUI mode.

Tests cover validation, precedence (including interactions with isolated config/data directories), and shell completion.

dgageot added 2 commits May 29, 2026 16:53
Validate explicit --theme values early with a new validateTheme helper
so typos fail fast with a helpful message listing available themes,
instead of silently falling back at TUI startup. Update flag help text
to clarify the theme is ignored outside the interactive TUI. Add tests
for validateTheme, applyTheme precedence, and theme completion.
@dgageot dgageot requested a review from a team as a code owner May 29, 2026 15:18
Copy link
Copy Markdown

@docker-agent docker-agent left a comment

Choose a reason for hiding this comment

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

Assessment: 🟡 NEEDS ATTENTION

This PR adds a --theme flag to preselect TUI themes. The implementation is generally clean with good validation and completion support. Two issues were found:

  1. Theme validation fires in --exec mode (CONFIRMED): contradicts the flag's own help text saying it's ignored outside TUI
  2. Missing precedence test (LIKELY): user config theme + flag override interaction is not covered by tests

The core logic (precedence order, error messages, shell completion) is correct.

Comment thread cmd/root/run.go
// Validate an explicit --theme value early so a typo fails fast with a
// helpful message instead of silently falling back to the default theme
// once the TUI starts.
if f.theme != "" {
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

[MEDIUM] --theme validation fires in --exec mode, contradicting "ignored outside TUI" docs

The flag's help text says the --theme flag is "ignored outside the interactive TUI", but validateTheme is called unconditionally from runRunCommand — the shared entry point for both interactive and --exec (non-TUI) modes.

This means:

docker agent run --exec --theme does-not-exist config.yaml

…will error out with unknown theme "does-not-exist"; available themes: … instead of silently ignoring the flag as the documentation promises.

Suggested fix: Gate the validation on whether the command is actually launching the interactive TUI (e.g. skip validation when --exec is set):

if f.theme != "" && !f.exec {
    if err := validateTheme(f.theme); err != nil {
        return err
    }
}

Or update the flag's help text to say the flag is validated even in exec mode (even if the theme is not applied).

})
}

func TestApplyThemePrecedence(t *testing.T) {
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

[MEDIUM] TestApplyThemePrecedence missing test for user-config theme + --theme flag precedence

TestApplyThemePrecedence never sets a user config theme (userSettings.Theme != ""), so the critical precedence path — where both a user config theme and the --theme flag override are present — is never exercised.

The applyTheme logic has two layers:

  1. Apply user config theme if set (overrides default)
  2. Apply --theme flag override if set (overrides user config)

If this ordering were accidentally swapped in a future refactor (user config checked after flag instead of before), the existing tests would not catch the regression because they only test the flag override against an empty user config.

Suggested addition to TestApplyThemePrecedence:

t.Run("flag override wins over user config theme", func(t *testing.T) {
    // Write a user config that pins a different theme
    userConfigPath := filepath.Join(dir, "config.json")
    _ = os.WriteFile(userConfigPath, []byte(`{"theme":"dracula"}`), 0o600)
    
    applyTheme("nord") // --theme flag should override the config's "dracula"
    assert.Equal(t, "nord", styles.CurrentTheme().Ref)
})

@aheritier aheritier added area/cli CLI commands, flags, output formatting area/tui For features/issues/fixes related to the TUI kind/feat PR adds a new feature (maps to feat: commit prefix) labels May 29, 2026
@dgageot dgageot merged commit ae1a07e into docker:main May 29, 2026
10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/cli CLI commands, flags, output formatting area/tui For features/issues/fixes related to the TUI kind/feat PR adds a new feature (maps to feat: commit prefix)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants