Skip to content

Commit cc6b12d

Browse files
committed
sr: restart account numbering per provider group in status view
The bare 'sr' status view numbered accounts continuously across providers (1..27). Restart at 1 for each group (Codex 1..N, Claude 1..M, etc.) so each category's count is obvious. The interactive switch picker keeps global numbering because it selects an account by that index; per-group numbering is a new display-only mode used by the status view.
1 parent 1640340 commit cc6b12d

3 files changed

Lines changed: 54 additions & 4 deletions

File tree

cmd/subrouter/sr.go

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1602,13 +1602,26 @@ func displayUsageRows(out io.Writer, rows []srUsageRow, numbered bool) {
16021602
return
16031603
}
16041604
colored := colorEnabled(out)
1605-
displayUsageRowsGrid(out, rows, numbered, colored)
1605+
displayUsageRowsGrid(out, rows, numbered, false, colored)
16061606
}
16071607

1608-
func displayUsageRowsGrid(out io.Writer, rows []srUsageRow, numbered bool, colored bool) {
1608+
// displayUsageRowsPerGroup renders the table with numbering that restarts at 1
1609+
// for each provider group. Use for the informational status view; the switch
1610+
// picker keeps global numbering because it selects an account by that index.
1611+
func displayUsageRowsPerGroup(out io.Writer, rows []srUsageRow) {
1612+
if len(rows) == 0 {
1613+
fmt.Fprintln(out, "No accounts configured. Run 'subrouter add' to add one.")
1614+
return
1615+
}
1616+
colored := colorEnabled(out)
1617+
displayUsageRowsGrid(out, rows, true, true, colored)
1618+
}
1619+
1620+
func displayUsageRowsGrid(out io.Writer, rows []srUsageRow, numbered, perGroupNumbers bool, colored bool) {
16091621
fmt.Fprintln(out)
16101622
currentGroup := ""
16111623
accountRowIndex := 0
1624+
groupRowIndex := 0
16121625
for i, row := range rows {
16131626
group := usageProviderLabel(row)
16141627
columns := usageGridColumns(out, numbered, usageProvider(row))
@@ -1622,16 +1635,22 @@ func displayUsageRowsGrid(out io.Writer, rows []srUsageRow, numbered bool, color
16221635
}, colored, "")
16231636
printUsageGridSeparator(out, columns, colored)
16241637
currentGroup = group
1638+
groupRowIndex = 0
16251639
}
16261640
rowIndex := ""
16271641
if numbered {
1628-
rowIndex = strconv.Itoa(i + 1)
1642+
if perGroupNumbers {
1643+
rowIndex = strconv.Itoa(groupRowIndex + 1)
1644+
} else {
1645+
rowIndex = strconv.Itoa(i + 1)
1646+
}
16291647
}
16301648
values := usageGridValues(row, rowIndex)
16311649
printUsageGridLine(out, columns, func(col usageGridColumn) usageGridCell {
16321650
return values[col.Key]
16331651
}, colored, usageGridRowStyle(accountRowIndex))
16341652
accountRowIndex++
1653+
groupRowIndex++
16351654
}
16361655
fmt.Fprintln(out)
16371656
if usageRowsHaveErrors(rows) {

cmd/subrouter/sr_reset_gto_test.go

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package main
22

33
import (
44
"bytes"
5+
"regexp"
56
"strings"
67
"testing"
78
"time"
@@ -186,3 +187,33 @@ func TestPrintResetCredits(t *testing.T) {
186187
t.Fatalf("totals wrong: %q", got)
187188
}
188189
}
190+
191+
func TestDisplayUsageRowsPerGroupRestartsNumbering(t *testing.T) {
192+
rem := 1
193+
rows := []srUsageRow{
194+
{email: "codexone@x.com", provider: accounts.ProviderCodex, authMode: accounts.AuthModeOAuth, complimentaryReset: &accounts.ComplimentaryResetInfo{Known: true, Remaining: &rem}},
195+
{email: "codextwo@x.com", provider: accounts.ProviderCodex, authMode: accounts.AuthModeOAuth},
196+
{email: "claudeprof", provider: accounts.ProviderClaude},
197+
}
198+
var out bytes.Buffer
199+
displayUsageRowsPerGroup(&out, rows)
200+
ansi := regexp.MustCompile(`\x1b\[[0-9;]*m`)
201+
nums := map[string]string{}
202+
for _, line := range strings.Split(ansi.ReplaceAllString(out.String(), ""), "\n") {
203+
fields := strings.Fields(line)
204+
if len(fields) < 2 {
205+
continue
206+
}
207+
for _, e := range []string{"codexone@x.com", "codextwo@x.com", "claudeprof"} {
208+
if strings.Contains(line, e) {
209+
nums[e] = fields[0]
210+
}
211+
}
212+
}
213+
if nums["codexone@x.com"] != "1" || nums["codextwo@x.com"] != "2" {
214+
t.Fatalf("codex numbering = %v, want 1,2", nums)
215+
}
216+
if nums["claudeprof"] != "1" {
217+
t.Fatalf("claude numbering = %q, want restart at 1", nums["claudeprof"])
218+
}
219+
}

cmd/subrouter/sr_server.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -522,7 +522,7 @@ func (r srRunner) serverStatus(ctx context.Context, store srServerStore, name st
522522
if available {
523523
rows := usageRowsFromServerUsageStatuses(usage)
524524
fmt.Fprintf(r.out, "Server: %s (%s)\n", server.Name, server.URL)
525-
displayUsageRows(r.out, rows, true)
525+
displayUsageRowsPerGroup(r.out, rows)
526526
printAccountCountSummary(r.out, rows)
527527
r.printBedrockStatus(ctx, server)
528528
return nil

0 commit comments

Comments
 (0)