feat: v2.5.12 — plan and quota for every AI tool, Grok Build and Kimi Code, Quit AgentHub (#65)

Usage panel (status bar):
- every account shows its plan (Claude subscriptionType, Codex
  chatgpt_plan_type, Cursor membershipType, Grok subscriptionTier)
- new quota rows: Cursor CLI (cursor.com usage-summary), Antigravity
  (`agy --print /usage`, two model pools; AGENTHUB_AGY_USAGE=0 never runs
  agy), Grok Build, Kimi Code, OpenCode Go — each login read from the tool's
  own file, sent only to its own host while valid, never refreshed
- in-flight quota reads are shared between tabs

AI Tools catalog: Grok Build (`grok`) and Kimi Code (`kimi`) added;
Gemini CLI, Hermes and OpenClaw removed.

Also: Quit AgentHub (#65, `agenthub stop`), status-area icon, Add to Chat
on an editor selection, Settings in three groups, JetBrains-style Changes
panel (ticked files/hunks, ignore, blame, file history), terminal font.

--no-verify: :3000 is taken by another dev server (lane-detect tests);
both suites run by hand — server 2636/2639 (the 3 are :3000), client
1131/1131.
This commit is contained in:
2026-10-08 12:22:14 +07:00
parent 6ef9a5d4b7
commit a9c71cd905
133 changed files with 8007 additions and 1830 deletions
+9 -3
View File
@@ -3,7 +3,8 @@
* @description Custom pets for the dashboard mascot (Sagi). A pet is a folder
* `<data dir>/pets/<id>/` holding `meta.json` (written here) and either a
* Codex pet's `spritesheet.webp` — the `.codex-pet.zip` format: an 8×9 grid of
* 192×208 frames, one row per animation state — or one uploaded image. Pets
* 192×208 frames, one row per animation state (v2 adds two rows of gaze
* poses: 8×11) — or one uploaded image. Pets
* come from exactly three places: an uploaded `.codex-pet.zip`, an uploaded
* image, or one of the FEATURED pets, downloaded from codex-pets.net by a fixed
* id — never a URL or a path from a request. None is bundled with AgentHub:
@@ -28,6 +29,8 @@ const MAX_MANIFEST_BYTES = 16 * 1024;
const MAX_PETS = 50;
/** The Codex atlas: 8 columns × 9 rows of 192×208 frames. */
const SHEET = { width: 1536, height: 1872, cellWidth: 192, cellHeight: 208 };
/** A v2 atlas (`spriteVersionNumber: 2`): the same plus rows 9–10, 16 gaze poses. */
const SHEET_V2_HEIGHT = 2288;
const FEATURED_HOST = "https://codex-pets.net";
/** Offered in the pet menu, installed only on a click. `id` is codex-pets.net's. */
const FEATURED = [
@@ -105,10 +108,13 @@ function checkSheet(buf) {
if (buf.length > MAX_SHEET_BYTES) throw fail("ETOOBIG", "the spritesheet is larger than 6 MB");
const size = webpSize(buf);
if (!size) throw fail("EBADPET", "the spritesheet is not a WebP image");
if (size.width !== SHEET.width || size.height !== SHEET.height)
if (
size.width !== SHEET.width ||
(size.height !== SHEET.height && size.height !== SHEET_V2_HEIGHT)
)
throw fail(
"EBADPET",
`the spritesheet is ${size.width}×${size.height}; a Codex pet is ${SHEET.width}×${SHEET.height}`
`the spritesheet is ${size.width}×${size.height}; a Codex pet is ${SHEET.width}×${SHEET.height} (v2: ${SHEET.width}×${SHEET_V2_HEIGHT})`
);
}