pi-provider-qoder-cn 0.2.18 → 0.2.19

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/README.md +8 -0
  2. package/dist/index.js +27 -15
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -133,6 +133,14 @@ Notes:
133
133
  agree with the numbers on the same row. The API's own `percentage` field is a
134
134
  0-1 fraction (94% arrives as `0.94`) and is only used — scaled by 100 — when a
135
135
  bucket comes back without numbers.
136
+ - `Add-on expiry` is only printed when a real check-in grant exists. A pool that
137
+ is a whole stack of daily grant packs (never more packs than the validity
138
+ window holds) is laid out as `Rolling 30d · earliest of N daily 100-credit
139
+ packs ~DATE`. A pool that is not one (a purchased top-up, or a leftover
140
+ remainder) prints only the expiry the campaign actually reported, `DATE ·
141
+ latest grant`, and an account that has never claimed prints no expiry line at
142
+ all, because with no grant there is nothing to date from, and inventing one
143
+ would show dates the API never sent.
136
144
  - `Expires never` means the API reported the year-9999 sentinel, i.e. the
137
145
  allowance has no expiry date.
138
146
  - `Note plan quota is prorated` appears after a mid-cycle plan change.
package/dist/index.js CHANGED
@@ -2402,30 +2402,39 @@ function isCredentialExpiredError(error) {
2402
2402
 
2403
2403
  // src/commands/usage.ts
2404
2404
  init_region();
2405
- function estimateRollingAddOnExpiry(addOn, latestExpiryMs, now = Date.now()) {
2405
+ var DEFAULT_GRANT_CREDITS = 100;
2406
+ var DEFAULT_GRANT_VALIDITY_DAYS = 30;
2407
+ function positiveOr(value, fallback) {
2408
+ return typeof value === "number" && Number.isFinite(value) && value > 0 ? value : fallback;
2409
+ }
2410
+ function estimateRollingAddOnExpiry(addOn, grant, now = Date.now()) {
2406
2411
  if (!addOn || !addOn.total || addOn.total <= 0 || !addOn.remaining || addOn.remaining <= 0) {
2407
2412
  return null;
2408
2413
  }
2409
- const packSize = 100;
2410
- const totalPacks = Math.max(1, Math.round(addOn.total / packSize));
2411
- if (totalPacks > 50) return null;
2414
+ const shape = typeof grant === "number" ? { expiryMs: grant } : grant ?? {};
2415
+ const packSize = positiveOr(shape.amount, DEFAULT_GRANT_CREDITS);
2416
+ const validityDays = positiveOr(shape.validityDays, DEFAULT_GRANT_VALIDITY_DAYS);
2417
+ const anchorMs = shape.expiryMs;
2418
+ if (typeof anchorMs !== "number" || !Number.isFinite(anchorMs) || anchorMs <= now) return null;
2419
+ if (addOn.total % packSize !== 0) return null;
2420
+ const totalPacks = Math.round(addOn.total / packSize);
2421
+ if (totalPacks < 1 || totalPacks > validityDays) return null;
2412
2422
  const used = Math.max(0, addOn.used ?? 0);
2413
2423
  const consumedPacks = Math.min(totalPacks - 1, Math.floor(used / packSize));
2414
- const earliestActiveIndex = consumedPacks;
2415
- const daysAgoClaimed = totalPacks - 1 - earliestActiveIndex;
2416
- const anchorExpiryMs = latestExpiryMs && Number.isFinite(latestExpiryMs) ? latestExpiryMs : now + 30 * 864e5;
2417
- const earliestMs = anchorExpiryMs - daysAgoClaimed * 864e5;
2424
+ const daysAgoClaimed = totalPacks - 1 - consumedPacks;
2425
+ const earliestMs = anchorMs - daysAgoClaimed * 864e5;
2418
2426
  const daysRemaining = Math.max(0, Math.round((earliestMs - now) / 864e5));
2419
2427
  const earliestRemaining = Math.min(addOn.remaining, packSize - used % packSize);
2420
2428
  const d = new Date(earliestMs);
2421
- const earliestDate = d.toISOString().slice(0, 10);
2422
2429
  return {
2423
- earliestDate,
2430
+ earliestDate: d.toISOString().slice(0, 10),
2424
2431
  earliestMs,
2425
2432
  earliestRemaining,
2426
2433
  totalPacks,
2427
2434
  consumedPacks,
2428
- daysRemaining
2435
+ daysRemaining,
2436
+ packSize,
2437
+ validityDays
2429
2438
  };
2430
2439
  }
2431
2440
  var ANSI2 = {
@@ -2607,14 +2616,17 @@ function formatQoderUsage(raw, mode, now = Date.now(), options = {}) {
2607
2616
  }
2608
2617
  const addOn = pickBucket2(raw, "addOnQuota");
2609
2618
  if (showAddOnQuota && (addOn?.remaining ?? 0) > 0 && checkin) {
2610
- const latestExpiryMs = checkin.expiresAt ? Date.parse(checkin.expiresAt) : void 0;
2611
- const estimate = estimateRollingAddOnExpiry(addOn, latestExpiryMs, now);
2619
+ const expiryMs = checkin.expiresAt ? Date.parse(checkin.expiresAt) : void 0;
2620
+ const grant = { expiryMs, amount: checkin.amount, validityDays: checkin.validityDays };
2621
+ const estimate = estimateRollingAddOnExpiry(addOn, grant, now);
2612
2622
  if (estimate) {
2613
- const earliestText = estimate.totalPacks > 1 ? `earliest active pack ~${estimate.earliestDate} \xB7 in ~${estimate.daysRemaining}d (~${formatAmount(estimate.earliestRemaining)} credits)` : `${estimate.earliestDate} (in ${estimate.daysRemaining}d)`;
2623
+ const expiryText = estimate.totalPacks > 1 ? `earliest of ${estimate.totalPacks} daily ${estimate.packSize}-credit packs ~${estimate.earliestDate} (in ~${estimate.daysRemaining}d, ~${formatAmount(estimate.earliestRemaining)} credits)` : `${estimate.earliestDate} (in ${estimate.daysRemaining}d)`;
2614
2624
  notes.push({
2615
2625
  label: "Add-on expiry",
2616
- value: `Rolling 30d (${earliestText})`
2626
+ value: `Rolling ${estimate.validityDays}d \xB7 ${expiryText}`
2617
2627
  });
2628
+ } else if (typeof expiryMs === "number" && Number.isFinite(expiryMs) && expiryMs > now) {
2629
+ notes.push({ label: "Add-on expiry", value: `${formatResetTime(expiryMs, now)} \xB7 latest grant` });
2618
2630
  }
2619
2631
  }
2620
2632
  notes.push({ label: "Expires", value: formatResetTime(raw?.expiresAt, now) });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-provider-qoder-cn",
3
- "version": "0.2.18",
3
+ "version": "0.2.19",
4
4
  "description": "Pi extension for Qoder CN — PAT/OAuth auth, /qoder-cn.usage quota command, and enterprise VPC endpoint support",
5
5
  "type": "module",
6
6
  "license": "MIT",