@yishiguji/tokenarena 0.7.1 → 0.8.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 +498 -294
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1153,24 +1153,172 @@ var HermesParser = class {
|
|
|
1153
1153
|
};
|
|
1154
1154
|
registerParser(new HermesParser());
|
|
1155
1155
|
|
|
1156
|
-
// src/parsers/
|
|
1157
|
-
import { existsSync as existsSync7
|
|
1156
|
+
// src/parsers/mimocode.ts
|
|
1157
|
+
import { existsSync as existsSync7 } from "fs";
|
|
1158
1158
|
import { homedir as homedir6 } from "os";
|
|
1159
|
-
import {
|
|
1160
|
-
var
|
|
1159
|
+
import { join as join7 } from "path";
|
|
1160
|
+
var TOOL_ID4 = "mimocode";
|
|
1161
|
+
var TOOL_NAME4 = "MiMoCode";
|
|
1162
|
+
var DEFAULT_DB_PATH2 = join7(
|
|
1163
|
+
homedir6(),
|
|
1164
|
+
".local",
|
|
1165
|
+
"share",
|
|
1166
|
+
"mimocode",
|
|
1167
|
+
"mimocode.db"
|
|
1168
|
+
);
|
|
1169
|
+
var MESSAGES_QUERY2 = `SELECT
|
|
1170
|
+
m.session_id as sessionId,
|
|
1171
|
+
json_extract(m.data, '$.modelID') as modelID,
|
|
1172
|
+
json_extract(m.data, '$.tokens.input') as inputTokens,
|
|
1173
|
+
json_extract(m.data, '$.tokens.output') as outputTokens,
|
|
1174
|
+
json_extract(m.data, '$.tokens.reasoning') as reasoningTokens,
|
|
1175
|
+
json_extract(m.data, '$.tokens.cache.read') as cacheReadTokens,
|
|
1176
|
+
json_extract(m.data, '$.tokens.cache.write') as cacheWriteTokens,
|
|
1177
|
+
json_extract(m.data, '$.time.created') as timeCreated,
|
|
1178
|
+
s.directory as directory
|
|
1179
|
+
FROM message m
|
|
1180
|
+
LEFT JOIN session s ON m.session_id = s.id
|
|
1181
|
+
WHERE json_extract(m.data, '$.role') = 'assistant'
|
|
1182
|
+
AND json_extract(m.data, '$.tokens') IS NOT NULL`;
|
|
1183
|
+
var SESSIONS_QUERY2 = `SELECT
|
|
1184
|
+
m.session_id as sessionId,
|
|
1185
|
+
json_extract(m.data, '$.role') as role,
|
|
1186
|
+
json_extract(m.data, '$.time.created') as timeCreated
|
|
1187
|
+
FROM message m
|
|
1188
|
+
WHERE json_extract(m.data, '$.role') IN ('user', 'assistant')
|
|
1189
|
+
ORDER BY json_extract(m.data, '$.time.created')`;
|
|
1190
|
+
function getMimocodeDbPaths() {
|
|
1191
|
+
const paths = [
|
|
1192
|
+
process.env.TOKEN_ARENA_MIMOCODE_DB,
|
|
1193
|
+
DEFAULT_DB_PATH2,
|
|
1194
|
+
process.env.LOCALAPPDATA ? join7(process.env.LOCALAPPDATA, "mimocode", "mimocode.db") : void 0,
|
|
1195
|
+
process.env.APPDATA ? join7(process.env.APPDATA, "mimocode", "mimocode.db") : void 0
|
|
1196
|
+
].filter((value) => Boolean(value));
|
|
1197
|
+
return Array.from(new Set(paths));
|
|
1198
|
+
}
|
|
1199
|
+
function toSafeNumber4(value) {
|
|
1200
|
+
const n = Number(value);
|
|
1201
|
+
return Number.isFinite(n) && n >= 0 ? Math.round(n) : 0;
|
|
1202
|
+
}
|
|
1203
|
+
function extractProject2(directory) {
|
|
1204
|
+
if (typeof directory !== "string" || !directory) return "unknown";
|
|
1205
|
+
const parts = directory.replace(/[/\\]+$/, "").split(/[/\\]/);
|
|
1206
|
+
return parts.length > 0 ? parts[parts.length - 1] : "unknown";
|
|
1207
|
+
}
|
|
1208
|
+
function toTimestamp(value) {
|
|
1209
|
+
const n = Number(value);
|
|
1210
|
+
if (!Number.isFinite(n) || n <= 0) return null;
|
|
1211
|
+
const d = new Date(n > 1e12 ? n : n * 1e3);
|
|
1212
|
+
return Number.isNaN(d.getTime()) ? null : d;
|
|
1213
|
+
}
|
|
1214
|
+
var MimocodeParser = class {
|
|
1215
|
+
constructor(resolveDbPaths = getMimocodeDbPaths) {
|
|
1216
|
+
this.resolveDbPaths = resolveDbPaths;
|
|
1217
|
+
this.tool = {
|
|
1218
|
+
id: TOOL_ID4,
|
|
1219
|
+
name: TOOL_NAME4,
|
|
1220
|
+
dataDir: DEFAULT_DB_PATH2
|
|
1221
|
+
};
|
|
1222
|
+
}
|
|
1223
|
+
resolveDbPaths;
|
|
1224
|
+
tool;
|
|
1225
|
+
async parse() {
|
|
1226
|
+
const allEntries = [];
|
|
1227
|
+
const allSessionEvents = [];
|
|
1228
|
+
for (const dbPath of this.resolveDbPaths()) {
|
|
1229
|
+
if (!existsSync7(dbPath)) continue;
|
|
1230
|
+
try {
|
|
1231
|
+
const { entries, sessionEvents } = await this.parseDb(dbPath);
|
|
1232
|
+
allEntries.push(...entries);
|
|
1233
|
+
allSessionEvents.push(...sessionEvents);
|
|
1234
|
+
} catch (err) {
|
|
1235
|
+
process.stderr.write(
|
|
1236
|
+
`warn: mimocode parse failed for ${dbPath} (${err.message})
|
|
1237
|
+
`
|
|
1238
|
+
);
|
|
1239
|
+
}
|
|
1240
|
+
}
|
|
1241
|
+
return {
|
|
1242
|
+
buckets: aggregateToBuckets(allEntries),
|
|
1243
|
+
sessions: extractSessions(allSessionEvents, allEntries)
|
|
1244
|
+
};
|
|
1245
|
+
}
|
|
1246
|
+
isInstalled() {
|
|
1247
|
+
return this.resolveDbPaths().some((p) => existsSync7(p));
|
|
1248
|
+
}
|
|
1249
|
+
async parseDb(dbPath) {
|
|
1250
|
+
const messageRows = await readSqliteRows(
|
|
1251
|
+
dbPath,
|
|
1252
|
+
MESSAGES_QUERY2
|
|
1253
|
+
);
|
|
1254
|
+
const sessionRows = await readSqliteRows(
|
|
1255
|
+
dbPath,
|
|
1256
|
+
SESSIONS_QUERY2
|
|
1257
|
+
);
|
|
1258
|
+
const entries = [];
|
|
1259
|
+
const sessionEvents = [];
|
|
1260
|
+
for (const row of messageRows) {
|
|
1261
|
+
const timestamp = toTimestamp(row.timeCreated);
|
|
1262
|
+
const model = typeof row.modelID === "string" ? row.modelID : "unknown";
|
|
1263
|
+
const sessionId = typeof row.sessionId === "string" ? row.sessionId : "unknown";
|
|
1264
|
+
const project = extractProject2(row.directory);
|
|
1265
|
+
const inputTokens = toSafeNumber4(row.inputTokens);
|
|
1266
|
+
const outputTokens = toSafeNumber4(row.outputTokens);
|
|
1267
|
+
const reasoningTokens = toSafeNumber4(row.reasoningTokens);
|
|
1268
|
+
const cachedTokens = toSafeNumber4(row.cacheReadTokens);
|
|
1269
|
+
if (inputTokens + outputTokens + reasoningTokens + cachedTokens === 0) {
|
|
1270
|
+
continue;
|
|
1271
|
+
}
|
|
1272
|
+
entries.push({
|
|
1273
|
+
sessionId,
|
|
1274
|
+
source: TOOL_ID4,
|
|
1275
|
+
model,
|
|
1276
|
+
project,
|
|
1277
|
+
timestamp: timestamp || /* @__PURE__ */ new Date(),
|
|
1278
|
+
inputTokens,
|
|
1279
|
+
outputTokens,
|
|
1280
|
+
reasoningTokens,
|
|
1281
|
+
cachedTokens
|
|
1282
|
+
});
|
|
1283
|
+
}
|
|
1284
|
+
for (const row of sessionRows) {
|
|
1285
|
+
const timestamp = toTimestamp(row.timeCreated);
|
|
1286
|
+
const sessionId = typeof row.sessionId === "string" ? row.sessionId : "unknown";
|
|
1287
|
+
const role = typeof row.role === "string" ? row.role : "unknown";
|
|
1288
|
+
if (!timestamp) continue;
|
|
1289
|
+
if (role === "user" || role === "assistant") {
|
|
1290
|
+
sessionEvents.push({
|
|
1291
|
+
sessionId,
|
|
1292
|
+
source: TOOL_ID4,
|
|
1293
|
+
project: "unknown",
|
|
1294
|
+
timestamp,
|
|
1295
|
+
role: role === "user" ? "user" : "assistant"
|
|
1296
|
+
});
|
|
1297
|
+
}
|
|
1298
|
+
}
|
|
1299
|
+
return { entries, sessionEvents };
|
|
1300
|
+
}
|
|
1301
|
+
};
|
|
1302
|
+
registerParser(new MimocodeParser());
|
|
1303
|
+
|
|
1304
|
+
// src/parsers/copilot-cli.ts
|
|
1305
|
+
import { existsSync as existsSync8, readdirSync as readdirSync3, readFileSync as readFileSync3 } from "fs";
|
|
1306
|
+
import { homedir as homedir7 } from "os";
|
|
1307
|
+
import { basename as basename3, dirname as dirname2, join as join8 } from "path";
|
|
1308
|
+
var ROOT_DIR = join8(homedir7(), ".copilot");
|
|
1161
1309
|
var TOOL3 = {
|
|
1162
1310
|
id: "copilot-cli",
|
|
1163
1311
|
name: "GitHub Copilot CLI",
|
|
1164
1312
|
dataDir: ROOT_DIR
|
|
1165
1313
|
};
|
|
1166
1314
|
function collectEventFiles(dir, results, visited) {
|
|
1167
|
-
if (!
|
|
1315
|
+
if (!existsSync8(dir) || visited.has(dir)) {
|
|
1168
1316
|
return;
|
|
1169
1317
|
}
|
|
1170
1318
|
visited.add(dir);
|
|
1171
1319
|
try {
|
|
1172
1320
|
for (const entry of readdirSync3(dir, { withFileTypes: true })) {
|
|
1173
|
-
const fullPath =
|
|
1321
|
+
const fullPath = join8(dir, entry.name);
|
|
1174
1322
|
if (entry.isDirectory()) {
|
|
1175
1323
|
collectEventFiles(fullPath, results, visited);
|
|
1176
1324
|
continue;
|
|
@@ -1274,26 +1422,26 @@ var CopilotCliParser = class {
|
|
|
1274
1422
|
};
|
|
1275
1423
|
}
|
|
1276
1424
|
isInstalled() {
|
|
1277
|
-
return
|
|
1425
|
+
return existsSync8(ROOT_DIR);
|
|
1278
1426
|
}
|
|
1279
1427
|
};
|
|
1280
1428
|
registerParser(new CopilotCliParser());
|
|
1281
1429
|
|
|
1282
1430
|
// src/parsers/oh-my-pi.ts
|
|
1283
|
-
import { existsSync as
|
|
1284
|
-
import { homedir as
|
|
1285
|
-
import { join as
|
|
1286
|
-
var
|
|
1287
|
-
var
|
|
1288
|
-
var DEFAULT_SESSIONS_DIR2 =
|
|
1431
|
+
import { existsSync as existsSync9 } from "fs";
|
|
1432
|
+
import { homedir as homedir8 } from "os";
|
|
1433
|
+
import { join as join9 } from "path";
|
|
1434
|
+
var TOOL_ID5 = "oh-my-pi";
|
|
1435
|
+
var TOOL_NAME5 = "omp";
|
|
1436
|
+
var DEFAULT_SESSIONS_DIR2 = join9(homedir8(), ".omp", "agent", "sessions");
|
|
1289
1437
|
function createToolDefinition4(dataDir) {
|
|
1290
1438
|
return {
|
|
1291
|
-
id:
|
|
1292
|
-
name:
|
|
1439
|
+
id: TOOL_ID5,
|
|
1440
|
+
name: TOOL_NAME5,
|
|
1293
1441
|
dataDir
|
|
1294
1442
|
};
|
|
1295
1443
|
}
|
|
1296
|
-
function
|
|
1444
|
+
function toSafeNumber5(value) {
|
|
1297
1445
|
const numberValue = Number(value);
|
|
1298
1446
|
return Number.isFinite(numberValue) ? numberValue : 0;
|
|
1299
1447
|
}
|
|
@@ -1308,7 +1456,7 @@ function normalizeForPrefix2(value) {
|
|
|
1308
1456
|
function getUsageNumber2(usage, ...keys) {
|
|
1309
1457
|
for (const key of keys) {
|
|
1310
1458
|
const value = usage[key];
|
|
1311
|
-
const numberValue =
|
|
1459
|
+
const numberValue = toSafeNumber5(value);
|
|
1312
1460
|
if (numberValue > 0) {
|
|
1313
1461
|
return numberValue;
|
|
1314
1462
|
}
|
|
@@ -1383,7 +1531,7 @@ var OhMyPiParser = class {
|
|
|
1383
1531
|
if (message.role === "user" || message.role === "assistant") {
|
|
1384
1532
|
sessionEvents.push({
|
|
1385
1533
|
sessionId,
|
|
1386
|
-
source:
|
|
1534
|
+
source: TOOL_ID5,
|
|
1387
1535
|
project,
|
|
1388
1536
|
timestamp,
|
|
1389
1537
|
role: message.role
|
|
@@ -1415,7 +1563,7 @@ var OhMyPiParser = class {
|
|
|
1415
1563
|
}
|
|
1416
1564
|
entries.push({
|
|
1417
1565
|
sessionId,
|
|
1418
|
-
source:
|
|
1566
|
+
source: TOOL_ID5,
|
|
1419
1567
|
model: message.model || "unknown",
|
|
1420
1568
|
project,
|
|
1421
1569
|
timestamp,
|
|
@@ -1432,17 +1580,17 @@ var OhMyPiParser = class {
|
|
|
1432
1580
|
};
|
|
1433
1581
|
}
|
|
1434
1582
|
isInstalled() {
|
|
1435
|
-
return
|
|
1583
|
+
return existsSync9(this.sessionsDir);
|
|
1436
1584
|
}
|
|
1437
1585
|
};
|
|
1438
1586
|
registerParser(new OhMyPiParser());
|
|
1439
1587
|
|
|
1440
1588
|
// src/parsers/opencode.ts
|
|
1441
1589
|
import { execFileSync as execFileSync2 } from "child_process";
|
|
1442
|
-
import { existsSync as
|
|
1443
|
-
import { homedir as
|
|
1444
|
-
import { basename as basename4, join as
|
|
1445
|
-
var DEFAULT_DATA_DIR2 =
|
|
1590
|
+
import { existsSync as existsSync10, readdirSync as readdirSync4, readFileSync as readFileSync4 } from "fs";
|
|
1591
|
+
import { homedir as homedir9 } from "os";
|
|
1592
|
+
import { basename as basename4, join as join10 } from "path";
|
|
1593
|
+
var DEFAULT_DATA_DIR2 = join10(homedir9(), ".local", "share", "opencode");
|
|
1446
1594
|
var TOOL4 = {
|
|
1447
1595
|
id: "opencode",
|
|
1448
1596
|
name: "OpenCode",
|
|
@@ -1451,10 +1599,10 @@ var TOOL4 = {
|
|
|
1451
1599
|
function getOpenCodeDataDirs(env = process.env) {
|
|
1452
1600
|
const dirs = [
|
|
1453
1601
|
env.TOKEN_ARENA_OPENCODE_DIR,
|
|
1454
|
-
env.XDG_DATA_HOME ?
|
|
1602
|
+
env.XDG_DATA_HOME ? join10(env.XDG_DATA_HOME, "opencode") : void 0,
|
|
1455
1603
|
DEFAULT_DATA_DIR2,
|
|
1456
|
-
env.LOCALAPPDATA ?
|
|
1457
|
-
env.APPDATA ?
|
|
1604
|
+
env.LOCALAPPDATA ? join10(env.LOCALAPPDATA, "opencode") : void 0,
|
|
1605
|
+
env.APPDATA ? join10(env.APPDATA, "opencode") : void 0
|
|
1458
1606
|
].filter((value) => Boolean(value));
|
|
1459
1607
|
return Array.from(new Set(dirs));
|
|
1460
1608
|
}
|
|
@@ -1548,12 +1696,12 @@ var OpenCodeParser = class {
|
|
|
1548
1696
|
return { buckets, sessions };
|
|
1549
1697
|
}
|
|
1550
1698
|
isInstalled() {
|
|
1551
|
-
return this.resolveRoots().some((dir) =>
|
|
1699
|
+
return this.resolveRoots().some((dir) => existsSync10(dir));
|
|
1552
1700
|
}
|
|
1553
1701
|
async parseRoot(rootDir) {
|
|
1554
|
-
const dbPath =
|
|
1555
|
-
const messagesDir =
|
|
1556
|
-
if (
|
|
1702
|
+
const dbPath = join10(rootDir, "opencode.db");
|
|
1703
|
+
const messagesDir = join10(rootDir, "storage", "message");
|
|
1704
|
+
if (existsSync10(dbPath)) {
|
|
1557
1705
|
try {
|
|
1558
1706
|
return await this.parseFromSqlite(dbPath);
|
|
1559
1707
|
} catch (err) {
|
|
@@ -1620,7 +1768,7 @@ var OpenCodeParser = class {
|
|
|
1620
1768
|
};
|
|
1621
1769
|
}
|
|
1622
1770
|
parseFromJson(messagesDir) {
|
|
1623
|
-
if (!
|
|
1771
|
+
if (!existsSync10(messagesDir)) return { buckets: [], sessions: [] };
|
|
1624
1772
|
const entries = [];
|
|
1625
1773
|
const sessionEvents = [];
|
|
1626
1774
|
let sessionDirs;
|
|
@@ -1632,7 +1780,7 @@ var OpenCodeParser = class {
|
|
|
1632
1780
|
return { buckets: [], sessions: [] };
|
|
1633
1781
|
}
|
|
1634
1782
|
for (const sessionDir of sessionDirs) {
|
|
1635
|
-
const sessionPath =
|
|
1783
|
+
const sessionPath = join10(messagesDir, sessionDir.name);
|
|
1636
1784
|
let messageFiles;
|
|
1637
1785
|
try {
|
|
1638
1786
|
messageFiles = readdirSync4(sessionPath).filter(
|
|
@@ -1642,7 +1790,7 @@ var OpenCodeParser = class {
|
|
|
1642
1790
|
continue;
|
|
1643
1791
|
}
|
|
1644
1792
|
for (const file of messageFiles) {
|
|
1645
|
-
const filePath =
|
|
1793
|
+
const filePath = join10(sessionPath, file);
|
|
1646
1794
|
let data;
|
|
1647
1795
|
try {
|
|
1648
1796
|
data = JSON.parse(readFileSync4(filePath, "utf-8"));
|
|
@@ -1688,16 +1836,16 @@ var OpenCodeParser = class {
|
|
|
1688
1836
|
registerParser(new OpenCodeParser());
|
|
1689
1837
|
|
|
1690
1838
|
// src/parsers/openclaw.ts
|
|
1691
|
-
import { existsSync as
|
|
1692
|
-
import { homedir as
|
|
1693
|
-
import { join as
|
|
1694
|
-
var
|
|
1695
|
-
var
|
|
1696
|
-
var DEFAULT_DATA_DIR3 =
|
|
1839
|
+
import { existsSync as existsSync11, readdirSync as readdirSync5, readFileSync as readFileSync5 } from "fs";
|
|
1840
|
+
import { homedir as homedir10 } from "os";
|
|
1841
|
+
import { join as join11 } from "path";
|
|
1842
|
+
var TOOL_ID6 = "openclaw";
|
|
1843
|
+
var TOOL_NAME6 = "OpenClaw";
|
|
1844
|
+
var DEFAULT_DATA_DIR3 = join11(homedir10(), ".openclaw");
|
|
1697
1845
|
var LEGACY_ROOT_NAMES = [".clawdbot", ".moltbot", ".moldbot"];
|
|
1698
1846
|
var TOOL5 = {
|
|
1699
|
-
id:
|
|
1700
|
-
name:
|
|
1847
|
+
id: TOOL_ID6,
|
|
1848
|
+
name: TOOL_NAME6,
|
|
1701
1849
|
dataDir: DEFAULT_DATA_DIR3
|
|
1702
1850
|
};
|
|
1703
1851
|
function getTokens(usage, ...keys) {
|
|
@@ -1707,16 +1855,16 @@ function getTokens(usage, ...keys) {
|
|
|
1707
1855
|
}
|
|
1708
1856
|
return 0;
|
|
1709
1857
|
}
|
|
1710
|
-
function getOpenClawRoots(homeDir =
|
|
1711
|
-
const roots = [
|
|
1858
|
+
function getOpenClawRoots(homeDir = homedir10()) {
|
|
1859
|
+
const roots = [join11(homeDir, ".openclaw")];
|
|
1712
1860
|
try {
|
|
1713
1861
|
const profileRoots = readdirSync5(homeDir, { withFileTypes: true }).filter(
|
|
1714
1862
|
(entry) => entry.isDirectory() && /^\.openclaw-.+/.test(entry.name)
|
|
1715
|
-
).map((entry) =>
|
|
1863
|
+
).map((entry) => join11(homeDir, entry.name)).sort((left, right) => left.localeCompare(right));
|
|
1716
1864
|
roots.push(...profileRoots);
|
|
1717
1865
|
} catch {
|
|
1718
1866
|
}
|
|
1719
|
-
roots.push(...LEGACY_ROOT_NAMES.map((name) =>
|
|
1867
|
+
roots.push(...LEGACY_ROOT_NAMES.map((name) => join11(homeDir, name)));
|
|
1720
1868
|
return Array.from(new Set(roots));
|
|
1721
1869
|
}
|
|
1722
1870
|
var OpenClawParser = class {
|
|
@@ -1729,8 +1877,8 @@ var OpenClawParser = class {
|
|
|
1729
1877
|
const entries = [];
|
|
1730
1878
|
const sessionEvents = [];
|
|
1731
1879
|
for (const root of this.resolveRoots()) {
|
|
1732
|
-
const agentsDir =
|
|
1733
|
-
if (!
|
|
1880
|
+
const agentsDir = join11(root, "agents");
|
|
1881
|
+
if (!existsSync11(agentsDir)) continue;
|
|
1734
1882
|
let agentDirs;
|
|
1735
1883
|
try {
|
|
1736
1884
|
agentDirs = readdirSync5(agentsDir, { withFileTypes: true }).filter(
|
|
@@ -1741,8 +1889,8 @@ var OpenClawParser = class {
|
|
|
1741
1889
|
}
|
|
1742
1890
|
for (const agentDir of agentDirs) {
|
|
1743
1891
|
const project = agentDir.name;
|
|
1744
|
-
const sessionsDir =
|
|
1745
|
-
if (!
|
|
1892
|
+
const sessionsDir = join11(agentsDir, agentDir.name, "sessions");
|
|
1893
|
+
if (!existsSync11(sessionsDir)) continue;
|
|
1746
1894
|
let files;
|
|
1747
1895
|
try {
|
|
1748
1896
|
files = readdirSync5(sessionsDir).filter((f) => f.endsWith(".jsonl"));
|
|
@@ -1750,7 +1898,7 @@ var OpenClawParser = class {
|
|
|
1750
1898
|
continue;
|
|
1751
1899
|
}
|
|
1752
1900
|
for (const file of files) {
|
|
1753
|
-
const filePath =
|
|
1901
|
+
const filePath = join11(sessionsDir, file);
|
|
1754
1902
|
let content;
|
|
1755
1903
|
try {
|
|
1756
1904
|
content = readFileSync5(filePath, "utf-8");
|
|
@@ -1773,7 +1921,7 @@ var OpenClawParser = class {
|
|
|
1773
1921
|
if (msg.role !== "user" && msg.role !== "assistant") continue;
|
|
1774
1922
|
sessionEvents.push({
|
|
1775
1923
|
sessionId: filePath,
|
|
1776
|
-
source:
|
|
1924
|
+
source: TOOL_ID6,
|
|
1777
1925
|
project,
|
|
1778
1926
|
timestamp: ts,
|
|
1779
1927
|
role: msg.role === "user" ? "user" : "assistant"
|
|
@@ -1783,7 +1931,7 @@ var OpenClawParser = class {
|
|
|
1783
1931
|
if (!usage) continue;
|
|
1784
1932
|
entries.push({
|
|
1785
1933
|
sessionId: filePath,
|
|
1786
|
-
source:
|
|
1934
|
+
source: TOOL_ID6,
|
|
1787
1935
|
model: msg.model || obj.model || "unknown",
|
|
1788
1936
|
project,
|
|
1789
1937
|
timestamp: ts,
|
|
@@ -1823,26 +1971,26 @@ var OpenClawParser = class {
|
|
|
1823
1971
|
};
|
|
1824
1972
|
}
|
|
1825
1973
|
isInstalled() {
|
|
1826
|
-
return this.resolveRoots().some((root) =>
|
|
1974
|
+
return this.resolveRoots().some((root) => existsSync11(join11(root, "agents")));
|
|
1827
1975
|
}
|
|
1828
1976
|
};
|
|
1829
1977
|
registerParser(new OpenClawParser());
|
|
1830
1978
|
|
|
1831
1979
|
// src/parsers/qwen-code.ts
|
|
1832
|
-
import { existsSync as
|
|
1833
|
-
import { homedir as
|
|
1834
|
-
import { join as
|
|
1835
|
-
var
|
|
1836
|
-
var
|
|
1837
|
-
var DEFAULT_DATA_DIR4 =
|
|
1980
|
+
import { existsSync as existsSync12, readdirSync as readdirSync6 } from "fs";
|
|
1981
|
+
import { homedir as homedir11 } from "os";
|
|
1982
|
+
import { join as join12 } from "path";
|
|
1983
|
+
var TOOL_ID7 = "qwen-code";
|
|
1984
|
+
var TOOL_NAME7 = "Qwen Code";
|
|
1985
|
+
var DEFAULT_DATA_DIR4 = join12(homedir11(), ".qwen", "tmp");
|
|
1838
1986
|
function createToolDefinition5(dataDir) {
|
|
1839
1987
|
return {
|
|
1840
|
-
id:
|
|
1841
|
-
name:
|
|
1988
|
+
id: TOOL_ID7,
|
|
1989
|
+
name: TOOL_NAME7,
|
|
1842
1990
|
dataDir
|
|
1843
1991
|
};
|
|
1844
1992
|
}
|
|
1845
|
-
function
|
|
1993
|
+
function toSafeNumber6(value) {
|
|
1846
1994
|
const numberValue = Number(value);
|
|
1847
1995
|
return Number.isFinite(numberValue) ? numberValue : 0;
|
|
1848
1996
|
}
|
|
@@ -1856,16 +2004,16 @@ function normalizeForPrefix3(value) {
|
|
|
1856
2004
|
}
|
|
1857
2005
|
function findSessionFiles2(baseDir) {
|
|
1858
2006
|
const results = [];
|
|
1859
|
-
if (!
|
|
2007
|
+
if (!existsSync12(baseDir)) return results;
|
|
1860
2008
|
try {
|
|
1861
2009
|
for (const entry of readdirSync6(baseDir, { withFileTypes: true })) {
|
|
1862
2010
|
if (!entry.isDirectory()) continue;
|
|
1863
|
-
const chatsDir =
|
|
1864
|
-
if (!
|
|
2011
|
+
const chatsDir = join12(baseDir, entry.name, "chats");
|
|
2012
|
+
if (!existsSync12(chatsDir)) continue;
|
|
1865
2013
|
try {
|
|
1866
2014
|
for (const file of readdirSync6(chatsDir)) {
|
|
1867
2015
|
if (file.endsWith(".jsonl")) {
|
|
1868
|
-
results.push(
|
|
2016
|
+
results.push(join12(chatsDir, file));
|
|
1869
2017
|
}
|
|
1870
2018
|
}
|
|
1871
2019
|
} catch {
|
|
@@ -1920,7 +2068,7 @@ var QwenCodeParser = class {
|
|
|
1920
2068
|
if (obj.type === "user" || obj.type === "assistant") {
|
|
1921
2069
|
sessionEvents.push({
|
|
1922
2070
|
sessionId,
|
|
1923
|
-
source:
|
|
2071
|
+
source: TOOL_ID7,
|
|
1924
2072
|
project,
|
|
1925
2073
|
timestamp,
|
|
1926
2074
|
role: obj.type
|
|
@@ -1929,10 +2077,10 @@ var QwenCodeParser = class {
|
|
|
1929
2077
|
if (obj.type !== "assistant") continue;
|
|
1930
2078
|
const usage = obj.usageMetadata || obj.usage;
|
|
1931
2079
|
if (!usage) continue;
|
|
1932
|
-
const totalInput =
|
|
1933
|
-
const totalOutput =
|
|
1934
|
-
const cachedTokens =
|
|
1935
|
-
const reasoningTokens =
|
|
2080
|
+
const totalInput = toSafeNumber6(usage.promptTokenCount) || toSafeNumber6(usage.input_tokens);
|
|
2081
|
+
const totalOutput = toSafeNumber6(usage.candidatesTokenCount) || toSafeNumber6(usage.output_tokens);
|
|
2082
|
+
const cachedTokens = toSafeNumber6(usage.cachedContentTokenCount);
|
|
2083
|
+
const reasoningTokens = toSafeNumber6(usage.thoughtsTokenCount);
|
|
1936
2084
|
if (totalInput === 0 && totalOutput === 0 && cachedTokens === 0 && reasoningTokens === 0) {
|
|
1937
2085
|
continue;
|
|
1938
2086
|
}
|
|
@@ -1942,7 +2090,7 @@ var QwenCodeParser = class {
|
|
|
1942
2090
|
}
|
|
1943
2091
|
entries.push({
|
|
1944
2092
|
sessionId,
|
|
1945
|
-
source:
|
|
2093
|
+
source: TOOL_ID7,
|
|
1946
2094
|
model: obj.model || "unknown",
|
|
1947
2095
|
project,
|
|
1948
2096
|
timestamp,
|
|
@@ -1961,19 +2109,19 @@ var QwenCodeParser = class {
|
|
|
1961
2109
|
};
|
|
1962
2110
|
}
|
|
1963
2111
|
isInstalled() {
|
|
1964
|
-
return
|
|
2112
|
+
return existsSync12(this.dataDir);
|
|
1965
2113
|
}
|
|
1966
2114
|
};
|
|
1967
2115
|
registerParser(new QwenCodeParser());
|
|
1968
2116
|
|
|
1969
2117
|
// src/parsers/kimi-code.ts
|
|
1970
|
-
import { existsSync as
|
|
1971
|
-
import { homedir as
|
|
1972
|
-
import { join as
|
|
1973
|
-
var
|
|
1974
|
-
var
|
|
1975
|
-
var DEFAULT_SESSIONS_DIR3 =
|
|
1976
|
-
var DEFAULT_CONFIG_PATH =
|
|
2118
|
+
import { existsSync as existsSync13, readdirSync as readdirSync7 } from "fs";
|
|
2119
|
+
import { homedir as homedir12 } from "os";
|
|
2120
|
+
import { join as join13 } from "path";
|
|
2121
|
+
var TOOL_ID8 = "kimi-code";
|
|
2122
|
+
var TOOL_NAME8 = "Kimi Code";
|
|
2123
|
+
var DEFAULT_SESSIONS_DIR3 = join13(homedir12(), ".kimi", "sessions");
|
|
2124
|
+
var DEFAULT_CONFIG_PATH = join13(homedir12(), ".kimi", "kimi.json");
|
|
1977
2125
|
var USER_EVENT_TYPES = /* @__PURE__ */ new Set(["UserMessage", "user_message", "Input"]);
|
|
1978
2126
|
var ASSISTANT_EVENT_TYPES = /* @__PURE__ */ new Set([
|
|
1979
2127
|
"AssistantMessage",
|
|
@@ -1984,12 +2132,12 @@ var ASSISTANT_EVENT_TYPES = /* @__PURE__ */ new Set([
|
|
|
1984
2132
|
]);
|
|
1985
2133
|
function createToolDefinition6(dataDir) {
|
|
1986
2134
|
return {
|
|
1987
|
-
id:
|
|
1988
|
-
name:
|
|
2135
|
+
id: TOOL_ID8,
|
|
2136
|
+
name: TOOL_NAME8,
|
|
1989
2137
|
dataDir
|
|
1990
2138
|
};
|
|
1991
2139
|
}
|
|
1992
|
-
function
|
|
2140
|
+
function toSafeNumber7(value) {
|
|
1993
2141
|
const numberValue = Number(value);
|
|
1994
2142
|
return Number.isFinite(numberValue) ? numberValue : 0;
|
|
1995
2143
|
}
|
|
@@ -2000,18 +2148,18 @@ function getPathLeaf5(value) {
|
|
|
2000
2148
|
}
|
|
2001
2149
|
function findWireFiles(baseDir) {
|
|
2002
2150
|
const results = [];
|
|
2003
|
-
if (!
|
|
2151
|
+
if (!existsSync13(baseDir)) return results;
|
|
2004
2152
|
try {
|
|
2005
2153
|
for (const workDir of readdirSync7(baseDir, { withFileTypes: true })) {
|
|
2006
2154
|
if (!workDir.isDirectory()) continue;
|
|
2007
|
-
const workDirPath =
|
|
2155
|
+
const workDirPath = join13(baseDir, workDir.name);
|
|
2008
2156
|
try {
|
|
2009
2157
|
for (const session of readdirSync7(workDirPath, {
|
|
2010
2158
|
withFileTypes: true
|
|
2011
2159
|
})) {
|
|
2012
2160
|
if (!session.isDirectory()) continue;
|
|
2013
|
-
const wireFile =
|
|
2014
|
-
if (
|
|
2161
|
+
const wireFile = join13(workDirPath, session.name, "wire.jsonl");
|
|
2162
|
+
if (existsSync13(wireFile)) {
|
|
2015
2163
|
results.push({ filePath: wireFile, workDirHash: workDir.name });
|
|
2016
2164
|
}
|
|
2017
2165
|
}
|
|
@@ -2108,7 +2256,7 @@ var KimiCodeParser = class {
|
|
|
2108
2256
|
if (role && timestamp) {
|
|
2109
2257
|
sessionEvents.push({
|
|
2110
2258
|
sessionId,
|
|
2111
|
-
source:
|
|
2259
|
+
source: TOOL_ID8,
|
|
2112
2260
|
project,
|
|
2113
2261
|
timestamp,
|
|
2114
2262
|
role
|
|
@@ -2117,10 +2265,10 @@ var KimiCodeParser = class {
|
|
|
2117
2265
|
if (obj.type !== "StatusUpdate") continue;
|
|
2118
2266
|
const tokenUsage = payload.token_usage;
|
|
2119
2267
|
if (!tokenUsage || !timestamp) continue;
|
|
2120
|
-
const inputTokens =
|
|
2121
|
-
const outputTokens =
|
|
2122
|
-
const cachedTokens =
|
|
2123
|
-
const cacheCreateTokens =
|
|
2268
|
+
const inputTokens = toSafeNumber7(tokenUsage.input_other);
|
|
2269
|
+
const outputTokens = toSafeNumber7(tokenUsage.output);
|
|
2270
|
+
const cachedTokens = toSafeNumber7(tokenUsage.input_cache_read);
|
|
2271
|
+
const cacheCreateTokens = toSafeNumber7(tokenUsage.input_cache_creation);
|
|
2124
2272
|
if (inputTokens === 0 && outputTokens === 0 && cachedTokens === 0 && cacheCreateTokens === 0) {
|
|
2125
2273
|
continue;
|
|
2126
2274
|
}
|
|
@@ -2131,7 +2279,7 @@ var KimiCodeParser = class {
|
|
|
2131
2279
|
if (!role) {
|
|
2132
2280
|
sessionEvents.push({
|
|
2133
2281
|
sessionId,
|
|
2134
|
-
source:
|
|
2282
|
+
source: TOOL_ID8,
|
|
2135
2283
|
project,
|
|
2136
2284
|
timestamp,
|
|
2137
2285
|
role: "assistant"
|
|
@@ -2139,7 +2287,7 @@ var KimiCodeParser = class {
|
|
|
2139
2287
|
}
|
|
2140
2288
|
entries.push({
|
|
2141
2289
|
sessionId,
|
|
2142
|
-
source:
|
|
2290
|
+
source: TOOL_ID8,
|
|
2143
2291
|
model: currentModel,
|
|
2144
2292
|
project,
|
|
2145
2293
|
timestamp,
|
|
@@ -2156,31 +2304,31 @@ var KimiCodeParser = class {
|
|
|
2156
2304
|
};
|
|
2157
2305
|
}
|
|
2158
2306
|
isInstalled() {
|
|
2159
|
-
return
|
|
2307
|
+
return existsSync13(this.sessionsDir);
|
|
2160
2308
|
}
|
|
2161
2309
|
};
|
|
2162
2310
|
registerParser(new KimiCodeParser());
|
|
2163
2311
|
|
|
2164
2312
|
// src/parsers/droid.ts
|
|
2165
|
-
import { existsSync as
|
|
2166
|
-
import { homedir as
|
|
2167
|
-
import { basename as basename5, dirname as dirname3, join as
|
|
2168
|
-
var
|
|
2169
|
-
var
|
|
2170
|
-
var DEFAULT_DATA_DIR5 =
|
|
2313
|
+
import { existsSync as existsSync14, readdirSync as readdirSync8 } from "fs";
|
|
2314
|
+
import { homedir as homedir13 } from "os";
|
|
2315
|
+
import { basename as basename5, dirname as dirname3, join as join14 } from "path";
|
|
2316
|
+
var TOOL_ID9 = "droid";
|
|
2317
|
+
var TOOL_NAME9 = "Droid";
|
|
2318
|
+
var DEFAULT_DATA_DIR5 = join14(homedir13(), ".factory", "sessions");
|
|
2171
2319
|
function createToolDefinition7(dataDir) {
|
|
2172
2320
|
return {
|
|
2173
|
-
id:
|
|
2174
|
-
name:
|
|
2321
|
+
id: TOOL_ID9,
|
|
2322
|
+
name: TOOL_NAME9,
|
|
2175
2323
|
dataDir
|
|
2176
2324
|
};
|
|
2177
2325
|
}
|
|
2178
2326
|
function findSessionFiles3(dir) {
|
|
2179
2327
|
const results = [];
|
|
2180
|
-
if (!
|
|
2328
|
+
if (!existsSync14(dir)) return results;
|
|
2181
2329
|
try {
|
|
2182
2330
|
for (const entry of readdirSync8(dir, { withFileTypes: true })) {
|
|
2183
|
-
const fullPath =
|
|
2331
|
+
const fullPath = join14(dir, entry.name);
|
|
2184
2332
|
if (entry.isDirectory()) {
|
|
2185
2333
|
results.push(...findSessionFiles3(fullPath));
|
|
2186
2334
|
} else if (entry.isFile() && entry.name.endsWith(".jsonl") && !entry.name.endsWith(".settings.json")) {
|
|
@@ -2195,7 +2343,7 @@ function extractDroidProject(slug) {
|
|
|
2195
2343
|
const parts = slug.split("-").filter(Boolean);
|
|
2196
2344
|
return parts.length > 0 ? parts[parts.length - 1] : "unknown";
|
|
2197
2345
|
}
|
|
2198
|
-
function
|
|
2346
|
+
function toSafeNumber8(value) {
|
|
2199
2347
|
const numberValue = Number(value);
|
|
2200
2348
|
return Number.isFinite(numberValue) ? numberValue : 0;
|
|
2201
2349
|
}
|
|
@@ -2237,13 +2385,13 @@ var DroidParser = class {
|
|
|
2237
2385
|
}
|
|
2238
2386
|
sessionEvents.push({
|
|
2239
2387
|
sessionId,
|
|
2240
|
-
source:
|
|
2388
|
+
source: TOOL_ID9,
|
|
2241
2389
|
project,
|
|
2242
2390
|
timestamp,
|
|
2243
2391
|
role
|
|
2244
2392
|
});
|
|
2245
2393
|
}
|
|
2246
|
-
const settingsPath =
|
|
2394
|
+
const settingsPath = join14(
|
|
2247
2395
|
dirname3(filePath),
|
|
2248
2396
|
`${basename5(filePath, ".jsonl")}.settings.json`
|
|
2249
2397
|
);
|
|
@@ -2257,22 +2405,22 @@ var DroidParser = class {
|
|
|
2257
2405
|
}
|
|
2258
2406
|
const tokenUsage = settings.tokenUsage;
|
|
2259
2407
|
if (!tokenUsage) continue;
|
|
2260
|
-
const cachedTokens =
|
|
2261
|
-
const reasoningTokens =
|
|
2408
|
+
const cachedTokens = toSafeNumber8(tokenUsage.cacheReadTokens);
|
|
2409
|
+
const reasoningTokens = toSafeNumber8(tokenUsage.thinkingTokens);
|
|
2262
2410
|
const inputTokens = Math.max(
|
|
2263
2411
|
0,
|
|
2264
|
-
|
|
2412
|
+
toSafeNumber8(tokenUsage.inputTokens) - cachedTokens
|
|
2265
2413
|
);
|
|
2266
2414
|
const outputTokens = Math.max(
|
|
2267
2415
|
0,
|
|
2268
|
-
|
|
2416
|
+
toSafeNumber8(tokenUsage.outputTokens) - reasoningTokens
|
|
2269
2417
|
);
|
|
2270
2418
|
if (inputTokens === 0 && outputTokens === 0 && cachedTokens === 0 && reasoningTokens === 0) {
|
|
2271
2419
|
continue;
|
|
2272
2420
|
}
|
|
2273
2421
|
entries.push({
|
|
2274
2422
|
sessionId,
|
|
2275
|
-
source:
|
|
2423
|
+
source: TOOL_ID9,
|
|
2276
2424
|
model: settings.model || "unknown",
|
|
2277
2425
|
project,
|
|
2278
2426
|
timestamp: firstMessageTimestamp,
|
|
@@ -2288,26 +2436,26 @@ var DroidParser = class {
|
|
|
2288
2436
|
};
|
|
2289
2437
|
}
|
|
2290
2438
|
isInstalled() {
|
|
2291
|
-
return
|
|
2439
|
+
return existsSync14(this.dataDir);
|
|
2292
2440
|
}
|
|
2293
2441
|
};
|
|
2294
2442
|
registerParser(new DroidParser());
|
|
2295
2443
|
|
|
2296
2444
|
// src/parsers/pi-coding-agent.ts
|
|
2297
|
-
import { existsSync as
|
|
2298
|
-
import { homedir as
|
|
2299
|
-
import { join as
|
|
2300
|
-
var
|
|
2301
|
-
var
|
|
2302
|
-
var DEFAULT_SESSIONS_DIR4 =
|
|
2445
|
+
import { existsSync as existsSync15 } from "fs";
|
|
2446
|
+
import { homedir as homedir14 } from "os";
|
|
2447
|
+
import { join as join15 } from "path";
|
|
2448
|
+
var TOOL_ID10 = "pi-coding-agent";
|
|
2449
|
+
var TOOL_NAME10 = "pi";
|
|
2450
|
+
var DEFAULT_SESSIONS_DIR4 = join15(homedir14(), ".pi", "agent", "sessions");
|
|
2303
2451
|
function createToolDefinition8(dataDir) {
|
|
2304
2452
|
return {
|
|
2305
|
-
id:
|
|
2306
|
-
name:
|
|
2453
|
+
id: TOOL_ID10,
|
|
2454
|
+
name: TOOL_NAME10,
|
|
2307
2455
|
dataDir
|
|
2308
2456
|
};
|
|
2309
2457
|
}
|
|
2310
|
-
function
|
|
2458
|
+
function toSafeNumber9(value) {
|
|
2311
2459
|
const numberValue = Number(value);
|
|
2312
2460
|
return Number.isFinite(numberValue) ? numberValue : 0;
|
|
2313
2461
|
}
|
|
@@ -2322,7 +2470,7 @@ function normalizeForPrefix4(value) {
|
|
|
2322
2470
|
function getUsageNumber3(usage, ...keys) {
|
|
2323
2471
|
for (const key of keys) {
|
|
2324
2472
|
const value = usage[key];
|
|
2325
|
-
const numberValue =
|
|
2473
|
+
const numberValue = toSafeNumber9(value);
|
|
2326
2474
|
if (numberValue > 0) {
|
|
2327
2475
|
return numberValue;
|
|
2328
2476
|
}
|
|
@@ -2397,7 +2545,7 @@ var PiCodingAgentParser = class {
|
|
|
2397
2545
|
if (message.role === "user" || message.role === "assistant") {
|
|
2398
2546
|
sessionEvents.push({
|
|
2399
2547
|
sessionId,
|
|
2400
|
-
source:
|
|
2548
|
+
source: TOOL_ID10,
|
|
2401
2549
|
project,
|
|
2402
2550
|
timestamp,
|
|
2403
2551
|
role: message.role
|
|
@@ -2429,7 +2577,7 @@ var PiCodingAgentParser = class {
|
|
|
2429
2577
|
}
|
|
2430
2578
|
entries.push({
|
|
2431
2579
|
sessionId,
|
|
2432
|
-
source:
|
|
2580
|
+
source: TOOL_ID10,
|
|
2433
2581
|
model: message.model || "unknown",
|
|
2434
2582
|
project,
|
|
2435
2583
|
timestamp,
|
|
@@ -2446,27 +2594,27 @@ var PiCodingAgentParser = class {
|
|
|
2446
2594
|
};
|
|
2447
2595
|
}
|
|
2448
2596
|
isInstalled() {
|
|
2449
|
-
return
|
|
2597
|
+
return existsSync15(this.sessionsDir);
|
|
2450
2598
|
}
|
|
2451
2599
|
};
|
|
2452
2600
|
registerParser(new PiCodingAgentParser());
|
|
2453
2601
|
|
|
2454
2602
|
// src/parsers/qwenpaw.ts
|
|
2455
|
-
import { existsSync as
|
|
2456
|
-
import { homedir as
|
|
2457
|
-
import { join as
|
|
2458
|
-
var
|
|
2459
|
-
var
|
|
2460
|
-
var DEFAULT_USAGE_PATH =
|
|
2461
|
-
var DEFAULT_WORKSPACE_PATH =
|
|
2603
|
+
import { existsSync as existsSync16, readdirSync as readdirSync9 } from "fs";
|
|
2604
|
+
import { homedir as homedir15, hostname as hostname3 } from "os";
|
|
2605
|
+
import { join as join16 } from "path";
|
|
2606
|
+
var TOOL_ID11 = "qwenpaw";
|
|
2607
|
+
var TOOL_NAME11 = "QwenPaw";
|
|
2608
|
+
var DEFAULT_USAGE_PATH = join16(homedir15(), ".qwenpaw", "token_usage.json");
|
|
2609
|
+
var DEFAULT_WORKSPACE_PATH = join16(homedir15(), ".qwenpaw", "workspace");
|
|
2462
2610
|
function createToolDefinition9(usagePath) {
|
|
2463
2611
|
return {
|
|
2464
|
-
id:
|
|
2465
|
-
name:
|
|
2612
|
+
id: TOOL_ID11,
|
|
2613
|
+
name: TOOL_NAME11,
|
|
2466
2614
|
dataDir: usagePath
|
|
2467
2615
|
};
|
|
2468
2616
|
}
|
|
2469
|
-
function
|
|
2617
|
+
function toSafeNumber10(value) {
|
|
2470
2618
|
const numberValue = Number(value);
|
|
2471
2619
|
return Number.isFinite(numberValue) && numberValue > 0 ? numberValue : 0;
|
|
2472
2620
|
}
|
|
@@ -2513,13 +2661,13 @@ var QwenPawParser = class {
|
|
|
2513
2661
|
if (!record || typeof record !== "object") {
|
|
2514
2662
|
continue;
|
|
2515
2663
|
}
|
|
2516
|
-
const inputTokens =
|
|
2517
|
-
const outputTokens =
|
|
2664
|
+
const inputTokens = toSafeNumber10(record.prompt_tokens);
|
|
2665
|
+
const outputTokens = toSafeNumber10(record.completion_tokens);
|
|
2518
2666
|
if (inputTokens === 0 && outputTokens === 0) {
|
|
2519
2667
|
continue;
|
|
2520
2668
|
}
|
|
2521
2669
|
entries.push({
|
|
2522
|
-
source:
|
|
2670
|
+
source: TOOL_ID11,
|
|
2523
2671
|
model: resolveModel(recordKey, record),
|
|
2524
2672
|
project: "unknown",
|
|
2525
2673
|
timestamp,
|
|
@@ -2542,15 +2690,15 @@ var QwenPawParser = class {
|
|
|
2542
2690
|
}
|
|
2543
2691
|
async parseWorkspaceSessions() {
|
|
2544
2692
|
const events = [];
|
|
2545
|
-
if (!
|
|
2693
|
+
if (!existsSync16(this.workspacePath)) {
|
|
2546
2694
|
return events;
|
|
2547
2695
|
}
|
|
2548
2696
|
try {
|
|
2549
2697
|
const workspaceDirs = readdirSync9(this.workspacePath);
|
|
2550
2698
|
for (const workspaceDir of workspaceDirs) {
|
|
2551
|
-
const workspacePath =
|
|
2552
|
-
const chatsPath =
|
|
2553
|
-
const sessionsPath =
|
|
2699
|
+
const workspacePath = join16(this.workspacePath, workspaceDir);
|
|
2700
|
+
const chatsPath = join16(workspacePath, "chats.json");
|
|
2701
|
+
const sessionsPath = join16(workspacePath, "sessions");
|
|
2554
2702
|
const chatsContent = readFileSafe(chatsPath);
|
|
2555
2703
|
if (!chatsContent) {
|
|
2556
2704
|
continue;
|
|
@@ -2578,7 +2726,7 @@ var QwenPawParser = class {
|
|
|
2578
2726
|
for (const msg of sessionMessages) {
|
|
2579
2727
|
events.push({
|
|
2580
2728
|
sessionId: chat.session_id,
|
|
2581
|
-
source:
|
|
2729
|
+
source: TOOL_ID11,
|
|
2582
2730
|
project: workspaceDir,
|
|
2583
2731
|
timestamp: new Date(msg.timestamp),
|
|
2584
2732
|
role: msg.role
|
|
@@ -2594,7 +2742,7 @@ var QwenPawParser = class {
|
|
|
2594
2742
|
}
|
|
2595
2743
|
getSessionFiles(sessionsPath) {
|
|
2596
2744
|
const files = /* @__PURE__ */ new Map();
|
|
2597
|
-
if (!
|
|
2745
|
+
if (!existsSync16(sessionsPath)) {
|
|
2598
2746
|
return files;
|
|
2599
2747
|
}
|
|
2600
2748
|
try {
|
|
@@ -2603,7 +2751,7 @@ var QwenPawParser = class {
|
|
|
2603
2751
|
if (!fileName.endsWith(".json")) {
|
|
2604
2752
|
continue;
|
|
2605
2753
|
}
|
|
2606
|
-
const filePath =
|
|
2754
|
+
const filePath = join16(sessionsPath, fileName);
|
|
2607
2755
|
const content = readFileSafe(filePath);
|
|
2608
2756
|
if (content) {
|
|
2609
2757
|
const sessionId = fileName.replace(/^[^_]+_/, "").replace(".json", "");
|
|
@@ -2701,15 +2849,15 @@ var QwenPawParser = class {
|
|
|
2701
2849
|
});
|
|
2702
2850
|
}
|
|
2703
2851
|
isInstalled() {
|
|
2704
|
-
return
|
|
2852
|
+
return existsSync16(this.usagePath) || existsSync16(this.workspacePath);
|
|
2705
2853
|
}
|
|
2706
2854
|
};
|
|
2707
2855
|
registerParser(new QwenPawParser());
|
|
2708
2856
|
|
|
2709
2857
|
// src/parsers/cline.ts
|
|
2710
2858
|
import { readFileSync as readFileSync6, statSync } from "fs";
|
|
2711
|
-
import { homedir as
|
|
2712
|
-
import { basename as basename6, join as
|
|
2859
|
+
import { homedir as homedir16 } from "os";
|
|
2860
|
+
import { basename as basename6, join as join17 } from "path";
|
|
2713
2861
|
var EXTENSION_ID = "saoudrizwan.claude-dev";
|
|
2714
2862
|
var HOSTS = [
|
|
2715
2863
|
"Code",
|
|
@@ -2723,26 +2871,26 @@ var HOSTS = [
|
|
|
2723
2871
|
var TOOL6 = {
|
|
2724
2872
|
id: "cline",
|
|
2725
2873
|
name: "Cline",
|
|
2726
|
-
dataDir:
|
|
2874
|
+
dataDir: join17(homedir16(), ".cline")
|
|
2727
2875
|
};
|
|
2728
2876
|
function getHostRoots() {
|
|
2729
2877
|
const out = [];
|
|
2730
2878
|
if (process.platform === "darwin") {
|
|
2731
|
-
const base =
|
|
2732
|
-
for (const h of HOSTS) out.push(
|
|
2879
|
+
const base = join17(homedir16(), "Library", "Application Support");
|
|
2880
|
+
for (const h of HOSTS) out.push(join17(base, h));
|
|
2733
2881
|
} else if (process.platform === "win32") {
|
|
2734
|
-
const appData = process.env.APPDATA?.trim() ||
|
|
2735
|
-
for (const h of HOSTS) out.push(
|
|
2882
|
+
const appData = process.env.APPDATA?.trim() || join17(homedir16(), "AppData", "Roaming");
|
|
2883
|
+
for (const h of HOSTS) out.push(join17(appData, h));
|
|
2736
2884
|
} else {
|
|
2737
|
-
const xdg = process.env.XDG_CONFIG_HOME?.trim() ||
|
|
2738
|
-
for (const h of HOSTS) out.push(
|
|
2885
|
+
const xdg = process.env.XDG_CONFIG_HOME?.trim() || join17(homedir16(), ".config");
|
|
2886
|
+
for (const h of HOSTS) out.push(join17(xdg, h));
|
|
2739
2887
|
}
|
|
2740
2888
|
return out;
|
|
2741
2889
|
}
|
|
2742
2890
|
function findClineExtensionDirs() {
|
|
2743
2891
|
const dirs = [];
|
|
2744
2892
|
for (const root of getHostRoots()) {
|
|
2745
|
-
const ext =
|
|
2893
|
+
const ext = join17(root, "User", "globalStorage", EXTENSION_ID);
|
|
2746
2894
|
try {
|
|
2747
2895
|
if (statSync(ext).isDirectory()) dirs.push(ext);
|
|
2748
2896
|
} catch {
|
|
@@ -2774,7 +2922,7 @@ var ClineParser = class {
|
|
|
2774
2922
|
const entries = [];
|
|
2775
2923
|
const sessionEvents = [];
|
|
2776
2924
|
for (const extDir of extDirs) {
|
|
2777
|
-
const history = readJsonSafe(
|
|
2925
|
+
const history = readJsonSafe(join17(extDir, "state", "taskHistory.json"));
|
|
2778
2926
|
if (!Array.isArray(history)) continue;
|
|
2779
2927
|
for (const item of history) {
|
|
2780
2928
|
try {
|
|
@@ -2785,7 +2933,7 @@ var ClineParser = class {
|
|
|
2785
2933
|
);
|
|
2786
2934
|
const fallbackModel = item.modelId && String(item.modelId).trim() || "cline-unknown";
|
|
2787
2935
|
const messages = readJsonSafe(
|
|
2788
|
-
|
|
2936
|
+
join17(extDir, "tasks", taskId, "ui_messages.json")
|
|
2789
2937
|
);
|
|
2790
2938
|
if (!Array.isArray(messages)) continue;
|
|
2791
2939
|
for (const msg of messages) {
|
|
@@ -2856,20 +3004,20 @@ registerParser(new ClineParser());
|
|
|
2856
3004
|
import { execFileSync as execFileSync3 } from "child_process";
|
|
2857
3005
|
import {
|
|
2858
3006
|
copyFileSync,
|
|
2859
|
-
existsSync as
|
|
3007
|
+
existsSync as existsSync17,
|
|
2860
3008
|
mkdtempSync,
|
|
2861
3009
|
readdirSync as readdirSync10,
|
|
2862
3010
|
readFileSync as readFileSync7,
|
|
2863
3011
|
rmSync,
|
|
2864
3012
|
statSync as statSync2
|
|
2865
3013
|
} from "fs";
|
|
2866
|
-
import { homedir as
|
|
2867
|
-
import { join as
|
|
2868
|
-
var KIROAGENT_RELATIVE =
|
|
3014
|
+
import { homedir as homedir17, tmpdir } from "os";
|
|
3015
|
+
import { join as join18, resolve } from "path";
|
|
3016
|
+
var KIROAGENT_RELATIVE = join18("User", "globalStorage", "kiro.kiroagent");
|
|
2869
3017
|
function getDefaultBasePath() {
|
|
2870
3018
|
if (process.platform === "darwin") {
|
|
2871
|
-
return
|
|
2872
|
-
|
|
3019
|
+
return join18(
|
|
3020
|
+
homedir17(),
|
|
2873
3021
|
"Library",
|
|
2874
3022
|
"Application Support",
|
|
2875
3023
|
"Kiro",
|
|
@@ -2877,11 +3025,11 @@ function getDefaultBasePath() {
|
|
|
2877
3025
|
);
|
|
2878
3026
|
}
|
|
2879
3027
|
if (process.platform === "win32") {
|
|
2880
|
-
const appData = process.env.APPDATA?.trim() ||
|
|
2881
|
-
return
|
|
3028
|
+
const appData = process.env.APPDATA?.trim() || join18(homedir17(), "AppData", "Roaming");
|
|
3029
|
+
return join18(appData, "Kiro", KIROAGENT_RELATIVE);
|
|
2882
3030
|
}
|
|
2883
|
-
const xdgConfigHome = process.env.XDG_CONFIG_HOME?.trim() ||
|
|
2884
|
-
return
|
|
3031
|
+
const xdgConfigHome = process.env.XDG_CONFIG_HOME?.trim() || join18(homedir17(), ".config");
|
|
3032
|
+
return join18(xdgConfigHome, "Kiro", KIROAGENT_RELATIVE);
|
|
2885
3033
|
}
|
|
2886
3034
|
var TOOL7 = {
|
|
2887
3035
|
id: "kiro",
|
|
@@ -2892,10 +3040,10 @@ function getKiroBasePath() {
|
|
|
2892
3040
|
const explicit = process.env.KIRO_BASE_PATH?.trim();
|
|
2893
3041
|
if (explicit) {
|
|
2894
3042
|
const r = resolve(explicit);
|
|
2895
|
-
return
|
|
3043
|
+
return existsSync17(r) ? r : null;
|
|
2896
3044
|
}
|
|
2897
3045
|
const def = getDefaultBasePath();
|
|
2898
|
-
return
|
|
3046
|
+
return existsSync17(def) ? def : null;
|
|
2899
3047
|
}
|
|
2900
3048
|
function isLockError(err) {
|
|
2901
3049
|
return err instanceof Error && typeof err.message === "string" && /database is locked/i.test(err.message);
|
|
@@ -2916,12 +3064,12 @@ function readDb(dbPath) {
|
|
|
2916
3064
|
return queryDb(dbPath, TOKENS_SQL);
|
|
2917
3065
|
} catch (err) {
|
|
2918
3066
|
if (!isLockError(err)) throw err;
|
|
2919
|
-
const snapshotDir = mkdtempSync(
|
|
2920
|
-
const queryPath =
|
|
3067
|
+
const snapshotDir = mkdtempSync(join18(tmpdir(), "vibe-usage-kiro-"));
|
|
3068
|
+
const queryPath = join18(snapshotDir, "devdata.sqlite");
|
|
2921
3069
|
copyFileSync(dbPath, queryPath);
|
|
2922
3070
|
for (const suffix of ["-shm", "-wal"]) {
|
|
2923
3071
|
const companion = `${dbPath}${suffix}`;
|
|
2924
|
-
if (
|
|
3072
|
+
if (existsSync17(companion))
|
|
2925
3073
|
copyFileSync(companion, `${queryPath}${suffix}`);
|
|
2926
3074
|
}
|
|
2927
3075
|
try {
|
|
@@ -2973,7 +3121,7 @@ function buildModelTimeline(base) {
|
|
|
2973
3121
|
}
|
|
2974
3122
|
for (const entry of entries) {
|
|
2975
3123
|
if (!entry.isDirectory() || entry.name === "dev_data") continue;
|
|
2976
|
-
const dirPath =
|
|
3124
|
+
const dirPath = join18(base, entry.name);
|
|
2977
3125
|
let files;
|
|
2978
3126
|
try {
|
|
2979
3127
|
files = readdirSync10(dirPath).filter((f) => f.endsWith(".chat"));
|
|
@@ -2982,7 +3130,7 @@ function buildModelTimeline(base) {
|
|
|
2982
3130
|
}
|
|
2983
3131
|
for (const file of files) {
|
|
2984
3132
|
try {
|
|
2985
|
-
const data = JSON.parse(readFileSync7(
|
|
3133
|
+
const data = JSON.parse(readFileSync7(join18(dirPath, file), "utf-8"));
|
|
2986
3134
|
const meta = data?.metadata;
|
|
2987
3135
|
if (!meta?.modelId || !meta?.startTime) continue;
|
|
2988
3136
|
const startMs = Number(meta.startTime);
|
|
@@ -3031,13 +3179,13 @@ var KiroParser = class {
|
|
|
3031
3179
|
async parse() {
|
|
3032
3180
|
const base = getKiroBasePath();
|
|
3033
3181
|
if (!base) return { buckets: [], sessions: [] };
|
|
3034
|
-
const dbPath =
|
|
3035
|
-
const jsonlPath =
|
|
3182
|
+
const dbPath = join18(base, "dev_data", "devdata.sqlite");
|
|
3183
|
+
const jsonlPath = join18(base, "dev_data", "tokens_generated.jsonl");
|
|
3036
3184
|
let rows;
|
|
3037
3185
|
try {
|
|
3038
|
-
if (
|
|
3186
|
+
if (existsSync17(dbPath)) {
|
|
3039
3187
|
rows = readDb(dbPath);
|
|
3040
|
-
} else if (
|
|
3188
|
+
} else if (existsSync17(jsonlPath)) {
|
|
3041
3189
|
rows = readJsonl(jsonlPath);
|
|
3042
3190
|
} else {
|
|
3043
3191
|
return { buckets: [], sessions: [] };
|
|
@@ -3088,8 +3236,8 @@ registerParser(new KiroParser());
|
|
|
3088
3236
|
|
|
3089
3237
|
// src/parsers/roo-code.ts
|
|
3090
3238
|
import { readdirSync as readdirSync11, readFileSync as readFileSync8, statSync as statSync3 } from "fs";
|
|
3091
|
-
import { homedir as
|
|
3092
|
-
import { basename as basename7, join as
|
|
3239
|
+
import { homedir as homedir18 } from "os";
|
|
3240
|
+
import { basename as basename7, join as join19 } from "path";
|
|
3093
3241
|
var EXTENSION_ID2 = "rooveterinaryinc.roo-cline";
|
|
3094
3242
|
var HOSTS2 = [
|
|
3095
3243
|
"Code",
|
|
@@ -3104,17 +3252,17 @@ function getHostRoots2() {
|
|
|
3104
3252
|
const out = [];
|
|
3105
3253
|
let roots;
|
|
3106
3254
|
if (process.platform === "darwin") {
|
|
3107
|
-
roots = [
|
|
3255
|
+
roots = [join19(homedir18(), "Library", "Application Support")];
|
|
3108
3256
|
} else if (process.platform === "win32") {
|
|
3109
3257
|
roots = [
|
|
3110
|
-
process.env.APPDATA?.trim() ||
|
|
3258
|
+
process.env.APPDATA?.trim() || join19(homedir18(), "AppData", "Roaming")
|
|
3111
3259
|
];
|
|
3112
3260
|
} else {
|
|
3113
|
-
roots = [process.env.XDG_CONFIG_HOME?.trim() ||
|
|
3261
|
+
roots = [process.env.XDG_CONFIG_HOME?.trim() || join19(homedir18(), ".config")];
|
|
3114
3262
|
}
|
|
3115
3263
|
for (const root of roots) {
|
|
3116
3264
|
for (const h of HOSTS2) {
|
|
3117
|
-
out.push(
|
|
3265
|
+
out.push(join19(root, h));
|
|
3118
3266
|
}
|
|
3119
3267
|
}
|
|
3120
3268
|
return out;
|
|
@@ -3122,7 +3270,7 @@ function getHostRoots2() {
|
|
|
3122
3270
|
function findExtensionDirs() {
|
|
3123
3271
|
const dirs = [];
|
|
3124
3272
|
for (const root of getHostRoots2()) {
|
|
3125
|
-
const ext =
|
|
3273
|
+
const ext = join19(root, "User", "globalStorage", EXTENSION_ID2);
|
|
3126
3274
|
try {
|
|
3127
3275
|
if (statSync3(ext).isDirectory()) dirs.push(ext);
|
|
3128
3276
|
} catch {
|
|
@@ -3144,9 +3292,9 @@ function projectFromPath2(absPath) {
|
|
|
3144
3292
|
return name || "unknown";
|
|
3145
3293
|
}
|
|
3146
3294
|
function readHistoryItems(extDir) {
|
|
3147
|
-
const tasksDir =
|
|
3295
|
+
const tasksDir = join19(extDir, "tasks");
|
|
3148
3296
|
const index = readJsonSafe2(
|
|
3149
|
-
|
|
3297
|
+
join19(tasksDir, "_index.json")
|
|
3150
3298
|
);
|
|
3151
3299
|
if (index?.entries && Array.isArray(index.entries)) return index.entries;
|
|
3152
3300
|
const items = [];
|
|
@@ -3160,7 +3308,7 @@ function readHistoryItems(extDir) {
|
|
|
3160
3308
|
if (!entry.isDirectory() || entry.name.startsWith("_") || entry.name.startsWith("."))
|
|
3161
3309
|
continue;
|
|
3162
3310
|
const item = readJsonSafe2(
|
|
3163
|
-
|
|
3311
|
+
join19(tasksDir, entry.name, "history_item.json")
|
|
3164
3312
|
);
|
|
3165
3313
|
if (item && typeof item === "object") items.push(item);
|
|
3166
3314
|
}
|
|
@@ -3187,7 +3335,7 @@ var RooCodeParser = class {
|
|
|
3187
3335
|
const project = projectFromPath2(item.workspace);
|
|
3188
3336
|
const fallbackModel = item.apiConfigName && String(item.apiConfigName).trim() || "roo-unknown";
|
|
3189
3337
|
const messages = readJsonSafe2(
|
|
3190
|
-
|
|
3338
|
+
join19(extDir, "tasks", taskId, "ui_messages.json")
|
|
3191
3339
|
);
|
|
3192
3340
|
if (!Array.isArray(messages)) continue;
|
|
3193
3341
|
for (const msg of messages) {
|
|
@@ -3250,21 +3398,77 @@ var RooCodeParser = class {
|
|
|
3250
3398
|
};
|
|
3251
3399
|
registerParser(new RooCodeParser());
|
|
3252
3400
|
|
|
3401
|
+
// src/parsers/snow.ts
|
|
3402
|
+
import { existsSync as existsSync18 } from "fs";
|
|
3403
|
+
import { homedir as homedir19 } from "os";
|
|
3404
|
+
import { join as join20 } from "path";
|
|
3405
|
+
var DEFAULT_DATA_DIR6 = join20(homedir19(), ".snow", "usage");
|
|
3406
|
+
function toNonNegativeNumber(value) {
|
|
3407
|
+
const numberValue = Number(value);
|
|
3408
|
+
return Number.isFinite(numberValue) && numberValue >= 0 ? numberValue : 0;
|
|
3409
|
+
}
|
|
3410
|
+
var SnowParser = class {
|
|
3411
|
+
constructor(dataDir = DEFAULT_DATA_DIR6) {
|
|
3412
|
+
this.dataDir = dataDir;
|
|
3413
|
+
this.tool = { id: "snow", name: "Snow CLI", dataDir };
|
|
3414
|
+
}
|
|
3415
|
+
dataDir;
|
|
3416
|
+
tool;
|
|
3417
|
+
async parse() {
|
|
3418
|
+
const entries = [];
|
|
3419
|
+
for (const filePath of findJsonlFiles(this.dataDir)) {
|
|
3420
|
+
const content = readFileSafe(filePath);
|
|
3421
|
+
if (!content) continue;
|
|
3422
|
+
for (const line of content.split("\n")) {
|
|
3423
|
+
if (!line.trim()) continue;
|
|
3424
|
+
try {
|
|
3425
|
+
const record = JSON.parse(line);
|
|
3426
|
+
if (typeof record.timestamp !== "string") continue;
|
|
3427
|
+
const timestamp = new Date(record.timestamp);
|
|
3428
|
+
if (Number.isNaN(timestamp.getTime())) continue;
|
|
3429
|
+
const inputTokens = toNonNegativeNumber(record.inputTokens);
|
|
3430
|
+
const outputTokens = toNonNegativeNumber(record.outputTokens);
|
|
3431
|
+
const cachedTokens = toNonNegativeNumber(record.cacheReadInputTokens);
|
|
3432
|
+
const reasoningTokens = toNonNegativeNumber(record.reasoningTokens);
|
|
3433
|
+
if (inputTokens + outputTokens + cachedTokens + reasoningTokens === 0)
|
|
3434
|
+
continue;
|
|
3435
|
+
entries.push({
|
|
3436
|
+
source: "snow",
|
|
3437
|
+
model: typeof record.model === "string" && record.model ? record.model : "unknown",
|
|
3438
|
+
project: "unknown",
|
|
3439
|
+
timestamp,
|
|
3440
|
+
inputTokens,
|
|
3441
|
+
outputTokens,
|
|
3442
|
+
reasoningTokens,
|
|
3443
|
+
cachedTokens
|
|
3444
|
+
});
|
|
3445
|
+
} catch {
|
|
3446
|
+
}
|
|
3447
|
+
}
|
|
3448
|
+
}
|
|
3449
|
+
return { buckets: aggregateToBuckets(entries), sessions: [] };
|
|
3450
|
+
}
|
|
3451
|
+
isInstalled() {
|
|
3452
|
+
return existsSync18(this.dataDir);
|
|
3453
|
+
}
|
|
3454
|
+
};
|
|
3455
|
+
registerParser(new SnowParser());
|
|
3456
|
+
|
|
3253
3457
|
// src/parsers/cursor.ts
|
|
3254
3458
|
import { execFileSync as execFileSync4 } from "child_process";
|
|
3255
|
-
import { copyFileSync as copyFileSync2, existsSync as
|
|
3256
|
-
import { homedir as
|
|
3257
|
-
import { dirname as dirname4, join as
|
|
3258
|
-
var
|
|
3259
|
-
var
|
|
3260
|
-
var STATE_DB_RELATIVE =
|
|
3459
|
+
import { copyFileSync as copyFileSync2, existsSync as existsSync19, mkdtempSync as mkdtempSync2, rmSync as rmSync2 } from "fs";
|
|
3460
|
+
import { homedir as homedir20, tmpdir as tmpdir2 } from "os";
|
|
3461
|
+
import { dirname as dirname4, join as join21, resolve as resolve2 } from "path";
|
|
3462
|
+
var TOOL_ID12 = "cursor";
|
|
3463
|
+
var TOOL_NAME12 = "Cursor";
|
|
3464
|
+
var STATE_DB_RELATIVE = join21("User", "globalStorage", "state.vscdb");
|
|
3261
3465
|
var ACCESS_TOKEN_KEY = "cursorAuth/accessToken";
|
|
3262
3466
|
var SESSION_COOKIE = "WorkosCursorSessionToken";
|
|
3263
3467
|
var FETCH_TIMEOUT_MS = 1e4;
|
|
3264
3468
|
function getDefaultStateDbPath() {
|
|
3265
3469
|
if (process.platform === "darwin") {
|
|
3266
|
-
return
|
|
3267
|
-
|
|
3470
|
+
return join21(
|
|
3471
|
+
homedir20(),
|
|
3268
3472
|
"Library",
|
|
3269
3473
|
"Application Support",
|
|
3270
3474
|
"Cursor",
|
|
@@ -3272,25 +3476,25 @@ function getDefaultStateDbPath() {
|
|
|
3272
3476
|
);
|
|
3273
3477
|
}
|
|
3274
3478
|
if (process.platform === "win32") {
|
|
3275
|
-
const appData = process.env.APPDATA?.trim() ||
|
|
3276
|
-
return
|
|
3479
|
+
const appData = process.env.APPDATA?.trim() || join21(homedir20(), "AppData", "Roaming");
|
|
3480
|
+
return join21(appData, "Cursor", STATE_DB_RELATIVE);
|
|
3277
3481
|
}
|
|
3278
|
-
const xdgConfigHome = process.env.XDG_CONFIG_HOME?.trim() ||
|
|
3279
|
-
return
|
|
3482
|
+
const xdgConfigHome = process.env.XDG_CONFIG_HOME?.trim() || join21(homedir20(), ".config");
|
|
3483
|
+
return join21(xdgConfigHome, "Cursor", STATE_DB_RELATIVE);
|
|
3280
3484
|
}
|
|
3281
3485
|
function getCursorStateDbPath() {
|
|
3282
3486
|
const explicit = process.env.CURSOR_STATE_DB_PATH?.trim();
|
|
3283
3487
|
if (explicit) {
|
|
3284
3488
|
const resolved = resolve2(explicit);
|
|
3285
|
-
return
|
|
3489
|
+
return existsSync19(resolved) ? resolved : null;
|
|
3286
3490
|
}
|
|
3287
3491
|
const configDirs = process.env.CURSOR_CONFIG_DIR?.trim();
|
|
3288
3492
|
const candidates = configDirs ? configDirs.split(",").map((v) => v.trim()).filter(Boolean).map((v) => {
|
|
3289
3493
|
const r = resolve2(v);
|
|
3290
|
-
return r.endsWith(".vscdb") ? r :
|
|
3494
|
+
return r.endsWith(".vscdb") ? r : join21(r, STATE_DB_RELATIVE);
|
|
3291
3495
|
}) : [getDefaultStateDbPath()];
|
|
3292
3496
|
for (const c of candidates) {
|
|
3293
|
-
if (
|
|
3497
|
+
if (existsSync19(c)) return c;
|
|
3294
3498
|
}
|
|
3295
3499
|
return null;
|
|
3296
3500
|
}
|
|
@@ -3330,13 +3534,13 @@ function readAccessToken(dbPath) {
|
|
|
3330
3534
|
return queryAccessToken(dbPath);
|
|
3331
3535
|
} catch (err) {
|
|
3332
3536
|
if (!isLockError2(err)) throw err;
|
|
3333
|
-
const snapshotDir = mkdtempSync2(
|
|
3334
|
-
const queryPath =
|
|
3537
|
+
const snapshotDir = mkdtempSync2(join21(tmpdir2(), "tokenarena-cursor-"));
|
|
3538
|
+
const queryPath = join21(snapshotDir, "state.vscdb");
|
|
3335
3539
|
try {
|
|
3336
3540
|
copyFileSync2(dbPath, queryPath);
|
|
3337
3541
|
for (const suffix of ["-shm", "-wal"]) {
|
|
3338
3542
|
const companion = `${dbPath}${suffix}`;
|
|
3339
|
-
if (
|
|
3543
|
+
if (existsSync19(companion))
|
|
3340
3544
|
copyFileSync2(companion, `${queryPath}${suffix}`);
|
|
3341
3545
|
}
|
|
3342
3546
|
return queryAccessToken(queryPath);
|
|
@@ -3464,8 +3668,8 @@ function parseInt0(value) {
|
|
|
3464
3668
|
}
|
|
3465
3669
|
function createToolDefinition10(dbPath) {
|
|
3466
3670
|
return {
|
|
3467
|
-
id:
|
|
3468
|
-
name:
|
|
3671
|
+
id: TOOL_ID12,
|
|
3672
|
+
name: TOOL_NAME12,
|
|
3469
3673
|
dataDir: dirname4(dbPath)
|
|
3470
3674
|
};
|
|
3471
3675
|
}
|
|
@@ -3481,7 +3685,7 @@ var CursorParser = class {
|
|
|
3481
3685
|
this.tool = createToolDefinition10(this.dbPath);
|
|
3482
3686
|
}
|
|
3483
3687
|
async parse() {
|
|
3484
|
-
if (!this.dbPath || !
|
|
3688
|
+
if (!this.dbPath || !existsSync19(this.dbPath)) {
|
|
3485
3689
|
return { buckets: [], sessions: [] };
|
|
3486
3690
|
}
|
|
3487
3691
|
let token;
|
|
@@ -3528,7 +3732,7 @@ var CursorParser = class {
|
|
|
3528
3732
|
const output = outputIdx >= 0 ? parseInt0(row[outputIdx]) : 0;
|
|
3529
3733
|
if (inputCacheWrite + inputNoCache + cacheRead + output === 0) continue;
|
|
3530
3734
|
entries.push({
|
|
3531
|
-
source:
|
|
3735
|
+
source: TOOL_ID12,
|
|
3532
3736
|
model,
|
|
3533
3737
|
project: "unknown",
|
|
3534
3738
|
timestamp,
|
|
@@ -3544,19 +3748,19 @@ var CursorParser = class {
|
|
|
3544
3748
|
};
|
|
3545
3749
|
}
|
|
3546
3750
|
isInstalled() {
|
|
3547
|
-
return
|
|
3751
|
+
return existsSync19(this.dbPath);
|
|
3548
3752
|
}
|
|
3549
3753
|
};
|
|
3550
3754
|
registerParser(new CursorParser());
|
|
3551
3755
|
|
|
3552
3756
|
// src/parsers/zcode.ts
|
|
3553
3757
|
import { createHash as createHash2 } from "crypto";
|
|
3554
|
-
import { existsSync as
|
|
3555
|
-
import { homedir as
|
|
3556
|
-
import { dirname as dirname5, join as
|
|
3557
|
-
var
|
|
3558
|
-
var
|
|
3559
|
-
var
|
|
3758
|
+
import { existsSync as existsSync20 } from "fs";
|
|
3759
|
+
import { homedir as homedir21, hostname as hostname4 } from "os";
|
|
3760
|
+
import { dirname as dirname5, join as join22 } from "path";
|
|
3761
|
+
var TOOL_ID13 = "zcode";
|
|
3762
|
+
var TOOL_NAME13 = "ZCode";
|
|
3763
|
+
var DEFAULT_DB_PATH3 = join22(homedir21(), ".zcode", "cli", "db", "db.sqlite");
|
|
3560
3764
|
var MODEL_USAGE_QUERY = `SELECT
|
|
3561
3765
|
model_usage.session_id as sessionId,
|
|
3562
3766
|
session.directory as directory,
|
|
@@ -3591,12 +3795,12 @@ var TURN_USAGE_QUERY = `SELECT
|
|
|
3591
3795
|
WHERE duration_ms IS NOT NULL`;
|
|
3592
3796
|
function createToolDefinition11(dbPath) {
|
|
3593
3797
|
return {
|
|
3594
|
-
id:
|
|
3595
|
-
name:
|
|
3798
|
+
id: TOOL_ID13,
|
|
3799
|
+
name: TOOL_NAME13,
|
|
3596
3800
|
dataDir: dirname5(dbPath)
|
|
3597
3801
|
};
|
|
3598
3802
|
}
|
|
3599
|
-
function
|
|
3803
|
+
function toSafeNumber11(value) {
|
|
3600
3804
|
const numberValue = Number(value);
|
|
3601
3805
|
return Number.isFinite(numberValue) && numberValue > 0 ? numberValue : 0;
|
|
3602
3806
|
}
|
|
@@ -3640,7 +3844,7 @@ function getOrCreateDraft(drafts, sessionId, project) {
|
|
|
3640
3844
|
}
|
|
3641
3845
|
const next = {
|
|
3642
3846
|
sessionId,
|
|
3643
|
-
source:
|
|
3847
|
+
source: TOOL_ID13,
|
|
3644
3848
|
project,
|
|
3645
3849
|
firstMessageAt: null,
|
|
3646
3850
|
lastMessageAt: null,
|
|
@@ -3734,7 +3938,7 @@ function buildSessions(input2) {
|
|
|
3734
3938
|
continue;
|
|
3735
3939
|
}
|
|
3736
3940
|
const draft = getOrCreateDraft(drafts, sessionId, "unknown");
|
|
3737
|
-
draft.activeSeconds += Math.round(
|
|
3941
|
+
draft.activeSeconds += Math.round(toSafeNumber11(row.durationMs) / 1e3);
|
|
3738
3942
|
}
|
|
3739
3943
|
const usageBySession = buildSessionUsage2(input2.entries);
|
|
3740
3944
|
const host = hostname4().replace(/\.local$/, "");
|
|
@@ -3803,12 +4007,12 @@ var ZCodeParser = class {
|
|
|
3803
4007
|
dbPath;
|
|
3804
4008
|
queryRows;
|
|
3805
4009
|
constructor(options = {}) {
|
|
3806
|
-
this.dbPath = options.dbPath ||
|
|
4010
|
+
this.dbPath = options.dbPath || DEFAULT_DB_PATH3;
|
|
3807
4011
|
this.queryRows = options.queryRows || readSqliteRows;
|
|
3808
4012
|
this.tool = createToolDefinition11(this.dbPath);
|
|
3809
4013
|
}
|
|
3810
4014
|
async parse() {
|
|
3811
|
-
if (!
|
|
4015
|
+
if (!existsSync20(this.dbPath)) {
|
|
3812
4016
|
return { buckets: [], sessions: [] };
|
|
3813
4017
|
}
|
|
3814
4018
|
const usageRows = await this.queryRows(
|
|
@@ -3821,16 +4025,16 @@ var ZCodeParser = class {
|
|
|
3821
4025
|
if (!timestamp) {
|
|
3822
4026
|
continue;
|
|
3823
4027
|
}
|
|
3824
|
-
const inputTokens =
|
|
3825
|
-
const outputTokens =
|
|
3826
|
-
const reasoningTokens =
|
|
3827
|
-
const cachedTokens =
|
|
4028
|
+
const inputTokens = toSafeNumber11(row.inputTokens);
|
|
4029
|
+
const outputTokens = toSafeNumber11(row.outputTokens);
|
|
4030
|
+
const reasoningTokens = toSafeNumber11(row.reasoningTokens);
|
|
4031
|
+
const cachedTokens = toSafeNumber11(row.cacheReadInputTokens);
|
|
3828
4032
|
if (inputTokens === 0 && outputTokens === 0 && reasoningTokens === 0 && cachedTokens === 0) {
|
|
3829
4033
|
continue;
|
|
3830
4034
|
}
|
|
3831
4035
|
entries.push({
|
|
3832
4036
|
sessionId: getString2(row.sessionId) ?? void 0,
|
|
3833
|
-
source:
|
|
4037
|
+
source: TOOL_ID13,
|
|
3834
4038
|
model: getString2(row.model) ?? "unknown",
|
|
3835
4039
|
project: getPathLeaf7(getString2(row.directory)),
|
|
3836
4040
|
timestamp,
|
|
@@ -3866,7 +4070,7 @@ var ZCodeParser = class {
|
|
|
3866
4070
|
};
|
|
3867
4071
|
}
|
|
3868
4072
|
isInstalled() {
|
|
3869
|
-
return
|
|
4073
|
+
return existsSync20(this.dbPath);
|
|
3870
4074
|
}
|
|
3871
4075
|
};
|
|
3872
4076
|
registerParser(new ZCodeParser());
|
|
@@ -3877,31 +4081,31 @@ import { Command, Option } from "commander";
|
|
|
3877
4081
|
// src/infrastructure/config/manager.ts
|
|
3878
4082
|
import { randomUUID } from "crypto";
|
|
3879
4083
|
import {
|
|
3880
|
-
existsSync as
|
|
4084
|
+
existsSync as existsSync21,
|
|
3881
4085
|
mkdirSync,
|
|
3882
4086
|
readFileSync as readFileSync9,
|
|
3883
4087
|
unlinkSync,
|
|
3884
4088
|
writeFileSync
|
|
3885
4089
|
} from "fs";
|
|
3886
|
-
import { join as
|
|
4090
|
+
import { join as join24 } from "path";
|
|
3887
4091
|
|
|
3888
4092
|
// src/infrastructure/xdg.ts
|
|
3889
|
-
import { homedir as
|
|
3890
|
-
import { join as
|
|
4093
|
+
import { homedir as homedir22 } from "os";
|
|
4094
|
+
import { join as join23 } from "path";
|
|
3891
4095
|
function getConfigHome() {
|
|
3892
|
-
return process.env.XDG_CONFIG_HOME ||
|
|
4096
|
+
return process.env.XDG_CONFIG_HOME || join23(homedir22(), ".config");
|
|
3893
4097
|
}
|
|
3894
4098
|
function getStateHome() {
|
|
3895
|
-
return process.env.XDG_STATE_HOME ||
|
|
4099
|
+
return process.env.XDG_STATE_HOME || join23(homedir22(), ".local", "state");
|
|
3896
4100
|
}
|
|
3897
4101
|
function getRuntimeDir() {
|
|
3898
4102
|
return process.env.XDG_RUNTIME_DIR || getStateHome();
|
|
3899
4103
|
}
|
|
3900
4104
|
|
|
3901
4105
|
// src/infrastructure/config/manager.ts
|
|
3902
|
-
var CONFIG_DIR =
|
|
4106
|
+
var CONFIG_DIR = join24(getConfigHome(), "tokenarena");
|
|
3903
4107
|
var isDev = process.env.TOKEN_ARENA_DEV === "1";
|
|
3904
|
-
var CONFIG_FILE =
|
|
4108
|
+
var CONFIG_FILE = join24(CONFIG_DIR, isDev ? "config.dev.json" : "config.json");
|
|
3905
4109
|
var DEFAULT_API_URL = "https://token.guji.uno";
|
|
3906
4110
|
var VALID_CONFIG_KEYS = [
|
|
3907
4111
|
"apiKey",
|
|
@@ -3917,7 +4121,7 @@ function getConfigDir() {
|
|
|
3917
4121
|
return CONFIG_DIR;
|
|
3918
4122
|
}
|
|
3919
4123
|
function loadConfig() {
|
|
3920
|
-
if (!
|
|
4124
|
+
if (!existsSync21(CONFIG_FILE)) return null;
|
|
3921
4125
|
try {
|
|
3922
4126
|
const raw = readFileSync9(CONFIG_FILE, "utf-8");
|
|
3923
4127
|
const config = JSON.parse(raw);
|
|
@@ -3935,7 +4139,7 @@ function saveConfig(config) {
|
|
|
3935
4139
|
`, "utf-8");
|
|
3936
4140
|
}
|
|
3937
4141
|
function deleteConfig() {
|
|
3938
|
-
if (
|
|
4142
|
+
if (existsSync21(CONFIG_FILE)) {
|
|
3939
4143
|
unlinkSync(CONFIG_FILE);
|
|
3940
4144
|
}
|
|
3941
4145
|
}
|
|
@@ -4791,7 +4995,7 @@ var ApiClient = class {
|
|
|
4791
4995
|
// src/infrastructure/runtime/lock.ts
|
|
4792
4996
|
import {
|
|
4793
4997
|
closeSync,
|
|
4794
|
-
existsSync as
|
|
4998
|
+
existsSync as existsSync22,
|
|
4795
4999
|
openSync,
|
|
4796
5000
|
readFileSync as readFileSync10,
|
|
4797
5001
|
rmSync as rmSync3,
|
|
@@ -4800,22 +5004,22 @@ import {
|
|
|
4800
5004
|
|
|
4801
5005
|
// src/infrastructure/runtime/paths.ts
|
|
4802
5006
|
import { mkdirSync as mkdirSync2 } from "fs";
|
|
4803
|
-
import { join as
|
|
5007
|
+
import { join as join25 } from "path";
|
|
4804
5008
|
var APP_NAME = "tokenarena";
|
|
4805
5009
|
function getRuntimeDirPath() {
|
|
4806
|
-
return
|
|
5010
|
+
return join25(getRuntimeDir(), APP_NAME);
|
|
4807
5011
|
}
|
|
4808
5012
|
function getStateDir() {
|
|
4809
|
-
return
|
|
5013
|
+
return join25(getStateHome(), APP_NAME);
|
|
4810
5014
|
}
|
|
4811
5015
|
function getSyncLockPath() {
|
|
4812
|
-
return
|
|
5016
|
+
return join25(getRuntimeDirPath(), "sync.lock");
|
|
4813
5017
|
}
|
|
4814
5018
|
function getSyncStatePath() {
|
|
4815
|
-
return
|
|
5019
|
+
return join25(getStateDir(), "status.json");
|
|
4816
5020
|
}
|
|
4817
5021
|
function getUploadManifestPath() {
|
|
4818
|
-
return
|
|
5022
|
+
return join25(getStateDir(), "upload-manifest.json");
|
|
4819
5023
|
}
|
|
4820
5024
|
function ensureAppDirs() {
|
|
4821
5025
|
mkdirSync2(getRuntimeDirPath(), { recursive: true });
|
|
@@ -4833,7 +5037,7 @@ function isProcessAlive(pid) {
|
|
|
4833
5037
|
}
|
|
4834
5038
|
}
|
|
4835
5039
|
function readLockMetadata(lockPath) {
|
|
4836
|
-
if (!
|
|
5040
|
+
if (!existsSync22(lockPath)) {
|
|
4837
5041
|
return null;
|
|
4838
5042
|
}
|
|
4839
5043
|
try {
|
|
@@ -4907,13 +5111,13 @@ function describeExistingSyncLock() {
|
|
|
4907
5111
|
}
|
|
4908
5112
|
|
|
4909
5113
|
// src/infrastructure/runtime/state.ts
|
|
4910
|
-
import { existsSync as
|
|
5114
|
+
import { existsSync as existsSync23, readFileSync as readFileSync11, writeFileSync as writeFileSync3 } from "fs";
|
|
4911
5115
|
function getDefaultState() {
|
|
4912
5116
|
return { status: "idle" };
|
|
4913
5117
|
}
|
|
4914
5118
|
function loadSyncState() {
|
|
4915
5119
|
const path = getSyncStatePath();
|
|
4916
|
-
if (!
|
|
5120
|
+
if (!existsSync23(path)) {
|
|
4917
5121
|
return getDefaultState();
|
|
4918
5122
|
}
|
|
4919
5123
|
try {
|
|
@@ -4974,7 +5178,7 @@ function markSyncFailed(source, error, status) {
|
|
|
4974
5178
|
}
|
|
4975
5179
|
|
|
4976
5180
|
// src/infrastructure/runtime/upload-manifest.ts
|
|
4977
|
-
import { existsSync as
|
|
5181
|
+
import { existsSync as existsSync24, readFileSync as readFileSync12, writeFileSync as writeFileSync4 } from "fs";
|
|
4978
5182
|
function isRecordOfStrings(value) {
|
|
4979
5183
|
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
4980
5184
|
return false;
|
|
@@ -4990,7 +5194,7 @@ function isUploadManifest(value) {
|
|
|
4990
5194
|
}
|
|
4991
5195
|
function loadUploadManifest() {
|
|
4992
5196
|
const path = getUploadManifestPath();
|
|
4993
|
-
if (!
|
|
5197
|
+
if (!existsSync24(path)) {
|
|
4994
5198
|
return null;
|
|
4995
5199
|
}
|
|
4996
5200
|
try {
|
|
@@ -5470,18 +5674,18 @@ View your dashboard at: ${apiUrl}/usage`);
|
|
|
5470
5674
|
|
|
5471
5675
|
// src/commands/init.ts
|
|
5472
5676
|
import { execFileSync as execFileSync7, spawn } from "child_process";
|
|
5473
|
-
import { existsSync as
|
|
5677
|
+
import { existsSync as existsSync27 } from "fs";
|
|
5474
5678
|
import { appendFile, mkdir, readFile } from "fs/promises";
|
|
5475
|
-
import { homedir as
|
|
5476
|
-
import { dirname as dirname6, join as
|
|
5679
|
+
import { homedir as homedir25, platform as platform5 } from "os";
|
|
5680
|
+
import { dirname as dirname6, join as join26, posix as posix3, win32 } from "path";
|
|
5477
5681
|
|
|
5478
5682
|
// src/infrastructure/service/index.ts
|
|
5479
5683
|
import { platform as platform4 } from "os";
|
|
5480
5684
|
|
|
5481
5685
|
// src/infrastructure/service/linux-systemd.ts
|
|
5482
5686
|
import { execFileSync as execFileSync5 } from "child_process";
|
|
5483
|
-
import { existsSync as
|
|
5484
|
-
import { homedir as
|
|
5687
|
+
import { existsSync as existsSync25, mkdirSync as mkdirSync3, rmSync as rmSync4, writeFileSync as writeFileSync5 } from "fs";
|
|
5688
|
+
import { homedir as homedir23, platform as platform2 } from "os";
|
|
5485
5689
|
import { posix } from "path";
|
|
5486
5690
|
|
|
5487
5691
|
// src/utils/command.ts
|
|
@@ -5550,10 +5754,10 @@ function escapeXml(value) {
|
|
|
5550
5754
|
|
|
5551
5755
|
// src/infrastructure/service/linux-systemd.ts
|
|
5552
5756
|
var SYSTEMD_SERVICE_NAME = "tokenarena";
|
|
5553
|
-
function getLinuxSystemdServiceDir(homePath =
|
|
5757
|
+
function getLinuxSystemdServiceDir(homePath = homedir23()) {
|
|
5554
5758
|
return posix.join(homePath, ".config", "systemd", "user");
|
|
5555
5759
|
}
|
|
5556
|
-
function getLinuxSystemdServiceFile(homePath =
|
|
5760
|
+
function getLinuxSystemdServiceFile(homePath = homedir23()) {
|
|
5557
5761
|
return posix.join(
|
|
5558
5762
|
getLinuxSystemdServiceDir(homePath),
|
|
5559
5763
|
`${SYSTEMD_SERVICE_NAME}.service`
|
|
@@ -5610,7 +5814,7 @@ function ensureSystemdAvailable() {
|
|
|
5610
5814
|
}
|
|
5611
5815
|
function createLinuxSystemdServiceBackend() {
|
|
5612
5816
|
function isInstalled() {
|
|
5613
|
-
return
|
|
5817
|
+
return existsSync25(getLinuxSystemdServiceFile());
|
|
5614
5818
|
}
|
|
5615
5819
|
async function setup(skipPrompt = false) {
|
|
5616
5820
|
if (!ensureSystemdAvailable()) {
|
|
@@ -5735,7 +5939,7 @@ function createLinuxSystemdServiceBackend() {
|
|
|
5735
5939
|
}
|
|
5736
5940
|
async function uninstall(skipPrompt = false) {
|
|
5737
5941
|
const serviceFile = getLinuxSystemdServiceFile();
|
|
5738
|
-
if (!
|
|
5942
|
+
if (!existsSync25(serviceFile)) {
|
|
5739
5943
|
logger.info(formatBullet("\u670D\u52A1\u6587\u4EF6\u4E0D\u5B58\u5728\u3002", "warning"));
|
|
5740
5944
|
return;
|
|
5741
5945
|
}
|
|
@@ -5796,17 +6000,17 @@ function createLinuxSystemdServiceBackend() {
|
|
|
5796
6000
|
|
|
5797
6001
|
// src/infrastructure/service/macos-launchd.ts
|
|
5798
6002
|
import { execFileSync as execFileSync6 } from "child_process";
|
|
5799
|
-
import { existsSync as
|
|
5800
|
-
import { homedir as
|
|
6003
|
+
import { existsSync as existsSync26, mkdirSync as mkdirSync4, rmSync as rmSync5, writeFileSync as writeFileSync6 } from "fs";
|
|
6004
|
+
import { homedir as homedir24, platform as platform3 } from "os";
|
|
5801
6005
|
import { posix as posix2 } from "path";
|
|
5802
6006
|
var MACOS_LAUNCHD_LABEL = "com.guji.tokenarena";
|
|
5803
6007
|
function getCurrentUid() {
|
|
5804
6008
|
return typeof process.getuid === "function" ? process.getuid() : null;
|
|
5805
6009
|
}
|
|
5806
|
-
function getMacosLaunchAgentDir(homePath =
|
|
6010
|
+
function getMacosLaunchAgentDir(homePath = homedir24()) {
|
|
5807
6011
|
return posix2.join(homePath, "Library", "LaunchAgents");
|
|
5808
6012
|
}
|
|
5809
|
-
function getMacosLaunchAgentFile(homePath =
|
|
6013
|
+
function getMacosLaunchAgentFile(homePath = homedir24()) {
|
|
5810
6014
|
return posix2.join(
|
|
5811
6015
|
getMacosLaunchAgentDir(homePath),
|
|
5812
6016
|
`${MACOS_LAUNCHD_LABEL}.plist`
|
|
@@ -5933,7 +6137,7 @@ function writeLaunchAgentPlist() {
|
|
|
5933
6137
|
label: MACOS_LAUNCHD_LABEL,
|
|
5934
6138
|
programArguments: [command.execPath, ...command.args],
|
|
5935
6139
|
environment: getManagedServiceEnvironment(),
|
|
5936
|
-
workingDirectory:
|
|
6140
|
+
workingDirectory: homedir24(),
|
|
5937
6141
|
standardOutPath: stdoutPath,
|
|
5938
6142
|
standardErrorPath: stderrPath
|
|
5939
6143
|
});
|
|
@@ -5958,7 +6162,7 @@ function bootstrapLaunchAgent() {
|
|
|
5958
6162
|
}
|
|
5959
6163
|
function createMacosLaunchdServiceBackend() {
|
|
5960
6164
|
function isInstalled() {
|
|
5961
|
-
return
|
|
6165
|
+
return existsSync26(getMacosLaunchAgentFile());
|
|
5962
6166
|
}
|
|
5963
6167
|
async function setup(skipPrompt = false) {
|
|
5964
6168
|
if (!ensureLaunchctlAvailable()) {
|
|
@@ -6099,7 +6303,7 @@ function createMacosLaunchdServiceBackend() {
|
|
|
6099
6303
|
}
|
|
6100
6304
|
async function uninstall(skipPrompt = false) {
|
|
6101
6305
|
const plistFile = getMacosLaunchAgentFile();
|
|
6102
|
-
if (!
|
|
6306
|
+
if (!existsSync26(plistFile)) {
|
|
6103
6307
|
logger.info(formatBullet("\u670D\u52A1\u6587\u4EF6\u4E0D\u5B58\u5728\u3002", "warning"));
|
|
6104
6308
|
return;
|
|
6105
6309
|
}
|
|
@@ -6210,7 +6414,7 @@ function resolvePowerShellProfilePath() {
|
|
|
6210
6414
|
const systemRoot = process.env.SYSTEMROOT || "C:\\Windows";
|
|
6211
6415
|
const candidates = [
|
|
6212
6416
|
"pwsh.exe",
|
|
6213
|
-
|
|
6417
|
+
join26(systemRoot, "System32", "WindowsPowerShell", "v1.0", "powershell.exe")
|
|
6214
6418
|
];
|
|
6215
6419
|
for (const command of candidates) {
|
|
6216
6420
|
try {
|
|
@@ -6239,8 +6443,8 @@ function resolvePowerShellProfilePath() {
|
|
|
6239
6443
|
function resolveShellAliasSetup(options = {}) {
|
|
6240
6444
|
const currentPlatform = options.currentPlatform ?? platform5();
|
|
6241
6445
|
const env = options.env ?? process.env;
|
|
6242
|
-
const homeDir = options.homeDir ??
|
|
6243
|
-
const pathExists = options.exists ??
|
|
6446
|
+
const homeDir = options.homeDir ?? homedir25();
|
|
6447
|
+
const pathExists = options.exists ?? existsSync27;
|
|
6244
6448
|
const shellFromEnv = env.SHELL ? basenameLikeShell(env.SHELL).toLowerCase() : "";
|
|
6245
6449
|
const shellName = shellFromEnv || (currentPlatform === "win32" ? "powershell" : "");
|
|
6246
6450
|
const aliasName = "ta";
|
|
@@ -6437,7 +6641,7 @@ async function setupShellAlias() {
|
|
|
6437
6641
|
try {
|
|
6438
6642
|
await mkdir(dirname6(setup.configFile), { recursive: true });
|
|
6439
6643
|
let existingContent = "";
|
|
6440
|
-
if (
|
|
6644
|
+
if (existsSync27(setup.configFile)) {
|
|
6441
6645
|
existingContent = await readFile(setup.configFile, "utf-8");
|
|
6442
6646
|
}
|
|
6443
6647
|
const normalizedContent = existingContent.toLowerCase();
|
|
@@ -6696,7 +6900,7 @@ function buildLocalUsageDashboardData(input2) {
|
|
|
6696
6900
|
|
|
6697
6901
|
// src/infrastructure/runtime/cli-version.ts
|
|
6698
6902
|
import { readFileSync as readFileSync13 } from "fs";
|
|
6699
|
-
import { dirname as dirname7, join as
|
|
6903
|
+
import { dirname as dirname7, join as join27 } from "path";
|
|
6700
6904
|
import { fileURLToPath } from "url";
|
|
6701
6905
|
var FALLBACK_VERSION = "0.0.0";
|
|
6702
6906
|
var cachedVersion;
|
|
@@ -6704,7 +6908,7 @@ function getCliVersion(metaUrl = import.meta.url) {
|
|
|
6704
6908
|
if (cachedVersion) {
|
|
6705
6909
|
return cachedVersion;
|
|
6706
6910
|
}
|
|
6707
|
-
const packageJsonPath =
|
|
6911
|
+
const packageJsonPath = join27(
|
|
6708
6912
|
dirname7(fileURLToPath(metaUrl)),
|
|
6709
6913
|
"..",
|
|
6710
6914
|
"package.json"
|
|
@@ -7115,8 +7319,8 @@ async function runSyncCommand(opts = {}) {
|
|
|
7115
7319
|
}
|
|
7116
7320
|
|
|
7117
7321
|
// src/commands/uninstall.ts
|
|
7118
|
-
import { existsSync as
|
|
7119
|
-
import { homedir as
|
|
7322
|
+
import { existsSync as existsSync28, readFileSync as readFileSync14, rmSync as rmSync6, writeFileSync as writeFileSync7 } from "fs";
|
|
7323
|
+
import { homedir as homedir26, platform as platform6 } from "os";
|
|
7120
7324
|
function removeShellAlias() {
|
|
7121
7325
|
const shell = process.env.SHELL;
|
|
7122
7326
|
if (!shell) return;
|
|
@@ -7125,22 +7329,22 @@ function removeShellAlias() {
|
|
|
7125
7329
|
let configFile;
|
|
7126
7330
|
switch (shellName) {
|
|
7127
7331
|
case "zsh":
|
|
7128
|
-
configFile = `${
|
|
7332
|
+
configFile = `${homedir26()}/.zshrc`;
|
|
7129
7333
|
break;
|
|
7130
7334
|
case "bash":
|
|
7131
|
-
if (platform6() === "darwin" &&
|
|
7132
|
-
configFile = `${
|
|
7335
|
+
if (platform6() === "darwin" && existsSync28(`${homedir26()}/.bash_profile`)) {
|
|
7336
|
+
configFile = `${homedir26()}/.bash_profile`;
|
|
7133
7337
|
} else {
|
|
7134
|
-
configFile = `${
|
|
7338
|
+
configFile = `${homedir26()}/.bashrc`;
|
|
7135
7339
|
}
|
|
7136
7340
|
break;
|
|
7137
7341
|
case "fish":
|
|
7138
|
-
configFile = `${
|
|
7342
|
+
configFile = `${homedir26()}/.config/fish/config.fish`;
|
|
7139
7343
|
break;
|
|
7140
7344
|
default:
|
|
7141
7345
|
return;
|
|
7142
7346
|
}
|
|
7143
|
-
if (!
|
|
7347
|
+
if (!existsSync28(configFile)) return;
|
|
7144
7348
|
try {
|
|
7145
7349
|
let content = readFileSync14(configFile, "utf-8");
|
|
7146
7350
|
const aliasPatterns = [
|
|
@@ -7179,7 +7383,7 @@ async function runUninstall() {
|
|
|
7179
7383
|
const runtimeDir = getRuntimeDirPath();
|
|
7180
7384
|
const serviceBackend = getServiceBackend();
|
|
7181
7385
|
const hasInstalledService = serviceBackend?.isInstalled() ?? false;
|
|
7182
|
-
const hasLocalArtifacts =
|
|
7386
|
+
const hasLocalArtifacts = existsSync28(configPath) || existsSync28(configDir) || existsSync28(stateDir) || existsSync28(runtimeDir) || hasInstalledService;
|
|
7183
7387
|
if (!hasLocalArtifacts) {
|
|
7184
7388
|
logger.info(formatHeader("\u5378\u8F7D TokenArena"));
|
|
7185
7389
|
logger.info(formatBullet("\u672A\u53D1\u73B0\u672C\u5730\u914D\u7F6E\uFF0C\u65E0\u9700\u5378\u8F7D\u3002"));
|
|
@@ -7223,22 +7427,22 @@ async function runUninstall() {
|
|
|
7223
7427
|
}
|
|
7224
7428
|
}
|
|
7225
7429
|
logger.info(formatSection("\u6267\u884C\u7ED3\u679C"));
|
|
7226
|
-
if (
|
|
7430
|
+
if (existsSync28(configPath)) {
|
|
7227
7431
|
deleteConfig();
|
|
7228
7432
|
logger.info(formatBullet("\u5DF2\u5220\u9664\u914D\u7F6E\u6587\u4EF6\u3002", "success"));
|
|
7229
7433
|
}
|
|
7230
|
-
if (
|
|
7434
|
+
if (existsSync28(configDir)) {
|
|
7231
7435
|
try {
|
|
7232
7436
|
rmSync6(configDir, { recursive: false, force: true });
|
|
7233
7437
|
logger.info(formatBullet("\u5DF2\u5220\u9664\u914D\u7F6E\u76EE\u5F55\u3002", "success"));
|
|
7234
7438
|
} catch {
|
|
7235
7439
|
}
|
|
7236
7440
|
}
|
|
7237
|
-
if (
|
|
7441
|
+
if (existsSync28(stateDir)) {
|
|
7238
7442
|
rmSync6(stateDir, { recursive: true, force: true });
|
|
7239
7443
|
logger.info(formatBullet("\u5DF2\u5220\u9664\u72B6\u6001\u6570\u636E\u3002", "success"));
|
|
7240
7444
|
}
|
|
7241
|
-
if (
|
|
7445
|
+
if (existsSync28(runtimeDir)) {
|
|
7242
7446
|
rmSync6(runtimeDir, { recursive: true, force: true });
|
|
7243
7447
|
logger.info(formatBullet("\u5DF2\u5220\u9664\u8FD0\u884C\u65F6\u6570\u636E\u3002", "success"));
|
|
7244
7448
|
}
|
|
@@ -7469,7 +7673,7 @@ function createCli() {
|
|
|
7469
7673
|
}
|
|
7470
7674
|
|
|
7471
7675
|
// src/infrastructure/runtime/main-module.ts
|
|
7472
|
-
import { existsSync as
|
|
7676
|
+
import { existsSync as existsSync29, realpathSync as realpathSync2 } from "fs";
|
|
7473
7677
|
import { resolve as resolve3 } from "path";
|
|
7474
7678
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
7475
7679
|
function isMainModule(argvEntry = process.argv[1], metaUrl = import.meta.url) {
|
|
@@ -7480,7 +7684,7 @@ function isMainModule(argvEntry = process.argv[1], metaUrl = import.meta.url) {
|
|
|
7480
7684
|
try {
|
|
7481
7685
|
return realpathSync2(argvEntry) === realpathSync2(currentModulePath);
|
|
7482
7686
|
} catch {
|
|
7483
|
-
if (!
|
|
7687
|
+
if (!existsSync29(argvEntry)) {
|
|
7484
7688
|
return false;
|
|
7485
7689
|
}
|
|
7486
7690
|
return resolve3(argvEntry) === resolve3(currentModulePath);
|