quotacap 0.0.31 → 0.0.32

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.
@@ -22,7 +22,7 @@ function parseGroup(g, provider, rawJsonString, now) {
22
22
  throw new Error("agy: bad weekly reset_time");
23
23
  const resetsAt = resetDate.toISOString();
24
24
  const periodStart = new Date(resetDate.getTime() - 7 * 86400000).toISOString();
25
- const fiveHour = g.buckets.find((b) => b.window === "5h");
25
+ const fiveHour = g.buckets.find((b) => b.window === "5h" || b.id?.includes("5h") || /5[- ]?h|five[- ]?hour/i.test(b.name ?? ""));
26
26
  const sessionPct = fiveHour
27
27
  ? usedPctFromRemaining(fiveHour.remaining_fraction) ?? undefined
28
28
  : undefined;
@@ -1,8 +1,9 @@
1
1
  import { trackedExecFile } from "../runtime/spawn.js";
2
2
  import { parseResetText } from "./parse.js";
3
3
  export function parseClaudeUsage(result, now = new Date()) {
4
- const sessionMatch = result.match(/Current session:\s+(\d+)% used[^·]*·\s*resets\s+([^\n(]+?)\s*\(/);
5
- const weeklyMatch = result.match(/Current week \(all models\):\s+(\d+)% used[^·]*·\s*resets\s+([^\n(]+?)\s*\(/);
4
+ const sessionMatch = result.match(/Current session:\s+(\d+)%\s+used/i);
5
+ const weeklyMatch = result.match(/Current week \(all models\):\s+(\d+)%\s+used/i) ??
6
+ result.match(/Current week[^\d%]*(\d+)%\s+used/i);
6
7
  const usedPct = weeklyMatch ? parseInt(weeklyMatch[1], 10) : 0;
7
8
  const sessionPct = sessionMatch ? parseInt(sessionMatch[1], 10) : undefined;
8
9
  let resetsAt = parseResetText(result, now);
@@ -10,22 +10,33 @@ export function parseKimiTui(text, now = new Date()) {
10
10
  if (!w)
11
11
  throw new Error("kimi: weekly limit not found in TUI output");
12
12
  const f = cleaned.match(fiveRe);
13
- if (!f)
13
+ let sessionPct = null;
14
+ let fiveRaw = null;
15
+ if (f) {
16
+ sessionPct = parseInt(f[1], 10);
17
+ fiveRaw = f[2].trim();
18
+ }
19
+ else {
20
+ const fallback = cleaned.match(/5h limit[^\d%]*(\d+)%\s+used/i);
21
+ if (fallback)
22
+ sessionPct = parseInt(fallback[1], 10);
23
+ }
24
+ if (sessionPct === null)
14
25
  throw new Error("kimi: 5h limit not found in TUI output");
15
26
  const usedPct = parseInt(w[1], 10);
16
- const sessionPct = parseInt(f[1], 10);
17
27
  if (!Number.isFinite(usedPct) || usedPct < 0 || usedPct > 100)
18
28
  throw new Error("kimi: bad weekly pct");
19
29
  if (!Number.isFinite(sessionPct) || sessionPct < 0 || sessionPct > 100)
20
30
  throw new Error("kimi: bad 5h pct");
21
31
  const weeklyRaw = w[2].trim();
22
- const fiveRaw = f[2].trim();
23
32
  const weeklyIso = parseResetText(`resets ${weeklyRaw}`, now);
24
33
  if (!weeklyIso)
25
34
  throw new Error(`kimi: bad weekly reset "${weeklyRaw}"`);
26
- const fiveIso = parseResetText(`resets ${fiveRaw}`, now);
27
- if (!fiveIso)
28
- throw new Error(`kimi: bad 5h reset "${fiveRaw}"`);
35
+ if (fiveRaw) {
36
+ const fiveIso = parseResetText(`resets ${fiveRaw}`, now);
37
+ if (!fiveIso)
38
+ throw new Error(`kimi: bad 5h reset "${fiveRaw}"`);
39
+ }
29
40
  let plan = "unknown";
30
41
  const paren = cleaned.match(/Weekly limit\s*\(([^)]+)\)/i);
31
42
  if (paren) {
@@ -5,10 +5,18 @@ export function parseManualUsage(provider, text, now = new Date()) {
5
5
  const parsedReset = parseResetText(text, now);
6
6
  const resetsAt = parsedReset ?? new Date(now.getTime() + 3 * 86400000).toISOString();
7
7
  const periodStart = (parsedReset ? new Date(new Date(resetsAt).getTime() - 7 * 86400000) : new Date(now.getTime() - 7 * 86400000)).toISOString();
8
+ let sessionPct;
9
+ const sm = text.match(/(?:5h|5-hour|session|current)[^\d%\n]*(\d+)%\s*used/i);
10
+ if (sm) {
11
+ const v = parseInt(sm[1], 10);
12
+ if (Number.isFinite(v) && v >= 0 && v <= 100)
13
+ sessionPct = v;
14
+ }
8
15
  return {
9
16
  provider,
10
17
  plan: "unknown",
11
18
  usedPct,
19
+ sessionPct,
12
20
  resetsAt,
13
21
  periodStart,
14
22
  source: "manual",
package/dist/version.js CHANGED
@@ -1,2 +1,2 @@
1
1
  // generated by scripts/build-embed.mjs — do not edit
2
- export const VERSION = "0.0.31";
2
+ export const VERSION = "0.0.32";
@@ -358,7 +358,7 @@ export function ProviderDrawer({ provider, asOf, recommendation, onClose, onRena
358
358
  margin: "0 var(--s4) var(--s3)",
359
359
  fontSize: "var(--t-2)",
360
360
  color: "var(--ink-soft)",
361
- }, children: provider.description })), _jsxs("section", { className: "dsec", "aria-label": "Weekly limit", children: [_jsx("h3", { children: "Weekly limit" }), _jsx("div", { className: "pcard-topline", children: _jsx(Badge, { provider: provider }) }), provider.quota ? (_jsxs(_Fragment, { children: [_jsx(PaceBar, { provider: provider, asOf: asOf }), underline && _jsx("div", { className: "pcard-underline", children: underline })] })) : (_jsx("p", { className: "cell-s", children: "No readings yet." }))] }), model.sessionPct !== undefined && model.sessionPct > 0 && (_jsxs("section", { className: "dsec", "aria-label": shortWindowLabel(provider.id) ?? "Session", children: [_jsx("h3", { children: shortWindowLabel(provider.id) ?? "Session" }), _jsx("div", { className: "pcard-topline", children: _jsxs("span", { className: "used", children: [model.sessionPct, "% used"] }) }), _jsx("div", { className: "track", role: "img", "aria-label": `${model.sessionPct} percent of ${(shortWindowLabel(provider.id) ?? "session").toLowerCase()} used`, children: _jsx("div", { className: "fill", style: {
361
+ }, children: provider.description })), _jsxs("section", { className: "dsec", "aria-label": "Weekly limit", children: [_jsx("h3", { children: "Weekly limit" }), _jsx("div", { className: "pcard-topline", children: _jsx(Badge, { provider: provider }) }), provider.quota ? (_jsxs(_Fragment, { children: [_jsx(PaceBar, { provider: provider, asOf: asOf }), underline && _jsx("div", { className: "pcard-underline", children: underline })] })) : (_jsx("p", { className: "cell-s", children: "No readings yet." }))] }), model.sessionPct !== undefined && model.sessionPct !== null && Number.isFinite(model.sessionPct) && (_jsxs("section", { className: "dsec", "aria-label": shortWindowLabel(provider.id) ?? "5h Limit", children: [_jsx("h3", { children: shortWindowLabel(provider.id) ?? "5h Limit" }), _jsx("div", { className: "pcard-topline", children: _jsxs("span", { className: "used", children: [model.sessionPct, "% used"] }) }), _jsx("div", { className: "track", role: "img", "aria-label": `${model.sessionPct} percent of ${(shortWindowLabel(provider.id) ?? "5h limit").toLowerCase()} used`, children: _jsx("div", { className: "fill", style: {
362
362
  width: `${Math.min(100, Math.max(0, model.sessionPct))}%`,
363
363
  background: "var(--fill-ontrack)",
364
364
  ["--fill-edge"]: "var(--edge-ontrack)",
@@ -10,7 +10,7 @@ export function ProviderRow({ provider, recommended, asOf, onSelect, }) {
10
10
  const plan = displayPlan(quota?.plan);
11
11
  const shortWindow = shortWindowLabel(provider.id);
12
12
  const reset = resetCellLines(provider, asOfMs);
13
- return (_jsxs("div", { "data-testid": `provider-row-${provider.id}`, className: `lrow ${recommended ? "is-recommended is-top-pick" : ""}`, onClick: () => onSelect(provider.id), children: [_jsxs("div", { className: "prov", "data-label": "Provider", children: [_jsx("span", { className: "dot", style: { background: `var(--p-${provider.id.split(":")[0]}, var(--surface-raised))` }, "aria-hidden": "true" }), _jsxs("span", { children: [_jsxs("span", { className: "nm", children: [name, recommended && (_jsx("span", { className: "rec-icon", title: "Recommended for next session", role: "img", "aria-label": "recommended", children: _jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.3", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: _jsx("path", { d: "m12 3-1.9 5.8a2 2 0 0 1-1.3 1.3L3 12l5.8 1.9a2 2 0 0 1 1.3 1.3L12 21l1.9-5.8a2 2 0 0 1 1.3-1.3L21 12l-5.8-1.9a2 2 0 0 1-1.3-1.3z" }) }) }))] }), plan && _jsx("span", { className: "pl", children: plan }), quota?.sessionPct !== undefined && quota.sessionPct !== null && (_jsxs("span", { className: "src", children: [shortWindow ?? "Session", " \u00B7 ", quota.sessionPct, "% used"] }))] })] }), _jsx("div", { "data-label": "Used vs elapsed", children: quota ? _jsx(PaceBar, { provider: provider, asOf: asOf }) : "—" }), _jsxs("div", { "data-label": "Reset", className: "reset-cell", children: [_jsx("span", { className: "cell-b", children: reset.top }), reset.bottom && _jsx("span", { className: "cell-s", children: reset.bottom })] }), _jsxs("div", { "data-label": "Pace", children: [_jsx(Badge, { provider: provider }), lines.length > 0 && (_jsx("div", { style: { marginTop: 2 }, children: lines.map((l) => (_jsxs("div", { className: "cell-s paceline", title: l.tip, children: [_jsx("span", { children: l.label }), _jsx("span", { className: "cell-b", children: l.value })] }, l.label))) }))] }), _jsx("button", { type: "button", className: "rowbtn", onClick: (e) => {
13
+ return (_jsxs("div", { "data-testid": `provider-row-${provider.id}`, className: `lrow ${recommended ? "is-recommended is-top-pick" : ""}`, onClick: () => onSelect(provider.id), children: [_jsxs("div", { className: "prov", "data-label": "Provider", children: [_jsx("span", { className: "dot", style: { background: `var(--p-${provider.id.split(":")[0]}, var(--surface-raised))` }, "aria-hidden": "true" }), _jsxs("span", { children: [_jsxs("span", { className: "nm", children: [name, recommended && (_jsx("span", { className: "rec-icon", title: "Recommended for next session", role: "img", "aria-label": "recommended", children: _jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.3", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: _jsx("path", { d: "m12 3-1.9 5.8a2 2 0 0 1-1.3 1.3L3 12l5.8 1.9a2 2 0 0 1 1.3 1.3L12 21l1.9-5.8a2 2 0 0 1 1.3-1.3L21 12l-5.8-1.9a2 2 0 0 1-1.3-1.3z" }) }) }))] }), plan && _jsx("span", { className: "pl", children: plan }), quota?.sessionPct !== undefined && quota.sessionPct !== null && (_jsxs("span", { className: "src", children: [shortWindow ?? "5h Limit", " \u00B7 ", quota.sessionPct, "% used"] }))] })] }), _jsx("div", { "data-label": "Used vs elapsed", children: quota ? _jsx(PaceBar, { provider: provider, asOf: asOf }) : "—" }), _jsxs("div", { "data-label": "Reset", className: "reset-cell", children: [_jsx("span", { className: "cell-b", children: reset.top }), reset.bottom && _jsx("span", { className: "cell-s", children: reset.bottom })] }), _jsxs("div", { "data-label": "Pace", children: [_jsx(Badge, { provider: provider }), lines.length > 0 && (_jsx("div", { style: { marginTop: 2 }, children: lines.map((l) => (_jsxs("div", { className: "cell-s paceline", title: l.tip, children: [_jsx("span", { children: l.label }), _jsx("span", { className: "cell-b", children: l.value })] }, l.label))) }))] }), _jsx("button", { type: "button", className: "rowbtn", onClick: (e) => {
14
14
  e.stopPropagation();
15
15
  onSelect(provider.id);
16
16
  }, children: "Inspect" }), _jsx("span", { className: "sr-only", children: forecastLine(provider) })] }));
@@ -115,10 +115,9 @@ export declare function providerSubtitle(p: Pick<ProviderView, "displayName" | "
115
115
  /** Plan for display. Vendors that expose no tier report "unknown", which never renders. */
116
116
  export declare function displayPlan(plan: string | null | undefined): string | null;
117
117
  /**
118
- * Short-window display name, mirroring each vendor's own /usage or /status
119
- * wording: codex, kimi, and agy call it a "5h" or "Five Hour" limit, claude
120
- * a "Current session" (a 5-hour rolling window), muse a "Current" window.
121
- * Null when the provider reports no short window (grok, manual).
118
+ * Short-window display name ("5h Limit"). Codex, Kimi, and Agy report a 5h limit;
119
+ * Claude (current session) and Muse (current window) report an equivalent 5-hour
120
+ * rolling window. Returns null when the provider reports no short window (grok, manual).
122
121
  */
123
122
  export declare function shortWindowLabel(id: string): string | null;
124
123
  /** "read Xm ago" from the last good snapshot's server timestamp. */
@@ -51,21 +51,18 @@ export function displayPlan(plan) {
51
51
  return plan;
52
52
  }
53
53
  /**
54
- * Short-window display name, mirroring each vendor's own /usage or /status
55
- * wording: codex, kimi, and agy call it a "5h" or "Five Hour" limit, claude
56
- * a "Current session" (a 5-hour rolling window), muse a "Current" window.
57
- * Null when the provider reports no short window (grok, manual).
54
+ * Short-window display name ("5h Limit"). Codex, Kimi, and Agy report a 5h limit;
55
+ * Claude (current session) and Muse (current window) report an equivalent 5-hour
56
+ * rolling window. Returns null when the provider reports no short window (grok, manual).
58
57
  */
59
58
  export function shortWindowLabel(id) {
60
59
  switch (id.split(":")[0]) {
61
60
  case "codex":
62
61
  case "kimi":
63
62
  case "agy":
64
- return "5-hour limit";
65
63
  case "claude":
66
- return "Current session";
67
64
  case "muse":
68
- return "Current window";
65
+ return "5h Limit";
69
66
  default:
70
67
  return null;
71
68
  }