Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
102 changes: 85 additions & 17 deletions pm-stack/aggregator/src/quota-extract.ts
Original file line number Diff line number Diff line change
Expand Up @@ -199,25 +199,93 @@ const extractClinePass: Extractor = (s) => {
};

const extractCommandCode: Extractor = (s, now) => {
const bal = first(s, /\$(\d+(?:\.\d+)?) of \$(\d+(?:\.\d+)?) used/i);
if (!bal) return null;
const end = first(s, /period ends (\w{3}) (\d{1,2}), (\d{2}:\d{2}) UTC/i);
const windows: QuotaWindow[] = [
usdWindow(
"monthly credits",
Number(bal[1]),
Number(bal[2]),
end ? monthDayTime(end[1], end[2], end[3], now) : null,
),
];
const short = first(s, /5h (\d+(?:\.\d+)?)%, weekly (\d+(?:\.\d+)?)%/i);
if (short) {
windows.push(pctWindow("5-hour", Number(short[1]), null));
windows.push(pctWindow("weekly", Number(short[2]), null));
// Drew's ruling (2026-11-01, #3410): Command Code quota reads report
// the PLAN windows only (monthly limit, weekly, 5-hour) — never the
// extra/top-up credit balance. The section preserves several dated
// reads by design, so select the LATEST dated read instead of the
// first pattern that matches anywhere: the old first-match on
// "$X of $Y used" rendered the 2026-10-25 read as current because
// the freshest (2026-10-27) console read is percentage-only.
//
// Split the section into segments at each ISO date stamp (the text
// before the first stamp is one undated segment). A segment is a
// parseable read when one of the recorded formats matches:
// - percentage-only console format: "monthly limit N% used",
// "weekly limit N%", "5-hour limit N%"
// - its compact restatement: "monthly N%, weekly N%, 5h N%"
// - the dollar format: "$X of $Y used" (the $ used of the $10
// included credits is a monthly-limit figure per the ruling)
// plus the "5h A%, weekly B%" short windows.
const stamps = [...s.matchAll(/\d{4}-\d{2}-\d{2}/g)];
const segments: { date: string; index: number; text: string }[] = [];
if (stamps.length === 0) {
segments.push({ date: "", index: 0, text: s });
} else {
if (stamps[0].index > 0) segments.push({ date: "", index: 0, text: s.slice(0, stamps[0].index) });
for (let i = 0; i < stamps.length; i++) {
const start = stamps[i].index;
const end = i + 1 < stamps.length ? stamps[i + 1].index : s.length;
segments.push({ date: stamps[i][0], index: start, text: s.slice(start, end) });
}
}
const parseRead = (text: string): QuotaWindow[] | null => {
const monthly = first(text, /monthly limit (\d+(?:\.\d+)?)% used/i);
if (monthly) {
const windows = [pctWindow("monthly", Number(monthly[1]), null)];
const weekly = first(text, /weekly limit (\d+(?:\.\d+)?)%/i);
if (weekly) windows.push(pctWindow("weekly", Number(weekly[1]), null));
const fiveHour = first(text, /5-hour limit (\d+(?:\.\d+)?)%/i);
if (fiveHour) windows.push(pctWindow("5-hour", Number(fiveHour[1]), null));
return windows;
}
const compact = first(text, /monthly (\d+(?:\.\d+)?)%, weekly (\d+(?:\.\d+)?)%, 5h (\d+(?:\.\d+)?)%/i);
if (compact) {
return [
pctWindow("monthly", Number(compact[1]), null),
pctWindow("weekly", Number(compact[2]), null),
pctWindow("5-hour", Number(compact[3]), null),
];
}
const bal = first(text, /\$(\d+(?:\.\d+)?) of \$(\d+(?:\.\d+)?) used/i);
if (bal) {
const end = first(text, /period ends (\w{3}) (\d{1,2}), (\d{2}:\d{2}) UTC/i);
const windows: QuotaWindow[] = [
usdWindow(
"monthly credits",
Number(bal[1]),
Number(bal[2]),
end ? monthDayTime(end[1], end[2], end[3], now) : null,
),
];
const short = first(text, /5h (\d+(?:\.\d+)?)%, weekly (\d+(?:\.\d+)?)%/i);
if (short) {
windows.push(pctWindow("5-hour", Number(short[1]), null));
windows.push(pctWindow("weekly", Number(short[2]), null));
}
return windows;
}
return null;
};
const parsed = segments
.map((seg) => ({ ...seg, windows: parseRead(seg.text) }))
.filter((seg) => seg.windows !== null);
if (parsed.length === 0) return null;
parsed.sort((a, b) => (a.date < b.date ? -1 : a.date > b.date ? 1 : a.index - b.index));
const latest = parsed[parsed.length - 1];
// A newer dated segment that carries a monthly figure none of the
// formats could parse is a fresher read we cannot read: render no
// windows rather than presenting the older read as current (#3410).
const stale = segments.some(
(seg) =>
(seg.date > latest.date || (seg.date === latest.date && seg.index > latest.index)) &&
parseRead(seg.text) === null &&
/monthly/i.test(seg.text) &&
/\d+(?:\.\d+)?\s*(%|percent)/i.test(seg.text),
);
if (stale) return null;
return {
windows,
note: "Registry: the Go plan does not include API access — wiring activates if the plan tier is upgraded.",
windows: latest.windows!,
note: "Plan windows only (Drew's 2026-11-01 ruling, #3410): freshest dated read in the quota view; the top-up credit balance is never reported as quota. Registry: the Go plan does not include API access — wiring activates if the plan tier is upgraded.",
};
};

Expand Down
42 changes: 42 additions & 0 deletions pm-stack/aggregator/test/quota.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,48 @@ describe("quota extractors", () => {
expect(p.windows[2].percent).toBe(8.8);
});

test("command code takes the latest dated read, percentage-only format (#3410)", () => {
const multi = `
### Command Code
- **Usage / dates:** **Newer dated read (model-efficiency plan, freshest reads 2026-10-25 morning): $6.57 of $10 used ($3.43 left); 5h 1.2%, weekly 8.8%; period ends Nov 2, 23:04 UTC.** **Freshest dated read (console, 2026-10-27 10:05 CDT, commandcode.ai Settings): monthly limit 69% used, resets Nov 2; weekly limit 14% (resets in 4d); 5-hour limit 0% ("No usage in this window yet"); extra/top-up credits $0.00 balance.**
`;
const p = extractQuotaPools(multi, NOW).find((x) => x.id === "commandcode:go")!;
expect(p.windows.map((w) => [w.name, w.percent])).toEqual([
["monthly", 69],
["weekly", 14],
["5-hour", 0],
]);
// No window is a dollar/balance figure: the top-up balance is not quota.
expect(p.windows.some((w) => w.unit === "usd")).toBe(false);
});

test("command code renders no windows when the freshest dated read is unparseable (#3410)", () => {
const stale = `
### Command Code
- **Usage / dates:** **Dated read (2026-10-25): $6.57 of $10 used; 5h 1.2%, weekly 8.8%; period ends Nov 2, 23:04 UTC.** **Freshest dated read (2026-10-30): monthly limit 55 percent used (the console printed the figure in words this cycle).**
`;
const p = extractQuotaPools(stale, NOW).find((x) => x.id === "commandcode:go")!;
expect(p.windows).toEqual([]);
});

test("command code: a later same-day unparseable read also invalidates the earlier one (#3410)", () => {
const sameDay = `
### Command Code
- **Usage / dates:** **Dated read (2026-10-30 09:00 CDT): monthly limit 55% used; weekly limit 20%; 5-hour limit 3%.** **Dated update (2026-10-30 12:00 CDT): monthly limit 100 percent used (the console printed the figure in words).**
`;
const p = extractQuotaPools(sameDay, NOW).find((x) => x.id === "commandcode:go")!;
expect(p.windows).toEqual([]);
});

test("command code never emits the top-up balance as quota (#3410)", () => {
const balanceOnly = `
### Command Code
- **Usage / dates:** **Dated read (2026-10-30): extra/top-up credits $0.10 balance; hub credits 0.1 flat.**
`;
const p = extractQuotaPools(balanceOnly, NOW).find((x) => x.id === "commandcode:go")!;
expect(p.windows).toEqual([]);
});

test("antigravity pools are independent, remaining -> used", () => {
expect(byId.get("antigravity:gemini")!.windows[0].percent).toBeCloseTo(0.9);
expect(byId.get("antigravity:claude-gpt")!.windows[0].percent).toBe(0);
Expand Down