@v1nvn/zai 0.33.0 → 0.34.0

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.
package/README.md CHANGED
@@ -18,17 +18,17 @@ claude plugin install zai@agentic
18
18
  In a terminal, bare:
19
19
 
20
20
  ```sh
21
- npx -y @v1nvn/zai@0.33.0
21
+ npx -y @v1nvn/zai@0.34.0
22
22
  ```
23
23
 
24
24
  ## Usage
25
25
 
26
26
  | Invocation | Does |
27
27
  |---|---|
28
- | `npx -y @v1nvn/zai@0.33.0` | usage report — models, quota window, remaining balance |
29
- | `npx -y @v1nvn/zai@0.33.0 --auth-token TOKEN` | same, key on the command line (visible in `ps`) |
30
- | `npx -y @v1nvn/zai@0.33.0 --auth-token=TOKEN` | `=` form — zsh quoting-safe |
31
- | `npx -y @v1nvn/zai@0.33.0 --base-url URL` | another GLM endpoint (default `api.z.ai`) |
28
+ | `npx -y @v1nvn/zai@0.34.0` | usage report — models, quota window, remaining balance |
29
+ | `npx -y @v1nvn/zai@0.34.0 --auth-token TOKEN` | same, key on the command line (visible in `ps`) |
30
+ | `npx -y @v1nvn/zai@0.34.0 --auth-token=TOKEN` | `=` form — zsh quoting-safe |
31
+ | `npx -y @v1nvn/zai@0.34.0 --base-url URL` | another GLM endpoint (default `api.z.ai`) |
32
32
 
33
33
  Each setting takes the first source that provides it:
34
34
 
