tokentracker-cli 0.83.9 → 0.83.11
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/dashboard/dist/assets/{AchievementBadge-X8YWBf82.js → AchievementBadge-Ddtn6vg2.js} +1 -1
- package/dashboard/dist/assets/AchievementsPage-AMo1Ib5I.js +2 -0
- package/dashboard/dist/assets/{AchievementsSection-Cquf4Guw.js → AchievementsSection-CUMjcYst.js} +1 -1
- package/dashboard/dist/assets/BadgeDetailModal-CA03iBRx.js +1 -0
- package/dashboard/dist/assets/{Card-D4zmc9F1.js → Card-DscI10IE.js} +1 -1
- package/dashboard/dist/assets/{ClawdAnimated-C71-Kl5E.js → ClawdAnimated-5cIXJ0NQ.js} +1 -1
- package/dashboard/dist/assets/CommandPalette-qCpUMoAO.js +1 -0
- package/dashboard/dist/assets/CommunityStatsModal-FT_T1UzH.js +1 -0
- package/dashboard/dist/assets/{ConfirmModal-CJvsJQEg.js → ConfirmModal-GI2RxzAE.js} +1 -1
- package/dashboard/dist/assets/DashboardPage-CkA3pfjj.js +1 -0
- package/dashboard/dist/assets/DevicePage-CdtlanVo.js +1 -0
- package/dashboard/dist/assets/DialogClose-cfdVTNyN.js +1 -0
- package/dashboard/dist/assets/DialogDescription-CKjbQpir.js +1 -0
- package/dashboard/dist/assets/DialogTitle-CtptgR8Z.js +1 -0
- package/dashboard/dist/assets/{FadeIn-DDStrEXn.js → FadeIn-CPpE5UGk.js} +1 -1
- package/dashboard/dist/assets/{HeaderGithubStar-Dr148Pod.js → HeaderGithubStar-vN3e1w0o.js} +1 -1
- package/dashboard/dist/assets/{IpCheckPage-_ZCkwB3u.js → IpCheckPage-BqJPwFGV.js} +1 -1
- package/dashboard/dist/assets/{LandingPage-DeF5OWD_.js → LandingPage-DrjAIdTL.js} +2 -2
- package/dashboard/dist/assets/{LeaderboardAvatar-BASZL-2J.js → LeaderboardAvatar-BRWPXDZl.js} +1 -1
- package/dashboard/dist/assets/LeaderboardPage-Dy55Qbr0.js +2 -0
- package/dashboard/dist/assets/{LeaderboardProfileModal-Cfh5POl9.js → LeaderboardProfileModal-Dm5bW2pX.js} +4 -4
- package/dashboard/dist/assets/{LeaderboardProfilePage-DJhhDxj0.js → LeaderboardProfilePage-CWmLrKsM.js} +3 -3
- package/dashboard/dist/assets/{LimitsPage-DkG3SpxN.js → LimitsPage-B538PSle.js} +1 -1
- package/dashboard/dist/assets/{LocalOnlyNotice-CrU-jyFU.js → LocalOnlyNotice-Dso8I7Y4.js} +1 -1
- package/dashboard/dist/assets/LoginCard-CnghY3oG.js +1 -0
- package/dashboard/dist/assets/{LoginModal-DW85E_2P.js → LoginModal-B30O2N_x.js} +1 -1
- package/dashboard/dist/assets/{LoginPage-DW9keM2l.js → LoginPage-DglsaA23.js} +1 -1
- package/dashboard/dist/assets/PetPage-C7-xrZix.js +1 -0
- package/dashboard/dist/assets/PopoverPopup-CTbuRUy2.js +1 -0
- package/dashboard/dist/assets/{ProviderIcon-VFnAt_kS.js → ProviderIcon-D-sr7Qko.js} +1 -1
- package/dashboard/dist/assets/{ResetPasswordPage-BBRVK154.js → ResetPasswordPage-CIbj5Hpp.js} +1 -1
- package/dashboard/dist/assets/SegmentedControl-dxer1vVZ.js +1 -0
- package/dashboard/dist/assets/Select-BSQkd3VW.js +1 -0
- package/dashboard/dist/assets/SelectItemText-EGKNiN7_.js +1 -0
- package/dashboard/dist/assets/SessionsPage-CugLdscs.js +1 -0
- package/dashboard/dist/assets/SettingsPage-3MQDH9bF.js +1 -0
- package/dashboard/dist/assets/SkillsPage-DZ8k3xK4.js +1 -0
- package/dashboard/dist/assets/{TokenGalaxy-DgsPNhDp.js → TokenGalaxy-B5q_U7lQ.js} +1 -1
- package/dashboard/dist/assets/ToolbarRootContext-DIy-0I9L.js +1 -0
- package/dashboard/dist/assets/TrendMonitor-Bj558t-a.js +19 -0
- package/dashboard/dist/assets/WidgetsPage-t9EgVnVK.js +1 -0
- package/dashboard/dist/assets/{WrappedPage-D8a9fYh6.js → WrappedPage-B-8f6-oI.js} +1 -1
- package/dashboard/dist/assets/__vite-browser-external-CvhQU1Bj.css +1 -0
- package/dashboard/dist/assets/{__vite-browser-external-CYtUwU4m.js → __vite-browser-external-DwFlHgQR.js} +50 -13
- package/dashboard/dist/assets/{agent-logos-p0jCcCWI.js → agent-logos-C6ooyoY_.js} +1 -1
- package/dashboard/dist/assets/{arrow-up-right-B8MNUpWz.js → arrow-up-right-CWOhbEwU.js} +1 -1
- package/dashboard/dist/assets/{check-ZBAFoU5c.js → check-DqrkOjUC.js} +1 -1
- package/dashboard/dist/assets/chevron-right-DlP0Hiu-.js +1 -0
- package/dashboard/dist/assets/{copy-zeYTJLdQ.js → copy-Dh_ZalIb.js} +1 -1
- package/dashboard/dist/assets/{download-jr0xhYlc.js → download-fssIVO33.js} +1 -1
- package/dashboard/dist/assets/{flame-DwM_jWVy.js → flame-COf56i7e.js} +1 -1
- package/dashboard/dist/assets/{format-tokens-CPxOZc6P.js → format-tokens-DA4cG58O.js} +1 -1
- package/dashboard/dist/assets/{icons-znz72ccY.js → icons-DigJtAfR.js} +1 -1
- package/dashboard/dist/assets/{index-fbrQEDiP.js → index-BR90lSkB.js} +1 -1
- package/dashboard/dist/assets/{index-BpuHelI9.js → index-DIEScXsc.js} +1 -1
- package/dashboard/dist/assets/{index-BCzrBLRN.js → index-b_fO7MtI.js} +1 -1
- package/dashboard/dist/assets/{info-Bpr2n0ZO.js → info-mwER43h2.js} +1 -1
- package/dashboard/dist/assets/{limits-providers-BBWY18ZF.js → limits-providers-DyEdxJUi.js} +1 -1
- package/dashboard/dist/assets/{link-2-C4GpDmFn.js → link-2-Bfgtp0co.js} +1 -1
- package/dashboard/dist/assets/{loader-circle-DFQK2RMn.js → loader-circle-B8ASQdW3.js} +1 -1
- package/dashboard/dist/assets/maximize-2-88sF_sdM.js +1 -0
- package/dashboard/dist/assets/provider-display-CYWy8Wjh.js +42 -0
- package/dashboard/dist/assets/{react-DWYxtoLr.js → react-CcvGEOfz.js} +1 -1
- package/dashboard/dist/assets/search-C3gFd5W0.js +1 -0
- package/dashboard/dist/assets/skills-api-BkjJfFxG.js +1 -0
- package/dashboard/dist/assets/store-CGE8neJG.js +1 -0
- package/dashboard/dist/assets/terminal-CjoZ2jlv.js +1 -0
- package/dashboard/dist/assets/{trash-2-Bukxuw5l.js → trash-2-Buwry_AW.js} +1 -1
- package/dashboard/dist/assets/{use-community-stats-CGcWNgR6.js → use-community-stats-DZW_XQoS.js} +1 -1
- package/dashboard/dist/assets/{use-limits-display-prefs-BrwnPXaU.js → use-limits-display-prefs-BD0CXAYR.js} +1 -1
- package/dashboard/dist/assets/{use-native-settings-BfQ-YyVL.js → use-native-settings-CPVIdR4z.js} +1 -1
- package/dashboard/dist/assets/{use-ordered-list-UV8OTApC.js → use-ordered-list-_yETN2gW.js} +1 -1
- package/dashboard/dist/assets/use-reduced-motion-BOf4gJaX.js +1 -0
- package/dashboard/dist/assets/{use-session-efficiency-pref-ptb44SuH.js → use-session-efficiency-pref-mOQHAb6j.js} +1 -1
- package/dashboard/dist/assets/{use-transform-Czq10OHT.js → use-transform-CvmlOKm0.js} +1 -1
- package/dashboard/dist/assets/{use-usage-limits-wP4w5mei.js → use-usage-limits-9W0OuOdp.js} +1 -1
- package/dashboard/dist/assets/{useCurrency-yGkGAfpB.js → useCurrency-BZVRsDTW.js} +1 -1
- package/dashboard/dist/assets/useScrollLock-Dw-jQnFB.js +1 -0
- package/dashboard/dist/assets/{useTokenFormat-myPlm960.js → useTokenFormat-BHw_Jkes.js} +1 -1
- package/dashboard/dist/assets/{zap-RGCJBL7C.js → zap-CeYmAnn-.js} +1 -1
- package/dashboard/dist/index.html +2 -2
- package/dashboard/dist/ip-check.html +2 -2
- package/dashboard/dist/leaderboard.html +2 -2
- package/dashboard/dist/share.html +2 -2
- package/package.json +1 -1
- package/src/commands/init.js +4 -2
- package/src/commands/status.js +2 -2
- package/src/commands/uninstall.js +8 -3
- package/src/lib/codex-config.js +18 -0
- package/src/lib/local-api.js +27 -0
- package/src/lib/pricing/seed-snapshot.json +1 -1
- package/src/lib/session-analytics.js +214 -6
- package/dashboard/dist/assets/AchievementsPage-IPRhV16E.js +0 -2
- package/dashboard/dist/assets/BadgeDetailModal-EO-f-kw5.js +0 -1
- package/dashboard/dist/assets/CommandPalette-CB5VZ4vS.js +0 -1
- package/dashboard/dist/assets/CommunityStatsModal-Blda5OsT.js +0 -1
- package/dashboard/dist/assets/DashboardPage-DMyu2wnD.js +0 -1
- package/dashboard/dist/assets/DevicePage-BttsYSQ-.js +0 -1
- package/dashboard/dist/assets/DialogClose-VrH-Z7vG.js +0 -1
- package/dashboard/dist/assets/DialogDescription-MAfXy8yJ.js +0 -1
- package/dashboard/dist/assets/DialogTitle-BjiS_5bA.js +0 -1
- package/dashboard/dist/assets/LeaderboardPage-NqEgsIk_.js +0 -2
- package/dashboard/dist/assets/LoginCard-CSfOJPpN.js +0 -1
- package/dashboard/dist/assets/PetPage-OL8YbusK.js +0 -1
- package/dashboard/dist/assets/PopoverPopup-Ds1h2_iH.js +0 -1
- package/dashboard/dist/assets/Select-BCP43fKb.js +0 -1
- package/dashboard/dist/assets/SelectItemText-CY-n8m9N.js +0 -1
- package/dashboard/dist/assets/SettingsPage-Bn6xZU72.js +0 -1
- package/dashboard/dist/assets/SkillsPage-BNoLm96g.js +0 -1
- package/dashboard/dist/assets/TrendMonitor-DSB2kwaQ.js +0 -19
- package/dashboard/dist/assets/WidgetsPage-BMsYJCl8.js +0 -1
- package/dashboard/dist/assets/__vite-browser-external-BEMfOISl.css +0 -1
- package/dashboard/dist/assets/provider-display-CqSazoQg.js +0 -42
- package/dashboard/dist/assets/skills-api-Bn_e1uWd.js +0 -1
- package/dashboard/dist/assets/terminal-BXaxyX4y.js +0 -1
- package/dashboard/dist/assets/use-reduced-motion-B4iythwk.js +0 -1
- package/dashboard/dist/assets/useScrollLock-C7zK-ZeS.js +0 -1
|
@@ -15,7 +15,14 @@ const { computeRowCost } = require("./pricing");
|
|
|
15
15
|
|
|
16
16
|
// Bump the sidecar when derived metrics change so cached rows are rebuilt
|
|
17
17
|
// instead of leaving the dashboard on the previous (over-counted) heuristic.
|
|
18
|
-
|
|
18
|
+
// v7 adds the raw session_id (local-only, needed to build resume commands for
|
|
19
|
+
// the session browser); it never leaves the Node process through the cloud.
|
|
20
|
+
// v8 adds an agent-authored one-line title: Claude's "ai-title" session-log
|
|
21
|
+
// record and Codex's thread_name from session_index.jsonl. Both are metadata
|
|
22
|
+
// the agent wrote itself, never the raw prompt body, and stay local-only
|
|
23
|
+
// alongside session_id (no self-parsed prompt fallback, so the strict
|
|
24
|
+
// metadata-only guarantee holds).
|
|
25
|
+
const SIDECAR_VERSION = 8;
|
|
19
26
|
const EDIT_TOOLS = new Set(["apply_patch", "edit", "write", "multiedit", "notebookedit"]);
|
|
20
27
|
const PLACEHOLDER_MODELS = new Set(["<synthetic>", "synthetic", "<unknown>", "unknown"]);
|
|
21
28
|
const CLAUDE_MEM_OBSERVER_PROJECT_SUFFIX = "--claude-mem-observer-sessions";
|
|
@@ -103,6 +110,17 @@ function promptFingerprint(prompt) {
|
|
|
103
110
|
return crypto.createHash("sha256").update(prompt.replace(/\s+/g, " ")).digest("hex");
|
|
104
111
|
}
|
|
105
112
|
|
|
113
|
+
// Normalize a session title into a single short line. Titles come ONLY from
|
|
114
|
+
// the agent's own metadata (Claude's ai-title, Codex's thread_name) — never
|
|
115
|
+
// the raw prompt body — so the metadata-only privacy guarantee holds. They
|
|
116
|
+
// stay local-only alongside session_id.
|
|
117
|
+
function cleanSessionTitle(value) {
|
|
118
|
+
if (typeof value !== "string") return null;
|
|
119
|
+
const text = value.replace(/\s+/g, " ").trim();
|
|
120
|
+
if (!text) return null;
|
|
121
|
+
return text.length > 120 ? `${text.slice(0, 117).trimEnd()}…` : text;
|
|
122
|
+
}
|
|
123
|
+
|
|
106
124
|
function extractCodexPrompt(obj) {
|
|
107
125
|
if (obj?.type !== "event_msg" || obj.payload?.type !== "user_message") return null;
|
|
108
126
|
if (typeof obj.payload.message === "string") {
|
|
@@ -171,6 +189,7 @@ async function scanClaudeSession(filePath) {
|
|
|
171
189
|
let rawSessionId = path.basename(filePath, ".jsonl");
|
|
172
190
|
let cwd = null;
|
|
173
191
|
let model = "unknown";
|
|
192
|
+
let aiTitle = null;
|
|
174
193
|
let turns = 0;
|
|
175
194
|
let editTurns = 0;
|
|
176
195
|
let retryTurns = 0;
|
|
@@ -192,6 +211,13 @@ async function scanClaudeSession(filePath) {
|
|
|
192
211
|
updateBounds(bounds, obj.timestamp || obj.message?.timestamp);
|
|
193
212
|
if (typeof obj.sessionId === "string" && obj.sessionId) rawSessionId = obj.sessionId;
|
|
194
213
|
if (typeof obj.cwd === "string" && obj.cwd) cwd = obj.cwd;
|
|
214
|
+
// Claude writes its own generated one-line summary as an "ai-title" record.
|
|
215
|
+
// It is agent-authored metadata (not the raw prompt body); keep the latest.
|
|
216
|
+
if (obj.type === "ai-title" && typeof obj.aiTitle === "string") {
|
|
217
|
+
const cleaned = cleanSessionTitle(obj.aiTitle);
|
|
218
|
+
if (cleaned) aiTitle = cleaned;
|
|
219
|
+
continue;
|
|
220
|
+
}
|
|
195
221
|
if (obj.type === "user") {
|
|
196
222
|
const prompt = extractClaudePrompt(obj);
|
|
197
223
|
if (!prompt) continue;
|
|
@@ -231,6 +257,12 @@ async function scanClaudeSession(filePath) {
|
|
|
231
257
|
return finalizeRecord({
|
|
232
258
|
version: SIDECAR_VERSION,
|
|
233
259
|
session_hash: sessionHash("claude", rawSessionId),
|
|
260
|
+
session_id: rawSessionId || null,
|
|
261
|
+
// Claude's own generated one-line title (the "ai-title" record). Agent-
|
|
262
|
+
// authored metadata, never the raw prompt body. Local-only: stripped in
|
|
263
|
+
// summarizeSessions before any cloud/CSV export. Null when Claude never
|
|
264
|
+
// wrote one — the UI then falls back to the project name.
|
|
265
|
+
title: aiTitle,
|
|
234
266
|
source: "claude",
|
|
235
267
|
project_key: projectKey(cwd, filePath),
|
|
236
268
|
project_ref: cwd || null,
|
|
@@ -327,9 +359,17 @@ async function scanCodexSession(filePath) {
|
|
|
327
359
|
const model = parsedModel && parsedModel.toLowerCase() !== provider?.toLowerCase()
|
|
328
360
|
? parsedModel
|
|
329
361
|
: "unknown";
|
|
362
|
+
// Codex's own thread title from session_index.jsonl (Codex-authored
|
|
363
|
+
// metadata, keyed by session id). Null when Codex never named the thread —
|
|
364
|
+
// the UI then falls back to the project name.
|
|
365
|
+
const titleIndex = loadCodexTitleIndex(filePath);
|
|
366
|
+
const title = (parsed.sessionId && titleIndex.get(parsed.sessionId)) || null;
|
|
330
367
|
return finalizeRecord({
|
|
331
368
|
version: SIDECAR_VERSION,
|
|
332
369
|
session_hash: sessionHash("codex", parsed.sessionId || filePath),
|
|
370
|
+
session_id: parsed.sessionId || null,
|
|
371
|
+
// Local-only: stripped in summarizeSessions before any cloud/CSV export.
|
|
372
|
+
title,
|
|
333
373
|
source: "codex",
|
|
334
374
|
project_key: projectKey(parsed.cwd, filePath),
|
|
335
375
|
project_ref: parsed.cwd || null,
|
|
@@ -398,6 +438,50 @@ function sessionFileStatKey(filePath) {
|
|
|
398
438
|
}
|
|
399
439
|
}
|
|
400
440
|
|
|
441
|
+
// Codex records its own per-thread title (thread_name) in
|
|
442
|
+
// ~/.codex/session_index.jsonl (`{ id, thread_name, updated_at }`). We read it
|
|
443
|
+
// once per build and memoize by the index's stat so repeated scans are cheap.
|
|
444
|
+
const codexTitleIndexCache = new Map();
|
|
445
|
+
|
|
446
|
+
function codexTitleIndexPathFor(filePath) {
|
|
447
|
+
const parts = path.resolve(filePath).split(path.sep);
|
|
448
|
+
const idx = parts.lastIndexOf(".codex");
|
|
449
|
+
if (idx === -1) return null;
|
|
450
|
+
return [...parts.slice(0, idx + 1), "session_index.jsonl"].join(path.sep);
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
function loadCodexTitleIndex(filePath) {
|
|
454
|
+
const indexPath = codexTitleIndexPathFor(filePath);
|
|
455
|
+
if (!indexPath) return new Map();
|
|
456
|
+
const statKey = sessionFileStatKey(indexPath);
|
|
457
|
+
const cached = codexTitleIndexCache.get(indexPath);
|
|
458
|
+
if (cached && cached.statKey === statKey) return cached.titles;
|
|
459
|
+
const titles = new Map();
|
|
460
|
+
if (statKey) {
|
|
461
|
+
try {
|
|
462
|
+
for (const line of fs.readFileSync(indexPath, "utf8").split("\n")) {
|
|
463
|
+
if (!line.trim()) continue;
|
|
464
|
+
let obj;
|
|
465
|
+
try { obj = JSON.parse(line); } catch { continue; }
|
|
466
|
+
const id = typeof obj?.id === "string" ? obj.id : null;
|
|
467
|
+
const name = cleanSessionTitle(obj?.thread_name);
|
|
468
|
+
if (id && name) titles.set(id, name);
|
|
469
|
+
}
|
|
470
|
+
} catch { /* no index yet */ }
|
|
471
|
+
}
|
|
472
|
+
codexTitleIndexCache.set(indexPath, { statKey, titles });
|
|
473
|
+
return titles;
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
// A Codex row also depends on session_index.jsonl, not just its rollout file.
|
|
477
|
+
// Include that dependency in the incremental cache key so renaming a thread is
|
|
478
|
+
// visible after the next refresh instead of leaving a stale title indefinitely.
|
|
479
|
+
function analyticsEntryStatKey(source, filePath) {
|
|
480
|
+
const sessionStat = sessionFileStatKey(filePath);
|
|
481
|
+
if (!sessionStat || source !== "codex") return sessionStat;
|
|
482
|
+
return `${sessionStat}|title-index:${sessionFileStatKey(codexTitleIndexPathFor(filePath)) || "missing"}`;
|
|
483
|
+
}
|
|
484
|
+
|
|
401
485
|
function readSidecar(sidecarPath) {
|
|
402
486
|
try {
|
|
403
487
|
return fs.readFileSync(sidecarPath, "utf8").split("\n").filter(Boolean).map((line) => JSON.parse(line));
|
|
@@ -429,7 +513,14 @@ async function buildSessionAnalyticsInternal({ home = os.homedir(), force = fals
|
|
|
429
513
|
} catch { /* first run */ }
|
|
430
514
|
}
|
|
431
515
|
const discovered = await discoverSessionFiles(home);
|
|
432
|
-
|
|
516
|
+
// Codex thread titles are stored separately from rollout files. Include the
|
|
517
|
+
// index in the overall signature so an index-only rename reaches the
|
|
518
|
+
// per-file dependency check below on the next refresh.
|
|
519
|
+
const signature = filesSignature([
|
|
520
|
+
...discovered.claude,
|
|
521
|
+
...discovered.codex,
|
|
522
|
+
...discovered.codex.map(codexTitleIndexPathFor).filter(Boolean),
|
|
523
|
+
]);
|
|
433
524
|
if (!force && previousMeta?.version === SIDECAR_VERSION && previousMeta.signature === signature) {
|
|
434
525
|
await writeAtomic(metaPath, `${JSON.stringify({ ...previousMeta, checked_at: new Date().toISOString() })}\n`);
|
|
435
526
|
return readSidecar(sidecarPath);
|
|
@@ -452,7 +543,7 @@ async function buildSessionAnalyticsInternal({ home = os.homedir(), force = fals
|
|
|
452
543
|
];
|
|
453
544
|
for (const entry of entries) {
|
|
454
545
|
const cacheKey = sessionFileCacheKey(entry.source, entry.filePath);
|
|
455
|
-
const statKey =
|
|
546
|
+
const statKey = analyticsEntryStatKey(entry.source, entry.filePath);
|
|
456
547
|
if (!statKey) continue;
|
|
457
548
|
let row = null;
|
|
458
549
|
if (!force && previousFiles[cacheKey]?.stat_key === statKey) {
|
|
@@ -565,10 +656,11 @@ function summarizeSessions(sessions, { from = "", to = "", includeSessions = tru
|
|
|
565
656
|
}, { sessions: 0, productive_sessions: 0, one_shot_sessions: 0, edit_turns: 0, retries: 0, total_tokens: 0, cost_usd: 0, edit_tokens: 0, edit_cost_usd: 0 });
|
|
566
657
|
return {
|
|
567
658
|
available: filtered.length > 0,
|
|
568
|
-
// Local filesystem paths are required internally for
|
|
569
|
-
//
|
|
659
|
+
// Local filesystem paths and raw session ids are required internally for
|
|
660
|
+
// Git attribution and the local-only session browser, but never leave the
|
|
661
|
+
// Node process through API/CSV payloads.
|
|
570
662
|
sessions: includeSessions
|
|
571
|
-
? filtered.map(({ project_ref: _projectRef, _cache_key: _cacheKey, ...row }) => row)
|
|
663
|
+
? filtered.map(({ project_ref: _projectRef, session_id: _sessionId, title: _title, _cache_key: _cacheKey, ...row }) => row)
|
|
572
664
|
: [],
|
|
573
665
|
session_count: filtered.length,
|
|
574
666
|
summary: {
|
|
@@ -595,6 +687,120 @@ function summarizeSessions(sessions, { from = "", to = "", includeSessions = tru
|
|
|
595
687
|
};
|
|
596
688
|
}
|
|
597
689
|
|
|
690
|
+
// Build the resume command a user can run to continue a past session. The
|
|
691
|
+
// session id is a vendor-generated UUID and never contains user prose.
|
|
692
|
+
function resumeCommandFor(source, sessionId) {
|
|
693
|
+
const id = typeof sessionId === "string" ? sessionId.trim() : "";
|
|
694
|
+
// Session ids come from local log files, which can be edited by other local
|
|
695
|
+
// processes. Only emit an unquoted shell token so copying the suggested
|
|
696
|
+
// command can never smuggle whitespace, flags, or shell metacharacters into
|
|
697
|
+
// the user's terminal. Claude also has a small set of legacy non-UUID ids,
|
|
698
|
+
// so keep the accepted alphabet broader than UUID while still shell-safe.
|
|
699
|
+
if (!/^[A-Za-z0-9][A-Za-z0-9._:-]{0,199}$/.test(id)) return null;
|
|
700
|
+
if (source === "claude") return `claude --resume ${id}`;
|
|
701
|
+
if (source === "codex") return `codex resume ${id}`;
|
|
702
|
+
return null;
|
|
703
|
+
}
|
|
704
|
+
|
|
705
|
+
function toSessionBrowserRow(row) {
|
|
706
|
+
return {
|
|
707
|
+
session_hash: row.session_hash,
|
|
708
|
+
session_id: row.session_id || null,
|
|
709
|
+
title: row.title || null,
|
|
710
|
+
source: row.source,
|
|
711
|
+
project_key: row.project_key,
|
|
712
|
+
// project_ref (the local cwd) only ever travels over the local API so the
|
|
713
|
+
// browser can show where a session ran and compose a resume command.
|
|
714
|
+
project_ref: row.project_ref || null,
|
|
715
|
+
model: row.model,
|
|
716
|
+
started_at: row.started_at || null,
|
|
717
|
+
ended_at: row.ended_at || null,
|
|
718
|
+
duration_ms: finite(row.duration_ms),
|
|
719
|
+
turns: finite(row.turns),
|
|
720
|
+
edit_turns: finite(row.edit_turns),
|
|
721
|
+
retry_turns: finite(row.retry_turns),
|
|
722
|
+
subagent_calls: finite(row.subagent_calls),
|
|
723
|
+
total_tokens: finite(row.total_tokens),
|
|
724
|
+
cost_usd: finite(row.cost_usd),
|
|
725
|
+
productive: Boolean(row.productive),
|
|
726
|
+
first_pass: Boolean(row.first_pass ?? row.one_shot),
|
|
727
|
+
resume_command: resumeCommandFor(row.source, row.session_id),
|
|
728
|
+
};
|
|
729
|
+
}
|
|
730
|
+
|
|
731
|
+
// Claude writes several on-disk files for one logical session (resumes and
|
|
732
|
+
// sub-agent sidechains) that all carry the same session id, so scanning yields
|
|
733
|
+
// multiple rows sharing an identical session_hash. Merge those fragments into
|
|
734
|
+
// one resumable session for the browser: sum the (non-overlapping) per-file
|
|
735
|
+
// token/turn counts, span the timestamps, and keep the agent-authored title.
|
|
736
|
+
// This also gives the UI a stable, unique key per row.
|
|
737
|
+
function mergeSessionFragments(rows) {
|
|
738
|
+
const byHash = new Map();
|
|
739
|
+
for (const row of rows || []) {
|
|
740
|
+
const key = row.session_hash;
|
|
741
|
+
const cur = byHash.get(key);
|
|
742
|
+
if (!cur) {
|
|
743
|
+
byHash.set(key, { ...row, _repr_tokens: finite(row.total_tokens) });
|
|
744
|
+
continue;
|
|
745
|
+
}
|
|
746
|
+
cur.turns = finite(cur.turns) + finite(row.turns);
|
|
747
|
+
cur.edit_turns = finite(cur.edit_turns) + finite(row.edit_turns);
|
|
748
|
+
cur.retry_turns = finite(cur.retry_turns) + finite(row.retry_turns);
|
|
749
|
+
cur.subagent_calls = finite(cur.subagent_calls) + finite(row.subagent_calls);
|
|
750
|
+
cur.total_tokens = finite(cur.total_tokens) + finite(row.total_tokens);
|
|
751
|
+
cur.cost_usd = finite(cur.cost_usd) + finite(row.cost_usd);
|
|
752
|
+
cur.productive = Boolean(cur.productive) || Boolean(row.productive);
|
|
753
|
+
if (!cur.title && row.title) cur.title = row.title;
|
|
754
|
+
// Representative model/project comes from the busiest fragment (most
|
|
755
|
+
// tokens) so a tiny sidechain cannot overwrite the real coding model.
|
|
756
|
+
if (finite(row.total_tokens) > finite(cur._repr_tokens)) {
|
|
757
|
+
cur._repr_tokens = finite(row.total_tokens);
|
|
758
|
+
if (row.model && row.model !== "unknown") cur.model = row.model;
|
|
759
|
+
cur.project_key = row.project_key;
|
|
760
|
+
cur.project_ref = row.project_ref;
|
|
761
|
+
}
|
|
762
|
+
if (row.started_at && (!cur.started_at || row.started_at < cur.started_at)) cur.started_at = row.started_at;
|
|
763
|
+
if (row.ended_at && (!cur.ended_at || row.ended_at > cur.ended_at)) cur.ended_at = row.ended_at;
|
|
764
|
+
}
|
|
765
|
+
const merged = [];
|
|
766
|
+
for (const row of byHash.values()) {
|
|
767
|
+
delete row._repr_tokens;
|
|
768
|
+
const startedMs = Date.parse(row.started_at || "");
|
|
769
|
+
const endedMs = Date.parse(row.ended_at || "");
|
|
770
|
+
row.duration_ms = Number.isFinite(startedMs) && Number.isFinite(endedMs) ? Math.max(0, endedMs - startedMs) : 0;
|
|
771
|
+
row.first_pass = finite(row.edit_turns) === 1 && finite(row.retry_turns) === 0;
|
|
772
|
+
row.one_shot = row.first_pass;
|
|
773
|
+
merged.push(row);
|
|
774
|
+
}
|
|
775
|
+
return merged;
|
|
776
|
+
}
|
|
777
|
+
|
|
778
|
+
// Local-only session list for the dashboard session browser. Unlike
|
|
779
|
+
// summarizeSessions (cloud/CSV safe), this retains session_id + project_ref so
|
|
780
|
+
// the UI can offer one-click resume. Callers must only expose it over the
|
|
781
|
+
// local API.
|
|
782
|
+
function listSessionsForBrowser(sessions, { from = "", to = "", limit = 0 } = {}) {
|
|
783
|
+
const filtered = mergeSessionFragments(sessions).filter((row) => {
|
|
784
|
+
const day = String(row.started_at || row.ended_at || "").slice(0, 10);
|
|
785
|
+
return (!from || day >= from) && (!to || day <= to);
|
|
786
|
+
});
|
|
787
|
+
filtered.sort((a, b) => String(b.ended_at || "").localeCompare(String(a.ended_at || "")));
|
|
788
|
+
const cap = Number(limit) > 0 ? Number(limit) : 0;
|
|
789
|
+
const limited = cap > 0 ? filtered.slice(0, cap) : filtered;
|
|
790
|
+
return {
|
|
791
|
+
available: filtered.length > 0,
|
|
792
|
+
session_count: filtered.length,
|
|
793
|
+
returned_count: limited.length,
|
|
794
|
+
sessions: limited.map(toSessionBrowserRow),
|
|
795
|
+
provenance: {
|
|
796
|
+
source: "local-session-log",
|
|
797
|
+
confidence: "observed",
|
|
798
|
+
privacy: "metadata-only",
|
|
799
|
+
scope: "local-only",
|
|
800
|
+
},
|
|
801
|
+
};
|
|
802
|
+
}
|
|
803
|
+
|
|
598
804
|
function sessionsToCsv(rows) {
|
|
599
805
|
const columns = ["session_hash", "source", "project_key", "model", "started_at", "ended_at", "duration_ms", "turns", "edit_turns", "retry_turns", "subagent_calls", "total_tokens", "cost_usd", "productive", "first_pass", "one_shot"];
|
|
600
806
|
const escape = (value) => `"${String(value ?? "").replaceAll('"', '""')}"`;
|
|
@@ -608,5 +814,7 @@ module.exports = {
|
|
|
608
814
|
scanCodexSession,
|
|
609
815
|
buildSessionAnalytics,
|
|
610
816
|
summarizeSessions,
|
|
817
|
+
listSessionsForBrowser,
|
|
818
|
+
resumeCommandFor,
|
|
611
819
|
sessionsToCsv,
|
|
612
820
|
};
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/BadgeDetailModal-EO-f-kw5.js","assets/__vite-browser-external-CYtUwU4m.js","assets/__vite-browser-external-BEMfOISl.css","assets/react-DWYxtoLr.js","assets/AchievementBadge-X8YWBf82.js","assets/zap-RGCJBL7C.js","assets/flame-DwM_jWVy.js","assets/use-transform-Czq10OHT.js","assets/use-reduced-motion-B4iythwk.js","assets/AchievementsSection-Cquf4Guw.js","assets/format-tokens-CPxOZc6P.js","assets/DialogTitle-BjiS_5bA.js","assets/useScrollLock-C7zK-ZeS.js"])))=>i.map(i=>d[i]);
|
|
2
|
-
import{r as l,F as x,G as f,H as v,j as e,c,L as p,R as g,a as y,I as b,J as k,_ as j}from"./__vite-browser-external-CYtUwU4m.js";import{A as w}from"./AchievementsSection-Cquf4Guw.js";import{B as h}from"./AchievementBadge-X8YWBf82.js";import"./react-DWYxtoLr.js";import"./format-tokens-CPxOZc6P.js";import"./use-reduced-motion-B4iythwk.js";import"./zap-RGCJBL7C.js";import"./flame-DwM_jWVy.js";function N({enabled:a=!0}={}){const[r,t]=l.useState({status:"loading",achievements:[],error:null}),s=l.useMemo(()=>x(),[]);return l.useEffect(()=>{if(!a){t({status:"disabled",achievements:[],error:null});return}let i=!1;return t(n=>({...n,status:"loading"})),f({timeZone:s,tzOffsetMinutes:v()}).then(n=>{i||t({status:"ready",achievements:Array.isArray(n?.achievements)?n.achievements:[],error:null})}).catch(n=>{i||t({status:"error",achievements:[],error:n})}),()=>{i=!0}},[a,s]),r}const A=g.lazy(()=>j(()=>import("./BadgeDetailModal-EO-f-kw5.js"),__vite__mapDeps([0,1,2,3,4,5,6,7,8,9,10,11,12])));function I({authLoading:a,authEnabled:r,authUserId:t,mockEnabled:s}){if(s)return{authLoading:!1,signedIn:!0,userId:"mock-user"};const i=!!(r&&t);return{authLoading:!!a,signedIn:i,userId:i?t:null}}function B(){const a=y(),[r,t]=l.useState({status:"loading",achievements:[],userId:null}),s=b(),{authLoading:i,signedIn:n,userId:o}=I({authLoading:a?.loading,authEnabled:a?.enabled,authUserId:a?.user?.id,mockEnabled:s});return l.useEffect(()=>{if(i){t({status:"loading",achievements:[],userId:null});return}if(!n){t({status:"signed-out",achievements:[],userId:null});return}let d=!1;return t({status:"loading",achievements:[],userId:o}),(async()=>{try{const u=s?null:await a.getAccessToken?.(),m=await k({accessToken:u,userId:o});if(d)return;t({status:"ready",achievements:Array.isArray(m?.badges)?m.badges:[],userId:o})}catch{d||t({status:"error",achievements:[],userId:o})}})(),()=>{d=!0}},[i,s,n,o]),{...r,signedIn:n,settled:_({authLoading:i,signedIn:n,userId:o,state:r})}}function _({authLoading:a,signedIn:r,userId:t,state:s}){return a?!1:r?s.userId===t&&(s.status==="ready"||s.status==="error"):s.status==="signed-out"}function S(){return e.jsx("div",{className:"mx-0 grid animate-pulse grid-cols-[repeat(3,max-content)] justify-between gap-y-7 sm:-mx-2 sm:grid-cols-[repeat(4,max-content)] lg:grid-cols-[repeat(5,max-content)]","aria-hidden":!0,children:Array.from({length:h.length}).map((a,r)=>e.jsxs("div",{className:"flex w-[6.75rem] flex-col items-center px-0 pb-3 pt-4 sm:w-[7.75rem]",children:[e.jsx("div",{className:"h-[108px] w-[108px] rounded-full bg-oai-gray-200 dark:bg-oai-gray-800"}),e.jsx("div",{className:"mt-3 h-3 w-16 rounded bg-oai-gray-200 dark:bg-oai-gray-800"}),e.jsx("div",{className:"mt-2 h-2 w-10 rounded bg-oai-gray-100 dark:bg-oai-gray-800/60"})]},r))})}function z(){const a=N(),r=B(),[t,s]=l.useState(null),i=a.status==="loading"||!r.settled,n=l.useMemo(()=>[...r.achievements||[],...a.achievements||[]],[r.achievements,a.achievements]),o=l.useMemo(()=>n.filter(u=>(u?.tier||0)>=1).length,[n]),d=h.length;return e.jsxs("div",{className:"flex flex-1 flex-col font-oai text-oai-black antialiased dark:text-oai-white",children:[e.jsx("main",{className:"flex-1 pb-12 pt-8 sm:pb-16 sm:pt-10",children:e.jsxs("div",{className:"mx-auto max-w-4xl px-4 sm:px-6",children:[e.jsxs("div",{className:"mb-7 flex items-baseline justify-between gap-4",children:[e.jsxs("div",{className:"min-w-0",children:[e.jsx("h1",{className:"text-3xl font-semibold tracking-tight text-oai-black dark:text-white sm:text-4xl",children:c("achievements.page.title")}),e.jsx("p",{className:"mt-1.5 text-sm text-oai-gray-500 dark:text-oai-gray-400",children:c("achievements.page.local_note")})]}),!i&&e.jsxs("div",{className:"shrink-0 text-right",children:[e.jsxs("div",{className:"font-mono text-2xl font-semibold leading-none tabular-nums text-oai-black dark:text-white",children:[o,e.jsxs("span",{className:"text-oai-gray-400 dark:text-oai-gray-600",children:["/",d]})]}),e.jsx("div",{className:"mt-2 h-1 w-24 overflow-hidden rounded-full bg-oai-gray-200 dark:bg-oai-gray-800",children:e.jsx("div",{className:"h-full rounded-full bg-oai-brand-600 transition-[width] duration-500",style:{width:`${Math.round(o/d*100)}%`}})})]})]}),!r.signedIn&&!i&&e.jsxs("div",{className:"mb-6 flex flex-wrap items-center justify-between gap-x-4 gap-y-2 rounded-xl border border-oai-gray-200 bg-oai-gray-50 px-4 py-3 dark:border-oai-gray-800 dark:bg-oai-gray-900/60",children:[e.jsx("p",{className:"text-sm text-oai-gray-600 dark:text-oai-gray-300",children:c("achievements.signin.prompt")}),e.jsx(p,{to:"/login",className:"shrink-0 rounded-lg bg-oai-brand-600 px-3 py-1.5 text-sm font-medium text-white transition-colors duration-200 hover:bg-oai-brand-700 active:scale-[0.98]",children:c("achievements.signin.action")})]}),i?e.jsx(S,{}):e.jsxs(e.Fragment,{children:[e.jsx(w,{achievements:n,isOwn:!0,columns:"wide",size:"lg",animateIn:!0,onSelect:s}),e.jsxs("p",{className:"mt-10 text-center text-xs text-oai-gray-400 dark:text-oai-gray-500",children:[c("achievements.page.suggest")," ",e.jsx("a",{href:"https://github.com/mm7894215/TokenTracker/issues",target:"_blank",rel:"noopener noreferrer",className:"underline decoration-oai-gray-300 underline-offset-2 transition-colors hover:text-oai-gray-700 hover:decoration-oai-gray-500 dark:decoration-oai-gray-600 dark:hover:text-oai-gray-300",children:c("achievements.page.suggest_link")})]})]})]})}),t&&e.jsx(g.Suspense,{fallback:null,children:e.jsx(A,{badge:t,onClose:()=>s(null)})})]})}export{_ as cloudBadgesSettled,z as default,I as resolveCloudBadgeIdentity};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{r as L,j as a,bb as De,c as h,d as ye,X as Ie}from"./__vite-browser-external-CYtUwU4m.js";import{k as _e,V as Me,l as Ve,r as Te,n as $e,o as be,q as ve,s as Oe,t as Re,v as Be,w as Pe,x as Ke,y as Ce,z as Fe,A as Le,B as Xe,S as Ge,H as We,C as G,D as ze,E as Ue,e as Ye,F as He,m as C}from"./react-DWYxtoLr.js";import{c as je,A as Ze,p as qe,b as U,t as le,a as T,d as Je}from"./AchievementBadge-X8YWBf82.js";import{u as Qe,a as z}from"./use-transform-Czq10OHT.js";import{u as et}from"./use-reduced-motion-B4iythwk.js";import{l as ce,f as ue,b as tt}from"./AchievementsSection-Cquf4Guw.js";import{D as nt,a as rt,b as at,c as st,d as it,e as ot}from"./DialogTitle-BjiS_5bA.js";import"./zap-RGCJBL7C.js";import"./flame-DwM_jWVy.js";import"./format-tokens-CPxOZc6P.js";import"./useScrollLock-C7zK-ZeS.js";const lt=(e,t,n)=>{const r=t-e;return((n-e)%r+r)%r+e};function Ne(e,t){return _e(e)?e[lt(0,e.length,t)]:e}class ct{constructor(t){this.stop=()=>this.runAll("stop"),this.animations=t.filter(Boolean)}get finished(){return Promise.all(this.animations.map(t=>t.finished))}getAll(t){return this.animations[0][t]}setAll(t,n){for(let r=0;r<this.animations.length;r++)this.animations[r][t]=n}attachTimeline(t){const n=this.animations.map(r=>r.attachTimeline(t));return()=>{n.forEach((r,s)=>{r&&r(),this.animations[s].stop()})}}get time(){return this.getAll("time")}set time(t){this.setAll("time",t)}get speed(){return this.getAll("speed")}set speed(t){this.setAll("speed",t)}get state(){return this.getAll("state")}get startTime(){return this.getAll("startTime")}get duration(){return de(this.animations,"duration")}get iterationDuration(){return de(this.animations,"iterationDuration")}runAll(t){this.animations.forEach(n=>n[t]())}play(){this.runAll("play")}pause(){this.runAll("pause")}cancel(){this.runAll("cancel")}complete(){this.runAll("complete")}}function de(e,t){let n=0;for(let r=0;r<e.length;r++){const s=e[r][t];s!==null&&s>n&&(n=s)}return n}class ut extends ct{then(t,n){return this.finished.finally(t).then(()=>{})}}function dt(e,t){return e in t}class mt extends Me{constructor(){super(...arguments),this.type="object"}readValueFromInstance(t,n){if(dt(n,t)){const r=t[n];if(typeof r=="string"||typeof r=="number")return r}}getBaseTargetFromProps(){}removeValueFromRenderState(t,n){delete n.output[t]}measureInstanceViewportBox(){return Ve()}build(t,n){Object.assign(t.output,n)}renderInstance(t,{output:n}){Object.assign(t,n)}sortInstanceNodePosition(){return 0}}function Y(e){return typeof e=="object"&&!Array.isArray(e)}function ke(e,t,n,r){return e==null?[]:typeof e=="string"&&Y(t)?Te(e,n,r):e instanceof NodeList?Array.from(e):Array.isArray(e)?e.filter(s=>s!=null):[e]}function ft(e,t,n){return e*(t+1)+n*t}function me(e,t,n,r){return typeof t=="number"?t:t.startsWith("-")||t.startsWith("+")?Math.max(0,e+parseFloat(t)):t==="<"?n:t.startsWith("<")?Math.max(0,n+parseFloat(t.slice(1))):r.get(t)??e}function pt(e,t,n){for(let r=0;r<e.length;r++){const s=e[r];s.at>t&&s.at<n&&(be(e,s),r--)}}function ht(e,t,n,r,s,c){pt(e,s,c);for(let i=0;i<t.length;i++)e.push({value:t[i],at:$e(s,c,r[i]),easing:Ne(n,i)})}function gt(e,t,n=0){const r=t+1+t*n;for(let s=0;s<e.length;s++)e[s]=e[s]/r}function xt(e,t){return e.at===t.at?e.value===null?1:t.value===null?-1:0:e.at-t.at}const yt="easeInOut",bt=20;function vt(e,{defaultTransition:t={},...n}={},r,s){const c=t.duration||.3,i=new Map,f=new Map,m={},p=new Map;let g=0,u=0,x=0;for(let N=0;N<e.length;N++){const k=e[N];if(typeof k=="string"){p.set(k,u);continue}else if(!Array.isArray(k)){p.set(k.name,me(u,k.at,g,p));continue}let[E,b,v={}]=k;v.at!==void 0&&(u=me(u,v.at,g,p));let j=0;const _=(w,M,A,o=0,l=0)=>{const d=jt(w),{delay:D=0,times:y=Oe(d),type:R=t.type||"keyframes",repeat:B,repeatType:W,repeatDelay:H=0,...Se}=M;let{ease:I=t.ease||"easeOut",duration:S}=M;const Z=typeof D=="function"?D(o,l):D,q=d.length,J=Ke(R)?R:s?.[R||"keyframes"];if(q<=2&&J){let $=100;if(q===2&&wt(d)){const P=d[1]-d[0];$=Math.abs(P)}const O={...t,...Se};S!==void 0&&(O.duration=Ce(S));const X=Re(O,$,J);I=X.ease,S=X.duration}S??(S=c);const Q=u+Z;y.length===1&&y[0]===0&&(y[1]=1);const ee=y.length-d.length;if(ee>0&&Be(y,ee),d.length===1&&d.unshift(null),B&&B<bt){const $=S>0?H/S:0;S=ft(S,B,H);const O=[...d],X=[...y];I=Array.isArray(I)?[...I]:[I];const P=[...I],ne=W==="reverse"||W==="mirror";let re=O,ae=P;ne&&(re=[...O].reverse(),W==="reverse"&&(ae=[...P].reverse().map(V=>typeof V=="function"?Pe(V):V)));for(let V=0;V<B;V++){const se=ne&&V%2===0,ie=se?re:O,Ee=se?ae:P,oe=(V+1)*(1+$);$>0&&(d.push(d[d.length-1]),y.push(oe),I.push("linear")),d.push(...ie);for(let K=0;K<ie.length;K++)y.push(X[K]+oe),I.push(K===0?"linear":Ne(Ee,K-1))}gt(y,B,$)}const te=Q+S;ht(A,d,I,y,Q,te),j=Math.max(Z+S,j),x=Math.max(te,x)};if(ve(E)){const w=fe(E,f);_(b,v,pe("default",w))}else{const w=ke(E,b,r,m),M=w.length;for(let A=0;A<M;A++){b=b,v=v;const o=w[A],l=fe(o,f);for(const d in b)_(b[d],Nt(v,d),pe(d,l),A,M)}}g=u,u+=j}return f.forEach((N,k)=>{for(const E in N){const b=N[E];b.sort(xt);const v=[],j=[],_=[];for(let o=0;o<b.length;o++){const{at:l,value:d,easing:D}=b[o];v.push(d),j.push(Fe(0,x,l)),_.push(D||"easeOut")}j[0]!==0&&(j.unshift(0),v.unshift(v[0]),_.unshift(yt)),j[j.length-1]!==1&&(j.push(1),v.push(null)),i.has(k)||i.set(k,{keyframes:{},transition:{}});const w=i.get(k);w.keyframes[E]=v;const{type:M,...A}=t;w.transition[E]={...A,duration:x,ease:_,times:j,...n}}}),i}function fe(e,t){return!t.has(e)&&t.set(e,{}),t.get(e)}function pe(e,t){return t[e]||(t[e]=[]),t[e]}function jt(e){return Array.isArray(e)?e:[e]}function Nt(e,t){return e&&e[t]?{...e,...e[t]}:{...e}}const kt=e=>typeof e=="number",wt=e=>e.every(kt);function At(e){const t={presenceContext:null,props:{},visualState:{renderState:{transform:{},transformOrigin:{},style:{},vars:{},attrs:{}},latestValues:{}}},n=Le(e)&&!Xe(e)?new Ge(t):new We(t);n.mount(e),G.set(e,n)}function St(e){const t={presenceContext:null,props:{},visualState:{renderState:{output:{}},latestValues:{}}},n=new mt(t);n.mount(e),G.set(e,n)}function Et(e,t){return ve(e)||typeof e=="number"||typeof e=="string"&&!Y(t)}function we(e,t,n,r){const s=[];if(Et(e,t))s.push(ze(e,Y(t)&&t.default||t,n&&(n.default||n)));else{if(e==null)return s;const c=ke(e,t,r),i=c.length;for(let f=0;f<i;f++){const m=c[f],p=m instanceof Element?At:St;G.has(m)||p(m);const g=G.get(m),u={...n};"delay"in u&&typeof u.delay=="function"&&(u.delay=u.delay(f,i)),s.push(...Ue(g,{...t,transition:u},{}))}}return s}function Dt(e,t,n){const r=[],s=e.map(i=>{if(Array.isArray(i)&&typeof i[0]=="function"){const f=i[0],m=Ye(0);return m.on("change",f),i.length===1?[m,[0,1]]:i.length===2?[m,[0,1],i[1]]:[m,i[1],i[2]]}return i});return vt(s,t,n,{spring:He}).forEach(({keyframes:i,transition:f},m)=>{r.push(...we(m,i,f))}),r}function It(e){return Array.isArray(e)&&e.some(Array.isArray)}function _t(e={}){const{scope:t,reduceMotion:n,skipAnimations:r}=e;function s(c,i,f){let m=[],p;const g={};if(n!==void 0&&(g.reduceMotion=n),r!==void 0&&(g.skipAnimations=r),It(c)){const{onComplete:x,...N}=i||{};typeof x=="function"&&(p=x),m=Dt(c,{...g,...N},t)}else{const{onComplete:x,...N}=f||{};typeof x=="function"&&(p=x),m=we(c,i,{...g,...N},t)}const u=new ut(m);return p&&u.finished.then(p),t&&(t.animations.push(u),u.finished.then(()=>{be(t.animations,u)})),u}return s}const F=_t(),he=8;function Mt({badgeId:e,tier:t,locked:n=!1,size:r=176,backLines:s=[],label:c}){const i=Qe(0),f=et(),m=L.useRef(null),p=L.useRef(null),g=L.useRef(!1),u=qe(t,n),x=je.get(e)?.icon||null,N=z(i,o=>`${(o%360+360)%360/360*160-80}%`),k=z(i,o=>`${80-(o%360+360)%360/360*160}%`),E=z(i,o=>{const l=Math.abs(Math.sin(o*Math.PI/180));return Math.max(0,(l-.35)/.65)*.3}),b=()=>{p.current?.stop?.(),p.current=null};L.useEffect(()=>{if(f||g.current)return;let o=!1;i.set(-360);const l=F(i,0,{duration:.9,ease:[.16,1,.3,1]});return p.current=l,l.then(()=>{o||g.current||(p.current=F(i,[0,-14,14,0],{duration:4.5,repeat:1/0,ease:"easeInOut"}))}),()=>{o=!0,b()}},[f,i]);const v=o=>{const l=i.get();if(f){const y=Math.round(l/180)*180;p.current=F(i,y,{duration:.2,ease:"easeOut"});return}const d=l+o*.35,D=Math.round(d/180)*180;p.current=F(i,D,{type:"spring",velocity:o,stiffness:58,damping:13.5,mass:1})},j=o=>{g.current=!0,b(),o.currentTarget.setPointerCapture?.(o.pointerId),m.current={pointerId:o.pointerId,startX:o.clientX,startRot:i.get(),samples:[{t:o.timeStamp,x:o.clientX}]}},_=o=>{const l=m.current;!l||l.pointerId!==o.pointerId||(i.set(l.startRot+(o.clientX-l.startX)*.55),l.samples.push({t:o.timeStamp,x:o.clientX}),l.samples.length>5&&l.samples.shift())},w=o=>{const l=m.current;if(!l||l.pointerId!==o.pointerId)return;m.current=null;const d=l.samples[0],D=l.samples[l.samples.length-1],y=D.t-d.t,R=y>0?(D.x-d.x)*.55*1e3/y:0;v(R)},M=o=>{if(o.key!=="ArrowLeft"&&o.key!=="ArrowRight")return;o.preventDefault(),g.current=!0,b();const l=o.key==="ArrowRight"?30:-30;p.current=F(i,i.get()+l,{duration:.15,ease:"easeOut"})},A={backfaceVisibility:"hidden",WebkitBackfaceVisibility:"hidden"};return a.jsx("div",{role:"img","aria-label":c,tabIndex:0,onPointerDown:j,onPointerMove:_,onPointerUp:w,onPointerCancel:w,onKeyDown:M,className:"inline-flex cursor-grab select-none items-center justify-center outline-none focus-visible:ring-2 focus-visible:ring-oai-brand/60 rounded-full active:cursor-grabbing",style:{perspective:900,touchAction:"pan-y"},children:a.jsxs("div",{className:"relative",style:{transform:"rotateX(-8deg)",transformStyle:"preserve-3d"},children:[a.jsxs(C.div,{className:"relative",style:{rotateY:i,transformStyle:"preserve-3d",width:r,height:r},children:[[-3,-1.5,0,1.5,3].map(o=>a.jsx("div",{"aria-hidden":!0,className:"absolute inset-0 rounded-full",style:{transform:`translateZ(${o}px)`,background:u.rim[1]}},o)),a.jsxs("div",{className:"absolute inset-0 overflow-hidden rounded-full",style:{...A,transform:`translateZ(${he/2}px)`},children:[a.jsx(Ze,{badgeId:e,tier:t,locked:n,size:"fill",className:"brightness-105 saturate-[1.08]"}),a.jsx("div",{"aria-hidden":!0,className:"pointer-events-none absolute inset-0 rounded-full",style:{background:"radial-gradient(circle at 30% 20%, rgba(255,255,255,0.45), rgba(255,255,255,0) 42%), linear-gradient(172deg, rgba(255,255,255,0.14) 0%, rgba(255,255,255,0) 38%, rgba(0,0,0,0.08) 100%)",boxShadow:"inset 0 3px 7px rgba(255,255,255,0.5), inset 0 -3px 8px rgba(0,0,0,0.15)"}}),a.jsx(C.div,{"aria-hidden":!0,className:"pointer-events-none absolute inset-0",style:{x:N,background:"linear-gradient(105deg, transparent 34%, rgba(255,255,255,0.5) 50%, transparent 66%)"}}),a.jsx(C.div,{"aria-hidden":!0,className:"pointer-events-none absolute inset-0 rounded-full",style:{opacity:E,background:"rgba(8, 12, 10, 0.9)"}})]}),a.jsxs("div",{className:"absolute inset-0 flex flex-col items-center justify-center gap-1 overflow-hidden rounded-full px-6 text-center",style:{...A,transform:`rotateY(180deg) translateZ(${he/2}px)`,background:`linear-gradient(145deg, ${u.face[0]}, ${u.face[1]})`,boxShadow:`inset 0 0 0 6px ${u.rim[1]}, inset 0 0 0 7.5px rgba(255,255,255,0.22), inset 0 3px 7px rgba(255,255,255,0.4), inset 0 -4px 12px rgba(0,0,0,0.22)`},children:[a.jsx("div",{"aria-hidden":!0,className:"pointer-events-none absolute inset-0 rounded-full",style:{background:"repeating-radial-gradient(circle at 50% 50%, rgba(255,255,255,0.06) 0px, rgba(255,255,255,0.06) 1px, transparent 1px, transparent 4px)"}}),x?a.jsx(x,{"aria-hidden":!0,size:Math.round(r*.62),strokeWidth:1.1,color:u.glyph,className:"pointer-events-none absolute opacity-[0.13]",style:{filter:"drop-shadow(0 1px 0 rgba(255,255,255,0.3)) drop-shadow(0 -1px 0 rgba(0,0,0,0.35))"}}):null,a.jsx("div",{"aria-hidden":!0,className:"pointer-events-none absolute inset-0 rounded-full",style:{background:"radial-gradient(circle at 70% 20%, rgba(255,255,255,0.4), rgba(255,255,255,0) 44%), linear-gradient(188deg, rgba(255,255,255,0.12) 0%, rgba(255,255,255,0) 38%, rgba(0,0,0,0.10) 100%)"}}),s.map((o,l)=>a.jsx("div",{className:`font-mono tabular-nums ${l===0?"text-[10px] uppercase tracking-[0.18em]":l===1?"text-lg font-bold":"text-[11px]"}`,style:{color:u.glyph,textShadow:"0 1px 0 rgba(255,255,255,0.28), 0 -1px 0 rgba(0,0,0,0.3)"},children:o},`${l}-${o}`)),a.jsx(C.div,{"aria-hidden":!0,className:"pointer-events-none absolute inset-0",style:{x:k,background:"linear-gradient(105deg, transparent 34%, rgba(255,255,255,0.45) 50%, transparent 66%)"}}),a.jsx(C.div,{"aria-hidden":!0,className:"pointer-events-none absolute inset-0 rounded-full",style:{opacity:E,background:"rgba(8, 12, 10, 0.9)"}})]})]}),a.jsx("div",{"aria-hidden":!0,className:"absolute left-1/2 h-3 w-3/5 rounded-[100%] bg-black/20 blur-md dark:bg-black/45",style:{bottom:-20,transform:"translateX(-50%)"}})]})})}function Ae(e){if(!e)return null;const t=Date.parse(e);return Number.isFinite(t)?new Date(t).toLocaleDateString():null}function Vt(e){const t=Number(e);return!Number.isSafeInteger(t)||t<1?null:String(t).padStart(6,"0")}function Tt(e,t,n){if(t?.scope!=="cloud"||!n)return null;const r=Number(e?.serials?.[n]);return Number.isSafeInteger(r)&&r>=1?r:null}function $t({badge:e}){return a.jsx("div",{className:"flex items-center gap-1",children:Je.map((t,n)=>{const r=(e.tier||0)>=n+1,s=Ae(e.achieved?.[t]),c=T[t];return a.jsx("span",{title:s?`${h(`achievements.tier.${t}`)} · ${s}`:h(`achievements.tier.${t}`),className:"inline-flex h-2 w-8 rounded-full",style:r?{background:`linear-gradient(120deg, ${c.rim[0]} 0%, ${c.ring} 55%, ${c.rim[1]} 100%)`,boxShadow:"inset 0 1px 1px rgba(255,255,255,0.4), 0 0 0 1px rgba(10,15,12,0.05)"}:void 0,children:!r&&a.jsx("span",{className:"h-full w-full rounded-full bg-oai-gray-200 dark:bg-oai-gray-800"})},t)})})}function ge({badge:e,onClose:t}){const n=je.get(e.id),r=h(U(e.id,"name")),s=(e.tier||0)>=1,c=s?le(e.tier):null,i=Ae(s?e.achieved?.[c]||(ce(e)?new Date(ce(e)).toISOString():null):null),f=ue(n?.format,e.metric_value),m=tt(e),p=e.tier<4?le((e.tier||0)+1):null,g=Tt(e,n,c),u=Vt(g),x=u?[h("achievements.modal.achieved_label"),h("achievements.modal.issue_number",{number:u}),i||r]:[s?h("achievements.modal.achieved_label"):h("achievements.modal.locked"),s?f:"···",s&&i?i:r];return a.jsxs("div",{className:"flex flex-col items-center px-6 pb-6 pt-5 text-center",children:[a.jsxs("div",{className:"flex w-full items-start justify-between gap-3",children:[a.jsxs("div",{className:"min-w-0 flex-1 text-left",children:[a.jsx("h2",{className:"truncate text-lg font-semibold tracking-tight text-oai-black dark:text-white",children:r}),a.jsx("p",{className:"mt-0.5 text-xs text-oai-gray-500 dark:text-oai-gray-400",children:h(U(e.id,"desc"))})]}),a.jsx("button",{type:"button",onClick:t,"aria-label":h("achievements.modal.close"),className:"shrink-0 rounded-md p-1.5 text-oai-gray-400 transition-colors hover:bg-oai-gray-100 hover:text-oai-gray-700 dark:hover:bg-oai-gray-900 dark:hover:text-oai-gray-200",children:a.jsx(Ie,{size:16})})]}),a.jsx("div",{className:"mt-5 mb-7",children:a.jsx(Mt,{badgeId:e.id,tier:e.tier,locked:!s,backLines:x,label:h("achievements.modal.coin_aria",{name:r})})}),a.jsxs("div",{className:"flex items-center gap-2",children:[a.jsx("span",{className:"rounded-full px-2.5 py-0.5 text-[11px] font-semibold uppercase tracking-wide",style:s?{background:`linear-gradient(120deg, ${T[c].rim[0]} 0%, ${T[c].ring} 55%, ${T[c].rim[1]} 100%)`,color:T[c].glyph,textShadow:"0 1px 0 rgba(255,255,255,0.35)",boxShadow:"inset 0 1px 1px rgba(255,255,255,0.4), 0 0 0 1px rgba(10,15,12,0.06)"}:{background:"rgba(128,134,130,0.75)",color:"rgba(250,250,250,0.95)"},children:s?h(`achievements.tier.${c}`):h("achievements.modal.locked")}),s&&i?a.jsx("span",{className:"text-xs tabular-nums text-oai-gray-500 dark:text-oai-gray-400",children:i}):null]}),a.jsxs("dl",{className:"mt-5 w-full space-y-3 border-t border-oai-gray-200/70 pt-4 text-left dark:border-oai-gray-800/60",children:[a.jsxs("div",{className:"flex items-baseline justify-between gap-3 text-sm",children:[a.jsx("dt",{className:"text-oai-gray-500 dark:text-oai-gray-400",children:h("achievements.modal.value_label")}),a.jsx("dd",{className:"font-mono font-semibold tabular-nums text-oai-black dark:text-white",children:f})]}),a.jsxs("div",{children:[a.jsxs("div",{className:"flex items-baseline justify-between gap-3 text-xs text-oai-gray-500 dark:text-oai-gray-400",children:[a.jsx("span",{children:e.tier>=4?h("achievements.modal.max_tier"):h("achievements.modal.progress_to_next",{tier:h(`achievements.tier.${p}`)})}),e.tier<4&&e.next_threshold!=null?a.jsxs("span",{className:"font-mono tabular-nums",children:[f," ",e.lower_is_better?"→":"/"," ",ue(n?.format,e.next_threshold)]}):null]}),a.jsx("div",{className:"mt-1.5 h-1.5 w-full overflow-hidden rounded-full bg-oai-gray-200 dark:bg-oai-gray-800",children:a.jsx("div",{className:"h-full rounded-full transition-[width] duration-500",style:{width:`${Math.round((e.tier>=4?1:m)*100)}%`,background:s?`linear-gradient(90deg, ${T[c].rim[0]} 0%, ${T[c].ring} 55%, ${T[c].rim[1]} 100%)`:"rgba(128,134,130,0.75)",boxShadow:s?"inset 0 1px 1px rgba(255,255,255,0.35)":void 0}})})]}),a.jsxs("div",{className:"flex items-center justify-between gap-3 text-xs text-oai-gray-500 dark:text-oai-gray-400",children:[a.jsx("span",{children:h("achievements.modal.tier_history")}),a.jsx($t,{badge:e})]})]})]})}const xe=ye("relative w-full max-w-[380px] flex flex-col","rounded-2xl bg-white dark:bg-oai-gray-950","shadow-[0_20px_60px_-20px_rgba(0,0,0,0.25)] dark:shadow-[0_20px_60px_-10px_rgba(0,0,0,0.65)]","ring-1 ring-oai-gray-200 dark:ring-oai-gray-800 overflow-hidden","dark:border-t dark:border-white/[0.08]");function zt({badge:e,onClose:t}){const n=De(),r=!!e;return L.useEffect(()=>{if(!n||!r)return;const s=c=>{c.key==="Escape"&&(c.stopPropagation(),t?.())};return window.addEventListener("keydown",s,!0),()=>window.removeEventListener("keydown",s,!0)},[n,r,t]),r?n?a.jsxs("div",{className:"fixed inset-0 z-[120] flex items-center justify-center p-4",children:[a.jsx("div",{className:"absolute inset-0 bg-black/40 backdrop-blur-[2px]",onClick:t,"aria-hidden":!0}),a.jsx("div",{className:xe,children:a.jsx(ge,{badge:e,onClose:t})})]}):a.jsx(nt,{open:!0,onOpenChange:s=>{s||t?.()},children:a.jsxs(rt,{children:[a.jsx(at,{className:"cost-modal-backdrop z-[110]"}),a.jsx(st,{className:"fixed inset-0 z-[120] flex items-center justify-center p-4",children:a.jsxs(it,{className:ye("cost-modal-popup",xe),children:[a.jsx(ot,{render:a.jsx("h2",{className:"sr-only"}),children:h(U(e.id,"name"))}),a.jsx(ge,{badge:e,onClose:t})]})})]})}):null}export{zt as BadgeDetailModal,Tt as currentBadgeIssueNumber,zt as default,Vt as formatIssueNumber};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{l as E,e as M,r,E as D,c as i,j as o,d as I}from"./__vite-browser-external-CYtUwU4m.js";import{m as j}from"./react-DWYxtoLr.js";import{P as L}from"./ProviderIcon-VFnAt_kS.js";import{g as A,S as $}from"./skills-api-Bn_e1uWd.js";import{u as R}from"./use-reduced-motion-B4iythwk.js";import{A as K}from"./index-fbrQEDiP.js";const q=[["path",{d:"M20 4v7a4 4 0 0 1-4 4H4",key:"6o5b7l"}],["path",{d:"m9 10-5 5 5 5",key:"1kshq7"}]],O=E("corner-down-left",q),T=typeof window<"u"&&(window.location.hostname==="localhost"||window.location.hostname==="127.0.0.1");function G(){const f=M(),d=R(),[u,g]=r.useState(!1),[x,h]=r.useState(""),[n,l]=r.useState(0),[p,k]=r.useState([]),b=r.useRef(null),w=r.useRef(null);r.useEffect(()=>{const e=t=>{(t.metaKey||t.ctrlKey)&&(t.key==="k"||t.key==="K")&&(t.preventDefault(),g(c=>!c))};return window.addEventListener("keydown",e),()=>window.removeEventListener("keydown",e)},[]),r.useEffect(()=>{if(!u)return;h(""),l(0);const e=requestAnimationFrame(()=>b.current?.focus());return T&&!p.length&&A().then(t=>k(t?.skills||[])).catch(()=>k([])),()=>cancelAnimationFrame(e)},[u,p.length]);const y=r.useMemo(()=>{const e=D().flatMap(a=>a.items.map(c=>({kind:"page",id:`page:${c.id}`,label:c.label,sub:i("cmdk.group.pages"),Icon:c.icon,run:()=>f(c.to)}))),t=(p||[]).map(a=>({kind:"skill",id:`skill:${a.id||a.directory}`,label:a.name||a.directory,sub:a.repoOwner&&a.repoName?`${a.repoOwner}/${a.repoName}`:i("cmdk.group.skills"),provider:(a.targets||[])[0]||"claude",run:()=>f(`/skills?skill=${encodeURIComponent(a.directory||a.id)}`)}));return[...e,...t]},[f,p]),s=r.useMemo(()=>{const e=x.trim().toLowerCase();return e?y.filter(t=>t.label.toLowerCase().includes(e)||String(t.sub||"").toLowerCase().includes(e)):y},[y,x]);r.useEffect(()=>{n>=s.length&&l(s.length?s.length-1:0)},[n,s.length]),r.useEffect(()=>{if(!u)return;w.current?.querySelector(`[data-cmdk-index="${n}"]`)?.scrollIntoView({block:"nearest"})},[n,u]);const m=r.useCallback(()=>g(!1),[]),v=r.useCallback(e=>{e&&(m(),e.run())},[m]),N=e=>{e.key==="ArrowDown"?(e.preventDefault(),l(t=>Math.min(t+1,Math.max(0,s.length-1)))):e.key==="ArrowUp"?(e.preventDefault(),l(t=>Math.max(t-1,0))):e.key==="Enter"?(e.preventDefault(),v(s[n])):e.key==="Escape"&&(e.preventDefault(),m())},C={duration:d?0:.12},S=d?{duration:0}:{type:"spring",stiffness:460,damping:34,mass:.6};return o.jsx(K,{children:u?o.jsxs(j.div,{className:"fixed inset-0 z-[120] flex items-start justify-center px-4 pt-[16vh]",initial:d?!1:{opacity:0},animate:{opacity:1},exit:{opacity:0},transition:C,children:[o.jsx("button",{type:"button","aria-label":i("cmdk.close"),onClick:m,className:"absolute inset-0 cursor-default bg-oai-black/40"}),o.jsxs(j.div,{role:"dialog","aria-modal":"true","aria-label":i("cmdk.open_aria"),initial:d?!1:{opacity:0,y:-8,scale:.985},animate:{opacity:1,y:0,scale:1},exit:d?{opacity:0}:{opacity:0,y:-8,scale:.985},transition:S,className:"relative w-full max-w-xl overflow-hidden rounded-2xl border border-oai-gray-200 bg-oai-white shadow-2xl dark:border-oai-gray-800 dark:bg-oai-gray-950",children:[o.jsxs("div",{className:"flex items-center gap-2.5 border-b border-oai-gray-200 px-4 dark:border-oai-gray-800",children:[o.jsx($,{className:"h-4 w-4 shrink-0 text-oai-gray-400","aria-hidden":!0}),o.jsx("input",{ref:b,type:"text",value:x,onChange:e=>{h(e.target.value),l(0)},onKeyDown:N,"aria-label":i("cmdk.placeholder"),"aria-controls":"cmdk-listbox","aria-activedescendant":s[n]?`cmdk-opt-${n}`:void 0,role:"combobox","aria-expanded":"true",placeholder:i("cmdk.placeholder"),className:"h-12 w-full bg-transparent text-sm text-oai-black placeholder:text-oai-gray-400 focus:outline-none dark:text-white"})]}),o.jsx("div",{ref:w,id:"cmdk-listbox",role:"listbox",className:"max-h-[min(56vh,22rem)] overflow-y-auto p-1.5",children:s.length===0?o.jsx("div",{className:"px-3 py-8 text-center text-sm text-oai-gray-500 dark:text-oai-gray-400",children:i("cmdk.empty")}):s.map((e,t)=>{const a=t===n;return o.jsxs("button",{type:"button",role:"option",id:`cmdk-opt-${t}`,"data-cmdk-index":t,"aria-selected":a,onMouseMove:()=>l(t),onClick:()=>v(e),className:I("flex w-full items-center gap-3 rounded-lg px-3 py-2 text-left text-sm transition-colors",a?"bg-oai-gray-100 text-oai-black dark:bg-oai-gray-800/70 dark:text-white":"text-oai-gray-700 dark:text-oai-gray-200"),children:[o.jsx("span",{className:"flex h-5 w-5 shrink-0 items-center justify-center text-oai-gray-500 dark:text-oai-gray-400",children:e.kind==="skill"?o.jsx(L,{provider:e.provider,size:16}):o.jsx(e.Icon,{className:"h-4 w-4","aria-hidden":!0})}),o.jsx("span",{className:"min-w-0 flex-1 truncate font-medium",children:e.label}),o.jsx("span",{className:"shrink-0 truncate text-xs text-oai-gray-400 dark:text-oai-gray-500",children:e.sub}),a?o.jsx(O,{className:"h-3.5 w-3.5 shrink-0 text-oai-gray-400","aria-hidden":!0}):null]},e.id)})})]})]}):null})}export{G as CommandPalette};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{l as L,j as e,U as R,m as P,r as D,c as n,X as z,k as S}from"./__vite-browser-external-CYtUwU4m.js";import{m as M}from"./react-DWYxtoLr.js";import{A as K,W as U}from"./icons-znz72ccY.js";import{u as B}from"./useTokenFormat-myPlm960.js";import{P as F}from"./ProviderIcon-VFnAt_kS.js";import{T as G}from"./TrendMonitor-DSB2kwaQ.js";import{T as W}from"./AchievementBadge-X8YWBf82.js";import{T as V}from"./terminal-BXaxyX4y.js";import{D as X,a as Y,b as Z,c as H,d as q,e as J}from"./DialogTitle-BjiS_5bA.js";import{D as Q}from"./DialogDescription-MAfXy8yJ.js";import{D as ee}from"./DialogClose-VrH-Z7vG.js";import"./useCurrency-yGkGAfpB.js";import"./PopoverPopup-Ds1h2_iH.js";import"./useScrollLock-C7zK-ZeS.js";import"./SelectItemText-CY-n8m9N.js";import"./use-reduced-motion-B4iythwk.js";import"./zap-RGCJBL7C.js";import"./flame-DwM_jWVy.js";const ae=[["path",{d:"M16 17h6v-6",key:"t6n2it"}],["path",{d:"m22 17-8.5-8.5-5 5L2 7",key:"x473p"}]],te=L("trending-down",ae),O=10,_={input:"var(--community-token-input)",cache_read:"var(--community-token-cache-read)",cache_write:"var(--community-token-cache-write)",output:"var(--community-token-output)",reasoning:"var(--community-token-reasoning)"},re={CLAUDE:"var(--community-claude)",CODEX:"var(--community-codex)",GEMINI:"var(--community-gemini)",CURSOR:"var(--community-cursor)",OPENCODE:"var(--community-opencode)",HERMES:"var(--community-hermes)",KIMI:"var(--community-kimi)",MIMO:"var(--community-mimo)",COPILOT:"var(--community-copilot)",KIRO:"var(--community-kiro)",GROK:"var(--community-grok)",DEEPSEEK:"var(--community-deepseek)",ZCODE:"var(--community-zcode)",WORKBUDDY:"var(--community-workbuddy)",MINIMAX:"var(--community-minimax)",DROID:"var(--community-droid)"};function ie(t){return re[String(t||"").toUpperCase()]||"var(--community-muted)"}const se=[[/claude|fable|opus|sonnet|haiku/,"CLAUDE"],[/gpt|codex|o3|o4/,"CODEX"],[/gemini/,"GEMINI"],[/composer|cursor/,"CURSOR"],[/kimi/,"KIMI"],[/mimo/,"MIMO"],[/copilot/,"COPILOT"],[/kiro/,"KIRO"],[/grok/,"GROK"],[/deepseek/,"DEEPSEEK"],[/glm/,"ZCODE"],[/hy3/,"WORKBUDDY"],[/minimax/,"MINIMAX"]],g=["overview","providers","community","models"];function oe(t){const s=String(t||"").toLowerCase(),a=se.find(([i])=>i.test(s));return a?a[1]:""}function u(t){const s=Number(t);return Number.isFinite(s)?`${s.toFixed(1)}%`:"—"}function p(t){return S(Number(t)||0)}function ne(t){return t?new Date(`${t}T00:00:00Z`).toLocaleDateString(void 0,{month:"short",day:"numeric",timeZone:"UTC"}):""}function k(){return e.jsx("div",{className:"flex h-full min-h-40 items-center justify-center text-xs text-oai-gray-400",children:n("leaderboard.community.modal.no_data")})}function b({children:t,detail:s}){return e.jsxs("div",{className:"mb-3 flex items-baseline justify-between gap-4",children:[e.jsx("h3",{className:"text-xs font-medium uppercase tracking-wide text-oai-gray-500 dark:text-oai-gray-400",children:t}),s?e.jsx("span",{className:"text-xs text-oai-gray-400",children:s}):null]})}function C({value:t,label:s}){const a=Number(t);if(!Number.isFinite(a))return null;const i=Math.sign(a)!==-1,r=i?W:te;return e.jsxs("span",{className:`inline-flex items-center gap-1 text-xs font-medium tabular-nums ${i?"text-emerald-600 dark:text-emerald-400":"text-rose-600 dark:text-rose-400"}`,title:s,children:[e.jsx(r,{className:"size-3","aria-hidden":"true"}),i?"+":"",a.toFixed(1),"%"]})}function j({label:t,value:s,title:a,delta:i,deltaLabel:r}){return e.jsxs("div",{className:"min-w-0",children:[e.jsx("div",{className:"truncate text-xs font-medium text-oai-gray-500 dark:text-oai-gray-400",children:t}),e.jsxs("div",{className:"mt-1 flex min-w-0 items-baseline gap-2",children:[e.jsx("span",{className:"truncate text-xl font-semibold leading-none tracking-tight text-oai-black tabular-nums dark:text-white",title:a,children:s}),e.jsx(C,{value:i,label:r})]})]})}function I({fillWidth:t,share:s,color:a="var(--oai-blue)",ariaLabel:i,dataAttrs:r,children:o}){return e.jsxs("div",{...r,className:"group relative grid min-h-11 grid-cols-[minmax(0,1fr)_auto] items-center gap-3 overflow-hidden px-2.5 transition-colors hover:bg-oai-gray-50 dark:hover:bg-oai-gray-900/60",children:[e.jsx("div",{className:"pointer-events-none absolute inset-y-0 left-0 opacity-[0.15] transition-opacity group-hover:opacity-[0.22] dark:opacity-[0.24] dark:group-hover:opacity-[0.32]",style:{width:`${t}%`,backgroundColor:a},role:"progressbar","aria-label":i,"aria-valuemin":"0","aria-valuemax":"100","aria-valuenow":Number(s)||0}),o]})}function A({rank:t,provider:s,name:a,fillWidth:i,share:r,tokens:o,tokensTitle:l,dataAttrs:c}){return e.jsxs(I,{fillWidth:i,share:r,color:ie(s),ariaLabel:`${a} ${u(r)}`,dataAttrs:c,children:[e.jsxs("div",{className:"relative flex min-w-0 items-center gap-2.5",children:[e.jsx("span",{className:`w-5 shrink-0 text-xs tabular-nums ${t<=3?"font-semibold text-oai-gray-700 dark:text-oai-gray-200":"text-oai-gray-400"}`,children:t}),e.jsx("span",{className:"grid size-6 shrink-0 place-items-center text-oai-gray-700 dark:text-oai-gray-200",children:e.jsx(F,{provider:s,size:15})}),e.jsx("span",{className:"truncate text-xs font-medium text-oai-gray-700 dark:text-oai-gray-200",title:a,children:a})]}),e.jsxs("div",{className:"relative min-w-[4.5rem] text-right",children:[e.jsx("div",{className:"text-xs font-semibold text-oai-black tabular-nums dark:text-white",title:l,children:o}),e.jsx("div",{className:"text-xs text-oai-gray-500 tabular-nums dark:text-oai-gray-400",children:u(r)})]})]})}function le({rows:t,formatTokensTooltip:s}){return t.length?e.jsxs("div",{className:"mt-7",children:[e.jsx(b,{children:n("leaderboard.community.modal.token_mix")}),e.jsx("div",{className:"flex h-1.5 overflow-hidden bg-oai-gray-100 dark:bg-oai-gray-800",children:t.map(a=>e.jsx("div",{style:{width:`${Math.max(Number(a.share)||0,0)}%`,backgroundColor:_[a.key]||"var(--community-muted)"},title:`${n(`leaderboard.community.modal.token_mix.${a.key}`)} · ${u(a.share)}`},a.key))}),e.jsx("div",{className:"mt-3 flex flex-wrap gap-x-5 gap-y-1.5",children:t.map(a=>e.jsxs("span",{className:"inline-flex items-center gap-1.5 text-xs text-oai-gray-500 dark:text-oai-gray-400",title:s(a.tokens),children:[e.jsx("span",{className:"size-2",style:{backgroundColor:_[a.key]||"var(--community-muted)"}}),n(`leaderboard.community.modal.token_mix.${a.key}`),e.jsx("span",{className:"tabular-nums text-oai-gray-700 dark:text-oai-gray-200",children:u(a.share)})]},a.key))})]}):null}function f({label:t,value:s,title:a,delta:i,deltaLabel:r,className:o=""}){return e.jsxs("div",{className:`min-w-0 ${o}`,children:[e.jsx("div",{className:"truncate text-xs text-oai-gray-500 dark:text-oai-gray-400",children:t}),e.jsxs("div",{className:"mt-1 flex min-w-0 items-baseline gap-2",children:[e.jsx("span",{className:"truncate text-base font-semibold leading-none tracking-tight tabular-nums text-oai-black dark:text-white",title:a,children:s}),e.jsx(C,{value:i,label:r})]})]})}function de({trendRows:t,activeDevelopers30d:s,developerGrowthPct:a,formatTokens:i,formatTokensTooltip:r}){if(!t.length)return null;const o=t.reduce((m,h)=>m+h.value,0),l=t.reduce((m,h)=>m.value<h.value?h:m,t[0]),c=o/t.length;return e.jsxs("div",{className:"mt-5 grid grid-cols-3 divide-x divide-oai-gray-100 border-y border-oai-gray-100 py-3.5 dark:divide-oai-gray-800/80 dark:border-oai-gray-800/80",children:[e.jsx(f,{className:"pr-4",label:n("leaderboard.community.modal.daily_average"),value:i(c),title:r(c)}),e.jsx(f,{className:"px-4",label:`${n("leaderboard.community.modal.peak_day")} · ${l.day}`,value:i(l.value),title:r(l.value)}),e.jsx(f,{className:"pl-4",label:n("leaderboard.community.modal.active_30d"),value:p(s),title:Number(s).toLocaleString(),delta:a,deltaLabel:n("leaderboard.community.modal.vs_previous_week")})]})}function me({trendRows:t,mix:s,activeDevelopers30d:a,developerGrowthPct:i,formatTokens:r,formatTokensTooltip:o}){return!t.length&&!s.length?e.jsx(k,{}):e.jsxs("div",{children:[e.jsx(b,{detail:n("leaderboard.community.modal.utc_note"),children:n("leaderboard.community.modal.community_activity")}),e.jsx(G,{embedded:!0,rows:t,from:t[0]?.day,to:t.at(-1)?.day,chartHeightClass:"h-44"}),e.jsx(de,{trendRows:t,activeDevelopers30d:a,developerGrowthPct:i,formatTokens:r,formatTokensTooltip:o}),e.jsx(le,{rows:s,formatTokensTooltip:o})]})}function ce({rows:t,maxShare:s,formatTokens:a,formatTokensTooltip:i}){return t.length?e.jsx("div",{className:"space-y-0.5",children:t.map((r,o)=>e.jsx(A,{rank:o+1,dataAttrs:{"data-provider-rank":o+1,"data-provider-name":r.name},provider:String(r.name).toUpperCase(),name:r.name,fillWidth:Math.max((Number(r.share)||0)/s*100,2),share:r.share,tokens:a(r.tokens),tokensTitle:i(r.tokens)},r.name))}):e.jsx(k,{})}function xe({rows:t,maxShare:s,formatTokens:a,formatTokensTooltip:i}){return t.length?e.jsx("div",{className:"space-y-0.5",children:t.map((r,o)=>{const l=Number(r.share)||0;return e.jsx(A,{rank:o+1,dataAttrs:{"data-model-rank":o+1,"data-model-name":r.name},provider:oe(r.name),name:r.name,fillWidth:Math.max(l/s*100,2),share:l,tokens:a(r.tokens),tokensTitle:i(r.tokens)},r.name)})}):e.jsx(k,{})}function ue({name:t}){const s=String(t||"").toLowerCase();return s==="darwin"?e.jsx(K,{className:"size-3.5"}):s==="win32"?e.jsx(U,{className:"size-3.5"}):e.jsx(V,{className:"size-4","aria-hidden":"true"})}const he=.175,ye=.3;function ge({bands:t,formatTokensTooltip:s}){const a=t.reduce((r,o)=>Math.max(r,Number(o.developer_share)||0),0)||1,i=r=>`${n(`leaderboard.community.modal.band.${r.key}`)} · ${n("leaderboard.community.modal.developer_count",{count:p(r.developers)})} (${s(r.tokens)})`;return e.jsxs("div",{children:[e.jsx("div",{className:"flex gap-2 border-b border-oai-gray-200 dark:border-oai-gray-800",children:t.map((r,o)=>{const l=Number(r.developer_share)||0,c=Math.max(l/a*80,2);return e.jsxs("div",{className:"relative h-32 min-w-0 flex-1",title:i(r),children:[e.jsx("div",{role:"progressbar","aria-label":n("leaderboard.community.modal.developer_share_title",{share:u(l)}),"aria-valuemin":"0","aria-valuemax":"100","aria-valuenow":l,className:"absolute inset-x-0 bottom-0",style:{height:`${c}%`,backgroundColor:"var(--oai-blue)",opacity:ye+o*he}}),e.jsx("div",{className:"absolute inset-x-0 text-center text-xs font-medium tabular-nums text-oai-gray-700 dark:text-oai-gray-200",style:{bottom:`calc(${c}% + 4px)`},children:u(l)})]},r.key)})}),e.jsx("div",{className:"mt-2 flex gap-2",children:t.map(r=>e.jsxs("div",{className:"min-w-0 flex-1 text-center",title:i(r),children:[e.jsx("div",{className:"truncate text-xs font-medium text-oai-gray-700 dark:text-oai-gray-200",children:n(`leaderboard.community.modal.band.${r.key}`)}),e.jsx("div",{className:"truncate text-xs tabular-nums text-oai-gray-500 dark:text-oai-gray-400",children:p(r.developers)})]},r.key))})]})}function pe({bands:t,platforms:s,formatTokensTooltip:a}){return!t.length&&!s.length?e.jsx(k,{}):e.jsxs("div",{className:"space-y-8",children:[t.length?e.jsxs("div",{children:[e.jsx(b,{children:n("leaderboard.community.modal.usage_distribution")}),e.jsx(ge,{bands:t,formatTokensTooltip:a})]}):null,s.length?e.jsxs("div",{children:[e.jsx(b,{children:n("leaderboard.community.modal.platforms")}),e.jsx("div",{className:"space-y-0.5",children:s.map(i=>e.jsxs(I,{fillWidth:Math.max(Number(i.share)||0,1),share:i.share,ariaLabel:`${n(`leaderboard.community.modal.platform.${i.name}`)} ${u(i.share)}`,children:[e.jsxs("div",{className:"relative flex min-w-0 items-center gap-2.5",children:[e.jsx("span",{className:"grid size-6 shrink-0 place-items-center text-oai-gray-700 dark:text-oai-gray-200",children:e.jsx(ue,{name:i.name})}),e.jsx("span",{className:"truncate text-xs font-medium text-oai-gray-700 dark:text-oai-gray-200",children:n(`leaderboard.community.modal.platform.${i.name}`)})]}),e.jsxs("div",{className:"relative min-w-[4.5rem] text-right",children:[e.jsx("div",{className:"text-xs font-semibold text-oai-black tabular-nums dark:text-white",children:u(i.share)}),e.jsx("div",{className:"text-xs text-oai-gray-500 tabular-nums dark:text-oai-gray-400",title:Number(i.machines||0).toLocaleString(),children:n("leaderboard.community.modal.machine_count",{count:p(i.machines)})})]})]},i.name))})]}):null]})}function ve({isOpen:t,onClose:s,communityStats:a}){const{formatTokens:i,formatTokensTooltip:r}=B(),[o,l]=D.useState("overview"),c=a?.status==="ready",m=D.useMemo(()=>{if(!c)return null;const d=(Array.isArray(a.providers)?a.providers:[]).slice(0,O),x=(Array.isArray(a.topModels)?a.topModels:[]).slice(0,O),y=v=>v.reduce((E,$)=>Math.max(E,Number($.share)||0),0)||1;return{providers:d,models:x,providersMaxShare:y(d),modelsMaxShare:y(x),trendRows:(Array.isArray(a.dailyGrowth)?a.dailyGrowth:[]).map(v=>({day:ne(v.day),value:Number(v.tokens)||0})),mix:Array.isArray(a.tokenMix)?a.tokenMix:[],bands:Array.isArray(a.userDistribution)?a.userDistribution:[],platforms:Array.isArray(a.platforms)?a.platforms:[]}},[c,a]);if(!m)return null;const h=Number(a.tokenFloor)||0,N=Number(a.activeDevelopersTotal)||Number(a.totalEntries)||0,w=Number(a.tokens30d)||0,T=d=>{if(d.key!=="ArrowRight"&&d.key!=="ArrowLeft")return;d.preventDefault();const x=d.key==="ArrowRight"?1:-1,y=g[(g.indexOf(o)+x+g.length)%g.length];l(y),d.currentTarget.querySelector(`[data-tab-id="${y}"]`)?.focus()};return e.jsx(X,{open:t,onOpenChange:d=>!d&&s(),children:e.jsxs(Y,{children:[e.jsx(Z,{className:"fixed inset-0 z-[100] bg-black/50 backdrop-blur-[3px] transition-opacity duration-200 ease-out data-[ending-style]:opacity-0 data-[starting-style]:opacity-0"}),e.jsx(H,{className:"fixed inset-0 z-[101] flex items-center justify-center p-2 sm:p-5",children:e.jsxs(q,{className:"relative flex h-[min(42rem,92vh)] w-full max-w-xl flex-col overflow-hidden rounded-2xl bg-white shadow-2xl ring-1 ring-black/10 transition-[opacity,transform] duration-[220ms] ease-[cubic-bezier(0.16,1,0.3,1)] data-[ending-style]:translate-y-3 data-[ending-style]:scale-[0.98] data-[ending-style]:opacity-0 data-[starting-style]:translate-y-3 data-[starting-style]:scale-[0.98] data-[starting-style]:opacity-0 dark:bg-oai-gray-950 dark:ring-white/10",children:[e.jsxs("header",{"data-testid":"community-metrics-header",className:"shrink-0 px-5 pt-5 sm:px-6",children:[e.jsxs("div",{className:"flex items-start justify-between gap-4",children:[e.jsxs("div",{children:[e.jsx(J,{className:"text-lg font-semibold tracking-[-0.02em] text-oai-black dark:text-white",children:n("leaderboard.community.modal.title")}),e.jsx(Q,{className:"sr-only",children:n("leaderboard.community.modal.description")})]}),e.jsx(ee,{className:"-mr-1 -mt-1 grid size-8 place-items-center rounded-full text-oai-gray-400 transition-colors hover:bg-black/5 hover:text-oai-black dark:hover:bg-white/10 dark:hover:text-white","aria-label":n("shared.dialog.close"),children:e.jsx(z,{className:"size-4"})})]}),e.jsxs("div",{className:"mt-4 grid grid-cols-3 gap-x-5",children:[e.jsx(j,{label:n("leaderboard.community.modal.total_tokens"),value:i(h),title:r(h)}),e.jsx(j,{label:n("leaderboard.community.modal.tokens_30d"),value:i(w),title:r(w),delta:a.tokenGrowthPct,deltaLabel:n("leaderboard.community.modal.vs_previous_week")}),e.jsx(j,{label:n("leaderboard.community.modal.contributors"),value:p(N),title:N.toLocaleString()})]}),e.jsx("div",{className:"mt-4 flex items-end overflow-x-auto border-b border-oai-gray-100 dark:border-oai-gray-900",role:"tablist","aria-label":n("leaderboard.community.modal.views"),onKeyDown:T,children:g.map(d=>{const x=o===d;return e.jsxs("button",{type:"button",role:"tab","data-tab-id":d,"aria-selected":x,tabIndex:x?0:-1,onClick:()=>l(d),className:`relative mr-5 h-10 shrink-0 text-sm font-medium transition-colors last:mr-0 ${x?"text-oai-black dark:text-white":"text-oai-gray-500 hover:text-oai-gray-700 dark:text-oai-gray-400 dark:hover:text-oai-gray-200"}`,children:[n(`leaderboard.community.modal.tab.${d}`),x?e.jsx(M.span,{layoutId:"community-metrics-tab-underline",className:"absolute inset-x-0 -bottom-px h-0.5 rounded-full bg-oai-black dark:bg-white",transition:{type:"spring",stiffness:420,damping:34}}):null]},d)})})]}),e.jsx("div",{"data-testid":"community-metrics-content",className:"min-h-0 flex-1 overflow-y-auto px-5 py-5 sm:px-6",children:e.jsxs(M.div,{initial:{opacity:0,y:4},animate:{opacity:1,y:0},transition:{duration:.18,ease:[.16,1,.3,1]},className:"h-full",children:[o==="overview"?e.jsx(me,{trendRows:m.trendRows,mix:m.mix,activeDevelopers30d:Number(a.activeDevelopers30d)||0,developerGrowthPct:a.developerGrowthPct,formatTokens:i,formatTokensTooltip:r}):null,o==="providers"?e.jsx(ce,{rows:m.providers,maxShare:m.providersMaxShare,formatTokens:i,formatTokensTooltip:r}):null,o==="community"?e.jsx(pe,{bands:m.bands,platforms:m.platforms,formatTokensTooltip:r}):null,o==="models"?e.jsx(xe,{rows:m.models,maxShare:m.modelsMaxShare,formatTokens:i,formatTokensTooltip:r}):null]},o)})]})})]})})}function Pe(t){return e.jsx(R,{mode:P.COMPACT,children:e.jsx(ve,{...t})})}export{Pe as CommunityStatsModal};
|