sessions_cli.go RawHistoryFolder
1package styles
2
3import (
4 "fmt"
5 "strings"
6
7 "github.com/bnema/dumber/internal/application/usecase"
8 "github.com/bnema/dumber/internal/domain/entity"
9)
10
11// SessionsCLIRenderer renders non-interactive CLI output for sessions subcommands
12// (e.g. `dumber sessions list`, `restore`, `delete`).
13type SessionsCLIRenderer struct {
14 theme *Theme
15}
16
17func NewSessionsCLIRenderer(theme *Theme) *SessionsCLIRenderer {
18 return &SessionsCLIRenderer{theme: theme}
19}
20
21func (r *SessionsCLIRenderer) RenderEmptyList() string {
22 return r.theme.Subtle.Render("No saved sessions found.")
23}
24
25func (r *SessionsCLIRenderer) RenderList(items []entity.SessionInfo, limit int) string {
26 if len(items) == 0 {
27 return r.RenderEmptyList()
28 }
29
30 var b strings.Builder
31 title := fmt.Sprintf("%s %s", r.theme.Highlight.Render(IconSessionStack), r.theme.Title.Render("Sessions"))
32 b.WriteString(title)
33 if limit > 0 {
34 b.WriteString(r.theme.Subtle.Render(fmt.Sprintf(" (showing up to %d)", limit)))
35 }
36 b.WriteString("\n\n")
37
38 for _, s := range items {
39 b.WriteString(r.renderOne(s))
40 b.WriteString("\n")
41 }
42
43 b.WriteString("\n")
44 b.WriteString(r.theme.Subtle.Render("Tip: use `dumber sessions` for the interactive browser."))
45 return b.String()
46}
47
48func (r *SessionsCLIRenderer) renderOne(info entity.SessionInfo) string {
49 status := " "
50 statusStyle := r.theme.Subtle
51 switch {
52 case info.IsCurrent:
53 status = "●"
54 statusStyle = r.theme.Highlight
55 case info.IsActive:
56 status = "○"
57 statusStyle = r.theme.Subtle
58 }
59
60 id := r.theme.Highlight.Render(string(info.Session.ID))
61 tabs := r.theme.BadgeMuted.Render(fmt.Sprintf("%d tabs", info.TabCount))
62 panes := r.theme.BadgeMuted.Render(fmt.Sprintf("%d panes", info.PaneCount))
63 updated := r.theme.Subtle.Render(usecase.GetRelativeTime(info.UpdatedAt))
64
65 return fmt.Sprintf("%s %s %s %s %s",
66 statusStyle.Render(status),
67 id,
68 tabs,
69 panes,
70 updated,
71 )
72}
73
74func (r *SessionsCLIRenderer) RenderRestoreStarted(sessionID entity.SessionID) string {
75 return fmt.Sprintf("%s Restoring session %s...",
76 r.theme.SuccessStyle.Render(IconRestore),
77 r.theme.Highlight.Render(string(sessionID)),
78 )
79}
80
81func (r *SessionsCLIRenderer) RenderDeleted(sessionID entity.SessionID) string {
82 return fmt.Sprintf("%s Session %s deleted.",
83 r.theme.SuccessStyle.Render(IconCheck),
84 r.theme.Highlight.Render(string(sessionID)),
85 )
86}
87
88func (r *SessionsCLIRenderer) RenderError(err error) string {
89 return fmt.Sprintf("%s %v", r.theme.ErrorStyle.Render(IconX), err)
90}