@@ -2,7 +2,6 @@ package cmd
22
33import (
44 "fmt"
5- "strconv"
65 "strings"
76 "sync"
87 "time"
@@ -15,14 +14,6 @@ func formatCents(cents int) string {
1514 return fmt .Sprintf ("$%.2f" , float64 (cents )/ 100 )
1615}
1716
18- func formatSubtotal (s string ) string {
19- v , err := strconv .ParseFloat (s , 64 )
20- if err != nil {
21- return "$" + s
22- }
23- return fmt .Sprintf ("$%.2f" , v )
24- }
25-
2617func shortDate (raw string ) string {
2718 t , err := time .Parse (time .RFC3339Nano , raw )
2819 if err != nil {
@@ -41,11 +32,11 @@ ink whoami --json`,
4132 client := newClient ()
4233
4334 var (
44- result * gql.AccountStatusResponse
45- accErr error
46- usage * gql.UsageBillBreakdownResponse
47- usageErr error
48- wg sync.WaitGroup
35+ result * gql.AccountStatusResponse
36+ accErr error
37+ wsList * gql.ListWorkspacesResponse
38+ wsErr error
39+ wg sync.WaitGroup
4940 )
5041
5142 wg .Add (2 )
@@ -55,7 +46,7 @@ ink whoami --json`,
5546 }()
5647 go func () {
5748 defer wg .Done ()
58- usage , usageErr = gql .UsageBillBreakdown (ctx (), client , wsPtr () )
49+ wsList , wsErr = gql .ListWorkspaces (ctx (), client )
5950 }()
6051 wg .Wait ()
6152
@@ -68,10 +59,44 @@ ink whoami --json`,
6859 fatal ("Could not fetch account" )
6960 }
7061
62+ // Fetch billing for each workspace in parallel
63+ type wsBilling struct {
64+ slug string
65+ data * gql.UsageBillBreakdownResponse
66+ }
67+ var billings []wsBilling
68+ if wsErr == nil && len (wsList .WorkspaceList ) > 0 {
69+ billings = make ([]wsBilling , len (wsList .WorkspaceList ))
70+ var bwg sync.WaitGroup
71+ for i , ws := range wsList .WorkspaceList {
72+ billings [i ].slug = ws .Slug
73+ bwg .Add (1 )
74+ go func (idx int , slug string ) {
75+ defer bwg .Done ()
76+ s := slug
77+ billings [idx ].data , _ = gql .UsageBillBreakdown (ctx (), client , & s )
78+ }(i , ws .Slug )
79+ }
80+ bwg .Wait ()
81+ }
82+
7183 if jsonOutput {
7284 out := map [string ]any {"account" : a }
73- if usageErr == nil {
74- out ["usage" ] = usage .UsageBillBreakdown
85+ if wsErr == nil {
86+ out ["workspaces" ] = wsList .WorkspaceList
87+ }
88+ if len (billings ) > 0 {
89+ bmap := make (map [string ]any )
90+ for _ , b := range billings {
91+ if b .data != nil {
92+ bmap [b .slug ] = b .data .UsageBillBreakdown
93+ }
94+ }
95+ out ["billing" ] = bmap
96+ }
97+ out ["config" ] = map [string ]string {
98+ "workspace" : cfg .Workspace ,
99+ "project" : cfg .Project ,
75100 }
76101 printJSON (out )
77102 return
@@ -81,24 +106,49 @@ ink whoami --json`,
81106 if a .Email != nil {
82107 d .kv ("Email" , * a .Email )
83108 }
84- d .kv ("Workspace" , a .DefaultWorkspace )
85109
86110 tier := "free"
87111 if a .SubscriptionTier != nil {
88112 tier = * a .SubscriptionTier
89113 }
90114 d .kv ("Plan" , tier )
91115
92- // Usage / Billing
93- if usageErr == nil {
94- u := usage .UsageBillBreakdown
95- period := shortDate (u .PeriodStart ) + " – " + shortDate (u .PeriodEnd )
116+ // Config
117+ d .blank ()
118+ d .section ("Config" )
119+ cfgWs := cfg .Workspace
120+ if cfgWs == "" {
121+ cfgWs = dim .Render ("(default)" )
122+ }
123+ d .kv ("Workspace" , cfgWs )
124+ cfgProj := cfg .Project
125+ if cfgProj == "" {
126+ cfgProj = dim .Render ("(default)" )
127+ }
128+ d .kv ("Project" , cfgProj )
129+
130+ // Workspaces
131+ if wsErr == nil && len (wsList .WorkspaceList ) > 0 {
96132 d .blank ()
97- d .section ("Usage (" + period + ")" )
98- d .kv ("Current Usage" , formatSubtotal (u .Subtotal ))
99- d .kv ("Current Bill" , formatCents (u .CurrentBillCents ))
100- if u .IncludedUsageCents > 0 {
101- d .kv ("Included" , formatCents (u .IncludedUsageCents ))
133+ d .section ("Workspaces" )
134+
135+ // Build billing lookup
136+ billingMap := make (map [string ]* gql.UsageBillBreakdownResponse )
137+ for _ , b := range billings {
138+ if b .data != nil {
139+ billingMap [b .slug ] = b .data
140+ }
141+ }
142+
143+ for _ , ws := range wsList .WorkspaceList {
144+ role := dim .Render (ws .Role )
145+ line := role
146+ if b , ok := billingMap [ws .Slug ]; ok {
147+ u := b .UsageBillBreakdown
148+ period := shortDate (u .PeriodStart ) + " – " + shortDate (u .PeriodEnd )
149+ line += " " + formatCents (u .CurrentBillCents ) + " " + dim .Render (period )
150+ }
151+ d .kv (ws .Slug , line )
102152 }
103153 }
104154
0 commit comments