@@ -5,28 +5,41 @@ import (
55 "encoding/json"
66 "fmt"
77 "io"
8+ "os"
89
910 "github.com/jgfranco17/delphi-cli/internal/tooling/git"
1011 "github.com/jgfranco17/delphi-cli/internal/tooling/model"
1112)
1213
13- // Renderer writes a formatted statusline to an io.Writer.
14- type Renderer struct {
15- out io.Writer
16- git git.Provider
14+ // StatusLine writes a formatted statusline to a writer.
15+ type StatusLine struct {
16+ out io.Writer
17+ git git.Provider
18+ options Options
1719}
1820
19- func NewRenderer (out io.Writer , g git.Provider ) * Renderer {
20- return & Renderer {out : out , git : g }
21+ type Options struct {
22+ OutputWriter io.Writer
23+ WithCurrentDir bool
24+ WithGitInfo bool
25+ WithUsageStats bool
2126}
2227
23- // New creates a Renderer with the real git provider writing to out.
24- func New (out io.Writer ) * Renderer {
25- return NewRenderer (out , git .NewExecProvider ())
28+ func newRenderer (out io.Writer , g git.Provider , opts Options ) * StatusLine {
29+ return & StatusLine {out : out , git : g , options : opts }
30+ }
31+
32+ // New creates a StatusLine with the real git provider writing to out.
33+ func New (opts Options ) * StatusLine {
34+ out := opts .OutputWriter
35+ if out == nil {
36+ out = os .Stdout
37+ }
38+ return newRenderer (out , git .NewExecProvider (), opts )
2639}
2740
2841// GenerateFrom decodes JSON from r and renders the statusline.
29- func (r * Renderer ) GenerateFrom (ctx context.Context , reader io.Reader ) error {
42+ func (r * StatusLine ) GenerateFrom (ctx context.Context , reader io.Reader ) error {
3043 data , err := io .ReadAll (reader )
3144 if err != nil {
3245 return fmt .Errorf ("failed reading input: %w" , err )
@@ -38,40 +51,51 @@ func (r *Renderer) GenerateFrom(ctx context.Context, reader io.Reader) error {
3851 return r .Render (ctx , & input )
3952}
4053
41- // Render writes the three-line statusline for the given input.
42- func (r * Renderer ) Render (ctx context.Context , input * model.AgentInput ) error {
43- pct := int (input .ContextWindow .UsedPercentage )
44- bar := input .ContextWindow .Render ()
45- costFmt := input .Cost .Format ()
46- limits := input .RateLimits .Format ()
47- gitInfo := r .formatGitInfo (ctx , input .Workspace .CurrentDir )
48-
49- fmt .Fprintf (
50- r .out , "%s %s %s %s\n " ,
51- model .ColorDim .Sprint ("Using" ),
52- model .ColorBoldCyan .Sprint (input .Model .DisplayName ),
53- model .ColorDim .Sprint ("in" ),
54- model .ColorYellow .Sprint (input .Workspace .CurrentDir ),
55- )
56- fmt .Fprintf (
57- r .out , "%s %s %s %s %s %s %s\n " ,
58- model .ColorDim .Sprint ("Usage:" ),
59- input .ContextWindow .Color ().Sprint (bar ),
60- model .ColorBold .Sprintf ("%d%%" , pct ),
61- model .ColorDim .Sprint ("|" ),
62- model .ColorGreen .Sprintf ("~%s equiv" , costFmt ),
63- model .ColorDim .Sprint ("|" ),
64- model .ColorMagenta .Sprint (limits ),
65- )
66- fmt .Fprintf (
67- r .out , "%s %s\n " ,
68- model .ColorDim .Sprint ("Git:" ),
69- gitInfo ,
70- )
54+ // Render writes the statusline for the given input, gated by Options.
55+ func (r * StatusLine ) Render (ctx context.Context , input * model.AgentInput ) error {
56+ if r .options .WithCurrentDir {
57+ fmt .Fprintf (
58+ r .out , "%s %s %s %s\n " ,
59+ model .ColorDim .Sprint ("Using" ),
60+ model .ColorBoldCyan .Sprint (input .Model .DisplayName ),
61+ model .ColorDim .Sprint ("in" ),
62+ model .ColorYellow .Sprint (input .Workspace .CurrentDir ),
63+ )
64+ } else {
65+ fmt .Fprintf (
66+ r .out , "%s %s\n " ,
67+ model .ColorDim .Sprint ("Using" ),
68+ model .ColorBoldCyan .Sprint (input .Model .DisplayName ),
69+ )
70+ }
71+ if r .options .WithUsageStats {
72+ pct := int (input .ContextWindow .UsedPercentage )
73+ bar := input .ContextWindow .Render ()
74+ costFmt := input .Cost .Format ()
75+ limits := input .RateLimits .Format ()
76+ fmt .Fprintf (
77+ r .out , "%s %s %s %s %s %s %s\n " ,
78+ model .ColorDim .Sprint ("Usage:" ),
79+ input .ContextWindow .Color ().Sprint (bar ),
80+ model .ColorBold .Sprintf ("%d%%" , pct ),
81+ model .ColorDim .Sprint ("|" ),
82+ model .ColorGreen .Sprintf ("~%s equiv" , costFmt ),
83+ model .ColorDim .Sprint ("|" ),
84+ model .ColorMagenta .Sprint (limits ),
85+ )
86+ }
87+ if r .options .WithGitInfo {
88+ gitInfo := r .formatGitInfo (ctx , input .Workspace .CurrentDir )
89+ fmt .Fprintf (
90+ r .out , "%s %s\n " ,
91+ model .ColorDim .Sprint ("Git:" ),
92+ gitInfo ,
93+ )
94+ }
7195 return nil
7296}
7397
74- func (r * Renderer ) formatGitInfo (ctx context.Context , dir string ) string {
98+ func (r * StatusLine ) formatGitInfo (ctx context.Context , dir string ) string {
7599 branch , dirty , err := r .git .BranchStatus (ctx , dir )
76100 if err != nil || branch == "" {
77101 return "none"
0 commit comments