commandcode: a plan's usage says its plan (为什么Command Code Plan没有用量?) — billing/credits has no planId, so the plan (and the account's badge) came up empty; it's read from billing/subscriptions: planId, currentPeriodEnd as when it ends, cancelAtPeriodEnd as whether it renews, and an account with none is "No plan" (无订阅). The plan is said even when billing/credits fails — Command Code answers it 503, "Couldn't verify your credit balance just now", at times — and an account with a balance but no 5-hour or weekly window shows the balance instead of 暂无用量数据. Checked against a live GOAT account: GOAT, $70.00, both windows
This commit is contained in:
4 files changed
+61
-9
No files matched your search
@@ -1594,7 +1594,7 @@ function accountPlan(a) {
|
||||
if (a.agent === "gemini" || a.agent === "antigravity") return a.plan || "Google";
|
||||
if (a.agent === "zcode") return a.plan || "GLM Coding Plan";
|
||||
if (a.agent === "workbuddy") return a.plan || "WorkBuddy";
|
||||
if (a.agent === "commandcode-plan") return "Command Code" + (a.plan ? " " + a.plan : "");
|
||||
if (a.agent === "commandcode-plan") return "Command Code" + (a.plan ? " " + t(a.plan) : "");
|
||||
return t("signed in");
|
||||
}
|
||||
|
||||
@@ -3765,8 +3765,15 @@ function accountQuota(data, user) {
|
||||
return line;
|
||||
}
|
||||
const q = data[user];
|
||||
// an account on no plan says so, whatever else can be read of it
|
||||
const noPlan = q?.plan === "No plan" ? [t("No plan")] : [];
|
||||
if (q && !q.error && !q.windows?.length && q.balance) {
|
||||
// no rolling limits, only what is left to spend
|
||||
line.append(el("span", "aq-none", [...noPlan, t("Balance") + " " + q.balance].join(" · ")));
|
||||
return line;
|
||||
}
|
||||
if (!q || q.error || !q.windows?.length) {
|
||||
line.append(el("span", "aq-none", q?.error ? quotaError(q.error) : t("No usage reported")));
|
||||
line.append(el("span", "aq-none", [...noPlan, q?.error ? quotaError(q.error) : t("No usage reported")].join(" · ")));
|
||||
if (q?.error) line.title = q.error;
|
||||
return line;
|
||||
}
|
||||
|
||||
@@ -263,6 +263,7 @@ const I18N = {
|
||||
"Stop using this account": "停用这个账号",
|
||||
"Use this account too": "同时启用这个账号",
|
||||
"No usage reported": "暂无用量数据",
|
||||
"No plan": "无订阅",
|
||||
"resets {in}": "{in}重置",
|
||||
"in {n}m": "{n} 分钟后",
|
||||
"in {n}h": "{n} 小时后",
|
||||
|
||||
@@ -277,12 +277,47 @@ func cmdQuotaOf(q SubscriptionQuota, c cmdCredits) SubscriptionQuota {
|
||||
|
||||
func cmdQuota(ctx context.Context, l Login, a cmdAuth) SubscriptionQuota {
|
||||
q := SubscriptionQuota{Provider: CommandCodePlanID, Name: "Command Code", Icon: "commandcode", Plan: l.Plan, User: l.User, Windows: []QuotaWindow{}}
|
||||
// the plan is said even while the credits can't be read (Command Code
|
||||
// answers 503, "Couldn't verify your credit balance just now", at times)
|
||||
plan, until, renew, planOK := cmdSubscription(ctx, a)
|
||||
var c cmdCredits
|
||||
if err := accountJSON(ctx, cmdAPI+"/alpha/billing/credits", a.APIKey, nil, &c); err != nil {
|
||||
q.Error = err.Error()
|
||||
return q
|
||||
} else {
|
||||
q = cmdQuotaOf(q, c)
|
||||
}
|
||||
return cmdQuotaOf(q, c)
|
||||
if planOK {
|
||||
q.Plan, q.Until, q.Renew = plan, until, renew
|
||||
}
|
||||
return q
|
||||
}
|
||||
|
||||
// cmdNoPlan is the plan of an account with no subscription: its key is
|
||||
// billed against the credits it bought, if any.
|
||||
const cmdNoPlan = "No plan"
|
||||
|
||||
// cmdSubscription is the account's plan, when its period ends and whether
|
||||
// it renews then, as billing/subscriptions says; cmdNoPlan when it has
|
||||
// none. ok is false when that can't be read.
|
||||
func cmdSubscription(ctx context.Context, a cmdAuth) (plan string, until *time.Time, renew string, ok bool) {
|
||||
var r struct {
|
||||
Data *struct {
|
||||
PlanID string `json:"planId"`
|
||||
Status string `json:"status"`
|
||||
CurrentPeriodEnd any `json:"currentPeriodEnd"`
|
||||
CancelAtEnd *bool `json:"cancelAtPeriodEnd"`
|
||||
} `json:"data"`
|
||||
}
|
||||
if accountJSON(ctx, cmdAPI+"/alpha/billing/subscriptions", a.APIKey, nil, &r) != nil {
|
||||
return "", nil, "", false
|
||||
}
|
||||
if d := r.Data; d != nil && d.PlanID != "" && d.Status != "canceled" && d.Status != "incomplete_expired" {
|
||||
if d.CancelAtEnd != nil {
|
||||
renew = map[bool]string{true: "off", false: "auto"}[*d.CancelAtEnd]
|
||||
}
|
||||
return firstNonEmpty(cmdPlanName(d.PlanID), d.PlanID), cmdTime(d.CurrentPeriodEnd), renew, true
|
||||
}
|
||||
return cmdNoPlan, nil, "", true
|
||||
}
|
||||
|
||||
func cmdLoginQuota(ctx context.Context, l Login) SubscriptionQuota {
|
||||
@@ -461,9 +496,8 @@ func cmdSignedIn(ctx context.Context, a cmdAuth) (who, plan string, err error) {
|
||||
if who == "" {
|
||||
return "", "", fmt.Errorf("Command Code didn't say which account signed in")
|
||||
}
|
||||
var c cmdCredits
|
||||
if accountJSON(ctx, cmdAPI+"/alpha/billing/credits", a.APIKey, nil, &c) == nil {
|
||||
plan = cmdPlanName(c.Credits.PlanID)
|
||||
if p, _, _, ok := cmdSubscription(ctx, a); ok {
|
||||
plan = p
|
||||
}
|
||||
return who, plan, nil
|
||||
}
|
||||
@@ -29,6 +29,12 @@ func TestCommandCodePlan(t *testing.T) {
|
||||
switch r.URL.Path {
|
||||
case "/alpha/whoami":
|
||||
ok(map[string]any{"user": map[string]any{"id": "u2", "userName": "two", "email": "two@example.com"}})
|
||||
case "/alpha/billing/subscriptions":
|
||||
if key == "own-key" { // as for an account with no plan
|
||||
ok(map[string]any{"success": true, "data": nil})
|
||||
return
|
||||
}
|
||||
ok(map[string]any{"success": true, "data": map[string]any{"planId": "individual-max-monthly", "status": "active", "currentPeriodEnd": "2026-10-28T00:00:00Z", "cancelAtPeriodEnd": true}})
|
||||
case "/alpha/billing/credits":
|
||||
ok(map[string]any{
|
||||
"credits": map[string]any{"planId": "individual-max-monthly", "monthlyCredits": 150.5, "purchasedCredits": 10, "freeCredits": 0},
|
||||
@@ -122,8 +128,12 @@ func TestCommandCodePlan(t *testing.T) {
|
||||
q.Windows[0].ResetsAt.Unix() != reset {
|
||||
t.Fatalf("usage: %+v", q)
|
||||
}
|
||||
if !strings.Contains(q.Balance, "160.5") {
|
||||
t.Fatalf("balance: %q", q.Balance)
|
||||
if !strings.Contains(q.Balance, "160.5") || q.Until == nil || q.Until.Format("2006-01-02") != "2026-10-28" || q.Renew != "off" {
|
||||
t.Fatalf("balance, period: %q %v", q.Balance, q.Until)
|
||||
}
|
||||
// an account with no subscription says so
|
||||
if q := LoginUsage(context.Background(), CommandCodePlanID)["ownuser"]; q.Error != "" || q.Plan != "No plan" || q.Balance == "" {
|
||||
t.Fatalf("no plan: %+v", q)
|
||||
}
|
||||
|
||||
if err := ForgetLogin(CommandCodePlanID, "ownuser"); err == nil {
|
||||
|
||||
Reference in new issue
Block a user