Skip to content

Commit a2539da

Browse files
committed
optional title and app name
1 parent b355a29 commit a2539da

3 files changed

Lines changed: 59 additions & 15 deletions

File tree

pkg/tui/components/statusbar/statusbar.go

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,14 @@ import (
88

99
"github.com/docker/docker-agent/pkg/tui/core"
1010
"github.com/docker/docker-agent/pkg/tui/styles"
11-
"github.com/docker/docker-agent/pkg/version"
1211
)
1312

1413
// StatusBar displays key-binding help on the left and version info on the right.
1514
// When the tab bar is hidden (single tab), it also shows a clickable "+ new tab" button.
1615
type StatusBar struct {
1716
width int
1817
help core.KeyMapHelp
18+
title string
1919

2020
showNewTab bool
2121
newTabStartX int
@@ -25,12 +25,31 @@ type StatusBar struct {
2525
cacheDirty bool
2626
}
2727

28+
// Option is a functional option for configuring a StatusBar.
29+
type Option func(*StatusBar)
30+
31+
// WithTitle sets a custom title for the status bar.
32+
//
33+
// If not provided, defaults to "docker agent".
34+
func WithTitle(title string) Option {
35+
return func(s *StatusBar) {
36+
s.title = title
37+
}
38+
}
39+
2840
// New creates a new StatusBar instance
29-
func New(help core.KeyMapHelp) StatusBar {
30-
return StatusBar{
41+
func New(help core.KeyMapHelp, opts ...Option) StatusBar {
42+
s := StatusBar{
3143
help: help,
44+
title: "docker agent",
3245
cacheDirty: true,
3346
}
47+
48+
for _, opt := range opts {
49+
opt(&s)
50+
}
51+
52+
return s
3453
}
3554

3655
// SetWidth sets the width of the status bar
@@ -76,19 +95,18 @@ func (s *StatusBar) rebuild() {
7695
s.newTabStartX = 0
7796
s.newTabEndX = 0
7897

79-
// Build the styled right side: optional new-tab button + version.
80-
var right string
98+
// Build the styled right side: optional new-tab button + title.
8199
var rightW, newTabW int
82-
ver := styles.MutedStyle.Render("docker agent " + version.Version)
100+
right := styles.MutedStyle.Render(s.title)
101+
83102
if s.showNewTab {
84103
newTab := styles.MutedStyle.Render(" \u2502 ") +
85104
styles.HighlightWhiteStyle.Render("+") +
86105
styles.SecondaryStyle.Render(" new tab")
87106
newTabW = lipgloss.Width(newTab)
88-
right = newTab + " " + ver
107+
right = newTab + " " + right
89108
rightW = lipgloss.Width(right)
90109
} else {
91-
right = ver
92110
rightW = lipgloss.Width(right)
93111
}
94112

pkg/tui/handlers.go

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -595,23 +595,25 @@ func (m *appModel) handleElicitationResponse(action tools.ElicitationAction, con
595595
}
596596

597597
func (m *appModel) startShell() (tea.Model, tea.Cmd) {
598+
exitMsg := fmt.Sprintf("Type 'exit' to return to %s", m.appName)
599+
598600
var cmd *exec.Cmd
599601
if goruntime.GOOS == "windows" {
600602
if path, err := exec.LookPath("pwsh.exe"); err == nil {
601603
cmd = exec.Command(path, "-NoLogo", "-NoExit", "-Command",
602-
`Write-Host ""; Write-Host "Type 'exit' to return to docker agent 🐳"`)
604+
fmt.Sprintf(`Write-Host ""; Write-Host "%s"`, exitMsg))
603605
} else if path, err := exec.LookPath("powershell.exe"); err == nil {
604606
cmd = exec.Command(path, "-NoLogo", "-NoExit", "-Command",
605-
`Write-Host ""; Write-Host "Type 'exit' to return to docker agent 🐳"`)
607+
fmt.Sprintf(`Write-Host ""; Write-Host "%s"`, exitMsg))
606608
} else {
607609
// Use absolute path to cmd.exe to prevent PATH hijacking (CWE-426).
608610
shell := shellpath.WindowsCmdExe()
609-
cmd = exec.Command(shell, "/K", `echo. & echo Type 'exit' to return to docker agent`)
611+
cmd = exec.Command(shell, "/K", fmt.Sprintf(`echo. & echo %s`, exitMsg))
610612
}
611613
} else {
612614
shell := shellpath.DetectUnixShell()
613615
cmd = exec.Command(shell, "-i", "-c",
614-
`echo -e "\nType 'exit' to return to docker agent 🐳"; exec `+shell)
616+
fmt.Sprintf(`echo -e "\n%s"; exec %s`, exitMsg, shell))
615617
}
616618
cmd.Stdin = os.Stdin
617619
cmd.Stdout = os.Stdout

pkg/tui/tui.go

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ import (
4242
"github.com/docker/docker-agent/pkg/tui/service/tuistate"
4343
"github.com/docker/docker-agent/pkg/tui/styles"
4444
"github.com/docker/docker-agent/pkg/userconfig"
45+
"github.com/docker/docker-agent/pkg/version"
4546
)
4647

4748
// SessionSpawner creates new sessions with their own runtime.
@@ -163,6 +164,9 @@ type appModel struct {
163164

164165
// buildCommandCategories is a function that returns the list of command categories.
165166
buildCommandCategories func(context.Context, tea.Model) []commands.Category
167+
168+
appName string
169+
appVersion string
166170
}
167171

168172
// Option configures the TUI.
@@ -176,6 +180,24 @@ func WithLeanMode() Option {
176180
}
177181
}
178182

183+
// WithAppName sets the application name.
184+
//
185+
// If not provided, defaults to "docker agent".
186+
func WithAppName(name string) Option {
187+
return func(m *appModel) {
188+
m.appName = name
189+
}
190+
}
191+
192+
// WithVersion sets the application version.
193+
//
194+
// If not provided, defaults to version.Version.
195+
func WithVersion(v string) Option {
196+
return func(m *appModel) {
197+
m.appVersion = v
198+
}
199+
}
200+
179201
// WithCommandBuilder builds the command categories shown in the command
180202
// palette from the given function. It overrides the default command category
181203
// builder. To include the default commands, the given function should call
@@ -242,6 +264,8 @@ func New(ctx context.Context, spawner SessionSpawner, initialApp *app.App, initi
242264
focusedPanel: PanelEditor,
243265
editorLines: 3,
244266
dockerDesktop: os.Getenv("TERM_PROGRAM") == "docker_desktop",
267+
appName: "docker agent",
268+
appVersion: version.Version,
245269
}
246270

247271
// Apply options
@@ -260,7 +284,7 @@ func New(ctx context.Context, spawner SessionSpawner, initialApp *app.App, initi
260284
m.chatPage = initialChatPage
261285

262286
// Initialize status bar (pass m as help provider)
263-
m.statusBar = statusbar.New(m)
287+
m.statusBar = statusbar.New(m, statusbar.WithTitle(m.appName+" "+m.appVersion))
264288

265289
// Add the initial session to the supervisor
266290
sv.AddSession(ctx, initialApp, initialApp.Session(), initialWorkingDir, cleanup)
@@ -2320,9 +2344,9 @@ func (m *appModel) View() tea.View {
23202344
// When the agent is working, a rotating spinner character is prepended so that
23212345
// terminal multiplexers (tmux) can detect activity in the pane.
23222346
func (m *appModel) windowTitle() string {
2323-
title := "docker agent"
2347+
title := m.appName
23242348
if sessionTitle := m.sessionState.SessionTitle(); sessionTitle != "" {
2325-
title = sessionTitle + " - docker agent"
2349+
title = sessionTitle + " - " + m.appName
23262350
}
23272351
if m.chatPage.IsWorking() {
23282352
title = spinner.Frame(m.animFrame) + " " + title

0 commit comments

Comments
 (0)