11package tui
22
33import (
4+ "os"
45 "strings"
56
67 "github.com/charmbracelet/lipgloss"
@@ -22,38 +23,65 @@ var (
2223)
2324
2425// welcome renders the splash shown in the conversation area before the first
25- // prompt: the wordmark, a tagline, and a few key bindings.
26- func welcome (th theme , width int ) string {
26+ // prompt: the wordmark, a tagline, the working directory, and a few key
27+ // bindings — left-aligned with a gentle margin.
28+ func welcome (th theme , width int , cwd string ) string {
2729 var b strings.Builder
2830 for _ , line := range bannerArt {
2931 b .WriteString (gradient (line , gradFrom , gradTo ))
3032 b .WriteByte ('\n' )
3133 }
3234 b .WriteByte ('\n' )
3335 b .WriteString (th .tagline .Render ("a beautiful terminal interface for the odek agent" ))
34- b .WriteString ("\n \n " )
36+ b .WriteByte ('\n' )
37+ if dir := shortenHome (cwd ); dir != "" {
38+ b .WriteString (th .statsDim .Render (dir ))
39+ b .WriteByte ('\n' )
40+ }
41+ b .WriteByte ('\n' )
3542
43+ // key column is right-aligned to a fixed width so the descriptions line up.
3644 tips := [][2 ]string {
3745 {"type a task" , "and press enter to run the agent" },
3846 {"/ commands" , "type / for commands, e.g. /help /sessions /model" },
47+ {"/stats" , "session metrics & live context-window gauge" },
3948 {"@ to attach" , "attach files, e.g. @main.go" },
4049 {"⏎ send" , "· ^J newline · ^T toggle thinking" },
4150 {"^L clear" , "· PgUp/PgDn scroll · ^C quit" },
4251 {"approvals" , "answer with [a]pprove [d]eny [t]rust" },
4352 }
53+ const keyW = 11
4454 for _ , t := range tips {
45- b .WriteString (" " + th .tipKey .Render (pad (t [0 ], 12 )) + th .tipText .Render (t [1 ]) + "\n " )
55+ b .WriteString (th .tipKey .Render (padLeft (t [0 ], keyW )) + " " + th .tipText .Render (t [1 ]) + "\n " )
4656 }
4757
48- block := b .String ()
49- // Center the splash block within the available width for a polished look .
50- return lipgloss .NewStyle ().Width (width ).Align ( lipgloss . Center ).Render (block )
58+ block := strings . TrimRight ( b .String (), " \n " )
59+ // Left-aligned (no centering) with a small left margin for breathing room .
60+ return lipgloss .NewStyle ().Width (width ).PaddingLeft ( 2 ).Render (block )
5161}
5262
53- // pad right-pads s with spaces to width n.
54- func pad (s string , n int ) string {
55- if lipgloss .Width (s ) >= n {
63+ // padLeft left-pads s with spaces to width n (right-aligns within the column).
64+ func padLeft (s string , n int ) string {
65+ w := lipgloss .Width (s )
66+ if w >= n {
5667 return s
5768 }
58- return s + strings .Repeat (" " , n - lipgloss .Width (s ))
69+ return strings .Repeat (" " , n - w ) + s
70+ }
71+
72+ // shortenHome replaces a leading $HOME with "~" for a compact, readable path.
73+ func shortenHome (p string ) string {
74+ p = strings .TrimSpace (p )
75+ if p == "" {
76+ return ""
77+ }
78+ if home , err := os .UserHomeDir (); err == nil && home != "" {
79+ if p == home {
80+ return "~"
81+ }
82+ if strings .HasPrefix (p , home + string (os .PathSeparator )) {
83+ return "~" + p [len (home ):]
84+ }
85+ }
86+ return p
5987}
0 commit comments