@yishiguji/tokenarena 0.12.1 → 0.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -226,6 +226,19 @@ function findJsonlFiles(dir) {
226
226
  }
227
227
  return results;
228
228
  }
229
+ function findJsonFiles(dir, pattern) {
230
+ const results = [];
231
+ if (!existsSync(dir)) return results;
232
+ try {
233
+ for (const entry of readdirSync(dir, { withFileTypes: true })) {
234
+ if (entry.isFile() && pattern.test(entry.name)) {
235
+ results.push(join(dir, entry.name));
236
+ }
237
+ }
238
+ } catch {
239
+ }
240
+ return results;
241
+ }
229
242
  function readFileSafe(filePath) {
230
243
  try {
231
244
  return readFileSync(filePath, "utf-8");
@@ -1318,24 +1331,263 @@ var MimocodeParser = class {
1318
1331
  };
1319
1332
  registerParser(new MimocodeParser());
1320
1333
 
1334
+ // src/parsers/mirasim.ts
1335
+ import { createHash as createHash2 } from "crypto";
1336
+ import { existsSync as existsSync8 } from "fs";
1337
+ import { homedir as homedir7, hostname as hostname3 } from "os";
1338
+ import { join as join8 } from "path";
1339
+ var TOOL_ID5 = "mirasim";
1340
+ var TOOL_NAME5 = "Mirasim";
1341
+ var DEFAULT_INSIGHTS_DIR = join8(homedir7(), ".mirasim", "insights");
1342
+ var USAGE_FILE_PATTERN = /^usage-\d{4}-\d{2}\.ndjson$/;
1343
+ var MIRASIM_OWN_AGENTS = ["gui", "pi-gui"];
1344
+ function getInsightsDirs(env = process.env) {
1345
+ const dirs = [
1346
+ env.TOKEN_ARENA_MIRASIM_DIR,
1347
+ env.MIRASIM_HOME ? join8(env.MIRASIM_HOME, "insights") : void 0,
1348
+ DEFAULT_INSIGHTS_DIR
1349
+ ].filter((value) => Boolean(value));
1350
+ return Array.from(new Set(dirs));
1351
+ }
1352
+ function toNonNegativeInteger(value) {
1353
+ const numberValue = Number(value);
1354
+ if (!Number.isFinite(numberValue) || numberValue <= 0) {
1355
+ return 0;
1356
+ }
1357
+ const rounded = Math.round(numberValue);
1358
+ return Number.isSafeInteger(rounded) ? rounded : 0;
1359
+ }
1360
+ function getString(value) {
1361
+ return typeof value === "string" && value.length > 0 ? value : null;
1362
+ }
1363
+ function normalizeAgent(value) {
1364
+ if (typeof value !== "string") {
1365
+ return null;
1366
+ }
1367
+ return value.trim().toLowerCase() || null;
1368
+ }
1369
+ function parseIsoDate(value) {
1370
+ const raw = getString(value);
1371
+ if (!raw) {
1372
+ return null;
1373
+ }
1374
+ const timestamp = new Date(raw);
1375
+ return Number.isNaN(timestamp.getTime()) ? null : timestamp;
1376
+ }
1377
+ function getPathLeaf3(value) {
1378
+ if (!value) {
1379
+ return "unknown";
1380
+ }
1381
+ const normalized = value.replace(/\\/g, "/").replace(/\/+$/, "");
1382
+ const leaf = normalized.split("/").filter(Boolean).pop();
1383
+ return leaf || "unknown";
1384
+ }
1385
+ function buildSessionUsage2(entries) {
1386
+ const usageBySession = /* @__PURE__ */ new Map();
1387
+ for (const entry of entries) {
1388
+ if (!entry.sessionId || hasInvalidTokenCounts(entry)) {
1389
+ continue;
1390
+ }
1391
+ let byModel = usageBySession.get(entry.sessionId);
1392
+ if (!byModel) {
1393
+ byModel = /* @__PURE__ */ new Map();
1394
+ usageBySession.set(entry.sessionId, byModel);
1395
+ }
1396
+ const totalTokens = entry.inputTokens + entry.outputTokens + entry.reasoningTokens + entry.cachedTokens;
1397
+ const existing = byModel.get(entry.model);
1398
+ if (existing) {
1399
+ existing.inputTokens += entry.inputTokens;
1400
+ existing.outputTokens += entry.outputTokens;
1401
+ existing.reasoningTokens += entry.reasoningTokens;
1402
+ existing.cachedTokens += entry.cachedTokens;
1403
+ existing.totalTokens += totalTokens;
1404
+ continue;
1405
+ }
1406
+ byModel.set(entry.model, {
1407
+ model: entry.model,
1408
+ inputTokens: entry.inputTokens,
1409
+ outputTokens: entry.outputTokens,
1410
+ reasoningTokens: entry.reasoningTokens,
1411
+ cachedTokens: entry.cachedTokens,
1412
+ totalTokens
1413
+ });
1414
+ }
1415
+ return usageBySession;
1416
+ }
1417
+ function buildSessions(drafts, entries) {
1418
+ const usageBySession = buildSessionUsage2(entries);
1419
+ const host = hostname3().replace(/\.local$/, "");
1420
+ return Array.from(drafts.values()).map((draft) => {
1421
+ const modelUsages = Array.from(
1422
+ usageBySession.get(draft.sessionId)?.values() ?? []
1423
+ ).sort((left, right) => {
1424
+ if (right.totalTokens !== left.totalTokens) {
1425
+ return right.totalTokens - left.totalTokens;
1426
+ }
1427
+ return left.model.localeCompare(right.model);
1428
+ });
1429
+ const inputTokens = modelUsages.reduce(
1430
+ (sum, usage) => sum + usage.inputTokens,
1431
+ 0
1432
+ );
1433
+ const outputTokens = modelUsages.reduce(
1434
+ (sum, usage) => sum + usage.outputTokens,
1435
+ 0
1436
+ );
1437
+ const reasoningTokens = modelUsages.reduce(
1438
+ (sum, usage) => sum + usage.reasoningTokens,
1439
+ 0
1440
+ );
1441
+ const cachedTokens = modelUsages.reduce(
1442
+ (sum, usage) => sum + usage.cachedTokens,
1443
+ 0
1444
+ );
1445
+ const totalTokens = modelUsages.reduce(
1446
+ (sum, usage) => sum + usage.totalTokens,
1447
+ 0
1448
+ );
1449
+ const durationSeconds = Math.max(
1450
+ 0,
1451
+ Math.round(
1452
+ (draft.lastCallEndAt.getTime() - draft.firstCallAt.getTime()) / 1e3
1453
+ )
1454
+ );
1455
+ return {
1456
+ source: TOOL_ID5,
1457
+ project: draft.project,
1458
+ sessionHash: createHash2("sha256").update(draft.sessionId).digest("hex").slice(0, 16),
1459
+ hostname: host,
1460
+ firstMessageAt: draft.firstCallAt.toISOString(),
1461
+ lastMessageAt: draft.lastCallEndAt.toISOString(),
1462
+ durationSeconds,
1463
+ // Relay calls can overlap (parallel sub-agent work), so the sum of call
1464
+ // durations may exceed the session's wall-clock span.
1465
+ activeSeconds: Math.min(
1466
+ Math.round(draft.activeMs / 1e3),
1467
+ durationSeconds
1468
+ ),
1469
+ messageCount: draft.callCount,
1470
+ // Mirasim's own sub-agents are driven by the orchestrator, not by a
1471
+ // human at a prompt, so there are no user messages to attribute.
1472
+ userMessageCount: 0,
1473
+ userPromptHours: new Array(24).fill(0),
1474
+ inputTokens,
1475
+ outputTokens,
1476
+ reasoningTokens,
1477
+ cachedTokens,
1478
+ totalTokens,
1479
+ primaryModel: modelUsages[0]?.model ?? "",
1480
+ modelUsages
1481
+ };
1482
+ });
1483
+ }
1484
+ var MirasimParser = class {
1485
+ tool;
1486
+ insightsDirs;
1487
+ ownAgents;
1488
+ constructor(options = {}) {
1489
+ this.insightsDirs = options.insightsDir ? [options.insightsDir] : getInsightsDirs();
1490
+ this.ownAgents = new Set(options.ownAgents ?? MIRASIM_OWN_AGENTS);
1491
+ this.tool = {
1492
+ id: TOOL_ID5,
1493
+ name: TOOL_NAME5,
1494
+ dataDir: this.insightsDirs[0] ?? DEFAULT_INSIGHTS_DIR
1495
+ };
1496
+ }
1497
+ async parse() {
1498
+ const entries = [];
1499
+ const drafts = /* @__PURE__ */ new Map();
1500
+ const seenCallIds = /* @__PURE__ */ new Set();
1501
+ for (const insightsDir of this.insightsDirs) {
1502
+ for (const filePath of findJsonFiles(insightsDir, USAGE_FILE_PATTERN)) {
1503
+ const content = readFileSafe(filePath);
1504
+ if (!content) continue;
1505
+ for (const row of parseJsonl(content)) {
1506
+ const agent = normalizeAgent(row.agent);
1507
+ if (!agent || !this.ownAgents.has(agent)) continue;
1508
+ const timestamp = parseIsoDate(row.ts);
1509
+ if (!timestamp) continue;
1510
+ const model = getString(row.model) ?? "unknown";
1511
+ const inputTokens = toNonNegativeInteger(row.input);
1512
+ const reasoningTokens = toNonNegativeInteger(row.reasoning);
1513
+ const outputTokens = Math.max(
1514
+ 0,
1515
+ toNonNegativeInteger(row.output) - reasoningTokens
1516
+ );
1517
+ const cachedTokens = toNonNegativeInteger(row.cacheRead) + toNonNegativeInteger(row.cacheWrite);
1518
+ if (inputTokens + outputTokens + reasoningTokens + cachedTokens === 0) {
1519
+ continue;
1520
+ }
1521
+ const sessionId = getString(row.sessionId);
1522
+ const project = getPathLeaf3(getString(row.workspace));
1523
+ const callId = getString(row.id) ?? [sessionId ?? "", timestamp.toISOString(), agent, model].join("|");
1524
+ if (seenCallIds.has(callId)) continue;
1525
+ seenCallIds.add(callId);
1526
+ entries.push({
1527
+ sessionId: sessionId ?? void 0,
1528
+ source: TOOL_ID5,
1529
+ model,
1530
+ project,
1531
+ timestamp,
1532
+ inputTokens,
1533
+ outputTokens,
1534
+ reasoningTokens,
1535
+ cachedTokens
1536
+ });
1537
+ if (!sessionId) continue;
1538
+ const durationMs = toNonNegativeInteger(row.durationMs);
1539
+ const callEndAt = new Date(timestamp.getTime() + durationMs);
1540
+ const draft = drafts.get(sessionId);
1541
+ if (!draft) {
1542
+ drafts.set(sessionId, {
1543
+ sessionId,
1544
+ project,
1545
+ firstCallAt: timestamp,
1546
+ lastCallEndAt: callEndAt,
1547
+ activeMs: durationMs,
1548
+ callCount: 1
1549
+ });
1550
+ continue;
1551
+ }
1552
+ if (draft.project === "unknown" && project !== "unknown") {
1553
+ draft.project = project;
1554
+ }
1555
+ if (timestamp < draft.firstCallAt) draft.firstCallAt = timestamp;
1556
+ if (callEndAt > draft.lastCallEndAt) draft.lastCallEndAt = callEndAt;
1557
+ draft.activeMs += durationMs;
1558
+ draft.callCount += 1;
1559
+ }
1560
+ }
1561
+ }
1562
+ return {
1563
+ buckets: aggregateToBuckets(entries),
1564
+ sessions: buildSessions(drafts, entries)
1565
+ };
1566
+ }
1567
+ isInstalled() {
1568
+ return this.insightsDirs.some((dir) => existsSync8(dir));
1569
+ }
1570
+ };
1571
+ registerParser(new MirasimParser());
1572
+
1321
1573
  // src/parsers/copilot-cli.ts
1322
- import { existsSync as existsSync8, readdirSync as readdirSync3, readFileSync as readFileSync3 } from "fs";
1323
- import { homedir as homedir7 } from "os";
1324
- import { basename as basename3, dirname as dirname2, join as join8 } from "path";
1325
- var ROOT_DIR = join8(homedir7(), ".copilot");
1574
+ import { existsSync as existsSync9, readdirSync as readdirSync3, readFileSync as readFileSync3 } from "fs";
1575
+ import { homedir as homedir8 } from "os";
1576
+ import { basename as basename3, dirname as dirname2, join as join9 } from "path";
1577
+ var ROOT_DIR = join9(homedir8(), ".copilot");
1326
1578
  var TOOL3 = {
1327
1579
  id: "copilot-cli",
1328
1580
  name: "GitHub Copilot CLI",
1329
1581
  dataDir: ROOT_DIR
1330
1582
  };
1331
1583
  function collectEventFiles(dir, results, visited) {
1332
- if (!existsSync8(dir) || visited.has(dir)) {
1584
+ if (!existsSync9(dir) || visited.has(dir)) {
1333
1585
  return;
1334
1586
  }
1335
1587
  visited.add(dir);
1336
1588
  try {
1337
1589
  for (const entry of readdirSync3(dir, { withFileTypes: true })) {
1338
- const fullPath = join8(dir, entry.name);
1590
+ const fullPath = join9(dir, entry.name);
1339
1591
  if (entry.isDirectory()) {
1340
1592
  collectEventFiles(fullPath, results, visited);
1341
1593
  continue;
@@ -1439,22 +1691,22 @@ var CopilotCliParser = class {
1439
1691
  };
1440
1692
  }
1441
1693
  isInstalled() {
1442
- return existsSync8(ROOT_DIR);
1694
+ return existsSync9(ROOT_DIR);
1443
1695
  }
1444
1696
  };
1445
1697
  registerParser(new CopilotCliParser());
1446
1698
 
1447
1699
  // src/parsers/oh-my-pi.ts
1448
- import { existsSync as existsSync9 } from "fs";
1449
- import { homedir as homedir8 } from "os";
1450
- import { join as join9 } from "path";
1451
- var TOOL_ID5 = "oh-my-pi";
1452
- var TOOL_NAME5 = "omp";
1453
- var DEFAULT_SESSIONS_DIR2 = join9(homedir8(), ".omp", "agent", "sessions");
1700
+ import { existsSync as existsSync10 } from "fs";
1701
+ import { homedir as homedir9 } from "os";
1702
+ import { join as join10 } from "path";
1703
+ var TOOL_ID6 = "oh-my-pi";
1704
+ var TOOL_NAME6 = "omp";
1705
+ var DEFAULT_SESSIONS_DIR2 = join10(homedir9(), ".omp", "agent", "sessions");
1454
1706
  function createToolDefinition4(dataDir) {
1455
1707
  return {
1456
- id: TOOL_ID5,
1457
- name: TOOL_NAME5,
1708
+ id: TOOL_ID6,
1709
+ name: TOOL_NAME6,
1458
1710
  dataDir
1459
1711
  };
1460
1712
  }
@@ -1462,7 +1714,7 @@ function toSafeNumber5(value) {
1462
1714
  const numberValue = Number(value);
1463
1715
  return Number.isFinite(numberValue) ? numberValue : 0;
1464
1716
  }
1465
- function getPathLeaf3(value) {
1717
+ function getPathLeaf4(value) {
1466
1718
  const normalized = value.replace(/\\/g, "/").replace(/\/+$/, "");
1467
1719
  const leaf = normalized.split("/").filter(Boolean).pop();
1468
1720
  return leaf || "unknown";
@@ -1481,7 +1733,7 @@ function getUsageNumber2(usage, ...keys) {
1481
1733
  return 0;
1482
1734
  }
1483
1735
  function extractOhMyPiProjectFromCwd(cwd) {
1484
- return getPathLeaf3(cwd);
1736
+ return getPathLeaf4(cwd);
1485
1737
  }
1486
1738
  function extractOhMyPiProjectFromDir(filePath, sessionsDir = DEFAULT_SESSIONS_DIR2) {
1487
1739
  const normalizedFilePath = normalizeForPrefix2(filePath);
@@ -1498,7 +1750,7 @@ function extractOhMyPiProjectFromDir(filePath, sessionsDir = DEFAULT_SESSIONS_DI
1498
1750
  try {
1499
1751
  const decoded = decodeURIComponent(firstSegment);
1500
1752
  if (decoded.includes("/") || decoded.includes("\\")) {
1501
- return getPathLeaf3(decoded);
1753
+ return getPathLeaf4(decoded);
1502
1754
  }
1503
1755
  } catch {
1504
1756
  }
@@ -1548,7 +1800,7 @@ var OhMyPiParser = class {
1548
1800
  if (message.role === "user" || message.role === "assistant") {
1549
1801
  sessionEvents.push({
1550
1802
  sessionId,
1551
- source: TOOL_ID5,
1803
+ source: TOOL_ID6,
1552
1804
  project,
1553
1805
  timestamp,
1554
1806
  role: message.role
@@ -1580,7 +1832,7 @@ var OhMyPiParser = class {
1580
1832
  }
1581
1833
  entries.push({
1582
1834
  sessionId,
1583
- source: TOOL_ID5,
1835
+ source: TOOL_ID6,
1584
1836
  model: message.model || "unknown",
1585
1837
  project,
1586
1838
  timestamp,
@@ -1597,17 +1849,17 @@ var OhMyPiParser = class {
1597
1849
  };
1598
1850
  }
1599
1851
  isInstalled() {
1600
- return existsSync9(this.sessionsDir);
1852
+ return existsSync10(this.sessionsDir);
1601
1853
  }
1602
1854
  };
1603
1855
  registerParser(new OhMyPiParser());
1604
1856
 
1605
1857
  // src/parsers/opencode.ts
1606
1858
  import { execFileSync as execFileSync2 } from "child_process";
1607
- import { existsSync as existsSync10, readdirSync as readdirSync4, readFileSync as readFileSync4 } from "fs";
1608
- import { homedir as homedir9 } from "os";
1609
- import { basename as basename4, join as join10 } from "path";
1610
- var DEFAULT_DATA_DIR2 = join10(homedir9(), ".local", "share", "opencode");
1859
+ import { existsSync as existsSync11, readdirSync as readdirSync4, readFileSync as readFileSync4 } from "fs";
1860
+ import { homedir as homedir10 } from "os";
1861
+ import { basename as basename4, join as join11 } from "path";
1862
+ var DEFAULT_DATA_DIR2 = join11(homedir10(), ".local", "share", "opencode");
1611
1863
  var TOOL4 = {
1612
1864
  id: "opencode",
1613
1865
  name: "OpenCode",
@@ -1616,10 +1868,10 @@ var TOOL4 = {
1616
1868
  function getOpenCodeDataDirs(env = process.env) {
1617
1869
  const dirs = [
1618
1870
  env.TOKEN_ARENA_OPENCODE_DIR,
1619
- env.XDG_DATA_HOME ? join10(env.XDG_DATA_HOME, "opencode") : void 0,
1871
+ env.XDG_DATA_HOME ? join11(env.XDG_DATA_HOME, "opencode") : void 0,
1620
1872
  DEFAULT_DATA_DIR2,
1621
- env.LOCALAPPDATA ? join10(env.LOCALAPPDATA, "opencode") : void 0,
1622
- env.APPDATA ? join10(env.APPDATA, "opencode") : void 0
1873
+ env.LOCALAPPDATA ? join11(env.LOCALAPPDATA, "opencode") : void 0,
1874
+ env.APPDATA ? join11(env.APPDATA, "opencode") : void 0
1623
1875
  ].filter((value) => Boolean(value));
1624
1876
  return Array.from(new Set(dirs));
1625
1877
  }
@@ -1713,12 +1965,12 @@ var OpenCodeParser = class {
1713
1965
  return { buckets, sessions };
1714
1966
  }
1715
1967
  isInstalled() {
1716
- return this.resolveRoots().some((dir) => existsSync10(dir));
1968
+ return this.resolveRoots().some((dir) => existsSync11(dir));
1717
1969
  }
1718
1970
  async parseRoot(rootDir) {
1719
- const dbPath = join10(rootDir, "opencode.db");
1720
- const messagesDir = join10(rootDir, "storage", "message");
1721
- if (existsSync10(dbPath)) {
1971
+ const dbPath = join11(rootDir, "opencode.db");
1972
+ const messagesDir = join11(rootDir, "storage", "message");
1973
+ if (existsSync11(dbPath)) {
1722
1974
  try {
1723
1975
  return await this.parseFromSqlite(dbPath);
1724
1976
  } catch (err) {
@@ -1785,7 +2037,7 @@ var OpenCodeParser = class {
1785
2037
  };
1786
2038
  }
1787
2039
  parseFromJson(messagesDir) {
1788
- if (!existsSync10(messagesDir)) return { buckets: [], sessions: [] };
2040
+ if (!existsSync11(messagesDir)) return { buckets: [], sessions: [] };
1789
2041
  const entries = [];
1790
2042
  const sessionEvents = [];
1791
2043
  let sessionDirs;
@@ -1797,7 +2049,7 @@ var OpenCodeParser = class {
1797
2049
  return { buckets: [], sessions: [] };
1798
2050
  }
1799
2051
  for (const sessionDir of sessionDirs) {
1800
- const sessionPath = join10(messagesDir, sessionDir.name);
2052
+ const sessionPath = join11(messagesDir, sessionDir.name);
1801
2053
  let messageFiles;
1802
2054
  try {
1803
2055
  messageFiles = readdirSync4(sessionPath).filter(
@@ -1807,7 +2059,7 @@ var OpenCodeParser = class {
1807
2059
  continue;
1808
2060
  }
1809
2061
  for (const file of messageFiles) {
1810
- const filePath = join10(sessionPath, file);
2062
+ const filePath = join11(sessionPath, file);
1811
2063
  let data;
1812
2064
  try {
1813
2065
  data = JSON.parse(readFileSync4(filePath, "utf-8"));
@@ -1853,16 +2105,16 @@ var OpenCodeParser = class {
1853
2105
  registerParser(new OpenCodeParser());
1854
2106
 
1855
2107
  // src/parsers/openclaw.ts
1856
- import { existsSync as existsSync11, readdirSync as readdirSync5, readFileSync as readFileSync5 } from "fs";
1857
- import { homedir as homedir10 } from "os";
1858
- import { join as join11 } from "path";
1859
- var TOOL_ID6 = "openclaw";
1860
- var TOOL_NAME6 = "OpenClaw";
1861
- var DEFAULT_DATA_DIR3 = join11(homedir10(), ".openclaw");
2108
+ import { existsSync as existsSync12, readdirSync as readdirSync5, readFileSync as readFileSync5 } from "fs";
2109
+ import { homedir as homedir11 } from "os";
2110
+ import { join as join12 } from "path";
2111
+ var TOOL_ID7 = "openclaw";
2112
+ var TOOL_NAME7 = "OpenClaw";
2113
+ var DEFAULT_DATA_DIR3 = join12(homedir11(), ".openclaw");
1862
2114
  var LEGACY_ROOT_NAMES = [".clawdbot", ".moltbot", ".moldbot"];
1863
2115
  var TOOL5 = {
1864
- id: TOOL_ID6,
1865
- name: TOOL_NAME6,
2116
+ id: TOOL_ID7,
2117
+ name: TOOL_NAME7,
1866
2118
  dataDir: DEFAULT_DATA_DIR3
1867
2119
  };
1868
2120
  function getTokens(usage, ...keys) {
@@ -1872,16 +2124,16 @@ function getTokens(usage, ...keys) {
1872
2124
  }
1873
2125
  return 0;
1874
2126
  }
1875
- function getOpenClawRoots(homeDir = homedir10()) {
1876
- const roots = [join11(homeDir, ".openclaw")];
2127
+ function getOpenClawRoots(homeDir = homedir11()) {
2128
+ const roots = [join12(homeDir, ".openclaw")];
1877
2129
  try {
1878
2130
  const profileRoots = readdirSync5(homeDir, { withFileTypes: true }).filter(
1879
2131
  (entry) => entry.isDirectory() && /^\.openclaw-.+/.test(entry.name)
1880
- ).map((entry) => join11(homeDir, entry.name)).sort((left, right) => left.localeCompare(right));
2132
+ ).map((entry) => join12(homeDir, entry.name)).sort((left, right) => left.localeCompare(right));
1881
2133
  roots.push(...profileRoots);
1882
2134
  } catch {
1883
2135
  }
1884
- roots.push(...LEGACY_ROOT_NAMES.map((name) => join11(homeDir, name)));
2136
+ roots.push(...LEGACY_ROOT_NAMES.map((name) => join12(homeDir, name)));
1885
2137
  return Array.from(new Set(roots));
1886
2138
  }
1887
2139
  var OpenClawParser = class {
@@ -1894,8 +2146,8 @@ var OpenClawParser = class {
1894
2146
  const entries = [];
1895
2147
  const sessionEvents = [];
1896
2148
  for (const root of this.resolveRoots()) {
1897
- const agentsDir = join11(root, "agents");
1898
- if (!existsSync11(agentsDir)) continue;
2149
+ const agentsDir = join12(root, "agents");
2150
+ if (!existsSync12(agentsDir)) continue;
1899
2151
  let agentDirs;
1900
2152
  try {
1901
2153
  agentDirs = readdirSync5(agentsDir, { withFileTypes: true }).filter(
@@ -1906,8 +2158,8 @@ var OpenClawParser = class {
1906
2158
  }
1907
2159
  for (const agentDir of agentDirs) {
1908
2160
  const project = agentDir.name;
1909
- const sessionsDir = join11(agentsDir, agentDir.name, "sessions");
1910
- if (!existsSync11(sessionsDir)) continue;
2161
+ const sessionsDir = join12(agentsDir, agentDir.name, "sessions");
2162
+ if (!existsSync12(sessionsDir)) continue;
1911
2163
  let files;
1912
2164
  try {
1913
2165
  files = readdirSync5(sessionsDir).filter((f) => f.endsWith(".jsonl"));
@@ -1915,7 +2167,7 @@ var OpenClawParser = class {
1915
2167
  continue;
1916
2168
  }
1917
2169
  for (const file of files) {
1918
- const filePath = join11(sessionsDir, file);
2170
+ const filePath = join12(sessionsDir, file);
1919
2171
  let content;
1920
2172
  try {
1921
2173
  content = readFileSync5(filePath, "utf-8");
@@ -1938,7 +2190,7 @@ var OpenClawParser = class {
1938
2190
  if (msg.role !== "user" && msg.role !== "assistant") continue;
1939
2191
  sessionEvents.push({
1940
2192
  sessionId: filePath,
1941
- source: TOOL_ID6,
2193
+ source: TOOL_ID7,
1942
2194
  project,
1943
2195
  timestamp: ts,
1944
2196
  role: msg.role === "user" ? "user" : "assistant"
@@ -1948,7 +2200,7 @@ var OpenClawParser = class {
1948
2200
  if (!usage) continue;
1949
2201
  entries.push({
1950
2202
  sessionId: filePath,
1951
- source: TOOL_ID6,
2203
+ source: TOOL_ID7,
1952
2204
  model: msg.model || obj.model || "unknown",
1953
2205
  project,
1954
2206
  timestamp: ts,
@@ -1988,22 +2240,22 @@ var OpenClawParser = class {
1988
2240
  };
1989
2241
  }
1990
2242
  isInstalled() {
1991
- return this.resolveRoots().some((root) => existsSync11(join11(root, "agents")));
2243
+ return this.resolveRoots().some((root) => existsSync12(join12(root, "agents")));
1992
2244
  }
1993
2245
  };
1994
2246
  registerParser(new OpenClawParser());
1995
2247
 
1996
2248
  // src/parsers/qwen-code.ts
1997
- import { existsSync as existsSync12, readdirSync as readdirSync6 } from "fs";
1998
- import { homedir as homedir11 } from "os";
1999
- import { join as join12 } from "path";
2000
- var TOOL_ID7 = "qwen-code";
2001
- var TOOL_NAME7 = "Qwen Code";
2002
- var DEFAULT_DATA_DIR4 = join12(homedir11(), ".qwen", "tmp");
2249
+ import { existsSync as existsSync13, readdirSync as readdirSync6 } from "fs";
2250
+ import { homedir as homedir12 } from "os";
2251
+ import { join as join13 } from "path";
2252
+ var TOOL_ID8 = "qwen-code";
2253
+ var TOOL_NAME8 = "Qwen Code";
2254
+ var DEFAULT_DATA_DIR4 = join13(homedir12(), ".qwen", "tmp");
2003
2255
  function createToolDefinition5(dataDir) {
2004
2256
  return {
2005
- id: TOOL_ID7,
2006
- name: TOOL_NAME7,
2257
+ id: TOOL_ID8,
2258
+ name: TOOL_NAME8,
2007
2259
  dataDir
2008
2260
  };
2009
2261
  }
@@ -2011,7 +2263,7 @@ function toSafeNumber6(value) {
2011
2263
  const numberValue = Number(value);
2012
2264
  return Number.isFinite(numberValue) ? numberValue : 0;
2013
2265
  }
2014
- function getPathLeaf4(value) {
2266
+ function getPathLeaf5(value) {
2015
2267
  const normalized = value.replace(/\\/g, "/").replace(/\/+$/, "");
2016
2268
  const leaf = normalized.split("/").filter(Boolean).pop();
2017
2269
  return leaf || "unknown";
@@ -2021,16 +2273,16 @@ function normalizeForPrefix3(value) {
2021
2273
  }
2022
2274
  function findSessionFiles2(baseDir) {
2023
2275
  const results = [];
2024
- if (!existsSync12(baseDir)) return results;
2276
+ if (!existsSync13(baseDir)) return results;
2025
2277
  try {
2026
2278
  for (const entry of readdirSync6(baseDir, { withFileTypes: true })) {
2027
2279
  if (!entry.isDirectory()) continue;
2028
- const chatsDir = join12(baseDir, entry.name, "chats");
2029
- if (!existsSync12(chatsDir)) continue;
2280
+ const chatsDir = join13(baseDir, entry.name, "chats");
2281
+ if (!existsSync13(chatsDir)) continue;
2030
2282
  try {
2031
2283
  for (const file of readdirSync6(chatsDir)) {
2032
2284
  if (file.endsWith(".jsonl")) {
2033
- results.push(join12(chatsDir, file));
2285
+ results.push(join13(chatsDir, file));
2034
2286
  }
2035
2287
  }
2036
2288
  } catch {
@@ -2043,7 +2295,7 @@ function findSessionFiles2(baseDir) {
2043
2295
  }
2044
2296
  function resolveQwenProject(cwd, filePath, dataDir = DEFAULT_DATA_DIR4) {
2045
2297
  if (cwd) {
2046
- return getPathLeaf4(cwd);
2298
+ return getPathLeaf5(cwd);
2047
2299
  }
2048
2300
  const normalizedFilePath = normalizeForPrefix3(filePath);
2049
2301
  const normalizedDataDir = normalizeForPrefix3(dataDir);
@@ -2085,7 +2337,7 @@ var QwenCodeParser = class {
2085
2337
  if (obj.type === "user" || obj.type === "assistant") {
2086
2338
  sessionEvents.push({
2087
2339
  sessionId,
2088
- source: TOOL_ID7,
2340
+ source: TOOL_ID8,
2089
2341
  project,
2090
2342
  timestamp,
2091
2343
  role: obj.type
@@ -2107,7 +2359,7 @@ var QwenCodeParser = class {
2107
2359
  }
2108
2360
  entries.push({
2109
2361
  sessionId,
2110
- source: TOOL_ID7,
2362
+ source: TOOL_ID8,
2111
2363
  model: obj.model || "unknown",
2112
2364
  project,
2113
2365
  timestamp,
@@ -2126,19 +2378,19 @@ var QwenCodeParser = class {
2126
2378
  };
2127
2379
  }
2128
2380
  isInstalled() {
2129
- return existsSync12(this.dataDir);
2381
+ return existsSync13(this.dataDir);
2130
2382
  }
2131
2383
  };
2132
2384
  registerParser(new QwenCodeParser());
2133
2385
 
2134
2386
  // src/parsers/kimi-code.ts
2135
- import { existsSync as existsSync13, readdirSync as readdirSync7 } from "fs";
2136
- import { homedir as homedir12 } from "os";
2137
- import { join as join13 } from "path";
2138
- var TOOL_ID8 = "kimi-code";
2139
- var TOOL_NAME8 = "Kimi Code";
2140
- var DEFAULT_SESSIONS_DIR3 = join13(homedir12(), ".kimi-code", "sessions");
2141
- var DEFAULT_CONFIG_PATH = join13(homedir12(), ".kimi-code", "workspaces.json");
2387
+ import { existsSync as existsSync14, readdirSync as readdirSync7 } from "fs";
2388
+ import { homedir as homedir13 } from "os";
2389
+ import { join as join14 } from "path";
2390
+ var TOOL_ID9 = "kimi-code";
2391
+ var TOOL_NAME9 = "Kimi Code";
2392
+ var DEFAULT_SESSIONS_DIR3 = join14(homedir13(), ".kimi-code", "sessions");
2393
+ var DEFAULT_CONFIG_PATH = join14(homedir13(), ".kimi-code", "workspaces.json");
2142
2394
  var USER_EVENT_TYPES = /* @__PURE__ */ new Set([
2143
2395
  "UserMessage",
2144
2396
  "user_message",
@@ -2154,8 +2406,8 @@ var ASSISTANT_EVENT_TYPES = /* @__PURE__ */ new Set([
2154
2406
  ]);
2155
2407
  function createToolDefinition6(dataDir) {
2156
2408
  return {
2157
- id: TOOL_ID8,
2158
- name: TOOL_NAME8,
2409
+ id: TOOL_ID9,
2410
+ name: TOOL_NAME9,
2159
2411
  dataDir
2160
2412
  };
2161
2413
  }
@@ -2163,36 +2415,36 @@ function toSafeNumber7(value) {
2163
2415
  const numberValue = Number(value);
2164
2416
  return Number.isFinite(numberValue) ? numberValue : 0;
2165
2417
  }
2166
- function getPathLeaf5(value) {
2418
+ function getPathLeaf6(value) {
2167
2419
  const normalized = value.replace(/\\/g, "/").replace(/\/+$/, "");
2168
2420
  const leaf = normalized.split("/").filter(Boolean).pop();
2169
2421
  return leaf || "unknown";
2170
2422
  }
2171
2423
  function findWireFiles(baseDir) {
2172
2424
  const results = [];
2173
- if (!existsSync13(baseDir)) return results;
2425
+ if (!existsSync14(baseDir)) return results;
2174
2426
  try {
2175
2427
  for (const workDir of readdirSync7(baseDir, { withFileTypes: true })) {
2176
2428
  if (!workDir.isDirectory()) continue;
2177
- const workDirPath = join13(baseDir, workDir.name);
2429
+ const workDirPath = join14(baseDir, workDir.name);
2178
2430
  try {
2179
2431
  for (const session of readdirSync7(workDirPath, {
2180
2432
  withFileTypes: true
2181
2433
  })) {
2182
2434
  if (!session.isDirectory()) continue;
2183
- const newWireFile = join13(
2435
+ const newWireFile = join14(
2184
2436
  workDirPath,
2185
2437
  session.name,
2186
2438
  "agents",
2187
2439
  "main",
2188
2440
  "wire.jsonl"
2189
2441
  );
2190
- if (existsSync13(newWireFile)) {
2442
+ if (existsSync14(newWireFile)) {
2191
2443
  results.push({ filePath: newWireFile, workDirHash: workDir.name });
2192
2444
  continue;
2193
2445
  }
2194
- const legacyWireFile = join13(workDirPath, session.name, "wire.jsonl");
2195
- if (existsSync13(legacyWireFile)) {
2446
+ const legacyWireFile = join14(workDirPath, session.name, "wire.jsonl");
2447
+ if (existsSync14(legacyWireFile)) {
2196
2448
  results.push({
2197
2449
  filePath: legacyWireFile,
2198
2450
  workDirHash: workDir.name
@@ -2242,7 +2494,7 @@ function loadProjectMap(configPath) {
2242
2494
  pathValue = info.root || info.path || info.dir || void 0;
2243
2495
  }
2244
2496
  if (!pathValue) continue;
2245
- const name = typeof info === "object" && info.name ? info.name : getPathLeaf5(pathValue);
2497
+ const name = typeof info === "object" && info.name ? info.name : getPathLeaf6(pathValue);
2246
2498
  projectMap.set(hash, name);
2247
2499
  }
2248
2500
  } catch {
@@ -2300,14 +2552,14 @@ var KimiCodeParser = class {
2300
2552
  }
2301
2553
  sessionEvents.push({
2302
2554
  sessionId,
2303
- source: TOOL_ID8,
2555
+ source: TOOL_ID9,
2304
2556
  project,
2305
2557
  timestamp: timestamp2,
2306
2558
  role: "assistant"
2307
2559
  });
2308
2560
  entries.push({
2309
2561
  sessionId,
2310
- source: TOOL_ID8,
2562
+ source: TOOL_ID9,
2311
2563
  model: obj.model || currentModel,
2312
2564
  project,
2313
2565
  timestamp: timestamp2,
@@ -2334,7 +2586,7 @@ var KimiCodeParser = class {
2334
2586
  if (role && timestamp) {
2335
2587
  sessionEvents.push({
2336
2588
  sessionId,
2337
- source: TOOL_ID8,
2589
+ source: TOOL_ID9,
2338
2590
  project,
2339
2591
  timestamp,
2340
2592
  role
@@ -2357,7 +2609,7 @@ var KimiCodeParser = class {
2357
2609
  if (!role) {
2358
2610
  sessionEvents.push({
2359
2611
  sessionId,
2360
- source: TOOL_ID8,
2612
+ source: TOOL_ID9,
2361
2613
  project,
2362
2614
  timestamp,
2363
2615
  role: "assistant"
@@ -2365,7 +2617,7 @@ var KimiCodeParser = class {
2365
2617
  }
2366
2618
  entries.push({
2367
2619
  sessionId,
2368
- source: TOOL_ID8,
2620
+ source: TOOL_ID9,
2369
2621
  model: currentModel,
2370
2622
  project,
2371
2623
  timestamp,
@@ -2382,23 +2634,23 @@ var KimiCodeParser = class {
2382
2634
  };
2383
2635
  }
2384
2636
  isInstalled() {
2385
- return existsSync13(this.sessionsDir);
2637
+ return existsSync14(this.sessionsDir);
2386
2638
  }
2387
2639
  };
2388
2640
  registerParser(new KimiCodeParser());
2389
2641
 
2390
2642
  // src/parsers/letcode.ts
2391
- import { existsSync as existsSync14 } from "fs";
2392
- import { homedir as homedir13 } from "os";
2393
- import { basename as basename5, join as join14 } from "path";
2394
- var TOOL_ID9 = "letcode";
2395
- var TOOL_NAME9 = "LetCode";
2396
- var DEFAULT_CONFIG_DIR = join14(homedir13(), ".config", "letcode");
2397
- var DEFAULT_SESSIONS_DIR4 = join14(DEFAULT_CONFIG_DIR, "sessions");
2643
+ import { existsSync as existsSync15 } from "fs";
2644
+ import { homedir as homedir14 } from "os";
2645
+ import { basename as basename5, join as join15 } from "path";
2646
+ var TOOL_ID10 = "letcode";
2647
+ var TOOL_NAME10 = "LetCode";
2648
+ var DEFAULT_CONFIG_DIR = join15(homedir14(), ".config", "letcode");
2649
+ var DEFAULT_SESSIONS_DIR4 = join15(DEFAULT_CONFIG_DIR, "sessions");
2398
2650
  function getLetcodeSessionsDirs(env = process.env) {
2399
2651
  const dirs = [
2400
2652
  env.TOKEN_ARENA_LETCODE_DIR,
2401
- env.XDG_CONFIG_HOME ? join14(env.XDG_CONFIG_HOME, "letcode", "sessions") : void 0,
2653
+ env.XDG_CONFIG_HOME ? join15(env.XDG_CONFIG_HOME, "letcode", "sessions") : void 0,
2402
2654
  DEFAULT_SESSIONS_DIR4
2403
2655
  ].filter((value) => Boolean(value));
2404
2656
  return Array.from(new Set(dirs));
@@ -2452,8 +2704,8 @@ var LetcodeParser = class {
2452
2704
  constructor(sessionsDir) {
2453
2705
  this.sessionsDirs = sessionsDir ? [sessionsDir] : getLetcodeSessionsDirs();
2454
2706
  this.tool = {
2455
- id: TOOL_ID9,
2456
- name: TOOL_NAME9,
2707
+ id: TOOL_ID10,
2708
+ name: TOOL_NAME10,
2457
2709
  dataDir: this.sessionsDirs[0] ?? DEFAULT_SESSIONS_DIR4
2458
2710
  };
2459
2711
  }
@@ -2476,7 +2728,7 @@ var LetcodeParser = class {
2476
2728
  if (role) {
2477
2729
  sessionEvents.push({
2478
2730
  sessionId,
2479
- source: TOOL_ID9,
2731
+ source: TOOL_ID10,
2480
2732
  project: "unknown",
2481
2733
  timestamp,
2482
2734
  role
@@ -2510,7 +2762,7 @@ var LetcodeParser = class {
2510
2762
  seenEntryKeys.add(entryKey);
2511
2763
  entries.push({
2512
2764
  sessionId,
2513
- source: TOOL_ID9,
2765
+ source: TOOL_ID10,
2514
2766
  model,
2515
2767
  project: "unknown",
2516
2768
  timestamp,
@@ -2528,31 +2780,31 @@ var LetcodeParser = class {
2528
2780
  };
2529
2781
  }
2530
2782
  isInstalled() {
2531
- return this.sessionsDirs.some((dir) => existsSync14(dir));
2783
+ return this.sessionsDirs.some((dir) => existsSync15(dir));
2532
2784
  }
2533
2785
  };
2534
2786
  registerParser(new LetcodeParser());
2535
2787
 
2536
2788
  // src/parsers/droid.ts
2537
- import { existsSync as existsSync15, readdirSync as readdirSync8 } from "fs";
2538
- import { homedir as homedir14 } from "os";
2539
- import { basename as basename6, dirname as dirname3, join as join15 } from "path";
2540
- var TOOL_ID10 = "droid";
2541
- var TOOL_NAME10 = "Droid";
2542
- var DEFAULT_DATA_DIR5 = join15(homedir14(), ".factory", "sessions");
2789
+ import { existsSync as existsSync16, readdirSync as readdirSync8 } from "fs";
2790
+ import { homedir as homedir15 } from "os";
2791
+ import { basename as basename6, dirname as dirname3, join as join16 } from "path";
2792
+ var TOOL_ID11 = "droid";
2793
+ var TOOL_NAME11 = "Droid";
2794
+ var DEFAULT_DATA_DIR5 = join16(homedir15(), ".factory", "sessions");
2543
2795
  function createToolDefinition7(dataDir) {
2544
2796
  return {
2545
- id: TOOL_ID10,
2546
- name: TOOL_NAME10,
2797
+ id: TOOL_ID11,
2798
+ name: TOOL_NAME11,
2547
2799
  dataDir
2548
2800
  };
2549
2801
  }
2550
2802
  function findSessionFiles3(dir) {
2551
2803
  const results = [];
2552
- if (!existsSync15(dir)) return results;
2804
+ if (!existsSync16(dir)) return results;
2553
2805
  try {
2554
2806
  for (const entry of readdirSync8(dir, { withFileTypes: true })) {
2555
- const fullPath = join15(dir, entry.name);
2807
+ const fullPath = join16(dir, entry.name);
2556
2808
  if (entry.isDirectory()) {
2557
2809
  results.push(...findSessionFiles3(fullPath));
2558
2810
  } else if (entry.isFile() && entry.name.endsWith(".jsonl") && !entry.name.endsWith(".settings.json")) {
@@ -2609,13 +2861,13 @@ var DroidParser = class {
2609
2861
  }
2610
2862
  sessionEvents.push({
2611
2863
  sessionId,
2612
- source: TOOL_ID10,
2864
+ source: TOOL_ID11,
2613
2865
  project,
2614
2866
  timestamp,
2615
2867
  role
2616
2868
  });
2617
2869
  }
2618
- const settingsPath = join15(
2870
+ const settingsPath = join16(
2619
2871
  dirname3(filePath),
2620
2872
  `${basename6(filePath, ".jsonl")}.settings.json`
2621
2873
  );
@@ -2644,7 +2896,7 @@ var DroidParser = class {
2644
2896
  }
2645
2897
  entries.push({
2646
2898
  sessionId,
2647
- source: TOOL_ID10,
2899
+ source: TOOL_ID11,
2648
2900
  model: settings.model || "unknown",
2649
2901
  project,
2650
2902
  timestamp: firstMessageTimestamp,
@@ -2660,22 +2912,22 @@ var DroidParser = class {
2660
2912
  };
2661
2913
  }
2662
2914
  isInstalled() {
2663
- return existsSync15(this.dataDir);
2915
+ return existsSync16(this.dataDir);
2664
2916
  }
2665
2917
  };
2666
2918
  registerParser(new DroidParser());
2667
2919
 
2668
2920
  // src/parsers/pi-coding-agent.ts
2669
- import { existsSync as existsSync16 } from "fs";
2670
- import { homedir as homedir15 } from "os";
2671
- import { join as join16 } from "path";
2672
- var TOOL_ID11 = "pi-coding-agent";
2673
- var TOOL_NAME11 = "pi";
2674
- var DEFAULT_SESSIONS_DIR5 = join16(homedir15(), ".pi", "agent", "sessions");
2921
+ import { existsSync as existsSync17 } from "fs";
2922
+ import { homedir as homedir16 } from "os";
2923
+ import { join as join17 } from "path";
2924
+ var TOOL_ID12 = "pi-coding-agent";
2925
+ var TOOL_NAME12 = "pi";
2926
+ var DEFAULT_SESSIONS_DIR5 = join17(homedir16(), ".pi", "agent", "sessions");
2675
2927
  function createToolDefinition8(dataDir) {
2676
2928
  return {
2677
- id: TOOL_ID11,
2678
- name: TOOL_NAME11,
2929
+ id: TOOL_ID12,
2930
+ name: TOOL_NAME12,
2679
2931
  dataDir
2680
2932
  };
2681
2933
  }
@@ -2683,7 +2935,7 @@ function toSafeNumber9(value) {
2683
2935
  const numberValue = Number(value);
2684
2936
  return Number.isFinite(numberValue) ? numberValue : 0;
2685
2937
  }
2686
- function getPathLeaf6(value) {
2938
+ function getPathLeaf7(value) {
2687
2939
  const normalized = value.replace(/\\/g, "/").replace(/\/+$/, "");
2688
2940
  const leaf = normalized.split("/").filter(Boolean).pop();
2689
2941
  return leaf || "unknown";
@@ -2702,7 +2954,7 @@ function getUsageNumber3(usage, ...keys) {
2702
2954
  return 0;
2703
2955
  }
2704
2956
  function extractPiProjectFromCwd(cwd) {
2705
- return getPathLeaf6(cwd);
2957
+ return getPathLeaf7(cwd);
2706
2958
  }
2707
2959
  function extractPiProjectFromDir(filePath, sessionsDir = DEFAULT_SESSIONS_DIR5) {
2708
2960
  const normalizedFilePath = normalizeForPrefix4(filePath);
@@ -2719,7 +2971,7 @@ function extractPiProjectFromDir(filePath, sessionsDir = DEFAULT_SESSIONS_DIR5)
2719
2971
  try {
2720
2972
  const decoded = decodeURIComponent(firstSegment);
2721
2973
  if (decoded.includes("/") || decoded.includes("\\")) {
2722
- return getPathLeaf6(decoded);
2974
+ return getPathLeaf7(decoded);
2723
2975
  }
2724
2976
  } catch {
2725
2977
  }
@@ -2769,7 +3021,7 @@ var PiCodingAgentParser = class {
2769
3021
  if (message.role === "user" || message.role === "assistant") {
2770
3022
  sessionEvents.push({
2771
3023
  sessionId,
2772
- source: TOOL_ID11,
3024
+ source: TOOL_ID12,
2773
3025
  project,
2774
3026
  timestamp,
2775
3027
  role: message.role
@@ -2801,7 +3053,7 @@ var PiCodingAgentParser = class {
2801
3053
  }
2802
3054
  entries.push({
2803
3055
  sessionId,
2804
- source: TOOL_ID11,
3056
+ source: TOOL_ID12,
2805
3057
  model: message.model || "unknown",
2806
3058
  project,
2807
3059
  timestamp,
@@ -2818,23 +3070,23 @@ var PiCodingAgentParser = class {
2818
3070
  };
2819
3071
  }
2820
3072
  isInstalled() {
2821
- return existsSync16(this.sessionsDir);
3073
+ return existsSync17(this.sessionsDir);
2822
3074
  }
2823
3075
  };
2824
3076
  registerParser(new PiCodingAgentParser());
2825
3077
 
2826
3078
  // src/parsers/qwenpaw.ts
2827
- import { existsSync as existsSync17, readdirSync as readdirSync9 } from "fs";
2828
- import { homedir as homedir16, hostname as hostname3 } from "os";
2829
- import { join as join17 } from "path";
2830
- var TOOL_ID12 = "qwenpaw";
2831
- var TOOL_NAME12 = "QwenPaw";
2832
- var DEFAULT_USAGE_PATH = join17(homedir16(), ".qwenpaw", "token_usage.json");
2833
- var DEFAULT_WORKSPACE_PATH = join17(homedir16(), ".qwenpaw", "workspace");
3079
+ import { existsSync as existsSync18, readdirSync as readdirSync9 } from "fs";
3080
+ import { homedir as homedir17, hostname as hostname4 } from "os";
3081
+ import { join as join18 } from "path";
3082
+ var TOOL_ID13 = "qwenpaw";
3083
+ var TOOL_NAME13 = "QwenPaw";
3084
+ var DEFAULT_USAGE_PATH = join18(homedir17(), ".qwenpaw", "token_usage.json");
3085
+ var DEFAULT_WORKSPACE_PATH = join18(homedir17(), ".qwenpaw", "workspace");
2834
3086
  function createToolDefinition9(usagePath) {
2835
3087
  return {
2836
- id: TOOL_ID12,
2837
- name: TOOL_NAME12,
3088
+ id: TOOL_ID13,
3089
+ name: TOOL_NAME13,
2838
3090
  dataDir: usagePath
2839
3091
  };
2840
3092
  }
@@ -2849,12 +3101,12 @@ function parseUsageDate(value) {
2849
3101
  const timestamp = /* @__PURE__ */ new Date(`${value}T00:00:00.000Z`);
2850
3102
  return Number.isNaN(timestamp.getTime()) ? null : timestamp;
2851
3103
  }
2852
- function getString(value) {
3104
+ function getString2(value) {
2853
3105
  return typeof value === "string" && value.length > 0 ? value : null;
2854
3106
  }
2855
3107
  function resolveModel(recordKey, record) {
2856
- const providerId = getString(record.provider_id);
2857
- const modelName = getString(record.model_name);
3108
+ const providerId = getString2(record.provider_id);
3109
+ const modelName = getString2(record.model_name);
2858
3110
  if (providerId && modelName) {
2859
3111
  return `${providerId}:${modelName}`;
2860
3112
  }
@@ -2891,7 +3143,7 @@ var QwenPawParser = class {
2891
3143
  continue;
2892
3144
  }
2893
3145
  entries.push({
2894
- source: TOOL_ID12,
3146
+ source: TOOL_ID13,
2895
3147
  model: resolveModel(recordKey, record),
2896
3148
  project: "unknown",
2897
3149
  timestamp,
@@ -2914,15 +3166,15 @@ var QwenPawParser = class {
2914
3166
  }
2915
3167
  async parseWorkspaceSessions() {
2916
3168
  const events = [];
2917
- if (!existsSync17(this.workspacePath)) {
3169
+ if (!existsSync18(this.workspacePath)) {
2918
3170
  return events;
2919
3171
  }
2920
3172
  try {
2921
3173
  const workspaceDirs = readdirSync9(this.workspacePath);
2922
3174
  for (const workspaceDir of workspaceDirs) {
2923
- const workspacePath = join17(this.workspacePath, workspaceDir);
2924
- const chatsPath = join17(workspacePath, "chats.json");
2925
- const sessionsPath = join17(workspacePath, "sessions");
3175
+ const workspacePath = join18(this.workspacePath, workspaceDir);
3176
+ const chatsPath = join18(workspacePath, "chats.json");
3177
+ const sessionsPath = join18(workspacePath, "sessions");
2926
3178
  const chatsContent = readFileSafe(chatsPath);
2927
3179
  if (!chatsContent) {
2928
3180
  continue;
@@ -2950,7 +3202,7 @@ var QwenPawParser = class {
2950
3202
  for (const msg of sessionMessages) {
2951
3203
  events.push({
2952
3204
  sessionId: chat.session_id,
2953
- source: TOOL_ID12,
3205
+ source: TOOL_ID13,
2954
3206
  project: workspaceDir,
2955
3207
  timestamp: new Date(msg.timestamp),
2956
3208
  role: msg.role
@@ -2966,7 +3218,7 @@ var QwenPawParser = class {
2966
3218
  }
2967
3219
  getSessionFiles(sessionsPath) {
2968
3220
  const files = /* @__PURE__ */ new Map();
2969
- if (!existsSync17(sessionsPath)) {
3221
+ if (!existsSync18(sessionsPath)) {
2970
3222
  return files;
2971
3223
  }
2972
3224
  try {
@@ -2975,7 +3227,7 @@ var QwenPawParser = class {
2975
3227
  if (!fileName.endsWith(".json")) {
2976
3228
  continue;
2977
3229
  }
2978
- const filePath = join17(sessionsPath, fileName);
3230
+ const filePath = join18(sessionsPath, fileName);
2979
3231
  const content = readFileSafe(filePath);
2980
3232
  if (content) {
2981
3233
  const sessionId = fileName.replace(/^[^_]+_/, "").replace(".json", "");
@@ -3051,7 +3303,7 @@ var QwenPawParser = class {
3051
3303
  source: sessionData.source,
3052
3304
  project: sessionData.project,
3053
3305
  sessionHash,
3054
- hostname: hostname3().replace(/\.local$/, ""),
3306
+ hostname: hostname4().replace(/\.local$/, ""),
3055
3307
  firstMessageAt,
3056
3308
  lastMessageAt,
3057
3309
  durationSeconds,
@@ -3073,15 +3325,15 @@ var QwenPawParser = class {
3073
3325
  });
3074
3326
  }
3075
3327
  isInstalled() {
3076
- return existsSync17(this.usagePath) || existsSync17(this.workspacePath);
3328
+ return existsSync18(this.usagePath) || existsSync18(this.workspacePath);
3077
3329
  }
3078
3330
  };
3079
3331
  registerParser(new QwenPawParser());
3080
3332
 
3081
3333
  // src/parsers/cline.ts
3082
3334
  import { readFileSync as readFileSync6, statSync } from "fs";
3083
- import { homedir as homedir17 } from "os";
3084
- import { basename as basename7, join as join18 } from "path";
3335
+ import { homedir as homedir18 } from "os";
3336
+ import { basename as basename7, join as join19 } from "path";
3085
3337
  var EXTENSION_ID = "saoudrizwan.claude-dev";
3086
3338
  var HOSTS = [
3087
3339
  "Code",
@@ -3095,26 +3347,26 @@ var HOSTS = [
3095
3347
  var TOOL6 = {
3096
3348
  id: "cline",
3097
3349
  name: "Cline",
3098
- dataDir: join18(homedir17(), ".cline")
3350
+ dataDir: join19(homedir18(), ".cline")
3099
3351
  };
3100
3352
  function getHostRoots() {
3101
3353
  const out = [];
3102
3354
  if (process.platform === "darwin") {
3103
- const base = join18(homedir17(), "Library", "Application Support");
3104
- for (const h of HOSTS) out.push(join18(base, h));
3355
+ const base = join19(homedir18(), "Library", "Application Support");
3356
+ for (const h of HOSTS) out.push(join19(base, h));
3105
3357
  } else if (process.platform === "win32") {
3106
- const appData = process.env.APPDATA?.trim() || join18(homedir17(), "AppData", "Roaming");
3107
- for (const h of HOSTS) out.push(join18(appData, h));
3358
+ const appData = process.env.APPDATA?.trim() || join19(homedir18(), "AppData", "Roaming");
3359
+ for (const h of HOSTS) out.push(join19(appData, h));
3108
3360
  } else {
3109
- const xdg = process.env.XDG_CONFIG_HOME?.trim() || join18(homedir17(), ".config");
3110
- for (const h of HOSTS) out.push(join18(xdg, h));
3361
+ const xdg = process.env.XDG_CONFIG_HOME?.trim() || join19(homedir18(), ".config");
3362
+ for (const h of HOSTS) out.push(join19(xdg, h));
3111
3363
  }
3112
3364
  return out;
3113
3365
  }
3114
3366
  function findClineExtensionDirs() {
3115
3367
  const dirs = [];
3116
3368
  for (const root of getHostRoots()) {
3117
- const ext = join18(root, "User", "globalStorage", EXTENSION_ID);
3369
+ const ext = join19(root, "User", "globalStorage", EXTENSION_ID);
3118
3370
  try {
3119
3371
  if (statSync(ext).isDirectory()) dirs.push(ext);
3120
3372
  } catch {
@@ -3146,7 +3398,7 @@ var ClineParser = class {
3146
3398
  const entries = [];
3147
3399
  const sessionEvents = [];
3148
3400
  for (const extDir of extDirs) {
3149
- const history = readJsonSafe(join18(extDir, "state", "taskHistory.json"));
3401
+ const history = readJsonSafe(join19(extDir, "state", "taskHistory.json"));
3150
3402
  if (!Array.isArray(history)) continue;
3151
3403
  for (const item of history) {
3152
3404
  try {
@@ -3157,7 +3409,7 @@ var ClineParser = class {
3157
3409
  );
3158
3410
  const fallbackModel = item.modelId && String(item.modelId).trim() || "cline-unknown";
3159
3411
  const messages = readJsonSafe(
3160
- join18(extDir, "tasks", taskId, "ui_messages.json")
3412
+ join19(extDir, "tasks", taskId, "ui_messages.json")
3161
3413
  );
3162
3414
  if (!Array.isArray(messages)) continue;
3163
3415
  for (const msg of messages) {
@@ -3228,20 +3480,20 @@ registerParser(new ClineParser());
3228
3480
  import { execFileSync as execFileSync3 } from "child_process";
3229
3481
  import {
3230
3482
  copyFileSync,
3231
- existsSync as existsSync18,
3483
+ existsSync as existsSync19,
3232
3484
  mkdtempSync,
3233
3485
  readdirSync as readdirSync10,
3234
3486
  readFileSync as readFileSync7,
3235
3487
  rmSync,
3236
3488
  statSync as statSync2
3237
3489
  } from "fs";
3238
- import { homedir as homedir18, tmpdir } from "os";
3239
- import { join as join19, resolve } from "path";
3240
- var KIROAGENT_RELATIVE = join19("User", "globalStorage", "kiro.kiroagent");
3490
+ import { homedir as homedir19, tmpdir } from "os";
3491
+ import { join as join20, resolve } from "path";
3492
+ var KIROAGENT_RELATIVE = join20("User", "globalStorage", "kiro.kiroagent");
3241
3493
  function getDefaultBasePath() {
3242
3494
  if (process.platform === "darwin") {
3243
- return join19(
3244
- homedir18(),
3495
+ return join20(
3496
+ homedir19(),
3245
3497
  "Library",
3246
3498
  "Application Support",
3247
3499
  "Kiro",
@@ -3249,11 +3501,11 @@ function getDefaultBasePath() {
3249
3501
  );
3250
3502
  }
3251
3503
  if (process.platform === "win32") {
3252
- const appData = process.env.APPDATA?.trim() || join19(homedir18(), "AppData", "Roaming");
3253
- return join19(appData, "Kiro", KIROAGENT_RELATIVE);
3504
+ const appData = process.env.APPDATA?.trim() || join20(homedir19(), "AppData", "Roaming");
3505
+ return join20(appData, "Kiro", KIROAGENT_RELATIVE);
3254
3506
  }
3255
- const xdgConfigHome = process.env.XDG_CONFIG_HOME?.trim() || join19(homedir18(), ".config");
3256
- return join19(xdgConfigHome, "Kiro", KIROAGENT_RELATIVE);
3507
+ const xdgConfigHome = process.env.XDG_CONFIG_HOME?.trim() || join20(homedir19(), ".config");
3508
+ return join20(xdgConfigHome, "Kiro", KIROAGENT_RELATIVE);
3257
3509
  }
3258
3510
  var TOOL7 = {
3259
3511
  id: "kiro",
@@ -3264,10 +3516,10 @@ function getKiroBasePath() {
3264
3516
  const explicit = process.env.KIRO_BASE_PATH?.trim();
3265
3517
  if (explicit) {
3266
3518
  const r = resolve(explicit);
3267
- return existsSync18(r) ? r : null;
3519
+ return existsSync19(r) ? r : null;
3268
3520
  }
3269
3521
  const def = getDefaultBasePath();
3270
- return existsSync18(def) ? def : null;
3522
+ return existsSync19(def) ? def : null;
3271
3523
  }
3272
3524
  function isLockError(err) {
3273
3525
  return err instanceof Error && typeof err.message === "string" && /database is locked/i.test(err.message);
@@ -3288,12 +3540,12 @@ function readDb(dbPath) {
3288
3540
  return queryDb(dbPath, TOKENS_SQL);
3289
3541
  } catch (err) {
3290
3542
  if (!isLockError(err)) throw err;
3291
- const snapshotDir = mkdtempSync(join19(tmpdir(), "vibe-usage-kiro-"));
3292
- const queryPath = join19(snapshotDir, "devdata.sqlite");
3543
+ const snapshotDir = mkdtempSync(join20(tmpdir(), "vibe-usage-kiro-"));
3544
+ const queryPath = join20(snapshotDir, "devdata.sqlite");
3293
3545
  copyFileSync(dbPath, queryPath);
3294
3546
  for (const suffix of ["-shm", "-wal"]) {
3295
3547
  const companion = `${dbPath}${suffix}`;
3296
- if (existsSync18(companion))
3548
+ if (existsSync19(companion))
3297
3549
  copyFileSync(companion, `${queryPath}${suffix}`);
3298
3550
  }
3299
3551
  try {
@@ -3345,7 +3597,7 @@ function buildModelTimeline(base) {
3345
3597
  }
3346
3598
  for (const entry of entries) {
3347
3599
  if (!entry.isDirectory() || entry.name === "dev_data") continue;
3348
- const dirPath = join19(base, entry.name);
3600
+ const dirPath = join20(base, entry.name);
3349
3601
  let files;
3350
3602
  try {
3351
3603
  files = readdirSync10(dirPath).filter((f) => f.endsWith(".chat"));
@@ -3354,7 +3606,7 @@ function buildModelTimeline(base) {
3354
3606
  }
3355
3607
  for (const file of files) {
3356
3608
  try {
3357
- const data = JSON.parse(readFileSync7(join19(dirPath, file), "utf-8"));
3609
+ const data = JSON.parse(readFileSync7(join20(dirPath, file), "utf-8"));
3358
3610
  const meta = data?.metadata;
3359
3611
  if (!meta?.modelId || !meta?.startTime) continue;
3360
3612
  const startMs = Number(meta.startTime);
@@ -3403,13 +3655,13 @@ var KiroParser = class {
3403
3655
  async parse() {
3404
3656
  const base = getKiroBasePath();
3405
3657
  if (!base) return { buckets: [], sessions: [] };
3406
- const dbPath = join19(base, "dev_data", "devdata.sqlite");
3407
- const jsonlPath = join19(base, "dev_data", "tokens_generated.jsonl");
3658
+ const dbPath = join20(base, "dev_data", "devdata.sqlite");
3659
+ const jsonlPath = join20(base, "dev_data", "tokens_generated.jsonl");
3408
3660
  let rows;
3409
3661
  try {
3410
- if (existsSync18(dbPath)) {
3662
+ if (existsSync19(dbPath)) {
3411
3663
  rows = readDb(dbPath);
3412
- } else if (existsSync18(jsonlPath)) {
3664
+ } else if (existsSync19(jsonlPath)) {
3413
3665
  rows = readJsonl(jsonlPath);
3414
3666
  } else {
3415
3667
  return { buckets: [], sessions: [] };
@@ -3460,8 +3712,8 @@ registerParser(new KiroParser());
3460
3712
 
3461
3713
  // src/parsers/roo-code.ts
3462
3714
  import { readdirSync as readdirSync11, readFileSync as readFileSync8, statSync as statSync3 } from "fs";
3463
- import { homedir as homedir19 } from "os";
3464
- import { basename as basename8, join as join20 } from "path";
3715
+ import { homedir as homedir20 } from "os";
3716
+ import { basename as basename8, join as join21 } from "path";
3465
3717
  var EXTENSION_ID2 = "rooveterinaryinc.roo-cline";
3466
3718
  var HOSTS2 = [
3467
3719
  "Code",
@@ -3476,17 +3728,17 @@ function getHostRoots2() {
3476
3728
  const out = [];
3477
3729
  let roots;
3478
3730
  if (process.platform === "darwin") {
3479
- roots = [join20(homedir19(), "Library", "Application Support")];
3731
+ roots = [join21(homedir20(), "Library", "Application Support")];
3480
3732
  } else if (process.platform === "win32") {
3481
3733
  roots = [
3482
- process.env.APPDATA?.trim() || join20(homedir19(), "AppData", "Roaming")
3734
+ process.env.APPDATA?.trim() || join21(homedir20(), "AppData", "Roaming")
3483
3735
  ];
3484
3736
  } else {
3485
- roots = [process.env.XDG_CONFIG_HOME?.trim() || join20(homedir19(), ".config")];
3737
+ roots = [process.env.XDG_CONFIG_HOME?.trim() || join21(homedir20(), ".config")];
3486
3738
  }
3487
3739
  for (const root of roots) {
3488
3740
  for (const h of HOSTS2) {
3489
- out.push(join20(root, h));
3741
+ out.push(join21(root, h));
3490
3742
  }
3491
3743
  }
3492
3744
  return out;
@@ -3494,7 +3746,7 @@ function getHostRoots2() {
3494
3746
  function findExtensionDirs() {
3495
3747
  const dirs = [];
3496
3748
  for (const root of getHostRoots2()) {
3497
- const ext = join20(root, "User", "globalStorage", EXTENSION_ID2);
3749
+ const ext = join21(root, "User", "globalStorage", EXTENSION_ID2);
3498
3750
  try {
3499
3751
  if (statSync3(ext).isDirectory()) dirs.push(ext);
3500
3752
  } catch {
@@ -3516,9 +3768,9 @@ function projectFromPath2(absPath) {
3516
3768
  return name || "unknown";
3517
3769
  }
3518
3770
  function readHistoryItems(extDir) {
3519
- const tasksDir = join20(extDir, "tasks");
3771
+ const tasksDir = join21(extDir, "tasks");
3520
3772
  const index = readJsonSafe2(
3521
- join20(tasksDir, "_index.json")
3773
+ join21(tasksDir, "_index.json")
3522
3774
  );
3523
3775
  if (index?.entries && Array.isArray(index.entries)) return index.entries;
3524
3776
  const items = [];
@@ -3532,7 +3784,7 @@ function readHistoryItems(extDir) {
3532
3784
  if (!entry.isDirectory() || entry.name.startsWith("_") || entry.name.startsWith("."))
3533
3785
  continue;
3534
3786
  const item = readJsonSafe2(
3535
- join20(tasksDir, entry.name, "history_item.json")
3787
+ join21(tasksDir, entry.name, "history_item.json")
3536
3788
  );
3537
3789
  if (item && typeof item === "object") items.push(item);
3538
3790
  }
@@ -3559,7 +3811,7 @@ var RooCodeParser = class {
3559
3811
  const project = projectFromPath2(item.workspace);
3560
3812
  const fallbackModel = item.apiConfigName && String(item.apiConfigName).trim() || "roo-unknown";
3561
3813
  const messages = readJsonSafe2(
3562
- join20(extDir, "tasks", taskId, "ui_messages.json")
3814
+ join21(extDir, "tasks", taskId, "ui_messages.json")
3563
3815
  );
3564
3816
  if (!Array.isArray(messages)) continue;
3565
3817
  for (const msg of messages) {
@@ -3623,10 +3875,10 @@ var RooCodeParser = class {
3623
3875
  registerParser(new RooCodeParser());
3624
3876
 
3625
3877
  // src/parsers/snow.ts
3626
- import { existsSync as existsSync19 } from "fs";
3627
- import { homedir as homedir20 } from "os";
3628
- import { join as join21 } from "path";
3629
- var DEFAULT_DATA_DIR6 = join21(homedir20(), ".snow", "usage");
3878
+ import { existsSync as existsSync20 } from "fs";
3879
+ import { homedir as homedir21 } from "os";
3880
+ import { join as join22 } from "path";
3881
+ var DEFAULT_DATA_DIR6 = join22(homedir21(), ".snow", "usage");
3630
3882
  function toNonNegativeNumber2(value) {
3631
3883
  const numberValue = Number(value);
3632
3884
  return Number.isFinite(numberValue) && numberValue >= 0 ? numberValue : 0;
@@ -3673,26 +3925,26 @@ var SnowParser = class {
3673
3925
  return { buckets: aggregateToBuckets(entries), sessions: [] };
3674
3926
  }
3675
3927
  isInstalled() {
3676
- return existsSync19(this.dataDir);
3928
+ return existsSync20(this.dataDir);
3677
3929
  }
3678
3930
  };
3679
3931
  registerParser(new SnowParser());
3680
3932
 
3681
3933
  // src/parsers/cursor.ts
3682
3934
  import { execFileSync as execFileSync4 } from "child_process";
3683
- import { copyFileSync as copyFileSync2, existsSync as existsSync20, mkdtempSync as mkdtempSync2, rmSync as rmSync2 } from "fs";
3684
- import { homedir as homedir21, tmpdir as tmpdir2 } from "os";
3685
- import { dirname as dirname4, join as join22, resolve as resolve2 } from "path";
3686
- var TOOL_ID13 = "cursor";
3687
- var TOOL_NAME13 = "Cursor";
3688
- var STATE_DB_RELATIVE = join22("User", "globalStorage", "state.vscdb");
3935
+ import { copyFileSync as copyFileSync2, existsSync as existsSync21, mkdtempSync as mkdtempSync2, rmSync as rmSync2 } from "fs";
3936
+ import { homedir as homedir22, tmpdir as tmpdir2 } from "os";
3937
+ import { dirname as dirname4, join as join23, resolve as resolve2 } from "path";
3938
+ var TOOL_ID14 = "cursor";
3939
+ var TOOL_NAME14 = "Cursor";
3940
+ var STATE_DB_RELATIVE = join23("User", "globalStorage", "state.vscdb");
3689
3941
  var ACCESS_TOKEN_KEY = "cursorAuth/accessToken";
3690
3942
  var SESSION_COOKIE = "WorkosCursorSessionToken";
3691
3943
  var FETCH_TIMEOUT_MS = 1e4;
3692
3944
  function getDefaultStateDbPath() {
3693
3945
  if (process.platform === "darwin") {
3694
- return join22(
3695
- homedir21(),
3946
+ return join23(
3947
+ homedir22(),
3696
3948
  "Library",
3697
3949
  "Application Support",
3698
3950
  "Cursor",
@@ -3700,25 +3952,25 @@ function getDefaultStateDbPath() {
3700
3952
  );
3701
3953
  }
3702
3954
  if (process.platform === "win32") {
3703
- const appData = process.env.APPDATA?.trim() || join22(homedir21(), "AppData", "Roaming");
3704
- return join22(appData, "Cursor", STATE_DB_RELATIVE);
3955
+ const appData = process.env.APPDATA?.trim() || join23(homedir22(), "AppData", "Roaming");
3956
+ return join23(appData, "Cursor", STATE_DB_RELATIVE);
3705
3957
  }
3706
- const xdgConfigHome = process.env.XDG_CONFIG_HOME?.trim() || join22(homedir21(), ".config");
3707
- return join22(xdgConfigHome, "Cursor", STATE_DB_RELATIVE);
3958
+ const xdgConfigHome = process.env.XDG_CONFIG_HOME?.trim() || join23(homedir22(), ".config");
3959
+ return join23(xdgConfigHome, "Cursor", STATE_DB_RELATIVE);
3708
3960
  }
3709
3961
  function getCursorStateDbPath() {
3710
3962
  const explicit = process.env.CURSOR_STATE_DB_PATH?.trim();
3711
3963
  if (explicit) {
3712
3964
  const resolved = resolve2(explicit);
3713
- return existsSync20(resolved) ? resolved : null;
3965
+ return existsSync21(resolved) ? resolved : null;
3714
3966
  }
3715
3967
  const configDirs = process.env.CURSOR_CONFIG_DIR?.trim();
3716
3968
  const candidates = configDirs ? configDirs.split(",").map((v) => v.trim()).filter(Boolean).map((v) => {
3717
3969
  const r = resolve2(v);
3718
- return r.endsWith(".vscdb") ? r : join22(r, STATE_DB_RELATIVE);
3970
+ return r.endsWith(".vscdb") ? r : join23(r, STATE_DB_RELATIVE);
3719
3971
  }) : [getDefaultStateDbPath()];
3720
3972
  for (const c of candidates) {
3721
- if (existsSync20(c)) return c;
3973
+ if (existsSync21(c)) return c;
3722
3974
  }
3723
3975
  return null;
3724
3976
  }
@@ -3758,13 +4010,13 @@ function readAccessToken(dbPath) {
3758
4010
  return queryAccessToken(dbPath);
3759
4011
  } catch (err) {
3760
4012
  if (!isLockError2(err)) throw err;
3761
- const snapshotDir = mkdtempSync2(join22(tmpdir2(), "tokenarena-cursor-"));
3762
- const queryPath = join22(snapshotDir, "state.vscdb");
4013
+ const snapshotDir = mkdtempSync2(join23(tmpdir2(), "tokenarena-cursor-"));
4014
+ const queryPath = join23(snapshotDir, "state.vscdb");
3763
4015
  try {
3764
4016
  copyFileSync2(dbPath, queryPath);
3765
4017
  for (const suffix of ["-shm", "-wal"]) {
3766
4018
  const companion = `${dbPath}${suffix}`;
3767
- if (existsSync20(companion))
4019
+ if (existsSync21(companion))
3768
4020
  copyFileSync2(companion, `${queryPath}${suffix}`);
3769
4021
  }
3770
4022
  return queryAccessToken(queryPath);
@@ -3892,8 +4144,8 @@ function parseInt0(value) {
3892
4144
  }
3893
4145
  function createToolDefinition10(dbPath) {
3894
4146
  return {
3895
- id: TOOL_ID13,
3896
- name: TOOL_NAME13,
4147
+ id: TOOL_ID14,
4148
+ name: TOOL_NAME14,
3897
4149
  dataDir: dirname4(dbPath)
3898
4150
  };
3899
4151
  }
@@ -3909,7 +4161,7 @@ var CursorParser = class {
3909
4161
  this.tool = createToolDefinition10(this.dbPath);
3910
4162
  }
3911
4163
  async parse() {
3912
- if (!this.dbPath || !existsSync20(this.dbPath)) {
4164
+ if (!this.dbPath || !existsSync21(this.dbPath)) {
3913
4165
  return { buckets: [], sessions: [] };
3914
4166
  }
3915
4167
  let token;
@@ -3956,7 +4208,7 @@ var CursorParser = class {
3956
4208
  const output = outputIdx >= 0 ? parseInt0(row[outputIdx]) : 0;
3957
4209
  if (inputCacheWrite + inputNoCache + cacheRead + output === 0) continue;
3958
4210
  entries.push({
3959
- source: TOOL_ID13,
4211
+ source: TOOL_ID14,
3960
4212
  model,
3961
4213
  project: "unknown",
3962
4214
  timestamp,
@@ -3972,19 +4224,19 @@ var CursorParser = class {
3972
4224
  };
3973
4225
  }
3974
4226
  isInstalled() {
3975
- return existsSync20(this.dbPath);
4227
+ return existsSync21(this.dbPath);
3976
4228
  }
3977
4229
  };
3978
4230
  registerParser(new CursorParser());
3979
4231
 
3980
4232
  // src/parsers/zcode.ts
3981
- import { createHash as createHash2 } from "crypto";
3982
- import { existsSync as existsSync21 } from "fs";
3983
- import { homedir as homedir22, hostname as hostname4 } from "os";
3984
- import { dirname as dirname5, join as join23 } from "path";
3985
- var TOOL_ID14 = "zcode";
3986
- var TOOL_NAME14 = "ZCode";
3987
- var DEFAULT_DB_PATH3 = join23(homedir22(), ".zcode", "cli", "db", "db.sqlite");
4233
+ import { createHash as createHash3 } from "crypto";
4234
+ import { existsSync as existsSync22 } from "fs";
4235
+ import { homedir as homedir23, hostname as hostname5 } from "os";
4236
+ import { dirname as dirname5, join as join24 } from "path";
4237
+ var TOOL_ID15 = "zcode";
4238
+ var TOOL_NAME15 = "ZCode";
4239
+ var DEFAULT_DB_PATH3 = join24(homedir23(), ".zcode", "cli", "db", "db.sqlite");
3988
4240
  var MODEL_USAGE_QUERY = `SELECT
3989
4241
  model_usage.session_id as sessionId,
3990
4242
  session.directory as directory,
@@ -4019,8 +4271,8 @@ var TURN_USAGE_QUERY = `SELECT
4019
4271
  WHERE duration_ms IS NOT NULL`;
4020
4272
  function createToolDefinition11(dbPath) {
4021
4273
  return {
4022
- id: TOOL_ID14,
4023
- name: TOOL_NAME14,
4274
+ id: TOOL_ID15,
4275
+ name: TOOL_NAME15,
4024
4276
  dataDir: dirname5(dbPath)
4025
4277
  };
4026
4278
  }
@@ -4028,7 +4280,7 @@ function toSafeNumber11(value) {
4028
4280
  const numberValue = Number(value);
4029
4281
  return Number.isFinite(numberValue) && numberValue > 0 ? numberValue : 0;
4030
4282
  }
4031
- function getString2(value) {
4283
+ function getString3(value) {
4032
4284
  return typeof value === "string" && value.length > 0 ? value : null;
4033
4285
  }
4034
4286
  function parseUnixMillis(value) {
@@ -4039,7 +4291,7 @@ function parseUnixMillis(value) {
4039
4291
  const timestamp = new Date(numberValue);
4040
4292
  return Number.isNaN(timestamp.getTime()) ? null : timestamp;
4041
4293
  }
4042
- function getPathLeaf7(value) {
4294
+ function getPathLeaf8(value) {
4043
4295
  if (!value) {
4044
4296
  return "unknown";
4045
4297
  }
@@ -4068,7 +4320,7 @@ function getOrCreateDraft(drafts, sessionId, project) {
4068
4320
  }
4069
4321
  const next = {
4070
4322
  sessionId,
4071
- source: TOOL_ID14,
4323
+ source: TOOL_ID15,
4072
4324
  project,
4073
4325
  firstMessageAt: null,
4074
4326
  lastMessageAt: null,
@@ -4082,7 +4334,7 @@ function getOrCreateDraft(drafts, sessionId, project) {
4082
4334
  drafts.set(sessionId, next);
4083
4335
  return next;
4084
4336
  }
4085
- function buildSessionUsage2(entries) {
4337
+ function buildSessionUsage3(entries) {
4086
4338
  const usageBySession = /* @__PURE__ */ new Map();
4087
4339
  for (const entry of entries) {
4088
4340
  if (!entry.sessionId || hasInvalidTokenCounts(entry)) {
@@ -4114,23 +4366,23 @@ function buildSessionUsage2(entries) {
4114
4366
  }
4115
4367
  return usageBySession;
4116
4368
  }
4117
- function buildSessions(input2) {
4369
+ function buildSessions2(input2) {
4118
4370
  const drafts = /* @__PURE__ */ new Map();
4119
4371
  for (const row of input2.sessionRows) {
4120
- const sessionId = getString2(row.id);
4372
+ const sessionId = getString3(row.id);
4121
4373
  if (!sessionId) {
4122
4374
  continue;
4123
4375
  }
4124
4376
  const draft = getOrCreateDraft(
4125
4377
  drafts,
4126
4378
  sessionId,
4127
- getPathLeaf7(getString2(row.directory))
4379
+ getPathLeaf8(getString3(row.directory))
4128
4380
  );
4129
4381
  draft.fallbackFirstAt = parseUnixMillis(row.timeCreated);
4130
4382
  draft.fallbackLastAt = parseUnixMillis(row.timeUpdated);
4131
4383
  }
4132
4384
  for (const row of input2.messageRows) {
4133
- const sessionId = getString2(row.sessionId);
4385
+ const sessionId = getString3(row.sessionId);
4134
4386
  if (!sessionId) {
4135
4387
  continue;
4136
4388
  }
@@ -4157,15 +4409,15 @@ function buildSessions(input2) {
4157
4409
  }
4158
4410
  }
4159
4411
  for (const row of input2.turnRows) {
4160
- const sessionId = getString2(row.sessionId);
4412
+ const sessionId = getString3(row.sessionId);
4161
4413
  if (!sessionId) {
4162
4414
  continue;
4163
4415
  }
4164
4416
  const draft = getOrCreateDraft(drafts, sessionId, "unknown");
4165
4417
  draft.activeSeconds += Math.round(toSafeNumber11(row.durationMs) / 1e3);
4166
4418
  }
4167
- const usageBySession = buildSessionUsage2(input2.entries);
4168
- const host = hostname4().replace(/\.local$/, "");
4419
+ const usageBySession = buildSessionUsage3(input2.entries);
4420
+ const host = hostname5().replace(/\.local$/, "");
4169
4421
  return Array.from(drafts.values()).map((draft) => {
4170
4422
  const firstMessageAt = draft.firstMessageAt ?? draft.fallbackFirstAt;
4171
4423
  const lastMessageAt = draft.lastMessageAt ?? draft.fallbackLastAt ?? firstMessageAt;
@@ -4207,7 +4459,7 @@ function buildSessions(input2) {
4207
4459
  return {
4208
4460
  source: draft.source,
4209
4461
  project: draft.project,
4210
- sessionHash: createHash2("sha256").update(draft.sessionId).digest("hex").slice(0, 16),
4462
+ sessionHash: createHash3("sha256").update(draft.sessionId).digest("hex").slice(0, 16),
4211
4463
  hostname: host,
4212
4464
  firstMessageAt: firstMessageAt.toISOString(),
4213
4465
  lastMessageAt: lastMessageAt.toISOString(),
@@ -4238,7 +4490,7 @@ var ZCodeParser = class {
4238
4490
  this.tool = createToolDefinition11(this.dbPath);
4239
4491
  }
4240
4492
  async parse() {
4241
- if (!existsSync21(this.dbPath)) {
4493
+ if (!existsSync22(this.dbPath)) {
4242
4494
  return { buckets: [], sessions: [] };
4243
4495
  }
4244
4496
  const usageRows = await this.queryRows(
@@ -4259,10 +4511,10 @@ var ZCodeParser = class {
4259
4511
  continue;
4260
4512
  }
4261
4513
  entries.push({
4262
- sessionId: getString2(row.sessionId) ?? void 0,
4263
- source: TOOL_ID14,
4264
- model: getString2(row.model) ?? "unknown",
4265
- project: getPathLeaf7(getString2(row.directory)),
4514
+ sessionId: getString3(row.sessionId) ?? void 0,
4515
+ source: TOOL_ID15,
4516
+ model: getString3(row.model) ?? "unknown",
4517
+ project: getPathLeaf8(getString3(row.directory)),
4266
4518
  timestamp,
4267
4519
  inputTokens,
4268
4520
  outputTokens,
@@ -4287,7 +4539,7 @@ var ZCodeParser = class {
4287
4539
  }
4288
4540
  return {
4289
4541
  buckets: aggregateToBuckets(entries),
4290
- sessions: buildSessions({
4542
+ sessions: buildSessions2({
4291
4543
  sessionRows,
4292
4544
  messageRows,
4293
4545
  turnRows,
@@ -4296,27 +4548,27 @@ var ZCodeParser = class {
4296
4548
  };
4297
4549
  }
4298
4550
  isInstalled() {
4299
- return existsSync21(this.dbPath);
4551
+ return existsSync22(this.dbPath);
4300
4552
  }
4301
4553
  };
4302
4554
  registerParser(new ZCodeParser());
4303
4555
 
4304
4556
  // src/parsers/qodercli.ts
4305
- import { existsSync as existsSync22, readdirSync as readdirSync12 } from "fs";
4306
- import { homedir as homedir23 } from "os";
4307
- import { basename as basename9, join as join24 } from "path";
4308
- var TOOL_ID15 = "qodercli";
4309
- var TOOL_NAME15 = "Qoder CLI";
4310
- var DEFAULT_PROJECTS_DIR = join24(homedir23(), ".qoder", "projects");
4311
- var DEFAULT_LOGS_DIR = join24(homedir23(), ".qoder", "logs", "sessions");
4312
- var DEFAULT_RUNS_DIR = join24(homedir23(), ".qoder", "logs", "runs");
4557
+ import { existsSync as existsSync23, readdirSync as readdirSync12 } from "fs";
4558
+ import { homedir as homedir24 } from "os";
4559
+ import { basename as basename9, join as join25 } from "path";
4560
+ var TOOL_ID16 = "qodercli";
4561
+ var TOOL_NAME16 = "Qoder CLI";
4562
+ var DEFAULT_PROJECTS_DIR = join25(homedir24(), ".qoder", "projects");
4563
+ var DEFAULT_LOGS_DIR = join25(homedir24(), ".qoder", "logs", "sessions");
4564
+ var DEFAULT_RUNS_DIR = join25(homedir24(), ".qoder", "logs", "runs");
4313
4565
  var CLI_ENTRYPOINT = "cli";
4314
4566
  var IDE_ENTRYPOINT = "acp";
4315
4567
  var CREDIT_MODEL_FALLBACK = "credits";
4316
4568
  function createToolDefinition12(projectsDir) {
4317
4569
  return {
4318
- id: TOOL_ID15,
4319
- name: TOOL_NAME15,
4570
+ id: TOOL_ID16,
4571
+ name: TOOL_NAME16,
4320
4572
  dataDir: projectsDir
4321
4573
  };
4322
4574
  }
@@ -4355,13 +4607,13 @@ function classifyQoderEntrypoint(content) {
4355
4607
  return "unknown";
4356
4608
  }
4357
4609
  function isQodercliBinaryPresent() {
4358
- const home = homedir23();
4610
+ const home = homedir24();
4359
4611
  const candidates = [
4360
- join24(home, ".local", "bin", "qodercli"),
4361
- join24(home, ".qoder", "bin", "qodercli"),
4362
- join24(home, ".qoder-cli")
4612
+ join25(home, ".local", "bin", "qodercli"),
4613
+ join25(home, ".qoder", "bin", "qodercli"),
4614
+ join25(home, ".qoder-cli")
4363
4615
  ];
4364
- return candidates.some((path) => existsSync22(path));
4616
+ return candidates.some((path) => existsSync23(path));
4365
4617
  }
4366
4618
  function projectFromEncodedSlug(slug) {
4367
4619
  const parts = slug.split("-").filter(Boolean);
@@ -4432,7 +4684,7 @@ function creditSnapshotsToEntries(snapshots) {
4432
4684
  if (creditDelta > 0) {
4433
4685
  entries.push({
4434
4686
  sessionId: snap.sessionId,
4435
- source: TOOL_ID15,
4687
+ source: TOOL_ID16,
4436
4688
  model: snap.model || CREDIT_MODEL_FALLBACK,
4437
4689
  project: snap.project,
4438
4690
  timestamp: snap.timestamp,
@@ -4470,7 +4722,7 @@ var QoderCliParser = class {
4470
4722
  };
4471
4723
  }
4472
4724
  parseProjectSessions(sessionEvents) {
4473
- if (!existsSync22(this.projectsDir)) return;
4725
+ if (!existsSync23(this.projectsDir)) return;
4474
4726
  for (const filePath of findJsonlFiles(this.projectsDir)) {
4475
4727
  if (basename9(filePath).startsWith("verified-")) continue;
4476
4728
  const content = readFileSafe(filePath);
@@ -4492,7 +4744,7 @@ var QoderCliParser = class {
4492
4744
  if (Number.isNaN(ts.getTime())) continue;
4493
4745
  sessionEvents.push({
4494
4746
  sessionId,
4495
- source: TOOL_ID15,
4747
+ source: TOOL_ID16,
4496
4748
  project,
4497
4749
  timestamp: ts,
4498
4750
  role: obj.type === "user" ? "user" : "assistant"
@@ -4507,7 +4759,7 @@ var QoderCliParser = class {
4507
4759
  * There is no token data here — only quota/usage credit totals.
4508
4760
  */
4509
4761
  parseCreditDeltas() {
4510
- if (!existsSync22(this.runsDir)) return [];
4762
+ if (!existsSync23(this.runsDir)) return [];
4511
4763
  let runDirs;
4512
4764
  try {
4513
4765
  runDirs = readdirSync12(this.runsDir, { withFileTypes: true }).filter(
@@ -4518,15 +4770,15 @@ var QoderCliParser = class {
4518
4770
  }
4519
4771
  const allSnapshots = [];
4520
4772
  for (const dir of runDirs) {
4521
- const runPath = join24(this.runsDir, dir.name);
4522
- const logPath = join24(runPath, "qodercli.log");
4523
- if (!existsSync22(logPath)) continue;
4773
+ const runPath = join25(this.runsDir, dir.name);
4774
+ const logPath = join25(runPath, "qodercli.log");
4775
+ if (!existsSync23(logPath)) continue;
4524
4776
  const logContent = readFileSafe(logPath);
4525
4777
  if (!logContent?.includes("quota/usage response:")) {
4526
4778
  continue;
4527
4779
  }
4528
4780
  const manifest = parseRunManifest(
4529
- readFileSafe(join24(runPath, "manifest.json"))
4781
+ readFileSafe(join25(runPath, "manifest.json"))
4530
4782
  );
4531
4783
  const project = manifest?.project_id ? projectFromEncodedSlug(manifest.project_id) : projectFromCwd(manifest?.cwd);
4532
4784
  const snapshots = extractCreditSnapshotsFromLog(logContent, {
@@ -4538,22 +4790,22 @@ var QoderCliParser = class {
4538
4790
  return creditSnapshotsToEntries(allSnapshots);
4539
4791
  }
4540
4792
  isInstalled() {
4541
- return isQodercliBinaryPresent() || existsSync22(this.runsDir) || existsSync22(this.logsDir) || existsSync22(this.projectsDir);
4793
+ return isQodercliBinaryPresent() || existsSync23(this.runsDir) || existsSync23(this.logsDir) || existsSync23(this.projectsDir);
4542
4794
  }
4543
4795
  };
4544
4796
  registerParser(new QoderCliParser());
4545
4797
 
4546
4798
  // src/parsers/grok-build.ts
4547
- import { existsSync as existsSync23, readdirSync as readdirSync13 } from "fs";
4548
- import { homedir as homedir24 } from "os";
4549
- import { basename as basename10, join as join25 } from "path";
4550
- var TOOL_ID16 = "grok-build";
4551
- var TOOL_NAME16 = "Grok Build";
4552
- var DEFAULT_DATA_DIR7 = join25(homedir24(), ".grok", "sessions");
4799
+ import { existsSync as existsSync24, readdirSync as readdirSync13 } from "fs";
4800
+ import { homedir as homedir25 } from "os";
4801
+ import { basename as basename10, join as join26 } from "path";
4802
+ var TOOL_ID17 = "grok-build";
4803
+ var TOOL_NAME17 = "Grok Build";
4804
+ var DEFAULT_DATA_DIR7 = join26(homedir25(), ".grok", "sessions");
4553
4805
  function createToolDefinition13(dataDir) {
4554
4806
  return {
4555
- id: TOOL_ID16,
4556
- name: TOOL_NAME16,
4807
+ id: TOOL_ID17,
4808
+ name: TOOL_NAME17,
4557
4809
  dataDir
4558
4810
  };
4559
4811
  }
@@ -4600,7 +4852,7 @@ function pushUsageEntries(entries, args) {
4600
4852
  }
4601
4853
  entries.push({
4602
4854
  sessionId,
4603
- source: TOOL_ID16,
4855
+ source: TOOL_ID17,
4604
4856
  model: model || fallbackModel || "unknown",
4605
4857
  project,
4606
4858
  timestamp,
@@ -4613,7 +4865,7 @@ function pushUsageEntries(entries, args) {
4613
4865
  }
4614
4866
  function findSessionDirs(dataDir) {
4615
4867
  const results = [];
4616
- if (!existsSync23(dataDir)) return results;
4868
+ if (!existsSync24(dataDir)) return results;
4617
4869
  let projectDirs;
4618
4870
  try {
4619
4871
  projectDirs = readdirSync13(dataDir, { withFileTypes: true });
@@ -4623,7 +4875,7 @@ function findSessionDirs(dataDir) {
4623
4875
  for (const projectEntry of projectDirs) {
4624
4876
  if (!projectEntry.isDirectory()) continue;
4625
4877
  if (projectEntry.name.endsWith(".sqlite")) continue;
4626
- const projectDir = join25(dataDir, projectEntry.name);
4878
+ const projectDir = join26(dataDir, projectEntry.name);
4627
4879
  const project = projectFromEncodedCwd(projectEntry.name);
4628
4880
  let sessionEntries;
4629
4881
  try {
@@ -4633,8 +4885,8 @@ function findSessionDirs(dataDir) {
4633
4885
  }
4634
4886
  for (const sessionEntry of sessionEntries) {
4635
4887
  if (!sessionEntry.isDirectory()) continue;
4636
- const sessionDir = join25(projectDir, sessionEntry.name);
4637
- if (!existsSync23(join25(sessionDir, "updates.jsonl"))) continue;
4888
+ const sessionDir = join26(projectDir, sessionEntry.name);
4889
+ if (!existsSync24(join26(sessionDir, "updates.jsonl"))) continue;
4638
4890
  results.push({
4639
4891
  sessionDir,
4640
4892
  project,
@@ -4645,7 +4897,7 @@ function findSessionDirs(dataDir) {
4645
4897
  return results;
4646
4898
  }
4647
4899
  function readFallbackModel(sessionDir) {
4648
- const summaryPath = join25(sessionDir, "summary.json");
4900
+ const summaryPath = join26(sessionDir, "summary.json");
4649
4901
  const content = readFileSafe(summaryPath);
4650
4902
  if (!content) return "unknown";
4651
4903
  try {
@@ -4667,7 +4919,7 @@ var GrokBuildParser = class {
4667
4919
  const sessionEvents = [];
4668
4920
  const sessions = findSessionDirs(this.dataDir);
4669
4921
  for (const { sessionDir, project, sessionId } of sessions) {
4670
- const updatesPath = join25(sessionDir, "updates.jsonl");
4922
+ const updatesPath = join26(sessionDir, "updates.jsonl");
4671
4923
  const content = readFileSafe(updatesPath);
4672
4924
  if (!content) continue;
4673
4925
  const fallbackModel = readFallbackModel(sessionDir);
@@ -4694,7 +4946,7 @@ var GrokBuildParser = class {
4694
4946
  seenUserPrompts.add(key);
4695
4947
  sessionEvents.push({
4696
4948
  sessionId: sid,
4697
- source: TOOL_ID16,
4949
+ source: TOOL_ID17,
4698
4950
  project,
4699
4951
  timestamp: ts,
4700
4952
  role: "user"
@@ -4705,7 +4957,7 @@ var GrokBuildParser = class {
4705
4957
  seenUserPrompts.delete(ANON_USER_OPEN);
4706
4958
  sessionEvents.push({
4707
4959
  sessionId: sid,
4708
- source: TOOL_ID16,
4960
+ source: TOOL_ID17,
4709
4961
  project,
4710
4962
  timestamp: ts,
4711
4963
  role: "assistant"
@@ -4727,22 +4979,22 @@ var GrokBuildParser = class {
4727
4979
  };
4728
4980
  }
4729
4981
  isInstalled() {
4730
- return existsSync23(this.dataDir) || existsSync23(join25(homedir24(), ".grok")) || existsSync23(join25(homedir24(), ".local", "bin", "grok"));
4982
+ return existsSync24(this.dataDir) || existsSync24(join26(homedir25(), ".grok")) || existsSync24(join26(homedir25(), ".local", "bin", "grok"));
4731
4983
  }
4732
4984
  };
4733
4985
  registerParser(new GrokBuildParser());
4734
4986
 
4735
4987
  // src/parsers/atomcode.ts
4736
- import { existsSync as existsSync24 } from "fs";
4737
- import { homedir as homedir25 } from "os";
4738
- import { basename as basename11, join as join26 } from "path";
4739
- var TOOL_ID17 = "atomcode";
4740
- var TOOL_NAME17 = "AtomCode";
4741
- var DEFAULT_SESSIONS_DIR6 = join26(homedir25(), ".atomcode", "sessions");
4988
+ import { existsSync as existsSync25 } from "fs";
4989
+ import { homedir as homedir26 } from "os";
4990
+ import { basename as basename11, join as join27 } from "path";
4991
+ var TOOL_ID18 = "atomcode";
4992
+ var TOOL_NAME18 = "AtomCode";
4993
+ var DEFAULT_SESSIONS_DIR6 = join27(homedir26(), ".atomcode", "sessions");
4742
4994
  function getAtomCodeSessionsDirs(env = process.env) {
4743
4995
  const dirs = [
4744
4996
  env.TOKEN_ARENA_ATOMCODE_DIR,
4745
- env.ATOMCODE_HOME ? join26(env.ATOMCODE_HOME, "sessions") : void 0,
4997
+ env.ATOMCODE_HOME ? join27(env.ATOMCODE_HOME, "sessions") : void 0,
4746
4998
  DEFAULT_SESSIONS_DIR6
4747
4999
  ].filter((value) => Boolean(value));
4748
5000
  return Array.from(new Set(dirs));
@@ -4800,8 +5052,8 @@ var AtomCodeParser = class {
4800
5052
  constructor(sessionsDir) {
4801
5053
  this.sessionsDirs = sessionsDir ? [sessionsDir] : getAtomCodeSessionsDirs();
4802
5054
  this.tool = {
4803
- id: TOOL_ID17,
4804
- name: TOOL_NAME17,
5055
+ id: TOOL_ID18,
5056
+ name: TOOL_NAME18,
4805
5057
  dataDir: this.sessionsDirs[0] ?? DEFAULT_SESSIONS_DIR6
4806
5058
  };
4807
5059
  }
@@ -4828,7 +5080,7 @@ var AtomCodeParser = class {
4828
5080
  if (row.user !== void 0 || row.assistant !== void 0) {
4829
5081
  sessionEvents.push({
4830
5082
  sessionId,
4831
- source: TOOL_ID17,
5083
+ source: TOOL_ID18,
4832
5084
  project,
4833
5085
  timestamp,
4834
5086
  role: row.user !== void 0 ? "user" : "assistant"
@@ -4857,7 +5109,7 @@ var AtomCodeParser = class {
4857
5109
  seenEntryKeys.add(entryKey);
4858
5110
  entries.push({
4859
5111
  sessionId,
4860
- source: TOOL_ID17,
5112
+ source: TOOL_ID18,
4861
5113
  model,
4862
5114
  project,
4863
5115
  timestamp,
@@ -4875,24 +5127,24 @@ var AtomCodeParser = class {
4875
5127
  };
4876
5128
  }
4877
5129
  isInstalled() {
4878
- return this.sessionsDirs.some((dir) => existsSync24(dir));
5130
+ return this.sessionsDirs.some((dir) => existsSync25(dir));
4879
5131
  }
4880
5132
  };
4881
5133
  registerParser(new AtomCodeParser());
4882
5134
 
4883
5135
  // src/parsers/dsh.ts
4884
- import { existsSync as existsSync25, readdirSync as readdirSync14, readFileSync as readFileSync9 } from "fs";
4885
- import { homedir as homedir26 } from "os";
4886
- import { basename as basename12, join as join27 } from "path";
5136
+ import { existsSync as existsSync26, readdirSync as readdirSync14, readFileSync as readFileSync9 } from "fs";
5137
+ import { homedir as homedir27 } from "os";
5138
+ import { basename as basename12, join as join28 } from "path";
4887
5139
  import * as zlib from "zlib";
4888
- var TOOL_ID18 = "dsh";
4889
- var TOOL_NAME18 = "DeepSeek Harness";
4890
- var DEFAULT_SESSIONS_DIR7 = join27(homedir26(), ".dsh", "sessions");
5140
+ var TOOL_ID19 = "dsh";
5141
+ var TOOL_NAME19 = "DeepSeek Harness";
5142
+ var DEFAULT_SESSIONS_DIR7 = join28(homedir27(), ".dsh", "sessions");
4891
5143
  var LOG_BASENAME = "session";
4892
5144
  function getDshSessionsDirs(env = process.env) {
4893
5145
  const dirs = [
4894
5146
  env.TOKEN_ARENA_DSH_DIR,
4895
- env.DSH_HOME ? join27(env.DSH_HOME, "sessions") : void 0,
5147
+ env.DSH_HOME ? join28(env.DSH_HOME, "sessions") : void 0,
4896
5148
  DEFAULT_SESSIONS_DIR7
4897
5149
  ].filter((value) => Boolean(value));
4898
5150
  return Array.from(new Set(dirs));
@@ -4981,10 +5233,10 @@ function readSessionLog(filePath) {
4981
5233
  }
4982
5234
  function findSessionLogs(dir) {
4983
5235
  const results = [];
4984
- if (!existsSync25(dir)) return results;
5236
+ if (!existsSync26(dir)) return results;
4985
5237
  try {
4986
5238
  for (const entry of readdirSync14(dir, { withFileTypes: true })) {
4987
- const fullPath = join27(dir, entry.name);
5239
+ const fullPath = join28(dir, entry.name);
4988
5240
  if (entry.isDirectory()) {
4989
5241
  results.push(...findSessionLogs(fullPath));
4990
5242
  } else if (entry.name === `${LOG_BASENAME}.jsonl` || entry.name === `${LOG_BASENAME}.jsonl.zstd`) {
@@ -5015,8 +5267,8 @@ var DshParser = class {
5015
5267
  constructor(sessionsDir) {
5016
5268
  this.sessionsDirs = sessionsDir ? [sessionsDir] : getDshSessionsDirs();
5017
5269
  this.tool = {
5018
- id: TOOL_ID18,
5019
- name: TOOL_NAME18,
5270
+ id: TOOL_ID19,
5271
+ name: TOOL_NAME19,
5020
5272
  dataDir: this.sessionsDirs[0] ?? DEFAULT_SESSIONS_DIR7
5021
5273
  };
5022
5274
  }
@@ -5053,7 +5305,7 @@ var DshParser = class {
5053
5305
  if (timestamp) {
5054
5306
  sessionEvents.push({
5055
5307
  sessionId,
5056
- source: TOOL_ID18,
5308
+ source: TOOL_ID19,
5057
5309
  project,
5058
5310
  timestamp,
5059
5311
  role: "user"
@@ -5066,7 +5318,7 @@ var DshParser = class {
5066
5318
  if (timestamp && !isCompaction) {
5067
5319
  sessionEvents.push({
5068
5320
  sessionId,
5069
- source: TOOL_ID18,
5321
+ source: TOOL_ID19,
5070
5322
  project,
5071
5323
  timestamp,
5072
5324
  role: "assistant"
@@ -5097,7 +5349,7 @@ var DshParser = class {
5097
5349
  seenEntryKeys.add(entryKey);
5098
5350
  entries.push({
5099
5351
  sessionId,
5100
- source: TOOL_ID18,
5352
+ source: TOOL_ID19,
5101
5353
  model,
5102
5354
  project,
5103
5355
  timestamp,
@@ -5115,7 +5367,7 @@ var DshParser = class {
5115
5367
  };
5116
5368
  }
5117
5369
  isInstalled() {
5118
- return this.sessionsDirs.some((dir) => existsSync25(dir));
5370
+ return this.sessionsDirs.some((dir) => existsSync26(dir));
5119
5371
  }
5120
5372
  };
5121
5373
  registerParser(new DshParser());
@@ -5126,31 +5378,31 @@ import { Command, Option } from "commander";
5126
5378
  // src/infrastructure/config/manager.ts
5127
5379
  import { randomUUID } from "crypto";
5128
5380
  import {
5129
- existsSync as existsSync26,
5381
+ existsSync as existsSync27,
5130
5382
  mkdirSync,
5131
5383
  readFileSync as readFileSync10,
5132
5384
  unlinkSync,
5133
5385
  writeFileSync
5134
5386
  } from "fs";
5135
- import { join as join29 } from "path";
5387
+ import { join as join30 } from "path";
5136
5388
 
5137
5389
  // src/infrastructure/xdg.ts
5138
- import { homedir as homedir27 } from "os";
5139
- import { join as join28 } from "path";
5390
+ import { homedir as homedir28 } from "os";
5391
+ import { join as join29 } from "path";
5140
5392
  function getConfigHome() {
5141
- return process.env.XDG_CONFIG_HOME || join28(homedir27(), ".config");
5393
+ return process.env.XDG_CONFIG_HOME || join29(homedir28(), ".config");
5142
5394
  }
5143
5395
  function getStateHome() {
5144
- return process.env.XDG_STATE_HOME || join28(homedir27(), ".local", "state");
5396
+ return process.env.XDG_STATE_HOME || join29(homedir28(), ".local", "state");
5145
5397
  }
5146
5398
  function getRuntimeDir() {
5147
5399
  return process.env.XDG_RUNTIME_DIR || getStateHome();
5148
5400
  }
5149
5401
 
5150
5402
  // src/infrastructure/config/manager.ts
5151
- var CONFIG_DIR = join29(getConfigHome(), "tokenarena");
5403
+ var CONFIG_DIR = join30(getConfigHome(), "tokenarena");
5152
5404
  var isDev = process.env.TOKEN_ARENA_DEV === "1";
5153
- var CONFIG_FILE = join29(CONFIG_DIR, isDev ? "config.dev.json" : "config.json");
5405
+ var CONFIG_FILE = join30(CONFIG_DIR, isDev ? "config.dev.json" : "config.json");
5154
5406
  var DEFAULT_API_URL = "https://token.guji.uno";
5155
5407
  var VALID_CONFIG_KEYS = [
5156
5408
  "apiKey",
@@ -5166,7 +5418,7 @@ function getConfigDir() {
5166
5418
  return CONFIG_DIR;
5167
5419
  }
5168
5420
  function loadConfig() {
5169
- if (!existsSync26(CONFIG_FILE)) return null;
5421
+ if (!existsSync27(CONFIG_FILE)) return null;
5170
5422
  try {
5171
5423
  const raw = readFileSync10(CONFIG_FILE, "utf-8");
5172
5424
  const config = JSON.parse(raw);
@@ -5184,7 +5436,7 @@ function saveConfig(config) {
5184
5436
  `, "utf-8");
5185
5437
  }
5186
5438
  function deleteConfig() {
5187
- if (existsSync26(CONFIG_FILE)) {
5439
+ if (existsSync27(CONFIG_FILE)) {
5188
5440
  unlinkSync(CONFIG_FILE);
5189
5441
  }
5190
5442
  }
@@ -5644,7 +5896,7 @@ async function handleConfig(args) {
5644
5896
  }
5645
5897
 
5646
5898
  // src/services/sync-service.ts
5647
- import { hostname as hostname5 } from "os";
5899
+ import { hostname as hostname6 } from "os";
5648
5900
 
5649
5901
  // src/domain/project-identity.ts
5650
5902
  import { createHmac } from "crypto";
@@ -5663,11 +5915,11 @@ function toProjectIdentity(input2) {
5663
5915
  }
5664
5916
 
5665
5917
  // src/domain/upload-manifest.ts
5666
- import { createHash as createHash3 } from "crypto";
5918
+ import { createHash as createHash4 } from "crypto";
5667
5919
  var MANIFEST_VERSION = 1;
5668
5920
  var SNAPSHOT_PROTOCOL_VERSION = 1;
5669
5921
  function fingerprint(value) {
5670
- return createHash3("sha256").update(value).digest("hex").slice(0, 16);
5922
+ return createHash4("sha256").update(value).digest("hex").slice(0, 16);
5671
5923
  }
5672
5924
  function normalizeApiUrl(apiUrl) {
5673
5925
  let end = apiUrl.length;
@@ -6046,7 +6298,7 @@ var ApiClient = class {
6046
6298
  // src/infrastructure/runtime/lock.ts
6047
6299
  import {
6048
6300
  closeSync,
6049
- existsSync as existsSync27,
6301
+ existsSync as existsSync28,
6050
6302
  openSync,
6051
6303
  readFileSync as readFileSync11,
6052
6304
  rmSync as rmSync3,
@@ -6055,22 +6307,22 @@ import {
6055
6307
 
6056
6308
  // src/infrastructure/runtime/paths.ts
6057
6309
  import { mkdirSync as mkdirSync2 } from "fs";
6058
- import { join as join30 } from "path";
6310
+ import { join as join31 } from "path";
6059
6311
  var APP_NAME = "tokenarena";
6060
6312
  function getRuntimeDirPath() {
6061
- return join30(getRuntimeDir(), APP_NAME);
6313
+ return join31(getRuntimeDir(), APP_NAME);
6062
6314
  }
6063
6315
  function getStateDir() {
6064
- return join30(getStateHome(), APP_NAME);
6316
+ return join31(getStateHome(), APP_NAME);
6065
6317
  }
6066
6318
  function getSyncLockPath() {
6067
- return join30(getRuntimeDirPath(), "sync.lock");
6319
+ return join31(getRuntimeDirPath(), "sync.lock");
6068
6320
  }
6069
6321
  function getSyncStatePath() {
6070
- return join30(getStateDir(), "status.json");
6322
+ return join31(getStateDir(), "status.json");
6071
6323
  }
6072
6324
  function getUploadManifestPath() {
6073
- return join30(getStateDir(), "upload-manifest.json");
6325
+ return join31(getStateDir(), "upload-manifest.json");
6074
6326
  }
6075
6327
  function ensureAppDirs() {
6076
6328
  mkdirSync2(getRuntimeDirPath(), { recursive: true });
@@ -6088,7 +6340,7 @@ function isProcessAlive(pid) {
6088
6340
  }
6089
6341
  }
6090
6342
  function readLockMetadata(lockPath) {
6091
- if (!existsSync27(lockPath)) {
6343
+ if (!existsSync28(lockPath)) {
6092
6344
  return null;
6093
6345
  }
6094
6346
  try {
@@ -6162,13 +6414,13 @@ function describeExistingSyncLock() {
6162
6414
  }
6163
6415
 
6164
6416
  // src/infrastructure/runtime/state.ts
6165
- import { existsSync as existsSync28, readFileSync as readFileSync12, writeFileSync as writeFileSync3 } from "fs";
6417
+ import { existsSync as existsSync29, readFileSync as readFileSync12, writeFileSync as writeFileSync3 } from "fs";
6166
6418
  function getDefaultState() {
6167
6419
  return { status: "idle" };
6168
6420
  }
6169
6421
  function loadSyncState() {
6170
6422
  const path = getSyncStatePath();
6171
- if (!existsSync28(path)) {
6423
+ if (!existsSync29(path)) {
6172
6424
  return getDefaultState();
6173
6425
  }
6174
6426
  try {
@@ -6229,7 +6481,7 @@ function markSyncFailed(source, error, status) {
6229
6481
  }
6230
6482
 
6231
6483
  // src/infrastructure/runtime/upload-manifest.ts
6232
- import { existsSync as existsSync29, readFileSync as readFileSync13, writeFileSync as writeFileSync4 } from "fs";
6484
+ import { existsSync as existsSync30, readFileSync as readFileSync13, writeFileSync as writeFileSync4 } from "fs";
6233
6485
  function isRecordOfStrings(value) {
6234
6486
  if (!value || typeof value !== "object" || Array.isArray(value)) {
6235
6487
  return false;
@@ -6245,7 +6497,7 @@ function isUploadManifest(value) {
6245
6497
  }
6246
6498
  function loadUploadManifest() {
6247
6499
  const path = getUploadManifestPath();
6248
- if (!existsSync29(path)) {
6500
+ if (!existsSync30(path)) {
6249
6501
  return null;
6250
6502
  }
6251
6503
  try {
@@ -6367,7 +6619,7 @@ function persistUploadManifest(manifest, quiet) {
6367
6619
  function toDeviceMetadata(config) {
6368
6620
  return {
6369
6621
  deviceId: getOrCreateDeviceId(config),
6370
- hostname: hostname5().replace(/\.local$/, "")
6622
+ hostname: hostname6().replace(/\.local$/, "")
6371
6623
  };
6372
6624
  }
6373
6625
  function toUploadBuckets(buckets, settings, device) {
@@ -6785,18 +7037,18 @@ View your dashboard at: ${apiUrl}/usage`);
6785
7037
 
6786
7038
  // src/commands/init.ts
6787
7039
  import { execFileSync as execFileSync7, spawn } from "child_process";
6788
- import { existsSync as existsSync32 } from "fs";
7040
+ import { existsSync as existsSync33 } from "fs";
6789
7041
  import { appendFile, mkdir, readFile } from "fs/promises";
6790
- import { homedir as homedir30, platform as platform5 } from "os";
6791
- import { dirname as dirname6, join as join31, posix as posix3, win32 } from "path";
7042
+ import { homedir as homedir31, platform as platform5 } from "os";
7043
+ import { dirname as dirname6, join as join32, posix as posix3, win32 } from "path";
6792
7044
 
6793
7045
  // src/infrastructure/service/index.ts
6794
7046
  import { platform as platform4 } from "os";
6795
7047
 
6796
7048
  // src/infrastructure/service/linux-systemd.ts
6797
7049
  import { execFileSync as execFileSync5 } from "child_process";
6798
- import { existsSync as existsSync30, mkdirSync as mkdirSync3, rmSync as rmSync4, writeFileSync as writeFileSync5 } from "fs";
6799
- import { homedir as homedir28, platform as platform2 } from "os";
7050
+ import { existsSync as existsSync31, mkdirSync as mkdirSync3, rmSync as rmSync4, writeFileSync as writeFileSync5 } from "fs";
7051
+ import { homedir as homedir29, platform as platform2 } from "os";
6800
7052
  import { posix } from "path";
6801
7053
 
6802
7054
  // src/utils/command.ts
@@ -6865,10 +7117,10 @@ function escapeXml(value) {
6865
7117
 
6866
7118
  // src/infrastructure/service/linux-systemd.ts
6867
7119
  var SYSTEMD_SERVICE_NAME = "tokenarena";
6868
- function getLinuxSystemdServiceDir(homePath = homedir28()) {
7120
+ function getLinuxSystemdServiceDir(homePath = homedir29()) {
6869
7121
  return posix.join(homePath, ".config", "systemd", "user");
6870
7122
  }
6871
- function getLinuxSystemdServiceFile(homePath = homedir28()) {
7123
+ function getLinuxSystemdServiceFile(homePath = homedir29()) {
6872
7124
  return posix.join(
6873
7125
  getLinuxSystemdServiceDir(homePath),
6874
7126
  `${SYSTEMD_SERVICE_NAME}.service`
@@ -6925,7 +7177,7 @@ function ensureSystemdAvailable() {
6925
7177
  }
6926
7178
  function createLinuxSystemdServiceBackend() {
6927
7179
  function isInstalled() {
6928
- return existsSync30(getLinuxSystemdServiceFile());
7180
+ return existsSync31(getLinuxSystemdServiceFile());
6929
7181
  }
6930
7182
  async function setup(skipPrompt = false) {
6931
7183
  if (!ensureSystemdAvailable()) {
@@ -7050,7 +7302,7 @@ function createLinuxSystemdServiceBackend() {
7050
7302
  }
7051
7303
  async function uninstall(skipPrompt = false) {
7052
7304
  const serviceFile = getLinuxSystemdServiceFile();
7053
- if (!existsSync30(serviceFile)) {
7305
+ if (!existsSync31(serviceFile)) {
7054
7306
  logger.info(formatBullet("\u670D\u52A1\u6587\u4EF6\u4E0D\u5B58\u5728\u3002", "warning"));
7055
7307
  return;
7056
7308
  }
@@ -7111,17 +7363,17 @@ function createLinuxSystemdServiceBackend() {
7111
7363
 
7112
7364
  // src/infrastructure/service/macos-launchd.ts
7113
7365
  import { execFileSync as execFileSync6 } from "child_process";
7114
- import { existsSync as existsSync31, mkdirSync as mkdirSync4, rmSync as rmSync5, writeFileSync as writeFileSync6 } from "fs";
7115
- import { homedir as homedir29, platform as platform3 } from "os";
7366
+ import { existsSync as existsSync32, mkdirSync as mkdirSync4, rmSync as rmSync5, writeFileSync as writeFileSync6 } from "fs";
7367
+ import { homedir as homedir30, platform as platform3 } from "os";
7116
7368
  import { posix as posix2 } from "path";
7117
7369
  var MACOS_LAUNCHD_LABEL = "com.guji.tokenarena";
7118
7370
  function getCurrentUid() {
7119
7371
  return typeof process.getuid === "function" ? process.getuid() : null;
7120
7372
  }
7121
- function getMacosLaunchAgentDir(homePath = homedir29()) {
7373
+ function getMacosLaunchAgentDir(homePath = homedir30()) {
7122
7374
  return posix2.join(homePath, "Library", "LaunchAgents");
7123
7375
  }
7124
- function getMacosLaunchAgentFile(homePath = homedir29()) {
7376
+ function getMacosLaunchAgentFile(homePath = homedir30()) {
7125
7377
  return posix2.join(
7126
7378
  getMacosLaunchAgentDir(homePath),
7127
7379
  `${MACOS_LAUNCHD_LABEL}.plist`
@@ -7248,7 +7500,7 @@ function writeLaunchAgentPlist() {
7248
7500
  label: MACOS_LAUNCHD_LABEL,
7249
7501
  programArguments: [command.execPath, ...command.args],
7250
7502
  environment: getManagedServiceEnvironment(),
7251
- workingDirectory: homedir29(),
7503
+ workingDirectory: homedir30(),
7252
7504
  standardOutPath: stdoutPath,
7253
7505
  standardErrorPath: stderrPath
7254
7506
  });
@@ -7273,7 +7525,7 @@ function bootstrapLaunchAgent() {
7273
7525
  }
7274
7526
  function createMacosLaunchdServiceBackend() {
7275
7527
  function isInstalled() {
7276
- return existsSync31(getMacosLaunchAgentFile());
7528
+ return existsSync32(getMacosLaunchAgentFile());
7277
7529
  }
7278
7530
  async function setup(skipPrompt = false) {
7279
7531
  if (!ensureLaunchctlAvailable()) {
@@ -7414,7 +7666,7 @@ function createMacosLaunchdServiceBackend() {
7414
7666
  }
7415
7667
  async function uninstall(skipPrompt = false) {
7416
7668
  const plistFile = getMacosLaunchAgentFile();
7417
- if (!existsSync31(plistFile)) {
7669
+ if (!existsSync32(plistFile)) {
7418
7670
  logger.info(formatBullet("\u670D\u52A1\u6587\u4EF6\u4E0D\u5B58\u5728\u3002", "warning"));
7419
7671
  return;
7420
7672
  }
@@ -7525,7 +7777,7 @@ function resolvePowerShellProfilePath() {
7525
7777
  const systemRoot = process.env.SYSTEMROOT || "C:\\Windows";
7526
7778
  const candidates = [
7527
7779
  "pwsh.exe",
7528
- join31(systemRoot, "System32", "WindowsPowerShell", "v1.0", "powershell.exe")
7780
+ join32(systemRoot, "System32", "WindowsPowerShell", "v1.0", "powershell.exe")
7529
7781
  ];
7530
7782
  for (const command of candidates) {
7531
7783
  try {
@@ -7554,8 +7806,8 @@ function resolvePowerShellProfilePath() {
7554
7806
  function resolveShellAliasSetup(options = {}) {
7555
7807
  const currentPlatform = options.currentPlatform ?? platform5();
7556
7808
  const env = options.env ?? process.env;
7557
- const homeDir = options.homeDir ?? homedir30();
7558
- const pathExists = options.exists ?? existsSync32;
7809
+ const homeDir = options.homeDir ?? homedir31();
7810
+ const pathExists = options.exists ?? existsSync33;
7559
7811
  const shellFromEnv = env.SHELL ? basenameLikeShell(env.SHELL).toLowerCase() : "";
7560
7812
  const shellName = shellFromEnv || (currentPlatform === "win32" ? "powershell" : "");
7561
7813
  const aliasName = "ta";
@@ -7752,7 +8004,7 @@ async function setupShellAlias() {
7752
8004
  try {
7753
8005
  await mkdir(dirname6(setup.configFile), { recursive: true });
7754
8006
  let existingContent = "";
7755
- if (existsSync32(setup.configFile)) {
8007
+ if (existsSync33(setup.configFile)) {
7756
8008
  existingContent = await readFile(setup.configFile, "utf-8");
7757
8009
  }
7758
8010
  const normalizedContent = existingContent.toLowerCase();
@@ -8011,7 +8263,7 @@ function buildLocalUsageDashboardData(input2) {
8011
8263
 
8012
8264
  // src/infrastructure/runtime/cli-version.ts
8013
8265
  import { readFileSync as readFileSync14 } from "fs";
8014
- import { dirname as dirname7, join as join32 } from "path";
8266
+ import { dirname as dirname7, join as join33 } from "path";
8015
8267
  import { fileURLToPath } from "url";
8016
8268
  var FALLBACK_VERSION = "0.0.0";
8017
8269
  var cachedVersion;
@@ -8019,7 +8271,7 @@ function getCliVersion(metaUrl = import.meta.url) {
8019
8271
  if (cachedVersion) {
8020
8272
  return cachedVersion;
8021
8273
  }
8022
- const packageJsonPath = join32(
8274
+ const packageJsonPath = join33(
8023
8275
  dirname7(fileURLToPath(metaUrl)),
8024
8276
  "..",
8025
8277
  "package.json"
@@ -8430,8 +8682,8 @@ async function runSyncCommand(opts = {}) {
8430
8682
  }
8431
8683
 
8432
8684
  // src/commands/uninstall.ts
8433
- import { existsSync as existsSync33, readFileSync as readFileSync15, rmSync as rmSync6, writeFileSync as writeFileSync7 } from "fs";
8434
- import { homedir as homedir31, platform as platform6 } from "os";
8685
+ import { existsSync as existsSync34, readFileSync as readFileSync15, rmSync as rmSync6, writeFileSync as writeFileSync7 } from "fs";
8686
+ import { homedir as homedir32, platform as platform6 } from "os";
8435
8687
  function removeShellAlias() {
8436
8688
  const shell = process.env.SHELL;
8437
8689
  if (!shell) return;
@@ -8440,22 +8692,22 @@ function removeShellAlias() {
8440
8692
  let configFile;
8441
8693
  switch (shellName) {
8442
8694
  case "zsh":
8443
- configFile = `${homedir31()}/.zshrc`;
8695
+ configFile = `${homedir32()}/.zshrc`;
8444
8696
  break;
8445
8697
  case "bash":
8446
- if (platform6() === "darwin" && existsSync33(`${homedir31()}/.bash_profile`)) {
8447
- configFile = `${homedir31()}/.bash_profile`;
8698
+ if (platform6() === "darwin" && existsSync34(`${homedir32()}/.bash_profile`)) {
8699
+ configFile = `${homedir32()}/.bash_profile`;
8448
8700
  } else {
8449
- configFile = `${homedir31()}/.bashrc`;
8701
+ configFile = `${homedir32()}/.bashrc`;
8450
8702
  }
8451
8703
  break;
8452
8704
  case "fish":
8453
- configFile = `${homedir31()}/.config/fish/config.fish`;
8705
+ configFile = `${homedir32()}/.config/fish/config.fish`;
8454
8706
  break;
8455
8707
  default:
8456
8708
  return;
8457
8709
  }
8458
- if (!existsSync33(configFile)) return;
8710
+ if (!existsSync34(configFile)) return;
8459
8711
  try {
8460
8712
  let content = readFileSync15(configFile, "utf-8");
8461
8713
  const aliasPatterns = [
@@ -8494,7 +8746,7 @@ async function runUninstall() {
8494
8746
  const runtimeDir = getRuntimeDirPath();
8495
8747
  const serviceBackend = getServiceBackend();
8496
8748
  const hasInstalledService = serviceBackend?.isInstalled() ?? false;
8497
- const hasLocalArtifacts = existsSync33(configPath) || existsSync33(configDir) || existsSync33(stateDir) || existsSync33(runtimeDir) || hasInstalledService;
8749
+ const hasLocalArtifacts = existsSync34(configPath) || existsSync34(configDir) || existsSync34(stateDir) || existsSync34(runtimeDir) || hasInstalledService;
8498
8750
  if (!hasLocalArtifacts) {
8499
8751
  logger.info(formatHeader("\u5378\u8F7D TokenArena"));
8500
8752
  logger.info(formatBullet("\u672A\u53D1\u73B0\u672C\u5730\u914D\u7F6E\uFF0C\u65E0\u9700\u5378\u8F7D\u3002"));
@@ -8538,22 +8790,22 @@ async function runUninstall() {
8538
8790
  }
8539
8791
  }
8540
8792
  logger.info(formatSection("\u6267\u884C\u7ED3\u679C"));
8541
- if (existsSync33(configPath)) {
8793
+ if (existsSync34(configPath)) {
8542
8794
  deleteConfig();
8543
8795
  logger.info(formatBullet("\u5DF2\u5220\u9664\u914D\u7F6E\u6587\u4EF6\u3002", "success"));
8544
8796
  }
8545
- if (existsSync33(configDir)) {
8797
+ if (existsSync34(configDir)) {
8546
8798
  try {
8547
8799
  rmSync6(configDir, { recursive: false, force: true });
8548
8800
  logger.info(formatBullet("\u5DF2\u5220\u9664\u914D\u7F6E\u76EE\u5F55\u3002", "success"));
8549
8801
  } catch {
8550
8802
  }
8551
8803
  }
8552
- if (existsSync33(stateDir)) {
8804
+ if (existsSync34(stateDir)) {
8553
8805
  rmSync6(stateDir, { recursive: true, force: true });
8554
8806
  logger.info(formatBullet("\u5DF2\u5220\u9664\u72B6\u6001\u6570\u636E\u3002", "success"));
8555
8807
  }
8556
- if (existsSync33(runtimeDir)) {
8808
+ if (existsSync34(runtimeDir)) {
8557
8809
  rmSync6(runtimeDir, { recursive: true, force: true });
8558
8810
  logger.info(formatBullet("\u5DF2\u5220\u9664\u8FD0\u884C\u65F6\u6570\u636E\u3002", "success"));
8559
8811
  }
@@ -8784,7 +9036,7 @@ function createCli() {
8784
9036
  }
8785
9037
 
8786
9038
  // src/infrastructure/runtime/main-module.ts
8787
- import { existsSync as existsSync34, realpathSync as realpathSync2 } from "fs";
9039
+ import { existsSync as existsSync35, realpathSync as realpathSync2 } from "fs";
8788
9040
  import { resolve as resolve3 } from "path";
8789
9041
  import { fileURLToPath as fileURLToPath2 } from "url";
8790
9042
  function isMainModule(argvEntry = process.argv[1], metaUrl = import.meta.url) {
@@ -8795,7 +9047,7 @@ function isMainModule(argvEntry = process.argv[1], metaUrl = import.meta.url) {
8795
9047
  try {
8796
9048
  return realpathSync2(argvEntry) === realpathSync2(currentModulePath);
8797
9049
  } catch {
8798
- if (!existsSync34(argvEntry)) {
9050
+ if (!existsSync35(argvEntry)) {
8799
9051
  return false;
8800
9052
  }
8801
9053
  return resolve3(argvEntry) === resolve3(currentModulePath);