package/dist/index.js CHANGED
@@ -139,8 +139,8 @@ function resolveConfig(env, parsed) {
139
139
  //#region ../tokens/dist/text.js
140
140
  /**
141
141
  * Plain-text rendering primitives for the fixed-width reports. Output targets
142
- * a monospace terminal — the status line and the pane — so everything here is
143
- * fixed-width: padding, block-glyph bars, and compact number formatting.
142
+ * a monospace terminal — the pane — so everything here is fixed-width:
143
+ * padding, block-glyph bars, and compact number formatting.
144
144
  */
145
145
  var MONTHS = [
146
146
  "Jan",
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../core/dist/index.js","../src/resolve.ts","../../tokens/dist/text.js","../src/format.ts","../src/usage.ts","../src/index.ts"],"sourcesContent":["import { existsSync, readFileSync, readdirSync, statSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\n//#region src/input.ts\nfunction readAll(stream) {\n\treturn new Promise((resolve, reject) => {\n\t\tlet data = \"\";\n\t\tstream.setEncoding(\"utf8\");\n\t\tstream.on(\"data\", (chunk) => {\n\t\t\tdata += chunk;\n\t\t});\n\t\tstream.on(\"end\", () => {\n\t\t\tresolve(data);\n\t\t});\n\t\tstream.on(\"error\", reject);\n\t});\n}\nfunction readStdin(stream = process.stdin) {\n\treturn readAll(stream);\n}\n/** A markdown file's contents, with the CLI's no-such-file error. */\nfunction readMarkdownFile(path) {\n\tif (!statSync(path, { throwIfNoEntry: false })?.isFile()) throw new Error(`no such file: ${path}`);\n\treturn readFileSync(path, \"utf8\");\n}\n//#endregion\n//#region src/hook.ts\n/**\n* Read the Claude Code hook event JSON from stdin; empty or unparseable input\n* yields an empty event, never a thrown error — a hook must always answer.\n*/\nfunction readHookEvent(stream = process.stdin) {\n\treturn readAll(stream).then((data) => {\n\t\ttry {\n\t\t\treturn JSON.parse(data);\n\t\t} catch {\n\t\t\treturn {};\n\t\t}\n\t}, () => ({}));\n}\n/**\n* Which transcript lastReply should read, per the hook event: transcript_path\n* when it names a real file, else session_id, else nothing (lastReply then\n* falls back to the newest session for the current project).\n*/\nfunction replyTarget(event) {\n\tif (event.transcript_path !== void 0 && isFile(event.transcript_path)) return event.transcript_path;\n\treturn event.session_id || void 0;\n}\nfunction isFile(path) {\n\ttry {\n\t\treturn statSync(path).isFile();\n\t} catch {\n\t\treturn false;\n\t}\n}\n/**\n* Print the UserPromptExpansion decision for a zero-token command: `block`\n* keeps the command from reaching the model, with the output as the `reason`.\n*/\nfunction emitHookBlock(reason) {\n\tprocess.stdout.write(`${JSON.stringify({\n\t\tdecision: \"block\",\n\t\treason\n\t})}\\n`);\n}\n//#endregion\n//#region src/cli.ts\nfunction parseQuietly(program, args, recover) {\n\ttry {\n\t\tprogram.allowExcessArguments(false).exitOverride().configureOutput({\n\t\t\twriteOut: () => void 0,\n\t\t\twriteErr: () => void 0\n\t\t}).parse([...args], { from: \"user\" });\n\t\treturn program;\n\t} catch (err) {\n\t\treturn recover?.(err);\n\t}\n}\nfunction printUsageAndExit(program) {\n\tconsole.error(program.helpInformation());\n\tprocess.exit(1);\n}\nasync function hookOrPrint(hook, failure, run, stdin = process.stdin) {\n\tif (hook) {\n\t\tlet reason;\n\t\ttry {\n\t\t\treason = await run(await readHookEvent(stdin));\n\t\t} catch (e) {\n\t\t\treason = `${failure}: ${e.message}`;\n\t\t}\n\t\temitHookBlock(reason);\n\t\treturn;\n\t}\n\ttry {\n\t\tconsole.log(await run(void 0));\n\t} catch (e) {\n\t\tconsole.error(e.message);\n\t\tprocess.exit(1);\n\t}\n}\n//#endregion\n//#region src/dev.ts\nvar RELOAD_DEBOUNCE_MS = 150;\nvar IGNORED_SEGMENTS = [\n\t\"/node_modules/\",\n\t\"/dist/\",\n\t\"/.git/\",\n\t\"/coverage/\"\n];\nfunction shouldReload(file) {\n\treturn IGNORED_SEGMENTS.every((seg) => !file.includes(seg));\n}\n/**\n* Debounced file-change reloads, serialized via a promise chain: concurrent\n* saves never overlap, and a mid-reload save still produces a follow-up.\n*/\nfunction watchWithReload(vite, reload) {\n\tlet chain = Promise.resolve();\n\tlet timer;\n\tvite.watcher.on(\"change\", (file) => {\n\t\tif (!shouldReload(file)) return;\n\t\tif (timer) clearTimeout(timer);\n\t\ttimer = setTimeout(() => {\n\t\t\ttimer = void 0;\n\t\t\tchain = chain.then(reload);\n\t\t}, RELOAD_DEBOUNCE_MS);\n\t});\n}\n//#endregion\n//#region src/last-reply.ts\nfunction textBlocks(entry) {\n\tconst content = entry.message?.content;\n\tif (entry.type !== \"assistant\" || !Array.isArray(content)) return;\n\tconst blocks = content.filter((b) => typeof b === \"object\" && b !== null && b.type === \"text\");\n\treturn blocks.length > 0 ? blocks : void 0;\n}\nfunction claudeProjectsDir() {\n\tconst claudeDir = process.env.CLAUDE_DIR ?? join(homedir(), \".claude\");\n\treturn join(claudeDir, \"projects\");\n}\n/**\n* The last assistant text reply from a Claude Code session, reproducing Claude\n* Code's `/copy` byte-for-byte: the last assistant entry that contains a\n* `text` block, only its `text` block(s) (tool_use / thinking dropped), blocks\n* joined with a blank line, and no trailing newline.\n*\n* @param arg a transcript file, a session UUID under the project dir, or\n* nothing to use the newest session for the current project.\n*/\nfunction lastReply(arg) {\n\tconst proj = (process.env.CLAUDE_PROJECT_DIR ?? process.cwd()).replaceAll(\"/\", \"-\");\n\tconst projDir = join(claudeProjectsDir(), proj);\n\tlet file;\n\tif (arg !== void 0) file = isFile(arg) ? arg : join(projDir, `${arg}.jsonl`);\n\telse if (existsSync(projDir)) {\n\t\tconst newest = readdirSync(projDir).filter((f) => f.endsWith(\".jsonl\")).map((f) => ({\n\t\t\tf,\n\t\t\tmtimeMs: statSync(join(projDir, f)).mtimeMs\n\t\t})).sort((a, b) => b.mtimeMs - a.mtimeMs).at(0);\n\t\tif (newest) file = join(projDir, newest.f);\n\t}\n\tif (file === void 0 || !isFile(file)) throw new Error(`no session transcript found in ${projDir}`);\n\tlet last;\n\tfor (const line of readFileSync(file, \"utf8\").split(\"\\n\")) {\n\t\tif (!line.includes(\"\\\"assistant\\\"\")) continue;\n\t\tlet entry;\n\t\ttry {\n\t\t\tentry = JSON.parse(line);\n\t\t} catch {\n\t\t\tcontinue;\n\t\t}\n\t\tconst blocks = textBlocks(entry);\n\t\tif (blocks) last = blocks;\n\t}\n\treturn (last ?? []).map((b) => b.text ?? \"\").join(\"\\n\\n\");\n}\n//#endregion\n//#region src/logger.ts\nvar LEVEL_RANK = {\n\tdebug: 10,\n\tinfo: 20,\n\twarn: 30,\n\terror: 40,\n\tsilent: Number.MAX_SAFE_INTEGER\n};\nfunction levelEnabled(active, wanted) {\n\treturn LEVEL_RANK[wanted] >= LEVEL_RANK[active];\n}\nvar LEVEL_LABEL = {\n\tdebug: \"DEBUG\",\n\terror: \"ERROR\",\n\tinfo: \"INFO\",\n\twarn: \"WARN\"\n};\nvar Logger = class {\n\tactiveLevel;\n\tstderr;\n\tconstructor(activeLevel, stderr = (line) => process.stderr.write(`${line}\\n`)) {\n\t\tthis.activeLevel = activeLevel;\n\t\tthis.stderr = stderr;\n\t}\n\tdebug(message) {\n\t\tthis.log(\"debug\", message);\n\t}\n\terror(message) {\n\t\tthis.log(\"error\", message);\n\t}\n\tinfo(message) {\n\t\tthis.log(\"info\", message);\n\t}\n\twarn(message) {\n\t\tthis.log(\"warn\", message);\n\t}\n\tlog(level, message) {\n\t\tif (levelEnabled(this.activeLevel, level)) this.stderr(`${LEVEL_LABEL[level]} ${message}`);\n\t}\n};\n//#endregion\n//#region src/shutdown.ts\n/** Close each closable in order (best-effort), then force-exit. */\nfunction shutdownOnSignals(closables, signals = [\"SIGINT\", \"SIGTERM\"]) {\n\tfunction shutdown() {\n\t\tclosables.reduce((acc, closable) => acc.then(async () => {\n\t\t\ttry {\n\t\t\t\tawait closable.close();\n\t\t\t} catch {}\n\t\t}), Promise.resolve()).finally(() => {\n\t\t\tprocess.exit(0);\n\t\t});\n\t}\n\tfor (const signal of signals) process.on(signal, shutdown);\n}\n//#endregion\nexport { Logger, claudeProjectsDir, emitHookBlock, hookOrPrint, isFile, lastReply, levelEnabled, parseQuietly, printUsageAndExit, readAll, readHookEvent, readMarkdownFile, readStdin, replyTarget, shutdownOnSignals, watchWithReload };\n\n//# sourceMappingURL=index.js.map","import { parseQuietly } from '@v1nvn/agentic-core';\nimport { Command, Option } from 'commander';\n\nconst DEFAULT_BASE_URL = 'https://api.z.ai';\n\nconst GLM_HOSTS = new Set(['api.z.ai', 'dev.bigmodel.cn', 'open.bigmodel.cn']);\n\nexport interface ParsedArgs {\n readonly authToken: string | undefined;\n readonly baseUrl: string | undefined;\n readonly hook: boolean;\n}\n\nexport interface ResolvedConfig {\n readonly token: string;\n readonly url: string;\n}\n\ninterface BaseUrl {\n readonly glm: boolean;\n readonly origin: string;\n}\n\nfunction fromEnv(value: string | undefined): string | undefined {\n return value ? value : undefined;\n}\n\nfunction originOf(value: string): string | undefined {\n try {\n const url = new URL(value);\n return url.protocol === 'https:' || url.protocol === 'http:'\n ? url.origin\n : undefined;\n } catch {\n return undefined;\n }\n}\n\nfunction isGlm(origin: string): boolean {\n return GLM_HOSTS.has(new URL(origin).hostname);\n}\n\nfunction resolveBaseUrl(\n flag: string | undefined,\n env: NodeJS.ProcessEnv,\n): BaseUrl {\n if (flag !== undefined) {\n const origin = originOf(flag);\n if (origin === undefined) {\n throw new Error(`invalid base URL: ${flag}`);\n }\n return { glm: isGlm(origin), origin };\n }\n const inherited = fromEnv(env.ANTHROPIC_BASE_URL);\n const origin = inherited === undefined ? undefined : originOf(inherited);\n if (origin !== undefined && isGlm(origin)) {\n return { glm: true, origin };\n }\n return { glm: false, origin: DEFAULT_BASE_URL };\n}\n\nexport function buildProgram(): Command {\n return new Command()\n .name('zai-usage')\n .addOption(\n new Option('--auth-token <token>', 'API key').env('ZAI_AUTH_TOKEN'),\n )\n .addOption(new Option('--base-url <url>', 'base URL').env('ZAI_BASE_URL'))\n .option('--hook', 'emit a UserPromptExpansion block instead of printing');\n}\n\nexport function parseArgs(args: readonly string[]): ParsedArgs | undefined {\n const program = parseQuietly(buildProgram(), args);\n if (program === undefined) {\n return undefined;\n }\n const { authToken, baseUrl, hook } = program.opts<{\n authToken: string | undefined;\n baseUrl: string | undefined;\n hook: boolean | undefined;\n }>();\n return {\n authToken: authToken || undefined,\n baseUrl: baseUrl || undefined,\n hook: hook ?? false,\n };\n}\n\nexport function resolveConfig(\n env: NodeJS.ProcessEnv,\n parsed: ParsedArgs,\n): ResolvedConfig {\n const base = resolveBaseUrl(parsed.baseUrl, env);\n const token =\n parsed.authToken ??\n (base.glm ? fromEnv(env.ANTHROPIC_AUTH_TOKEN) : undefined);\n if (token === undefined) {\n throw new Error(\n env.ANTHROPIC_AUTH_TOKEN\n ? 'ANTHROPIC_AUTH_TOKEN is set, but the resolved base URL does not name a GLM host, so it is not a GLM Coding Plan token — set ZAI_AUTH_TOKEN (or --auth-token)'\n : 'no API key: set ZAI_AUTH_TOKEN (or --auth-token)',\n );\n }\n return { token, url: base.origin };\n}\n","//#region src/text.ts\n/**\n* Plain-text rendering primitives for the fixed-width reports. Output targets\n* a monospace terminal — the status line and the pane — so everything here is\n* fixed-width: padding, block-glyph bars, and compact number formatting.\n*/\nvar MONTHS = [\n\t\"Jan\",\n\t\"Feb\",\n\t\"Mar\",\n\t\"Apr\",\n\t\"May\",\n\t\"Jun\",\n\t\"Jul\",\n\t\"Aug\",\n\t\"Sep\",\n\t\"Oct\",\n\t\"Nov\",\n\t\"Dec\"\n];\nvar EIGHTHS = [\n\t\"\",\n\t\"▏\",\n\t\"▎\",\n\t\"▍\",\n\t\"▌\",\n\t\"▋\",\n\t\"▊\",\n\t\"▉\"\n];\nvar RULE_WIDTH = 68;\nfunction rule() {\n\treturn \"─\".repeat(68);\n}\nfunction pad2(n) {\n\treturn String(n).padStart(2, \"0\");\n}\n/** Local-time `YYYY-MM-DD` key. */\nfunction ymd(date) {\n\treturn `${date.getFullYear()}-${pad2(date.getMonth() + 1)}-${pad2(date.getDate())}`;\n}\nfunction fmtTokens(n) {\n\tif (n == null || Number.isNaN(n)) return \"—\";\n\tif (n >= 1e9) return (n / 1e9).toFixed(1) + \"B\";\n\tif (n >= 1e6) return (n / 1e6).toFixed(1) + \"M\";\n\tif (n >= 1e3) return (n / 1e3).toFixed(1) + \"K\";\n\treturn String(n);\n}\nfunction fmtNum(n) {\n\treturn (n || 0).toLocaleString(\"en-US\");\n}\nfunction padR(s, n) {\n\treturn s.length >= n ? s : s + \" \".repeat(n - s.length);\n}\nfunction padL(s, n) {\n\treturn s.length >= n ? s : \" \".repeat(n - s.length) + s;\n}\n/** Fixed-width bar field (width cols): █ blocks + an eighth-fraction + trailing spaces. */\nfunction barField(v, max, width) {\n\tif (!v || v <= 0 || max <= 0) return \" \".repeat(width);\n\tconst scaled = v / max * width;\n\tlet full = Math.floor(scaled);\n\tlet fi = Math.round((scaled - full) * 8);\n\tif (fi === 8) {\n\t\tfull += 1;\n\t\tfi = 0;\n\t}\n\tif (full === 0 && fi === 0) fi = 1;\n\tlet s = \"█\".repeat(Math.min(full, width));\n\tif (full < width && fi > 0) s += EIGHTHS[fi] ?? \"\";\n\tif (s.length < width) s += \" \".repeat(width - s.length);\n\treturn s.slice(0, width);\n}\n/** Filled/empty meter: █ for used, ░ for remaining. */\nfunction meter(pct, width) {\n\tlet filled = Math.round((pct || 0) / 100 * width);\n\tfilled = Math.max(0, Math.min(width, filled));\n\treturn \"█\".repeat(filled) + \"░\".repeat(width - filled);\n}\n//#endregion\nexport { MONTHS, RULE_WIDTH, barField, fmtNum, fmtTokens, meter, pad2, padL, padR, rule, ymd };\n\n//# sourceMappingURL=text.js.map","/**\n * Plain-text usage report renderer.\n *\n * Rendered for a monospace terminal / hook-block `reason`, so it must NOT rely on\n * markdown (bold, tables, fenced code). Alignment comes from fixed-width columns\n * and unicode block glyphs. Input is the parsed `data` of the three ZAI/ZHIPU\n * monitor endpoints (model-usage, tool-usage, quota/limit — the last already\n * passed through processQuotaLimit).\n */\n\nimport {\n barField,\n fmtNum,\n fmtTokens,\n meter,\n MONTHS,\n pad2,\n padL,\n padR,\n rule,\n RULE_WIDTH,\n} from '@v1nvn/tokens/text';\n\n// Lower-half block eighths for vertical bars (1/8 .. 7/8); a full cell uses '█'.\nconst VBLOCKS = '▁▂▃▄▅▆▇';\n\nexport interface ModelMixEntry {\n modelName?: string;\n sortOrder?: number;\n totalTokens?: number;\n}\n\nexport interface ZaiModelUsage {\n modelCallCount?: number[];\n modelDataList?: ModelMixEntry[];\n modelSummaryList?: ModelMixEntry[];\n tokensUsage?: number[];\n totalUsage?: { totalModelCallCount?: number; totalTokensUsage?: number };\n x_time?: string[];\n}\n\nexport interface ZaiToolUsage {\n totalUsage?: {\n totalNetworkSearchCount?: number;\n totalSearchMcpCount?: number;\n totalWebReadMcpCount?: number;\n totalZreadMcpCount?: number;\n };\n}\n\nexport interface ZaiQuotaLimit {\n currentUsage?: number;\n nextResetTime?: string;\n percentage?: number;\n totol?: number;\n type?: string;\n usageDetails?: { modelCode?: string; usage?: number }[];\n}\n\nexport interface ZaiQuota {\n level?: string;\n limits?: ZaiQuotaLimit[];\n}\n\nexport interface RenderInput {\n apiOffsetMin?: number;\n localOffsetMin?: number;\n model: ZaiModelUsage;\n now?: Date;\n platform: string;\n quota: ZaiQuota;\n tool: ZaiToolUsage;\n}\n\ninterface Slot {\n day: string;\n h: number;\n time: string;\n}\n\nfunction parseSlot(s: string | undefined): null | Slot {\n const m = /^(\\d{4})-(\\d{2})-(\\d{2}) (\\d{2}):(\\d{2})/.exec(s ?? '');\n if (!m) {\n return null;\n }\n return {\n h: +m[4],\n day: `${MONTHS[+m[2] - 1]} ${m[3]}`,\n time: `${m[4]}:${m[5]}`,\n };\n}\n\n/**\n * Re-express a naive \"YYYY-MM-DD HH:MM\" string from one UTC offset to another.\n * Offsets are minutes east of UTC (Beijing = 480, IST = 330). Pure — does not\n * depend on the runtime timezone, so it is deterministic under test.\n */\nfunction shiftSlot(\n s: string,\n fromOffsetMin: number,\n toOffsetMin: number,\n): null | Slot {\n const m = /^(\\d{4})-(\\d{2})-(\\d{2}) (\\d{2}):(\\d{2})/.exec(s);\n if (!m) {\n return null;\n }\n const utcMs =\n Date.UTC(+m[1], +m[2] - 1, +m[3], +m[4], +m[5]) - fromOffsetMin * 60000;\n const dt = new Date(utcMs + toOffsetMin * 60000);\n return {\n h: dt.getUTCHours(),\n day: `${MONTHS[dt.getUTCMonth()]} ${pad2(dt.getUTCDate())}`,\n time: `${pad2(dt.getUTCHours())}:${pad2(dt.getUTCMinutes())}`,\n };\n}\n\nfunction friendlyTool(code: string | undefined): string {\n switch ((code ?? '').toLowerCase()) {\n case 'search-prime':\n return 'web search';\n case 'web-reader':\n return 'web read';\n default:\n return code || 'other';\n }\n}\n\nfunction idleRuns(tok: number[]): { i: number; j: number; len: number }[] {\n const runs: { i: number; j: number; len: number }[] = [];\n let i = 0;\n while (i < tok.length) {\n if ((tok[i] || 0) === 0) {\n let j = i;\n while (j < tok.length && (tok[j] || 0) === 0) {\n j++;\n }\n runs.push({ i, j: j - 1, len: j - i });\n i = j;\n } else {\n i++;\n }\n }\n return runs;\n}\n\nfunction idleLabel(\n run: { i: number; j: number; len: number },\n x: string[],\n slotFn: (s: string) => null | Slot,\n): string {\n const a = slotFn(x[run.i]);\n const b = slotFn(x[run.j]);\n if (!a || !b) {\n return `idle (${run.len}h)`;\n }\n const start = `${a.day} ${a.time}`;\n const end = a.day === b.day ? b.time : `${b.day} ${b.time}`;\n return `idle ${start} → ${end} (${run.len}h)`;\n}\n\n// Per the usage-revision notice: Mon–Fri 14:00–18:00 Beijing (UTC+8) are peak\n// hours, where GLM-5.2 / GLM-5-Turbo tokens are billed at a 3× coefficient\n// (GLM-4.7 stays 1× all day). A bucket labelled \"HH:00\" spans HH:00–HH+1, so\n// the peak buckets are HH ∈ {14,15,16,17} on a weekday.\nfunction isPeakBucket(s: string | undefined): boolean {\n const m = /^(\\d{4})-(\\d{2})-(\\d{2}) (\\d{2}):/.exec(s ?? '');\n if (!m) {\n return false;\n }\n const wd = new Date(Date.UTC(+m[1], +m[2] - 1, +m[3])).getUTCDay(); // 0=Sun … 6=Sat\n return wd >= 1 && wd <= 5 && +m[4] >= 14 && +m[4] <= 17;\n}\n\n/** Local-time start/end of the 14:00–18:00 Beijing peak window (e.g. 11:30 / 15:30). */\nfunction localPeakWindow(\n apiOffsetMin: number,\n toOffsetMin: number,\n): null | { end: string; start: string } {\n const a = shiftSlot('2000-01-03 14:00', apiOffsetMin, toOffsetMin);\n const b = shiftSlot('2000-01-03 18:00', apiOffsetMin, toOffsetMin);\n if (!a || !b) {\n return null;\n }\n return { start: a.time, end: b.time };\n}\n\n/**\n * Vertical bar chart of hourly tokens. Returns an array of plain-text lines\n * (without the section header), or null if there are fewer than 2 buckets.\n *\n * Bars are scaled to `maxTok` across `ROWS` rows; the topmost filled cell of a\n * bar uses a fractional lower-block glyph (▁▂▃▄▅▆▇) for sub-row height. The\n * y-axis labels only the peak (top) and 0 (baseline); the header window and the\n * caller's peak annotation carry the exact values.\n */\nfunction hourlyVerticalChart({\n x,\n tok,\n nh,\n maxTok,\n peakIdx,\n slotFn,\n}: {\n maxTok: number;\n nh: number;\n peakIdx: number;\n slotFn: (s: string) => null | Slot;\n tok: number[];\n x: string[];\n}): null | string[] {\n const ROWS = 6; // bar rows above the baseline\n if (nh < 2 || maxTok <= 0) {\n return null;\n }\n\n const lines: string[] = [];\n const maxLab = fmtTokens(maxTok);\n const L = maxLab.length;\n const IND = 1; // leading indent\n const AXIS = IND + L + 1; // axis spine col (1-space gap after the label)\n const P0 = AXIS + 2; // first bar column (axis + 1-char gap)\n const PW = RULE_WIDTH - P0; // columns available for bars + gaps\n const slot = Math.max(1, Math.floor(PW / nh));\n const barW = slot >= 2 ? slot - 1 : 1;\n function barLeft(i: number): number {\n return P0 + i * slot;\n }\n function barCenter(i: number): number {\n return barLeft(i) + Math.floor(barW / 2);\n }\n const usedCols = nh * slot;\n function blank(): string[] {\n return Array<string>(RULE_WIDTH).fill(' ');\n }\n\n // bar glyph for hour i at row r (0 = bottom bar-row, ROWS-1 = top)\n function glyph(i: number, r: number): string {\n const v = tok[i] || 0;\n if (v <= 0) {\n return ' ';\n }\n const fill = (v / maxTok) * ROWS - r; // how much of row r the bar covers\n if (fill >= 1) {\n return '█';\n }\n if (fill > 0) {\n let e = Math.round(fill * 8); // 1..7 eighths\n if (e < 1) {\n e = 1;\n }\n if (e > 7) {\n e = 7;\n }\n return VBLOCKS[e - 1];\n }\n return ' ';\n }\n\n // bar rows, top → bottom; top row carries the max label + '┤', rest are '│'\n for (let r = ROWS - 1; r >= 0; r--) {\n const line = blank();\n line[AXIS] = r === ROWS - 1 ? '┤' : '│';\n if (r === ROWS - 1) {\n for (let k = 0; k < L; k++) {\n line[AXIS - 1 - L + k] = maxLab[k];\n }\n }\n for (let i = 0; i < nh; i++) {\n const g = glyph(i, r);\n if (g !== ' ') {\n for (let c = 0; c < barW; c++) {\n line[barLeft(i) + c] = g;\n }\n }\n }\n lines.push(line.join('').trimEnd());\n }\n\n // x-axis ticks: first, last, and every bucket landing on a 6h boundary (local)\n function slotOf(i: number): null | Slot {\n return slotFn(x[i]);\n }\n function isTick(i: number): boolean {\n if (i === 0 || i === nh - 1) {\n return true;\n }\n const s = slotOf(i);\n return !!s && s.h % 6 === 0;\n }\n\n // baseline: '0' label + corner '└' + '─' run, with '┬' under each tick\n const base = blank();\n base[AXIS - 2] = '0';\n base[AXIS] = '└';\n for (let c = AXIS + 1; c < P0 + usedCols; c++) {\n base[c] = '─';\n }\n for (let i = 0; i < nh; i++) {\n if (isTick(i)) {\n base[barCenter(i)] = '┬';\n }\n }\n lines.push(base.join('').trimEnd());\n\n // hour labels under ticks (skip if too close to the previous label)\n const hr = blank();\n let last = -10;\n for (let i = 0; i < nh; i++) {\n if (!isTick(i)) {\n continue;\n }\n const col = barCenter(i);\n if (col - last < 3) {\n continue;\n }\n const s = slotOf(i);\n const txt = s ? pad2(s.h) : ' ';\n hr[col] = txt[0];\n hr[col + 1] = txt[1];\n last = col;\n }\n lines.push(hr.join('').trimEnd());\n\n // day labels under the first tick of each new local day\n const day = blank();\n let lastDay: null | string = null;\n last = -10;\n for (let i = 0; i < nh; i++) {\n if (!isTick(i)) {\n continue;\n }\n const s = slotOf(i);\n if (!s || s.day === lastDay) {\n continue;\n }\n const col = barCenter(i);\n if (col - last >= s.day.length && col + s.day.length <= RULE_WIDTH) {\n for (let k = 0; k < s.day.length; k++) {\n day[col + k] = s.day[k];\n }\n lastDay = s.day;\n last = col + s.day.length;\n }\n }\n if (day.some(c => c !== ' ')) {\n lines.push(day.join('').trimEnd());\n }\n\n // peak-window (↑) and peak (◂) markers under bar centers\n const mark = blank();\n for (let i = 0; i < nh; i++) {\n if (isPeakBucket(x[i])) {\n mark[barCenter(i)] = '↑';\n }\n }\n if (peakIdx >= 0) {\n mark[barCenter(peakIdx)] = '◂';\n }\n if (mark.some(c => c !== ' ')) {\n lines.push(mark.join('').trimEnd());\n }\n\n return lines;\n}\n\nexport function render({\n platform,\n model,\n tool,\n quota,\n apiOffsetMin = 480,\n localOffsetMin,\n now = new Date(),\n}: RenderInput): string {\n const out: string[] = [];\n\n // The monitor API labels every bucket in Beijing time (UTC+8). Shift each\n // timestamp to the caller's offset (minutes east of UTC) for display.\n // Defaults to the JS runtime's local zone.\n const toOffset =\n localOffsetMin != null ? localOffsetMin : -new Date().getTimezoneOffset();\n function convertSlot(s: string): null | Slot {\n return shiftSlot(s, apiOffsetMin, toOffset) ?? parseSlot(s);\n }\n\n const x = model.x_time ?? [];\n const tok = model.tokensUsage ?? [];\n const calls = model.modelCallCount ?? [];\n const nh = x.length;\n\n const tu = model.totalUsage ?? {};\n const total =\n tu.totalTokensUsage != null\n ? tu.totalTokensUsage\n : tok.reduce((a, b) => a + (b || 0), 0);\n const totalCalls =\n tu.totalModelCallCount != null\n ? tu.totalModelCallCount\n : calls.reduce((a, b) => a + (b || 0), 0);\n\n // peak hour\n let peakIdx = -1;\n let peakTok = 0;\n for (let i = 0; i < tok.length; i++) {\n if (tok[i] > peakTok) {\n peakTok = tok[i];\n peakIdx = i;\n }\n }\n const peakCalls = peakIdx >= 0 ? calls[peakIdx] || 0 : 0;\n const pctPeak = total > 0 ? (peakTok / total) * 100 : 0;\n const peakSlot = peakIdx >= 0 ? convertSlot(x[peakIdx]) : null;\n\n const level = quota.level\n ? quota.level.charAt(0).toUpperCase() + quota.level.slice(1)\n : '';\n\n const left = ` GLM Coding Plan${level ? ' · ' + level : ''}`;\n const firstSlot = convertSlot(x[0]);\n const lastSlot = convertSlot(x[nh - 1]);\n const win =\n firstSlot && lastSlot\n ? `${firstSlot.day} ${firstSlot.time} → ${lastSlot.day} ${lastSlot.time} · ${nh}h`\n : platform;\n out.push(rule());\n out.push(left + padL(win, RULE_WIDTH - left.length));\n out.push(rule());\n\n let lead = ` ${fmtTokens(total)} tokens across ${fmtNum(totalCalls)} model calls`;\n if (peakIdx >= 0 && peakSlot) {\n lead += ` — ${Math.round(pctPeak)}% of it in a single hour (${peakSlot.day} ${peakSlot.time}, ${fmtTokens(peakTok)} tokens / ${fmtNum(peakCalls)} calls)`;\n }\n lead += '.';\n out.push('');\n out.push(lead);\n\n const activeHours = tok.filter(t => t > 0).length;\n const longest = idleRuns(tok)\n .filter(r => r.len >= 2)\n .sort((a, b) => b.len - a.len)\n .at(0);\n const tt = tool.totalUsage ?? {};\n const searchN = tt.totalNetworkSearchCount || 0;\n const readN = tt.totalWebReadMcpCount || 0;\n const zreadN = tt.totalZreadMcpCount || 0;\n const toolTotal =\n tt.totalSearchMcpCount != null\n ? tt.totalSearchMcpCount\n : searchN + readN + zreadN;\n\n // how much of the window's usage fell inside the 3× billing peak hours\n let peakWinActive = 0;\n let peakWinTokens = 0;\n for (let k = 0; k < nh; k++) {\n if (isPeakBucket(x[k]) && tok[k] > 0) {\n peakWinActive++;\n peakWinTokens += tok[k];\n }\n }\n const peakWinPct = total > 0 ? (peakWinTokens / total) * 100 : 0;\n const peakWin = localPeakWindow(apiOffsetMin, toOffset);\n\n out.push('');\n out.push(\n ` Peak ${padR(peakSlot ? peakSlot.day + ' ' + peakSlot.time : '—', 15)}${padL(fmtTokens(peakTok), 7)} tokens · ${padL(fmtNum(peakCalls), 5)} calls`,\n );\n out.push(\n ` Active ${padR(`${activeHours} / ${nh} hours`, 15)}${longest ? idleLabel(longest, x, convertSlot) : 'no idle gaps'}`,\n );\n out.push(\n ` Tools ${padR(`${toolTotal} calls`, 15)}${searchN} searches · ${readN} reads${zreadN ? ` · ${zreadN} zread` : ''}`,\n );\n if (peakWin) {\n out.push(\n ` Peak hrs Mon–Fri ${peakWin.start}–${peakWin.end} · GLM-5.2 3× · ${peakWinActive}h active · ${fmtTokens(peakWinTokens)} (${Math.round(peakWinPct)}%)`,\n );\n }\n\n out.push('');\n const chartHdr = ' Hourly tokens · ↑ peak hour ';\n out.push(chartHdr + '─'.repeat(Math.max(0, RULE_WIDTH - chartHdr.length)));\n const maxTok = peakTok || 1;\n const chartLines = hourlyVerticalChart({\n x,\n tok,\n nh,\n maxTok,\n peakIdx,\n slotFn: convertSlot,\n });\n if (chartLines) {\n out.push(...chartLines);\n if (peakIdx >= 0 && peakSlot) {\n out.push(\n ` ◂ peak ${peakSlot.day} ${peakSlot.time} ${fmtTokens(peakTok)} tokens · ${fmtNum(peakCalls)} calls`,\n );\n }\n } else {\n out.push(' (not enough hourly data to chart)');\n }\n\n out.push('');\n out.push(' Model mix ' + '─'.repeat(Math.max(0, RULE_WIDTH - 11)));\n const mixSrc = model.modelSummaryList ?? model.modelDataList ?? [];\n const denom = mixSrc.reduce((a, m) => a + (m.totalTokens ?? 0), 0) || 1;\n const mixSorted = [...mixSrc].sort(\n (a, b) => (a.sortOrder || 0) - (b.sortOrder || 0),\n );\n for (const m of mixSorted) {\n const pct = ((m.totalTokens ?? 0) / denom) * 100;\n out.push(\n ` ${padR(m.modelName || '?', 11)}${padL(fmtTokens(m.totalTokens), 8)} ${padL(pct.toFixed(1) + '%', 6)} ${barField(pct, 100, 20)}`,\n );\n }\n\n out.push('');\n out.push(' Limits ' + '─'.repeat(Math.max(0, RULE_WIDTH - 8)));\n\n // Peak-window row, always present under Limits. The bar is now's progress\n // through the 14:00–18:00 Beijing window: empty before it opens, full after\n // it closes, and no fill on weekends, when the window does not bill. The\n // start/end labels come from peakWin, already shifted to the caller's offset.\n const bj = new Date(now.getTime() + apiOffsetMin * 60000);\n const bjDay = bj.getUTCDay();\n const inWindow = bjDay >= 1 && bjDay <= 5;\n const elapsedMin = inWindow\n ? Math.max(\n 0,\n Math.min(240, (bj.getUTCHours() - 14) * 60 + bj.getUTCMinutes()),\n )\n : 0;\n if (peakWin) {\n out.push(\n ` ${padR('Peak', 16)}${padL(peakWin.start, 5)} ${meter(Math.round((elapsedMin / 240) * 100), 22)} ${peakWin.end}`,\n );\n }\n\n const limits = quota.limits ?? [];\n const mcp = limits.find(l => /mcp/i.test(l.type ?? ''));\n const tok5 = limits.find(l => /token/i.test(l.type ?? ''));\n if (tok5) {\n const reset = new Date(tok5.nextResetTime ?? '').toLocaleTimeString(\n 'en-IN',\n );\n out.push(\n ` ${padR('Tokens · 5h', 16)}${padL(`${tok5.percentage || 0}%`, 5)} ${meter(tok5.percentage, 22)} ${reset}`,\n );\n }\n\n if (tok5 && mcp) {\n out.push('');\n }\n\n if (mcp) {\n const reset = new Date(mcp.nextResetTime ?? '').toLocaleString('en-IN');\n out.push(\n ` ${padR('MCP · this month', 16)}${padL(`${mcp.percentage || 0}%`, 5)} ${meter(mcp.percentage, 22)} ${reset}`,\n );\n const det = mcp.usageDetails ?? [];\n const parts = det\n .map(d => `${friendlyTool(d.modelCode)} ${fmtNum(d.usage)}`)\n .join(' ');\n if (parts) {\n out.push(\n ` ${fmtNum(mcp.currentUsage)}M / ${fmtNum(mcp.totol)}M · ${parts}`,\n );\n }\n }\n\n out.push('');\n out.push(rule());\n return out.join('\\n');\n}\n","/**\n * Usage query. Fetches model usage, tool usage, and quota limits from the GLM\n * Coding Plan monitor API of the resolved base URL (paths are fixed) and\n * renders the plain-text report.\n */\n\nimport { pad2 } from '@v1nvn/tokens/text';\n\nimport type { ZaiModelUsage, ZaiQuota, ZaiToolUsage } from './format.js';\nimport type { ResolvedConfig } from './resolve.js';\n\nimport { render } from './format.js';\n\ninterface RawLimit {\n currentValue?: number;\n nextResetTime?: string;\n percentage?: number;\n type?: string;\n usage?: number;\n usageDetails?: { modelCode?: string; usage?: number }[];\n}\n\ninterface RawQuota {\n level?: string;\n limits?: RawLimit[];\n}\n\n// Auth failures arrive as HTTP 200 with success false.\ninterface RawEnvelope {\n code?: number;\n data?: unknown;\n msg?: string;\n success?: boolean;\n}\n\n// The monitor API labels every bucket in Beijing time; the query window runs\n// from yesterday at the current hour to the end of today's current hour.\nfunction queryParams(now = new Date()): string {\n const startDate = new Date(\n now.getFullYear(),\n now.getMonth(),\n now.getDate() - 1,\n now.getHours(),\n 0,\n 0,\n 0,\n );\n const endDate = new Date(\n now.getFullYear(),\n now.getMonth(),\n now.getDate(),\n now.getHours(),\n 59,\n 59,\n 999,\n );\n function formatDateTime(date: Date): string {\n return `${date.getFullYear()}-${pad2(date.getMonth() + 1)}-${pad2(date.getDate())} ${pad2(date.getHours())}:${pad2(date.getMinutes())}:${pad2(date.getSeconds())}`;\n }\n return `?startTime=${encodeURIComponent(formatDateTime(startDate))}&endTime=${encodeURIComponent(formatDateTime(endDate))}`;\n}\n\n// Rename the API's limit kinds to their display names; `totol` is the field the\n// renderer reads (sic — the upstream spelling).\nfunction processQuotaLimit(data: RawQuota): ZaiQuota {\n if (!data.limits) {\n return data;\n }\n data.limits = data.limits.map(item => {\n if (item.type === 'TOKENS_LIMIT') {\n return {\n type: 'Token usage(5 Hour)',\n percentage: item.percentage,\n nextResetTime: item.nextResetTime,\n };\n }\n if (item.type === 'TIME_LIMIT') {\n return {\n type: 'MCP usage(1 Month)',\n percentage: item.percentage,\n currentUsage: item.currentValue,\n totol: item.usage,\n usageDetails: item.usageDetails,\n nextResetTime: item.nextResetTime,\n };\n }\n return item;\n });\n return data;\n}\n\nasync function fetchJson(\n apiUrl: string,\n label: string,\n authToken: string,\n query = '',\n): Promise<unknown> {\n const res = await fetch(apiUrl + query, {\n headers: {\n Authorization: authToken,\n 'Accept-Language': 'en-US,en',\n 'Content-Type': 'application/json',\n },\n });\n const body = await res.text();\n if (res.status !== 200) {\n throw new Error(`[${label}] HTTP ${res.status}\\n${body}`);\n }\n let json: RawEnvelope;\n try {\n json = JSON.parse(body) as RawEnvelope;\n } catch (e) {\n throw new Error(\n `[${label}] could not parse response: ${(e as Error).message}`,\n { cause: e },\n );\n }\n if (json.success === false) {\n throw new Error(\n `[${label}] ${json.msg ?? 'request failed'} (code ${json.code ?? '?'})`,\n );\n }\n return json.data ?? json;\n}\n\nexport async function fetchReport(config: ResolvedConfig): Promise<string> {\n const platform = config.url.includes('bigmodel') ? 'ZHIPU' : 'ZAI';\n\n const query = queryParams();\n try {\n const [model, tool, quotaRaw] = await Promise.all([\n fetchJson(\n `${config.url}/api/monitor/usage/model-usage`,\n 'Model usage',\n config.token,\n query,\n ),\n fetchJson(\n `${config.url}/api/monitor/usage/tool-usage`,\n 'Tool usage',\n config.token,\n query,\n ),\n fetchJson(\n `${config.url}/api/monitor/usage/quota/limit`,\n 'Quota limit',\n config.token,\n ),\n ]);\n return render({\n platform,\n model: model as ZaiModelUsage,\n tool: tool as ZaiToolUsage,\n quota: processQuotaLimit(quotaRaw as RawQuota),\n });\n } catch (e) {\n throw new Error(`Request failed: ${(e as Error).message}`, { cause: e });\n }\n}\n","import { hookOrPrint, printUsageAndExit } from '@v1nvn/agentic-core';\n\nimport { buildProgram, parseArgs, resolveConfig } from './resolve.js';\nimport { fetchReport } from './usage.js';\n\nconst parsed =\n parseArgs(process.argv.slice(2)) ?? printUsageAndExit(buildProgram());\n\nawait hookOrPrint(parsed.hook, 'query failed', () =>\n fetchReport(resolveConfig(process.env, parsed)),\n);\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../core/dist/index.js","../src/resolve.ts","../../tokens/dist/text.js","../src/format.ts","../src/usage.ts","../src/index.ts"],"sourcesContent":["import { existsSync, readFileSync, readdirSync, statSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\n//#region src/input.ts\nfunction readAll(stream) {\n\treturn new Promise((resolve, reject) => {\n\t\tlet data = \"\";\n\t\tstream.setEncoding(\"utf8\");\n\t\tstream.on(\"data\", (chunk) => {\n\t\t\tdata += chunk;\n\t\t});\n\t\tstream.on(\"end\", () => {\n\t\t\tresolve(data);\n\t\t});\n\t\tstream.on(\"error\", reject);\n\t});\n}\nfunction readStdin(stream = process.stdin) {\n\treturn readAll(stream);\n}\n/** A markdown file's contents, with the CLI's no-such-file error. */\nfunction readMarkdownFile(path) {\n\tif (!statSync(path, { throwIfNoEntry: false })?.isFile()) throw new Error(`no such file: ${path}`);\n\treturn readFileSync(path, \"utf8\");\n}\n//#endregion\n//#region src/hook.ts\n/**\n* Read the Claude Code hook event JSON from stdin; empty or unparseable input\n* yields an empty event, never a thrown error — a hook must always answer.\n*/\nfunction readHookEvent(stream = process.stdin) {\n\treturn readAll(stream).then((data) => {\n\t\ttry {\n\t\t\treturn JSON.parse(data);\n\t\t} catch {\n\t\t\treturn {};\n\t\t}\n\t}, () => ({}));\n}\n/**\n* Which transcript lastReply should read, per the hook event: transcript_path\n* when it names a real file, else session_id, else nothing (lastReply then\n* falls back to the newest session for the current project).\n*/\nfunction replyTarget(event) {\n\tif (event.transcript_path !== void 0 && isFile(event.transcript_path)) return event.transcript_path;\n\treturn event.session_id || void 0;\n}\nfunction isFile(path) {\n\ttry {\n\t\treturn statSync(path).isFile();\n\t} catch {\n\t\treturn false;\n\t}\n}\n/**\n* Print the UserPromptExpansion decision for a zero-token command: `block`\n* keeps the command from reaching the model, with the output as the `reason`.\n*/\nfunction emitHookBlock(reason) {\n\tprocess.stdout.write(`${JSON.stringify({\n\t\tdecision: \"block\",\n\t\treason\n\t})}\\n`);\n}\n//#endregion\n//#region src/cli.ts\nfunction parseQuietly(program, args, recover) {\n\ttry {\n\t\tprogram.allowExcessArguments(false).exitOverride().configureOutput({\n\t\t\twriteOut: () => void 0,\n\t\t\twriteErr: () => void 0\n\t\t}).parse([...args], { from: \"user\" });\n\t\treturn program;\n\t} catch (err) {\n\t\treturn recover?.(err);\n\t}\n}\nfunction printUsageAndExit(program) {\n\tconsole.error(program.helpInformation());\n\tprocess.exit(1);\n}\nasync function hookOrPrint(hook, failure, run, stdin = process.stdin) {\n\tif (hook) {\n\t\tlet reason;\n\t\ttry {\n\t\t\treason = await run(await readHookEvent(stdin));\n\t\t} catch (e) {\n\t\t\treason = `${failure}: ${e.message}`;\n\t\t}\n\t\temitHookBlock(reason);\n\t\treturn;\n\t}\n\ttry {\n\t\tconsole.log(await run(void 0));\n\t} catch (e) {\n\t\tconsole.error(e.message);\n\t\tprocess.exit(1);\n\t}\n}\n//#endregion\n//#region src/dev.ts\nvar RELOAD_DEBOUNCE_MS = 150;\nvar IGNORED_SEGMENTS = [\n\t\"/node_modules/\",\n\t\"/dist/\",\n\t\"/.git/\",\n\t\"/coverage/\"\n];\nfunction shouldReload(file) {\n\treturn IGNORED_SEGMENTS.every((seg) => !file.includes(seg));\n}\n/**\n* Debounced file-change reloads, serialized via a promise chain: concurrent\n* saves never overlap, and a mid-reload save still produces a follow-up.\n*/\nfunction watchWithReload(vite, reload) {\n\tlet chain = Promise.resolve();\n\tlet timer;\n\tvite.watcher.on(\"change\", (file) => {\n\t\tif (!shouldReload(file)) return;\n\t\tif (timer) clearTimeout(timer);\n\t\ttimer = setTimeout(() => {\n\t\t\ttimer = void 0;\n\t\t\tchain = chain.then(reload);\n\t\t}, RELOAD_DEBOUNCE_MS);\n\t});\n}\n//#endregion\n//#region src/last-reply.ts\nfunction textBlocks(entry) {\n\tconst content = entry.message?.content;\n\tif (entry.type !== \"assistant\" || !Array.isArray(content)) return;\n\tconst blocks = content.filter((b) => typeof b === \"object\" && b !== null && b.type === \"text\");\n\treturn blocks.length > 0 ? blocks : void 0;\n}\nfunction claudeProjectsDir() {\n\tconst claudeDir = process.env.CLAUDE_DIR ?? join(homedir(), \".claude\");\n\treturn join(claudeDir, \"projects\");\n}\n/**\n* The last assistant text reply from a Claude Code session, reproducing Claude\n* Code's `/copy` byte-for-byte: the last assistant entry that contains a\n* `text` block, only its `text` block(s) (tool_use / thinking dropped), blocks\n* joined with a blank line, and no trailing newline.\n*\n* @param arg a transcript file, a session UUID under the project dir, or\n* nothing to use the newest session for the current project.\n*/\nfunction lastReply(arg) {\n\tconst proj = (process.env.CLAUDE_PROJECT_DIR ?? process.cwd()).replaceAll(\"/\", \"-\");\n\tconst projDir = join(claudeProjectsDir(), proj);\n\tlet file;\n\tif (arg !== void 0) file = isFile(arg) ? arg : join(projDir, `${arg}.jsonl`);\n\telse if (existsSync(projDir)) {\n\t\tconst newest = readdirSync(projDir).filter((f) => f.endsWith(\".jsonl\")).map((f) => ({\n\t\t\tf,\n\t\t\tmtimeMs: statSync(join(projDir, f)).mtimeMs\n\t\t})).sort((a, b) => b.mtimeMs - a.mtimeMs).at(0);\n\t\tif (newest) file = join(projDir, newest.f);\n\t}\n\tif (file === void 0 || !isFile(file)) throw new Error(`no session transcript found in ${projDir}`);\n\tlet last;\n\tfor (const line of readFileSync(file, \"utf8\").split(\"\\n\")) {\n\t\tif (!line.includes(\"\\\"assistant\\\"\")) continue;\n\t\tlet entry;\n\t\ttry {\n\t\t\tentry = JSON.parse(line);\n\t\t} catch {\n\t\t\tcontinue;\n\t\t}\n\t\tconst blocks = textBlocks(entry);\n\t\tif (blocks) last = blocks;\n\t}\n\treturn (last ?? []).map((b) => b.text ?? \"\").join(\"\\n\\n\");\n}\n//#endregion\n//#region src/logger.ts\nvar LEVEL_RANK = {\n\tdebug: 10,\n\tinfo: 20,\n\twarn: 30,\n\terror: 40,\n\tsilent: Number.MAX_SAFE_INTEGER\n};\nfunction levelEnabled(active, wanted) {\n\treturn LEVEL_RANK[wanted] >= LEVEL_RANK[active];\n}\nvar LEVEL_LABEL = {\n\tdebug: \"DEBUG\",\n\terror: \"ERROR\",\n\tinfo: \"INFO\",\n\twarn: \"WARN\"\n};\nvar Logger = class {\n\tactiveLevel;\n\tstderr;\n\tconstructor(activeLevel, stderr = (line) => process.stderr.write(`${line}\\n`)) {\n\t\tthis.activeLevel = activeLevel;\n\t\tthis.stderr = stderr;\n\t}\n\tdebug(message) {\n\t\tthis.log(\"debug\", message);\n\t}\n\terror(message) {\n\t\tthis.log(\"error\", message);\n\t}\n\tinfo(message) {\n\t\tthis.log(\"info\", message);\n\t}\n\twarn(message) {\n\t\tthis.log(\"warn\", message);\n\t}\n\tlog(level, message) {\n\t\tif (levelEnabled(this.activeLevel, level)) this.stderr(`${LEVEL_LABEL[level]} ${message}`);\n\t}\n};\n//#endregion\n//#region src/shutdown.ts\n/** Close each closable in order (best-effort), then force-exit. */\nfunction shutdownOnSignals(closables, signals = [\"SIGINT\", \"SIGTERM\"]) {\n\tfunction shutdown() {\n\t\tclosables.reduce((acc, closable) => acc.then(async () => {\n\t\t\ttry {\n\t\t\t\tawait closable.close();\n\t\t\t} catch {}\n\t\t}), Promise.resolve()).finally(() => {\n\t\t\tprocess.exit(0);\n\t\t});\n\t}\n\tfor (const signal of signals) process.on(signal, shutdown);\n}\n//#endregion\nexport { Logger, claudeProjectsDir, emitHookBlock, hookOrPrint, isFile, lastReply, levelEnabled, parseQuietly, printUsageAndExit, readAll, readHookEvent, readMarkdownFile, readStdin, replyTarget, shutdownOnSignals, watchWithReload };\n\n//# sourceMappingURL=index.js.map","import { parseQuietly } from '@v1nvn/agentic-core';\nimport { Command, Option } from 'commander';\n\nconst DEFAULT_BASE_URL = 'https://api.z.ai';\n\nconst GLM_HOSTS = new Set(['api.z.ai', 'dev.bigmodel.cn', 'open.bigmodel.cn']);\n\nexport interface ParsedArgs {\n readonly authToken: string | undefined;\n readonly baseUrl: string | undefined;\n readonly hook: boolean;\n}\n\nexport interface ResolvedConfig {\n readonly token: string;\n readonly url: string;\n}\n\ninterface BaseUrl {\n readonly glm: boolean;\n readonly origin: string;\n}\n\nfunction fromEnv(value: string | undefined): string | undefined {\n return value ? value : undefined;\n}\n\nfunction originOf(value: string): string | undefined {\n try {\n const url = new URL(value);\n return url.protocol === 'https:' || url.protocol === 'http:'\n ? url.origin\n : undefined;\n } catch {\n return undefined;\n }\n}\n\nfunction isGlm(origin: string): boolean {\n return GLM_HOSTS.has(new URL(origin).hostname);\n}\n\nfunction resolveBaseUrl(\n flag: string | undefined,\n env: NodeJS.ProcessEnv,\n): BaseUrl {\n if (flag !== undefined) {\n const origin = originOf(flag);\n if (origin === undefined) {\n throw new Error(`invalid base URL: ${flag}`);\n }\n return { glm: isGlm(origin), origin };\n }\n const inherited = fromEnv(env.ANTHROPIC_BASE_URL);\n const origin = inherited === undefined ? undefined : originOf(inherited);\n if (origin !== undefined && isGlm(origin)) {\n return { glm: true, origin };\n }\n return { glm: false, origin: DEFAULT_BASE_URL };\n}\n\nexport function buildProgram(): Command {\n return new Command()\n .name('zai-usage')\n .addOption(\n new Option('--auth-token <token>', 'API key').env('ZAI_AUTH_TOKEN'),\n )\n .addOption(new Option('--base-url <url>', 'base URL').env('ZAI_BASE_URL'))\n .option('--hook', 'emit a UserPromptExpansion block instead of printing');\n}\n\nexport function parseArgs(args: readonly string[]): ParsedArgs | undefined {\n const program = parseQuietly(buildProgram(), args);\n if (program === undefined) {\n return undefined;\n }\n const { authToken, baseUrl, hook } = program.opts<{\n authToken: string | undefined;\n baseUrl: string | undefined;\n hook: boolean | undefined;\n }>();\n return {\n authToken: authToken || undefined,\n baseUrl: baseUrl || undefined,\n hook: hook ?? false,\n };\n}\n\nexport function resolveConfig(\n env: NodeJS.ProcessEnv,\n parsed: ParsedArgs,\n): ResolvedConfig {\n const base = resolveBaseUrl(parsed.baseUrl, env);\n const token =\n parsed.authToken ??\n (base.glm ? fromEnv(env.ANTHROPIC_AUTH_TOKEN) : undefined);\n if (token === undefined) {\n throw new Error(\n env.ANTHROPIC_AUTH_TOKEN\n ? 'ANTHROPIC_AUTH_TOKEN is set, but the resolved base URL does not name a GLM host, so it is not a GLM Coding Plan token — set ZAI_AUTH_TOKEN (or --auth-token)'\n : 'no API key: set ZAI_AUTH_TOKEN (or --auth-token)',\n );\n }\n return { token, url: base.origin };\n}\n","//#region src/text.ts\n/**\n* Plain-text rendering primitives for the fixed-width reports. Output targets\n* a monospace terminal — the pane — so everything here is fixed-width:\n* padding, block-glyph bars, and compact number formatting.\n*/\nvar MONTHS = [\n\t\"Jan\",\n\t\"Feb\",\n\t\"Mar\",\n\t\"Apr\",\n\t\"May\",\n\t\"Jun\",\n\t\"Jul\",\n\t\"Aug\",\n\t\"Sep\",\n\t\"Oct\",\n\t\"Nov\",\n\t\"Dec\"\n];\nvar EIGHTHS = [\n\t\"\",\n\t\"▏\",\n\t\"▎\",\n\t\"▍\",\n\t\"▌\",\n\t\"▋\",\n\t\"▊\",\n\t\"▉\"\n];\nvar RULE_WIDTH = 68;\nfunction rule() {\n\treturn \"─\".repeat(68);\n}\n/** '2026-08-15' → 'Aug 15'. */\nfunction dayLabel(day) {\n\tconst [, , month, date] = /^(\\d{4})-(\\d{2})-(\\d{2})$/.exec(day) ?? [];\n\treturn month !== void 0 && date !== void 0 ? `${MONTHS[+month - 1] ?? day} ${date}` : day;\n}\nfunction fmtClock(date) {\n\treturn `${pad2(date.getHours())}:${pad2(date.getMinutes())}`;\n}\nfunction pad2(n) {\n\treturn String(n).padStart(2, \"0\");\n}\n/** Local-time `YYYY-MM-DD` key. */\nfunction ymd(date) {\n\treturn `${date.getFullYear()}-${pad2(date.getMonth() + 1)}-${pad2(date.getDate())}`;\n}\nfunction fmtTokens(n) {\n\tif (n == null || Number.isNaN(n)) return \"—\";\n\tif (n >= 1e9) return (n / 1e9).toFixed(1) + \"B\";\n\tif (n >= 1e6) return (n / 1e6).toFixed(1) + \"M\";\n\tif (n >= 1e3) return (n / 1e3).toFixed(1) + \"K\";\n\treturn String(n);\n}\nfunction fmtNum(n) {\n\treturn (n || 0).toLocaleString(\"en-US\");\n}\nfunction padR(s, n) {\n\treturn s.length >= n ? s : s + \" \".repeat(n - s.length);\n}\nfunction padL(s, n) {\n\treturn s.length >= n ? s : \" \".repeat(n - s.length) + s;\n}\n/** Fixed-width bar field (width cols): █ blocks + an eighth-fraction + trailing spaces. */\nfunction barField(v, max, width) {\n\tif (!v || v <= 0 || max <= 0) return \" \".repeat(width);\n\tconst scaled = v / max * width;\n\tlet full = Math.floor(scaled);\n\tlet fi = Math.round((scaled - full) * 8);\n\tif (fi === 8) {\n\t\tfull += 1;\n\t\tfi = 0;\n\t}\n\tif (full === 0 && fi === 0) fi = 1;\n\tlet s = \"█\".repeat(Math.min(full, width));\n\tif (full < width && fi > 0) s += EIGHTHS[fi] ?? \"\";\n\tif (s.length < width) s += \" \".repeat(width - s.length);\n\treturn s.slice(0, width);\n}\n/** Filled/empty meter: █ for used, ░ for remaining. */\nfunction meter(pct, width) {\n\tlet filled = Math.round((pct || 0) / 100 * width);\n\tfilled = Math.max(0, Math.min(width, filled));\n\treturn \"█\".repeat(filled) + \"░\".repeat(width - filled);\n}\n//#endregion\nexport { MONTHS, RULE_WIDTH, barField, dayLabel, fmtClock, fmtNum, fmtTokens, meter, pad2, padL, padR, rule, ymd };\n\n//# sourceMappingURL=text.js.map","/**\n * Plain-text usage report renderer.\n *\n * Rendered for a monospace terminal / hook-block `reason`, so it must NOT rely on\n * markdown (bold, tables, fenced code). Alignment comes from fixed-width columns\n * and unicode block glyphs. Input is the parsed `data` of the three ZAI/ZHIPU\n * monitor endpoints (model-usage, tool-usage, quota/limit — the last already\n * passed through processQuotaLimit).\n */\n\nimport {\n barField,\n fmtNum,\n fmtTokens,\n meter,\n MONTHS,\n pad2,\n padL,\n padR,\n rule,\n RULE_WIDTH,\n} from '@v1nvn/tokens/text';\n\n// Lower-half block eighths for vertical bars (1/8 .. 7/8); a full cell uses '█'.\nconst VBLOCKS = '▁▂▃▄▅▆▇';\n\nexport interface ModelMixEntry {\n modelName?: string;\n sortOrder?: number;\n totalTokens?: number;\n}\n\nexport interface ZaiModelUsage {\n modelCallCount?: number[];\n modelDataList?: ModelMixEntry[];\n modelSummaryList?: ModelMixEntry[];\n tokensUsage?: number[];\n totalUsage?: { totalModelCallCount?: number; totalTokensUsage?: number };\n x_time?: string[];\n}\n\nexport interface ZaiToolUsage {\n totalUsage?: {\n totalNetworkSearchCount?: number;\n totalSearchMcpCount?: number;\n totalWebReadMcpCount?: number;\n totalZreadMcpCount?: number;\n };\n}\n\nexport interface ZaiQuotaLimit {\n currentUsage?: number;\n nextResetTime?: string;\n percentage?: number;\n totol?: number;\n type?: string;\n usageDetails?: { modelCode?: string; usage?: number }[];\n}\n\nexport interface ZaiQuota {\n level?: string;\n limits?: ZaiQuotaLimit[];\n}\n\nexport interface RenderInput {\n apiOffsetMin?: number;\n localOffsetMin?: number;\n model: ZaiModelUsage;\n now?: Date;\n platform: string;\n quota: ZaiQuota;\n tool: ZaiToolUsage;\n}\n\ninterface Slot {\n day: string;\n h: number;\n time: string;\n}\n\nfunction parseSlot(s: string | undefined): null | Slot {\n const m = /^(\\d{4})-(\\d{2})-(\\d{2}) (\\d{2}):(\\d{2})/.exec(s ?? '');\n if (!m) {\n return null;\n }\n return {\n h: +m[4],\n day: `${MONTHS[+m[2] - 1]} ${m[3]}`,\n time: `${m[4]}:${m[5]}`,\n };\n}\n\n/**\n * Re-express a naive \"YYYY-MM-DD HH:MM\" string from one UTC offset to another.\n * Offsets are minutes east of UTC (Beijing = 480, IST = 330). Pure — does not\n * depend on the runtime timezone, so it is deterministic under test.\n */\nfunction shiftSlot(\n s: string,\n fromOffsetMin: number,\n toOffsetMin: number,\n): null | Slot {\n const m = /^(\\d{4})-(\\d{2})-(\\d{2}) (\\d{2}):(\\d{2})/.exec(s);\n if (!m) {\n return null;\n }\n const utcMs =\n Date.UTC(+m[1], +m[2] - 1, +m[3], +m[4], +m[5]) - fromOffsetMin * 60000;\n const dt = new Date(utcMs + toOffsetMin * 60000);\n return {\n h: dt.getUTCHours(),\n day: `${MONTHS[dt.getUTCMonth()]} ${pad2(dt.getUTCDate())}`,\n time: `${pad2(dt.getUTCHours())}:${pad2(dt.getUTCMinutes())}`,\n };\n}\n\nfunction friendlyTool(code: string | undefined): string {\n switch ((code ?? '').toLowerCase()) {\n case 'search-prime':\n return 'web search';\n case 'web-reader':\n return 'web read';\n default:\n return code || 'other';\n }\n}\n\nfunction idleRuns(tok: number[]): { i: number; j: number; len: number }[] {\n const runs: { i: number; j: number; len: number }[] = [];\n let i = 0;\n while (i < tok.length) {\n if ((tok[i] || 0) === 0) {\n let j = i;\n while (j < tok.length && (tok[j] || 0) === 0) {\n j++;\n }\n runs.push({ i, j: j - 1, len: j - i });\n i = j;\n } else {\n i++;\n }\n }\n return runs;\n}\n\nfunction idleLabel(\n run: { i: number; j: number; len: number },\n x: string[],\n slotFn: (s: string) => null | Slot,\n): string {\n const a = slotFn(x[run.i]);\n const b = slotFn(x[run.j]);\n if (!a || !b) {\n return `idle (${run.len}h)`;\n }\n const start = `${a.day} ${a.time}`;\n const end = a.day === b.day ? b.time : `${b.day} ${b.time}`;\n return `idle ${start} → ${end} (${run.len}h)`;\n}\n\n// Per the usage-revision notice: Mon–Fri 14:00–18:00 Beijing (UTC+8) are peak\n// hours, where GLM-5.2 / GLM-5-Turbo tokens are billed at a 3× coefficient\n// (GLM-4.7 stays 1× all day). A bucket labelled \"HH:00\" spans HH:00–HH+1, so\n// the peak buckets are HH ∈ {14,15,16,17} on a weekday.\nfunction isPeakBucket(s: string | undefined): boolean {\n const m = /^(\\d{4})-(\\d{2})-(\\d{2}) (\\d{2}):/.exec(s ?? '');\n if (!m) {\n return false;\n }\n const wd = new Date(Date.UTC(+m[1], +m[2] - 1, +m[3])).getUTCDay(); // 0=Sun … 6=Sat\n return wd >= 1 && wd <= 5 && +m[4] >= 14 && +m[4] <= 17;\n}\n\n/** Local-time start/end of the 14:00–18:00 Beijing peak window (e.g. 11:30 / 15:30). */\nfunction localPeakWindow(\n apiOffsetMin: number,\n toOffsetMin: number,\n): null | { end: string; start: string } {\n const a = shiftSlot('2000-01-03 14:00', apiOffsetMin, toOffsetMin);\n const b = shiftSlot('2000-01-03 18:00', apiOffsetMin, toOffsetMin);\n if (!a || !b) {\n return null;\n }\n return { start: a.time, end: b.time };\n}\n\n/**\n * Vertical bar chart of hourly tokens. Returns an array of plain-text lines\n * (without the section header), or null if there are fewer than 2 buckets.\n *\n * Bars are scaled to `maxTok` across `ROWS` rows; the topmost filled cell of a\n * bar uses a fractional lower-block glyph (▁▂▃▄▅▆▇) for sub-row height. The\n * y-axis labels only the peak (top) and 0 (baseline); the header window and the\n * caller's peak annotation carry the exact values.\n */\nfunction hourlyVerticalChart({\n x,\n tok,\n nh,\n maxTok,\n peakIdx,\n slotFn,\n}: {\n maxTok: number;\n nh: number;\n peakIdx: number;\n slotFn: (s: string) => null | Slot;\n tok: number[];\n x: string[];\n}): null | string[] {\n const ROWS = 6; // bar rows above the baseline\n if (nh < 2 || maxTok <= 0) {\n return null;\n }\n\n const lines: string[] = [];\n const maxLab = fmtTokens(maxTok);\n const L = maxLab.length;\n const IND = 1; // leading indent\n const AXIS = IND + L + 1; // axis spine col (1-space gap after the label)\n const P0 = AXIS + 2; // first bar column (axis + 1-char gap)\n const PW = RULE_WIDTH - P0; // columns available for bars + gaps\n const slot = Math.max(1, Math.floor(PW / nh));\n const barW = slot >= 2 ? slot - 1 : 1;\n function barLeft(i: number): number {\n return P0 + i * slot;\n }\n function barCenter(i: number): number {\n return barLeft(i) + Math.floor(barW / 2);\n }\n const usedCols = nh * slot;\n function blank(): string[] {\n return Array<string>(RULE_WIDTH).fill(' ');\n }\n\n // bar glyph for hour i at row r (0 = bottom bar-row, ROWS-1 = top)\n function glyph(i: number, r: number): string {\n const v = tok[i] || 0;\n if (v <= 0) {\n return ' ';\n }\n const fill = (v / maxTok) * ROWS - r; // how much of row r the bar covers\n if (fill >= 1) {\n return '█';\n }\n if (fill > 0) {\n let e = Math.round(fill * 8); // 1..7 eighths\n if (e < 1) {\n e = 1;\n }\n if (e > 7) {\n e = 7;\n }\n return VBLOCKS[e - 1];\n }\n return ' ';\n }\n\n // bar rows, top → bottom; top row carries the max label + '┤', rest are '│'\n for (let r = ROWS - 1; r >= 0; r--) {\n const line = blank();\n line[AXIS] = r === ROWS - 1 ? '┤' : '│';\n if (r === ROWS - 1) {\n for (let k = 0; k < L; k++) {\n line[AXIS - 1 - L + k] = maxLab[k];\n }\n }\n for (let i = 0; i < nh; i++) {\n const g = glyph(i, r);\n if (g !== ' ') {\n for (let c = 0; c < barW; c++) {\n line[barLeft(i) + c] = g;\n }\n }\n }\n lines.push(line.join('').trimEnd());\n }\n\n // x-axis ticks: first, last, and every bucket landing on a 6h boundary (local)\n function slotOf(i: number): null | Slot {\n return slotFn(x[i]);\n }\n function isTick(i: number): boolean {\n if (i === 0 || i === nh - 1) {\n return true;\n }\n const s = slotOf(i);\n return !!s && s.h % 6 === 0;\n }\n\n // baseline: '0' label + corner '└' + '─' run, with '┬' under each tick\n const base = blank();\n base[AXIS - 2] = '0';\n base[AXIS] = '└';\n for (let c = AXIS + 1; c < P0 + usedCols; c++) {\n base[c] = '─';\n }\n for (let i = 0; i < nh; i++) {\n if (isTick(i)) {\n base[barCenter(i)] = '┬';\n }\n }\n lines.push(base.join('').trimEnd());\n\n // hour labels under ticks (skip if too close to the previous label)\n const hr = blank();\n let last = -10;\n for (let i = 0; i < nh; i++) {\n if (!isTick(i)) {\n continue;\n }\n const col = barCenter(i);\n if (col - last < 3) {\n continue;\n }\n const s = slotOf(i);\n const txt = s ? pad2(s.h) : ' ';\n hr[col] = txt[0];\n hr[col + 1] = txt[1];\n last = col;\n }\n lines.push(hr.join('').trimEnd());\n\n // day labels under the first tick of each new local day\n const day = blank();\n let lastDay: null | string = null;\n last = -10;\n for (let i = 0; i < nh; i++) {\n if (!isTick(i)) {\n continue;\n }\n const s = slotOf(i);\n if (!s || s.day === lastDay) {\n continue;\n }\n const col = barCenter(i);\n if (col - last >= s.day.length && col + s.day.length <= RULE_WIDTH) {\n for (let k = 0; k < s.day.length; k++) {\n day[col + k] = s.day[k];\n }\n lastDay = s.day;\n last = col + s.day.length;\n }\n }\n if (day.some(c => c !== ' ')) {\n lines.push(day.join('').trimEnd());\n }\n\n // peak-window (↑) and peak (◂) markers under bar centers\n const mark = blank();\n for (let i = 0; i < nh; i++) {\n if (isPeakBucket(x[i])) {\n mark[barCenter(i)] = '↑';\n }\n }\n if (peakIdx >= 0) {\n mark[barCenter(peakIdx)] = '◂';\n }\n if (mark.some(c => c !== ' ')) {\n lines.push(mark.join('').trimEnd());\n }\n\n return lines;\n}\n\nexport function render({\n platform,\n model,\n tool,\n quota,\n apiOffsetMin = 480,\n localOffsetMin,\n now = new Date(),\n}: RenderInput): string {\n const out: string[] = [];\n\n // The monitor API labels every bucket in Beijing time (UTC+8). Shift each\n // timestamp to the caller's offset (minutes east of UTC) for display.\n // Defaults to the JS runtime's local zone.\n const toOffset =\n localOffsetMin != null ? localOffsetMin : -new Date().getTimezoneOffset();\n function convertSlot(s: string): null | Slot {\n return shiftSlot(s, apiOffsetMin, toOffset) ?? parseSlot(s);\n }\n\n const x = model.x_time ?? [];\n const tok = model.tokensUsage ?? [];\n const calls = model.modelCallCount ?? [];\n const nh = x.length;\n\n const tu = model.totalUsage ?? {};\n const total =\n tu.totalTokensUsage != null\n ? tu.totalTokensUsage\n : tok.reduce((a, b) => a + (b || 0), 0);\n const totalCalls =\n tu.totalModelCallCount != null\n ? tu.totalModelCallCount\n : calls.reduce((a, b) => a + (b || 0), 0);\n\n // peak hour\n let peakIdx = -1;\n let peakTok = 0;\n for (let i = 0; i < tok.length; i++) {\n if (tok[i] > peakTok) {\n peakTok = tok[i];\n peakIdx = i;\n }\n }\n const peakCalls = peakIdx >= 0 ? calls[peakIdx] || 0 : 0;\n const pctPeak = total > 0 ? (peakTok / total) * 100 : 0;\n const peakSlot = peakIdx >= 0 ? convertSlot(x[peakIdx]) : null;\n\n const level = quota.level\n ? quota.level.charAt(0).toUpperCase() + quota.level.slice(1)\n : '';\n\n const left = ` GLM Coding Plan${level ? ' · ' + level : ''}`;\n const firstSlot = convertSlot(x[0]);\n const lastSlot = convertSlot(x[nh - 1]);\n const win =\n firstSlot && lastSlot\n ? `${firstSlot.day} ${firstSlot.time} → ${lastSlot.day} ${lastSlot.time} · ${nh}h`\n : platform;\n out.push(rule());\n out.push(left + padL(win, RULE_WIDTH - left.length));\n out.push(rule());\n\n let lead = ` ${fmtTokens(total)} tokens across ${fmtNum(totalCalls)} model calls`;\n if (peakIdx >= 0 && peakSlot) {\n lead += ` — ${Math.round(pctPeak)}% of it in a single hour (${peakSlot.day} ${peakSlot.time}, ${fmtTokens(peakTok)} tokens / ${fmtNum(peakCalls)} calls)`;\n }\n lead += '.';\n out.push('');\n out.push(lead);\n\n const activeHours = tok.filter(t => t > 0).length;\n const longest = idleRuns(tok)\n .filter(r => r.len >= 2)\n .sort((a, b) => b.len - a.len)\n .at(0);\n const tt = tool.totalUsage ?? {};\n const searchN = tt.totalNetworkSearchCount || 0;\n const readN = tt.totalWebReadMcpCount || 0;\n const zreadN = tt.totalZreadMcpCount || 0;\n const toolTotal =\n tt.totalSearchMcpCount != null\n ? tt.totalSearchMcpCount\n : searchN + readN + zreadN;\n\n // how much of the window's usage fell inside the 3× billing peak hours\n let peakWinActive = 0;\n let peakWinTokens = 0;\n for (let k = 0; k < nh; k++) {\n if (isPeakBucket(x[k]) && tok[k] > 0) {\n peakWinActive++;\n peakWinTokens += tok[k];\n }\n }\n const peakWinPct = total > 0 ? (peakWinTokens / total) * 100 : 0;\n const peakWin = localPeakWindow(apiOffsetMin, toOffset);\n\n out.push('');\n out.push(\n ` Peak ${padR(peakSlot ? peakSlot.day + ' ' + peakSlot.time : '—', 15)}${padL(fmtTokens(peakTok), 7)} tokens · ${padL(fmtNum(peakCalls), 5)} calls`,\n );\n out.push(\n ` Active ${padR(`${activeHours} / ${nh} hours`, 15)}${longest ? idleLabel(longest, x, convertSlot) : 'no idle gaps'}`,\n );\n out.push(\n ` Tools ${padR(`${toolTotal} calls`, 15)}${searchN} searches · ${readN} reads${zreadN ? ` · ${zreadN} zread` : ''}`,\n );\n if (peakWin) {\n out.push(\n ` Peak hrs Mon–Fri ${peakWin.start}–${peakWin.end} · GLM-5.2 3× · ${peakWinActive}h active · ${fmtTokens(peakWinTokens)} (${Math.round(peakWinPct)}%)`,\n );\n }\n\n out.push('');\n const chartHdr = ' Hourly tokens · ↑ peak hour ';\n out.push(chartHdr + '─'.repeat(Math.max(0, RULE_WIDTH - chartHdr.length)));\n const maxTok = peakTok || 1;\n const chartLines = hourlyVerticalChart({\n x,\n tok,\n nh,\n maxTok,\n peakIdx,\n slotFn: convertSlot,\n });\n if (chartLines) {\n out.push(...chartLines);\n if (peakIdx >= 0 && peakSlot) {\n out.push(\n ` ◂ peak ${peakSlot.day} ${peakSlot.time} ${fmtTokens(peakTok)} tokens · ${fmtNum(peakCalls)} calls`,\n );\n }\n } else {\n out.push(' (not enough hourly data to chart)');\n }\n\n out.push('');\n out.push(' Model mix ' + '─'.repeat(Math.max(0, RULE_WIDTH - 11)));\n const mixSrc = model.modelSummaryList ?? model.modelDataList ?? [];\n const denom = mixSrc.reduce((a, m) => a + (m.totalTokens ?? 0), 0) || 1;\n const mixSorted = [...mixSrc].sort(\n (a, b) => (a.sortOrder || 0) - (b.sortOrder || 0),\n );\n for (const m of mixSorted) {\n const pct = ((m.totalTokens ?? 0) / denom) * 100;\n out.push(\n ` ${padR(m.modelName || '?', 11)}${padL(fmtTokens(m.totalTokens), 8)} ${padL(pct.toFixed(1) + '%', 6)} ${barField(pct, 100, 20)}`,\n );\n }\n\n out.push('');\n out.push(' Limits ' + '─'.repeat(Math.max(0, RULE_WIDTH - 8)));\n\n // Peak-window row, always present under Limits. The bar is now's progress\n // through the 14:00–18:00 Beijing window: empty before it opens, full after\n // it closes, and no fill on weekends, when the window does not bill. The\n // start/end labels come from peakWin, already shifted to the caller's offset.\n const bj = new Date(now.getTime() + apiOffsetMin * 60000);\n const bjDay = bj.getUTCDay();\n const inWindow = bjDay >= 1 && bjDay <= 5;\n const elapsedMin = inWindow\n ? Math.max(\n 0,\n Math.min(240, (bj.getUTCHours() - 14) * 60 + bj.getUTCMinutes()),\n )\n : 0;\n if (peakWin) {\n out.push(\n ` ${padR('Peak', 16)}${padL(peakWin.start, 5)} ${meter(Math.round((elapsedMin / 240) * 100), 22)} ${peakWin.end}`,\n );\n }\n\n const limits = quota.limits ?? [];\n const mcp = limits.find(l => /mcp/i.test(l.type ?? ''));\n const tok5 = limits.find(l => /token/i.test(l.type ?? ''));\n if (tok5) {\n const reset = new Date(tok5.nextResetTime ?? '').toLocaleTimeString(\n 'en-IN',\n );\n out.push(\n ` ${padR('Tokens · 5h', 16)}${padL(`${tok5.percentage || 0}%`, 5)} ${meter(tok5.percentage, 22)} ${reset}`,\n );\n }\n\n if (tok5 && mcp) {\n out.push('');\n }\n\n if (mcp) {\n const reset = new Date(mcp.nextResetTime ?? '').toLocaleString('en-IN');\n out.push(\n ` ${padR('MCP · this month', 16)}${padL(`${mcp.percentage || 0}%`, 5)} ${meter(mcp.percentage, 22)} ${reset}`,\n );\n const det = mcp.usageDetails ?? [];\n const parts = det\n .map(d => `${friendlyTool(d.modelCode)} ${fmtNum(d.usage)}`)\n .join(' ');\n if (parts) {\n out.push(\n ` ${fmtNum(mcp.currentUsage)}M / ${fmtNum(mcp.totol)}M · ${parts}`,\n );\n }\n }\n\n out.push('');\n out.push(rule());\n return out.join('\\n');\n}\n","/**\n * Usage query. Fetches model usage, tool usage, and quota limits from the GLM\n * Coding Plan monitor API of the resolved base URL (paths are fixed) and\n * renders the plain-text report.\n */\n\nimport { pad2 } from '@v1nvn/tokens/text';\n\nimport type { ZaiModelUsage, ZaiQuota, ZaiToolUsage } from './format.js';\nimport type { ResolvedConfig } from './resolve.js';\n\nimport { render } from './format.js';\n\ninterface RawLimit {\n currentValue?: number;\n nextResetTime?: string;\n percentage?: number;\n type?: string;\n usage?: number;\n usageDetails?: { modelCode?: string; usage?: number }[];\n}\n\ninterface RawQuota {\n level?: string;\n limits?: RawLimit[];\n}\n\n// Auth failures arrive as HTTP 200 with success false.\ninterface RawEnvelope {\n code?: number;\n data?: unknown;\n msg?: string;\n success?: boolean;\n}\n\n// The monitor API labels every bucket in Beijing time; the query window runs\n// from yesterday at the current hour to the end of today's current hour.\nfunction queryParams(now = new Date()): string {\n const startDate = new Date(\n now.getFullYear(),\n now.getMonth(),\n now.getDate() - 1,\n now.getHours(),\n 0,\n 0,\n 0,\n );\n const endDate = new Date(\n now.getFullYear(),\n now.getMonth(),\n now.getDate(),\n now.getHours(),\n 59,\n 59,\n 999,\n );\n function formatDateTime(date: Date): string {\n return `${date.getFullYear()}-${pad2(date.getMonth() + 1)}-${pad2(date.getDate())} ${pad2(date.getHours())}:${pad2(date.getMinutes())}:${pad2(date.getSeconds())}`;\n }\n return `?startTime=${encodeURIComponent(formatDateTime(startDate))}&endTime=${encodeURIComponent(formatDateTime(endDate))}`;\n}\n\n// Rename the API's limit kinds to their display names; `totol` is the field the\n// renderer reads (sic — the upstream spelling).\nfunction processQuotaLimit(data: RawQuota): ZaiQuota {\n if (!data.limits) {\n return data;\n }\n data.limits = data.limits.map(item => {\n if (item.type === 'TOKENS_LIMIT') {\n return {\n type: 'Token usage(5 Hour)',\n percentage: item.percentage,\n nextResetTime: item.nextResetTime,\n };\n }\n if (item.type === 'TIME_LIMIT') {\n return {\n type: 'MCP usage(1 Month)',\n percentage: item.percentage,\n currentUsage: item.currentValue,\n totol: item.usage,\n usageDetails: item.usageDetails,\n nextResetTime: item.nextResetTime,\n };\n }\n return item;\n });\n return data;\n}\n\nasync function fetchJson(\n apiUrl: string,\n label: string,\n authToken: string,\n query = '',\n): Promise<unknown> {\n const res = await fetch(apiUrl + query, {\n headers: {\n Authorization: authToken,\n 'Accept-Language': 'en-US,en',\n 'Content-Type': 'application/json',\n },\n });\n const body = await res.text();\n if (res.status !== 200) {\n throw new Error(`[${label}] HTTP ${res.status}\\n${body}`);\n }\n let json: RawEnvelope;\n try {\n json = JSON.parse(body) as RawEnvelope;\n } catch (e) {\n throw new Error(\n `[${label}] could not parse response: ${(e as Error).message}`,\n { cause: e },\n );\n }\n if (json.success === false) {\n throw new Error(\n `[${label}] ${json.msg ?? 'request failed'} (code ${json.code ?? '?'})`,\n );\n }\n return json.data ?? json;\n}\n\nexport async function fetchReport(config: ResolvedConfig): Promise<string> {\n const platform = config.url.includes('bigmodel') ? 'ZHIPU' : 'ZAI';\n\n const query = queryParams();\n try {\n const [model, tool, quotaRaw] = await Promise.all([\n fetchJson(\n `${config.url}/api/monitor/usage/model-usage`,\n 'Model usage',\n config.token,\n query,\n ),\n fetchJson(\n `${config.url}/api/monitor/usage/tool-usage`,\n 'Tool usage',\n config.token,\n query,\n ),\n fetchJson(\n `${config.url}/api/monitor/usage/quota/limit`,\n 'Quota limit',\n config.token,\n ),\n ]);\n return render({\n platform,\n model: model as ZaiModelUsage,\n tool: tool as ZaiToolUsage,\n quota: processQuotaLimit(quotaRaw as RawQuota),\n });\n } catch (e) {\n throw new Error(`Request failed: ${(e as Error).message}`, { cause: e });\n }\n}\n","import { hookOrPrint, printUsageAndExit } from '@v1nvn/agentic-core';\n\nimport { buildProgram, parseArgs, resolveConfig } from './resolve.js';\nimport { fetchReport } from './usage.js';\n\nconst parsed =\n parseArgs(process.argv.slice(2)) ?? printUsageAndExit(buildProgram());\n\nawait hookOrPrint(parsed.hook, 'query failed', () =>\n fetchReport(resolveConfig(process.env, parsed)),\n);\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@v1nvn/zai",
3
- "version": "0.33.0",
3
+ "version": "0.34.0",
4
4
  "description": "GLM Coding Plan usage and quota report — the zai-usage CLI behind the zai plugin.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -37,8 +37,8 @@
37
37
  "node": ">=22"
38
38
  },
39
39
  "dependencies": {
40
- "@v1nvn/agentic-core": "^0.33.0",
41
- "@v1nvn/tokens": "^0.33.0",
40
+ "@v1nvn/agentic-core": "^0.34.0",
41
+ "@v1nvn/tokens": "^0.34.0",
42
42
  "commander": "^15.0.0"
43
43
  },
44
44
  "devDependencies": {