zcode-acp-server 0.53.3 → 0.55.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.
@@ -0,0 +1,462 @@
1
+ /**
2
+ * Platform usage statistics — the account-level monitor data behind the
3
+ * desktop app's Coding Plan usage tab, aggregated for the mobile app's Usage
4
+ * page (contract: `.zcode/docs/platform-usage-backend-requirements.md` in the
5
+ * app repo).
6
+ *
7
+ * Lives in `src/quota/` next to the monitor client: same upstream family
8
+ * (BigModel/Z.AI monitor API), same host derivation and credentials as the
9
+ * quota windows. The settings route (`src/remote/settings-endpoint.ts`) mounts
10
+ * it under `GET /settings/usage-platform`.
11
+ *
12
+ * Three upstream blocks are read in parallel (activity is a fixed 365-day
13
+ * window; model/tool detail follow the requested range), each defensively
14
+ * parsed: a missing block is empty data, not an error, and only a total
15
+ * failure surfaces an error kind. Normalization is ported from the desktop
16
+ * mapper (`packages/services/src/usage-stats/providers/bigmodelUsageMonitorMapper.ts`),
17
+ * including its two load-bearing quirks:
18
+ *
19
+ * - credit-usage "cached/uncached/output" rows are billing components, not
20
+ * models — unfiltered they would double the totals;
21
+ * - every numeric field may arrive as number, numeric string or null.
22
+ */
23
+ import { fetchMonitorResponse, } from "./monitor-client.js";
24
+ import { isAuthFailureMessage, isRateLimitedMessage } from "./parse.js";
25
+ import { log } from "../utils.js";
26
+ export const PLATFORM_USAGE_RANGES = new Set(["today", "7d", "30d"]);
27
+ export function isPlatformUsageRange(value) {
28
+ return PLATFORM_USAGE_RANGES.has(value);
29
+ }
30
+ // ---- numeric tolerance (desktop `toFiniteNumber` semantics) --------------------
31
+ function toFiniteNumber(value) {
32
+ const n = typeof value === "number"
33
+ ? value
34
+ : typeof value === "string" && value.trim().length > 0
35
+ ? Number(value)
36
+ : Number.NaN;
37
+ return Number.isFinite(n) ? n : null;
38
+ }
39
+ function sumSeries(series) {
40
+ return (series ?? []).reduce((sum, value) => sum + (toFiniteNumber(value) ?? 0), 0);
41
+ }
42
+ /** First series in the list with any positive value, normalized to numbers. */
43
+ function firstNonEmptySeries(list) {
44
+ const found = list.find((s) => Array.isArray(s) && s.some((v) => (toFiniteNumber(v) ?? 0) > 0));
45
+ return found ? found.map((v) => toFiniteNumber(v) ?? 0) : undefined;
46
+ }
47
+ /** Element-wise sum (desktop `sumSeries`) — pads shorter lists with zeros. */
48
+ function sumSeriesAll(list) {
49
+ const maxLength = Math.max(0, ...list.map((s) => s?.length ?? 0));
50
+ if (maxLength === 0)
51
+ return undefined;
52
+ return Array.from({ length: maxLength }, (_, i) => list.reduce((sum, s) => sum + (toFiniteNumber(s?.[i]) ?? 0), 0));
53
+ }
54
+ function classifyMonitor(resp) {
55
+ if (resp.status === 429 || isRateLimitedMessage(resp.text)) {
56
+ return { ok: false, kind: "rate_limited" };
57
+ }
58
+ const payload = resp.json;
59
+ if (!payload || typeof payload !== "object")
60
+ return { ok: false, kind: "unavailable" };
61
+ const success = payload.success === true || (payload.success === undefined && payload.code === 200);
62
+ if (!success) {
63
+ if (resp.status === 401 ||
64
+ resp.status === 403 ||
65
+ payload.code === 1001 ||
66
+ payload.code === 401 ||
67
+ isAuthFailureMessage(payload.msg)) {
68
+ return { ok: false, kind: "auth_error" };
69
+ }
70
+ if (isRateLimitedMessage(payload.msg))
71
+ return { ok: false, kind: "rate_limited" };
72
+ return { ok: false, kind: "unavailable" };
73
+ }
74
+ // `data: null` is an empty payload, not an error (desktop treats it the same).
75
+ const data = payload.data;
76
+ return { ok: true, data: data && typeof data === "object" ? data : {} };
77
+ }
78
+ async function safeFetch(endpoint, search) {
79
+ try {
80
+ return classifyMonitor(await fetchMonitorResponse(endpoint, search));
81
+ }
82
+ catch (e) {
83
+ log(`platform-usage: ${endpoint} failed (${e instanceof Error ? e.message : String(e)})`);
84
+ return { ok: false, kind: "unavailable" };
85
+ }
86
+ }
87
+ // ---- time ranges (desktop parity: local day keys, `YYYY-MM-DD HH:mm:ss`) -------
88
+ function localDateKey(date) {
89
+ // en-CA formats as YYYY-MM-DD.
90
+ return new Intl.DateTimeFormat("en-CA", {
91
+ year: "numeric",
92
+ month: "2-digit",
93
+ day: "2-digit",
94
+ }).format(date);
95
+ }
96
+ function addDays(dateKey, days) {
97
+ const [y = 1970, m = 1, d = 1] = dateKey.split("-").map(Number);
98
+ const date = new Date(Date.UTC(y, m - 1, d + days));
99
+ const pad = (v) => String(v).padStart(2, "0");
100
+ return `${date.getUTCFullYear()}-${pad(date.getUTCMonth() + 1)}-${pad(date.getUTCDate())}`;
101
+ }
102
+ function monitorTimeRange(range, now) {
103
+ const endKey = localDateKey(now);
104
+ if (range === "today") {
105
+ return { startTime: `${endKey} 00:00:00`, endTime: `${endKey} 23:59:59`, granularity: "hour" };
106
+ }
107
+ const startKey = addDays(endKey, range === "7d" ? -6 : -29);
108
+ return { startTime: `${startKey} 00:00:00`, endTime: `${endKey} 23:59:59`, granularity: "day" };
109
+ }
110
+ function activityTimeRange(now) {
111
+ const endKey = localDateKey(now);
112
+ return { startTime: `${addDays(endKey, -365)} 00:00:00`, endTime: `${endKey} 23:59:59` };
113
+ }
114
+ // ---- activity + heatmap ----------------------------------------------------------
115
+ const DAY_MS = 86_400_000;
116
+ const DATE_KEY_PATTERN = /^\d{4}-\d{2}-\d{2}$/u;
117
+ function dateKeyToUtcDayIndex(dateKey) {
118
+ const date = new Date(`${dateKey}T00:00:00.000Z`);
119
+ if (Number.isNaN(date.getTime()))
120
+ return null;
121
+ return Math.floor(date.getTime() / DAY_MS);
122
+ }
123
+ function utcDayIndexToDateKey(dayIndex) {
124
+ return new Date(dayIndex * DAY_MS).toISOString().slice(0, 10);
125
+ }
126
+ function levelForTokens(value, max) {
127
+ if (value <= 0 || max <= 0)
128
+ return 0;
129
+ return Math.min(4, Math.max(1, Math.ceil((value / max) * 4)));
130
+ }
131
+ function buildActivity(payload) {
132
+ const raw = payload;
133
+ const cells = (raw.series ?? [])
134
+ .map((item) => {
135
+ const date = typeof item.date === "string" ? item.date.trim() : "";
136
+ if (!DATE_KEY_PATTERN.test(date))
137
+ return null;
138
+ return {
139
+ date,
140
+ tokens: toFiniteNumber(item.totalTokens) ?? 0,
141
+ calls: toFiniteNumber(item.modelCallCount) ?? 0,
142
+ };
143
+ })
144
+ .filter((cell) => cell !== null)
145
+ .sort((a, b) => a.date.localeCompare(b.date));
146
+ const maxTokens = Math.max(0, ...cells.map((cell) => cell.tokens));
147
+ const byDate = new Map(cells.map((cell) => [cell.date, cell]));
148
+ // UTC week starts (Sunday); days missing from the series stay null so the
149
+ // grid keeps its shape.
150
+ const weekStarts = new Map();
151
+ for (const cell of cells) {
152
+ const dayIndex = dateKeyToUtcDayIndex(cell.date);
153
+ if (dayIndex === null)
154
+ continue;
155
+ const weekStart = dayIndex - new Date(dayIndex * DAY_MS).getUTCDay();
156
+ if (weekStarts.has(weekStart))
157
+ continue;
158
+ weekStarts.set(weekStart, Array.from({ length: 7 }, (_, i) => {
159
+ const date = utcDayIndexToDateKey(weekStart + i);
160
+ const source = byDate.get(date);
161
+ return source
162
+ ? { date, level: levelForTokens(source.tokens, maxTokens), tokens: source.tokens }
163
+ : null;
164
+ }));
165
+ }
166
+ const weeks = [...weekStarts.entries()]
167
+ .sort(([left], [right]) => left - right)
168
+ .map(([, days]) => ({ days }));
169
+ return {
170
+ summary: {
171
+ totalTokens: toFiniteNumber(raw.summary?.totalTokens) ?? 0,
172
+ peakDailyTokens: toFiniteNumber(raw.summary?.peakDailyTokens) ?? 0,
173
+ peakDailyTokensDate: raw.summary?.peakDailyTokensDate?.trim() || null,
174
+ totalUsageDurationMs: toFiniteNumber(raw.summary?.totalUsageDurationMs) ?? 0,
175
+ currentStreakDays: toFiniteNumber(raw.summary?.currentStreakDays) ?? 0,
176
+ longestStreakDays: toFiniteNumber(raw.summary?.longestStreakDays) ?? 0,
177
+ },
178
+ heatmap: {
179
+ startDate: cells[0]?.date ?? null,
180
+ endDate: cells.at(-1)?.date ?? null,
181
+ maxTokens,
182
+ weeks,
183
+ },
184
+ };
185
+ }
186
+ // ---- usage detail + models -------------------------------------------------------
187
+ const BREAKDOWN_BUCKET_CODES = new Set([
188
+ "cached_input",
189
+ "cachedInput",
190
+ "cache_input",
191
+ "cacheInput",
192
+ "uncached_input",
193
+ "uncachedInput",
194
+ "output",
195
+ "output_tokens",
196
+ "outputTokens",
197
+ ]);
198
+ function isBreakdownBucket(item) {
199
+ const code = item.modelCode?.trim();
200
+ if (code && BREAKDOWN_BUCKET_CODES.has(code))
201
+ return true;
202
+ const name = item.modelName?.trim().toLowerCase();
203
+ return name === "缓存" || name === "未缓存" || name === "输出";
204
+ }
205
+ function hasModelRows(block) {
206
+ return (block.modelDataList ?? []).some((item) => Boolean(item?.modelName?.trim() || item?.modelCode?.trim()));
207
+ }
208
+ function hasToolRows(block) {
209
+ return (block.mcpDataList ?? []).some((item) => Boolean(item?.mcpCode?.trim() ||
210
+ item?.mcpName?.trim() ||
211
+ item?.toolCode?.trim() ||
212
+ item?.toolName?.trim()));
213
+ }
214
+ function buildDetailSummary(payload) {
215
+ const raw = payload.summary;
216
+ return {
217
+ cacheHitRate: toFiniteNumber(raw?.cacheHitRate?.value),
218
+ cacheHitRateTrend: toFiniteNumber(raw?.cacheHitRate?.trend),
219
+ totalCredits: toFiniteNumber(raw?.totalCredits?.value) ?? 0,
220
+ totalCreditsTrend: toFiniteNumber(raw?.totalCredits?.trend),
221
+ averageDailyCredits: toFiniteNumber(raw?.averageDailyCredits?.value) ?? 0,
222
+ averageDailyCreditsTrend: toFiniteNumber(raw?.averageDailyCredits?.trend),
223
+ };
224
+ }
225
+ function buildModelsFromDetail(block, granularity) {
226
+ const rows = (block.modelDataList ?? [])
227
+ .filter((item) => Boolean(item?.modelName?.trim() || item?.modelCode?.trim()))
228
+ .filter((item) => !isBreakdownBucket(item))
229
+ .map((item, index) => {
230
+ const tokens = firstNonEmptySeries([
231
+ item.totalTokensUsage,
232
+ item.tokensUsage,
233
+ sumSeriesAll([
234
+ item.cachedInputTokensUsage,
235
+ item.uncachedInputTokensUsage,
236
+ item.outputTokensUsage,
237
+ ]),
238
+ ]) ?? [];
239
+ const credits = firstNonEmptySeries([
240
+ item.totalCreditsUsage,
241
+ sumSeriesAll([
242
+ item.cachedInputCreditsUsage,
243
+ item.uncachedInputCreditsUsage,
244
+ item.outputCreditsUsage,
245
+ ]),
246
+ ]) ?? [];
247
+ return {
248
+ name: item.modelName?.trim() || item.modelCode?.trim() || "unknown",
249
+ sortOrder: toFiniteNumber(item.sortOrder) ?? index,
250
+ tokens,
251
+ totalTokens: toFiniteNumber(item.totalTokens) ?? sumSeries(tokens),
252
+ totalCredits: toFiniteNumber(item.totalCredits) ?? sumSeries(credits),
253
+ cachedInputTokens: sumSeries(item.cachedInputTokensUsage),
254
+ uncachedInputTokens: sumSeries(item.uncachedInputTokensUsage),
255
+ outputTokens: sumSeries(item.outputTokensUsage),
256
+ };
257
+ })
258
+ .sort((a, b) => a.sortOrder - b.sortOrder);
259
+ // All rows share the payload's xTime, so element-wise summation IS the
260
+ // per-bucket aggregate.
261
+ const totals = rows.reduce((acc, row) => row.tokens.map((value, i) => (acc[i] ?? 0) + value), []);
262
+ const xTime = block.xTime ?? [];
263
+ return {
264
+ models: rows.map(({ tokens: _tokens, ...rest }) => rest),
265
+ series: xTime.length > 0 ? { granularity, xTime, totals } : null,
266
+ };
267
+ }
268
+ function buildModelsFromLegacy(payload, granularity) {
269
+ const raw = payload;
270
+ const models = (raw.modelSummaryList ?? raw.totalUsage?.modelSummaryList ?? [])
271
+ .filter((item) => Boolean(item?.modelName?.trim()))
272
+ .map((item, index) => ({
273
+ name: item.modelName.trim(),
274
+ sortOrder: toFiniteNumber(item.sortOrder) ?? index,
275
+ totalTokens: toFiniteNumber(item.totalTokens) ?? 0,
276
+ }))
277
+ .sort((a, b) => a.sortOrder - b.sortOrder);
278
+ const xTime = raw.x_time ?? [];
279
+ return {
280
+ models,
281
+ series: xTime.length > 0
282
+ ? {
283
+ granularity,
284
+ xTime,
285
+ totals: (raw.tokensUsage ?? []).map((v) => toFiniteNumber(v) ?? 0),
286
+ }
287
+ : null,
288
+ };
289
+ }
290
+ function buildToolsFromDetail(block) {
291
+ return (block.mcpDataList ?? [])
292
+ .filter((item) => Boolean(item?.mcpCode?.trim() ||
293
+ item?.mcpName?.trim() ||
294
+ item?.toolCode?.trim() ||
295
+ item?.toolName?.trim()))
296
+ .map((item, index) => {
297
+ const usage = firstNonEmptySeries([item.mcpCallCount, item.usageCount]) ?? [];
298
+ const credits = item.creditsUsage ?? [];
299
+ return {
300
+ name: item.mcpName?.trim() ||
301
+ item.toolName?.trim() ||
302
+ item.mcpCode?.trim() ||
303
+ item.toolCode?.trim() ||
304
+ "unknown",
305
+ sortOrder: toFiniteNumber(item.sortOrder) ?? index,
306
+ totalUsageCount: toFiniteNumber(item.totalUsageCount) ?? sumSeries(usage),
307
+ totalCredits: toFiniteNumber(item.totalCredits) ?? sumSeries(credits),
308
+ };
309
+ })
310
+ .sort((a, b) => a.sortOrder - b.sortOrder)
311
+ .map(({ sortOrder: _sortOrder, ...rest }) => rest);
312
+ }
313
+ function buildToolsFromLegacy(payload) {
314
+ const raw = payload;
315
+ return (raw.toolSummaryList ?? raw.totalUsage?.toolSummaryList ?? [])
316
+ .filter((item) => Boolean(item?.toolCode?.trim() || item?.toolName?.trim()))
317
+ .map((item) => ({
318
+ name: item.toolName?.trim() || item.toolCode?.trim() || "unknown",
319
+ totalUsageCount: toFiniteNumber(item.totalUsageCount) ?? 0,
320
+ }));
321
+ }
322
+ // ---- orchestration ----------------------------------------------------------------
323
+ function dominantError(kinds) {
324
+ if (kinds.includes("auth_error"))
325
+ return "auth_error";
326
+ if (kinds.includes("rate_limited"))
327
+ return "rate_limited";
328
+ return "unavailable";
329
+ }
330
+ async function aggregate(range) {
331
+ try {
332
+ const now = new Date();
333
+ const detailRange = monitorTimeRange(range, now);
334
+ const failures = [];
335
+ const failed = (outcome) => {
336
+ if (!outcome.ok)
337
+ failures.push(outcome.kind);
338
+ };
339
+ const [activityBlock, modelBlock, toolBlock] = await Promise.all([
340
+ safeFetch("/api/monitor/credit-usage/activity", { ...activityTimeRange(now), type: "1" }),
341
+ safeFetch("/api/monitor/credit-usage/usage-detail", {
342
+ ...detailRange,
343
+ type: "1",
344
+ usageType: "MODEL",
345
+ }),
346
+ safeFetch("/api/monitor/credit-usage/usage-detail", {
347
+ ...detailRange,
348
+ type: "1",
349
+ usageType: "MCP",
350
+ }),
351
+ ]);
352
+ const anyPrimaryOk = activityBlock.ok || modelBlock.ok || toolBlock.ok;
353
+ failed(activityBlock);
354
+ failed(modelBlock);
355
+ failed(toolBlock);
356
+ let models = null;
357
+ let tools = null;
358
+ let series = null;
359
+ // Fallback chain: the legacy monitor series when usage-detail carries no
360
+ // usable rows for the block (absent, empty, or errored).
361
+ const modelDetail = modelBlock.ok
362
+ ? (modelBlock.data.modelUsage ?? null)
363
+ : null;
364
+ if (modelDetail && hasModelRows(modelDetail)) {
365
+ ({ models, series } = buildModelsFromDetail(modelDetail, detailRange.granularity));
366
+ }
367
+ else {
368
+ const legacy = await safeFetch("/api/monitor/usage/model-usage", {
369
+ ...detailRange,
370
+ type: "1",
371
+ });
372
+ if (legacy.ok) {
373
+ ({ models, series } = buildModelsFromLegacy(legacy.data, detailRange.granularity));
374
+ }
375
+ else {
376
+ failed(legacy);
377
+ }
378
+ }
379
+ const toolDetail = toolBlock.ok
380
+ ? (toolBlock.data.mcpUsage ?? null)
381
+ : null;
382
+ if (toolDetail && hasToolRows(toolDetail)) {
383
+ tools = buildToolsFromDetail(toolDetail);
384
+ }
385
+ else {
386
+ const legacy = await safeFetch("/api/monitor/usage/tool-usage", {
387
+ ...detailRange,
388
+ type: "1",
389
+ });
390
+ if (legacy.ok) {
391
+ tools = buildToolsFromLegacy(legacy.data);
392
+ }
393
+ else {
394
+ failed(legacy);
395
+ }
396
+ }
397
+ if (!anyPrimaryOk && models === null && tools === null && failures.length > 0) {
398
+ // Every block failed everywhere — surface the dominant error state
399
+ // rather than a success with nothing in it.
400
+ return { kind: dominantError(failures), range, generatedAt: Date.now() };
401
+ }
402
+ return {
403
+ kind: "success",
404
+ range,
405
+ generatedAt: Date.now(),
406
+ ...(activityBlock.ok ? { activity: buildActivity(activityBlock.data) } : {}),
407
+ detail: {
408
+ model: modelBlock.ok ? buildDetailSummary(modelBlock.data) : null,
409
+ tool: toolBlock.ok ? buildDetailSummary(toolBlock.data) : null,
410
+ },
411
+ models: models ?? [],
412
+ tools: tools ?? [],
413
+ ...(series ? { series } : {}),
414
+ };
415
+ }
416
+ catch (e) {
417
+ log(`platform-usage: aggregation failed (${e instanceof Error ? e.message : String(e)})`);
418
+ return { kind: "unavailable", range, generatedAt: Date.now() };
419
+ }
420
+ }
421
+ // ---- TTL cache + single flight (queryQuota pattern, one slot per range) ----------
422
+ const TTL_MS = 15_000;
423
+ const cache = new Map();
424
+ const inflight = new Map();
425
+ let clock = () => Date.now();
426
+ /**
427
+ * Read the platform usage snapshot for a range.
428
+ *
429
+ * Serves a cached result when fresh (< 15s); concurrent reads for the same
430
+ * range share one upstream round trip (the 365-day activity fetch is the
431
+ * expensive one, and a burst of range taps must not fan out).
432
+ */
433
+ export async function readPlatformUsage(range = "7d") {
434
+ const hit = cache.get(range);
435
+ if (hit && clock() - hit.at < TTL_MS) {
436
+ log("platform-usage: serving cached result");
437
+ return hit.result;
438
+ }
439
+ const running = inflight.get(range);
440
+ if (running)
441
+ return running;
442
+ const promise = aggregate(range)
443
+ .then((result) => {
444
+ cache.set(range, { result, at: clock() });
445
+ return result;
446
+ })
447
+ .finally(() => {
448
+ inflight.delete(range);
449
+ });
450
+ inflight.set(range, promise);
451
+ return promise;
452
+ }
453
+ /** Test helper: drop cached results and in-flight promises. */
454
+ export function resetPlatformUsageCacheForTest() {
455
+ cache.clear();
456
+ inflight.clear();
457
+ }
458
+ /** Test helper: inject a fake clock. Pass `undefined` to restore real time. */
459
+ export function setPlatformUsageClockForTest(fn) {
460
+ clock = fn ?? (() => Date.now());
461
+ }
462
+ //# sourceMappingURL=platform-usage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"platform-usage.js","sourceRoot":"","sources":["../../src/quota/platform-usage.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"settings-endpoint.d.ts","sourceRoot":"","sources":["../../src/remote/settings-endpoint.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAIjE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAiOnD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,qBAAqB,CACnC,MAAM,CAAC,EAAE,cAAc,GACtB,CAAC,GAAG,EAAE,eAAe,EAAE,GAAG,EAAE,cAAc,KAAK,IAAI,CAiBrD;AAkRD,wEAAwE;AACxE,wBAAgB,0BAA0B,IAAI,IAAI,CAEjD;AAmsBD,kDAAkD;AAClD,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAE1E;AA+jBD,4EAA4E;AAC5E,wBAAgB,0BAA0B,IAAI,IAAI,CAEjD"}
1
+ {"version":3,"file":"settings-endpoint.d.ts","sourceRoot":"","sources":["../../src/remote/settings-endpoint.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAIjE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAsOnD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,qBAAqB,CACnC,MAAM,CAAC,EAAE,cAAc,GACtB,CAAC,GAAG,EAAE,eAAe,EAAE,GAAG,EAAE,cAAc,KAAK,IAAI,CAiBrD;AAmRD,wEAAwE;AACxE,wBAAgB,0BAA0B,IAAI,IAAI,CAEjD;AAotBD,kDAAkD;AAClD,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAE1E;AA+jBD,4EAA4E;AAC5E,wBAAgB,0BAA0B,IAAI,IAAI,CAEjD"}
@@ -36,6 +36,7 @@ import { amendRunSettings, conversationRuns, deleteWorkflow, getWorkflow, listRu
36
36
  import { workflowOverrideNow } from "../config/workflow-gate.js";
37
37
  import { codingPlanProviderIds, isCodingPlanProvider, markResetHistoryRead, readResetStatus, requestResetOpportunity, resolveResetAuthorization, useResetCard, } from "../settings/coding-plan.js";
38
38
  import { queryQuota } from "../quota/index.js";
39
+ import { isPlatformUsageRange, readPlatformUsage, } from "../quota/platform-usage.js";
39
40
  import { zcodeCliConfigPath, zcodePersonalProviderPath } from "../utils.js";
40
41
  /** Body size cap. Settings payloads are small; hooks are the largest. */
41
42
  const MAX_BODY_BYTES = 256 * 1024;
@@ -228,6 +229,8 @@ async function route(req, res, url, path, server) {
228
229
  return void (await handleBackups(res));
229
230
  if (path === "/settings/usage")
230
231
  return void (await handleUsage(res, url));
232
+ if (path === "/settings/usage-platform")
233
+ return void (await handleUsagePlatform(res, url));
231
234
  if (path === "/settings/quota")
232
235
  return void (await handleQuota(res));
233
236
  if (path === "/settings/reset-cards")
@@ -924,6 +927,22 @@ async function handleUsage(res, url) {
924
927
  usage: await readUsageStats(requested),
925
928
  }));
926
929
  }
930
+ /**
931
+ * Platform usage (the account-level monitor data behind the desktop app's
932
+ * Coding Plan usage tab). The module owns its error states, so the handler is
933
+ * a pure translation like handleQuota.
934
+ */
935
+ async function handleUsagePlatform(res, url) {
936
+ const requested = url.searchParams.get("range") ?? "7d";
937
+ if (!isPlatformUsageRange(requested)) {
938
+ sendError(res, 400, "range must be one of today, 7d, 30d");
939
+ return;
940
+ }
941
+ await guard(res, async () => ({
942
+ ok: true,
943
+ platformUsage: await readPlatformUsage(requested),
944
+ }));
945
+ }
927
946
  async function handleQuota(res) {
928
947
  // Quota is account-level and already has a full result model; it is passed
929
948
  // through so a settings screen and the CLI card render the same data.