From 7f3a910f0d38b0269b59198bed91487ed716773c Mon Sep 17 00:00:00 2001 From: lawrencecchen <54008264+lawrencecchen@users.noreply.github.com> Date: Wed, 5 Aug 2026 00:35:04 -0700 Subject: [PATCH 1/2] test: cover hosted default dashboard --- cmd/subrouter/sr_hosted_login_test.go | 58 +++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/cmd/subrouter/sr_hosted_login_test.go b/cmd/subrouter/sr_hosted_login_test.go index cb8bac6c7..e5cc11b57 100644 --- a/cmd/subrouter/sr_hosted_login_test.go +++ b/cmd/subrouter/sr_hosted_login_test.go @@ -226,6 +226,64 @@ func TestHostedCodexAddUsesTemporaryHomeAndUploadsCredential(t *testing.T) { } } +func TestHostedDefaultOutputUsesUsageDashboard(t *testing.T) { + t.Setenv("HOME", t.TempDir()) + t.Setenv("COLUMNS", "160") + tenantKey := "srt_0123456789abcdef0123456789abcdef" + var requests int + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + requests++ + if r.Method != http.MethodGet || r.URL.Path != "/t/"+tenantKey+"/_subrouter/usage-status" { + http.Error(w, "unexpected request", http.StatusBadRequest) + return + } + _ = json.NewEncoder(w).Encode([]broker.UsageStatus{{ + ID: "hosted@example.com", Provider: accounts.ProviderCodex, + AuthMode: accounts.AuthModeOAuth, Email: "hosted@example.com", + AuthChecked: true, AuthValid: true, PlanType: "pro", + Windows: []accounts.UsageWindow{{ + Name: "weekly", UsedPercent: 25, + LimitWindowSeconds: int64((7 * 24 * time.Hour) / time.Second), + }}, + }}) + })) + defer server.Close() + + configPath := filepath.Join(t.TempDir(), "cloud.json") + t.Setenv("SUBROUTER_CLOUD_CONFIG", configPath) + if err := broker.SaveConfig(configPath, broker.Config{ + Version: 1, BaseURL: "https://cmux.com", + AccessToken: "access", RefreshToken: "refresh", + TeamID: "team-1", TeamName: "Hosted team", + CredentialSource: broker.CredentialSourceHosted, + HostedURL: server.URL, TenantKey: tenantKey, + }); err != nil { + t.Fatal(err) + } + + var output bytes.Buffer + runner := srRunner{ + program: "sr", store: accounts.CodexStore{Dir: t.TempDir()}, + out: &output, errOut: &output, + } + if err := runner.run(context.Background(), nil); err != nil { + t.Fatal(err) + } + if requests != 1 { + t.Fatalf("usage requests = %d, want 1", requests) + } + for _, want := range []string{ + "Credential storage: hosted cmux (Hosted team, team-1)", + "Codex accounts", + "hosted@example.com", + "75% left", + } { + if !strings.Contains(output.String(), want) { + t.Fatalf("hosted dashboard missing %q:\n%s", want, output.String()) + } + } +} + func TestHostedAndLocalEgressStorageAliasesStayDistinct(t *testing.T) { for _, value := range []string{"hosted", "cmux", "cloud"} { got, err := parseCredentialSource(value, false) From 3951eb1271c8d271a291e850aab8226fe39ac535 Mon Sep 17 00:00:00 2001 From: lawrencecchen <54008264+lawrencecchen@users.noreply.github.com> Date: Wed, 5 Aug 2026 00:35:41 -0700 Subject: [PATCH 2/2] fix: show hosted usage by default --- cmd/subrouter/sr.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmd/subrouter/sr.go b/cmd/subrouter/sr.go index a17910ba2..f94485374 100644 --- a/cmd/subrouter/sr.go +++ b/cmd/subrouter/sr.go @@ -747,7 +747,7 @@ func (r srRunner) status(ctx context.Context) error { return err } switch config.EffectiveCredentialSource() { - case broker.CredentialSourceTeam: + case broker.CredentialSourceTeam, broker.CredentialSourceHosted: return r.cloudStatus(ctx) case broker.CredentialSourceLegacy: if server, ok, err := r.defaultRemoteServer(); err != nil { @@ -827,7 +827,7 @@ func (r srRunner) defaultInteractive(ctx context.Context, opts srSwitchOptions) return err } switch config.EffectiveCredentialSource() { - case broker.CredentialSourceTeam: + case broker.CredentialSourceTeam, broker.CredentialSourceHosted: return r.cloudStatus(ctx) case broker.CredentialSourceLegacy: if server, ok, err := r.defaultRemoteServer(); err != nil {