@yishiguji/tokenarena 0.12.0 → 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 +670 -399
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
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");
|
|
@@ -486,6 +499,8 @@ var CodexParser = class {
|
|
|
486
499
|
if (files.length === 0) {
|
|
487
500
|
return { buckets: [], sessions: [] };
|
|
488
501
|
}
|
|
502
|
+
const seenTotalStates = /* @__PURE__ */ new Set();
|
|
503
|
+
const seenLastOnly = /* @__PURE__ */ new Set();
|
|
489
504
|
for (const filePath of files) {
|
|
490
505
|
const content = readFileSafe(filePath);
|
|
491
506
|
if (!content) continue;
|
|
@@ -532,13 +547,28 @@ var CodexParser = class {
|
|
|
532
547
|
if (!info) continue;
|
|
533
548
|
const timestamp = obj.timestamp ? new Date(obj.timestamp) : null;
|
|
534
549
|
if (!timestamp || Number.isNaN(timestamp.getTime())) continue;
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
550
|
+
const model = info.model || payload.model || turnContextModel || sessionModel;
|
|
551
|
+
let isDuplicate = false;
|
|
552
|
+
if (info.total_token_usage) {
|
|
553
|
+
const curr = info.total_token_usage;
|
|
554
|
+
const stateKey = `${model}|${toSafeNumber(curr.input_tokens)}|${toSafeNumber(curr.output_tokens)}|${toSafeNumber(curr.cached_input_tokens)}|${toSafeNumber(curr.reasoning_output_tokens)}`;
|
|
555
|
+
isDuplicate = seenTotalStates.has(stateKey);
|
|
556
|
+
if (!isDuplicate) seenTotalStates.add(stateKey);
|
|
557
|
+
} else if (info.last_token_usage) {
|
|
558
|
+
const u = info.last_token_usage;
|
|
559
|
+
const lastKey = `${obj.timestamp}|${toSafeNumber(u.input_tokens)}|${toSafeNumber(u.output_tokens)}|${toSafeNumber(u.cached_input_tokens)}|${toSafeNumber(u.reasoning_output_tokens)}`;
|
|
560
|
+
isDuplicate = seenLastOnly.has(lastKey);
|
|
561
|
+
if (!isDuplicate) seenLastOnly.add(lastKey);
|
|
562
|
+
}
|
|
563
|
+
if (!isDuplicate) {
|
|
564
|
+
sessionEvents.push({
|
|
565
|
+
sessionId: filePath,
|
|
566
|
+
source: TOOL_ID,
|
|
567
|
+
project: sessionProject,
|
|
568
|
+
timestamp,
|
|
569
|
+
role: "assistant"
|
|
570
|
+
});
|
|
571
|
+
}
|
|
542
572
|
let usage = info.last_token_usage;
|
|
543
573
|
if (!usage && info.total_token_usage) {
|
|
544
574
|
const totalKey = `${info.model || payload.model || turnContextModel || ""}`;
|
|
@@ -569,7 +599,7 @@ var CodexParser = class {
|
|
|
569
599
|
prevTotal.set(totalKey, { ...curr });
|
|
570
600
|
}
|
|
571
601
|
if (!usage) continue;
|
|
572
|
-
|
|
602
|
+
if (isDuplicate) continue;
|
|
573
603
|
const cachedInput = toSafeNumber(usage.cached_input_tokens);
|
|
574
604
|
const reasoningTokens = toSafeNumber(usage.reasoning_output_tokens);
|
|
575
605
|
const inputTokens = Math.max(
|
|
@@ -1301,24 +1331,263 @@ var MimocodeParser = class {
|
|
|
1301
1331
|
};
|
|
1302
1332
|
registerParser(new MimocodeParser());
|
|
1303
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
|
+
|
|
1304
1573
|
// src/parsers/copilot-cli.ts
|
|
1305
|
-
import { existsSync as
|
|
1306
|
-
import { homedir as
|
|
1307
|
-
import { basename as basename3, dirname as dirname2, join as
|
|
1308
|
-
var ROOT_DIR =
|
|
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");
|
|
1309
1578
|
var TOOL3 = {
|
|
1310
1579
|
id: "copilot-cli",
|
|
1311
1580
|
name: "GitHub Copilot CLI",
|
|
1312
1581
|
dataDir: ROOT_DIR
|
|
1313
1582
|
};
|
|
1314
1583
|
function collectEventFiles(dir, results, visited) {
|
|
1315
|
-
if (!
|
|
1584
|
+
if (!existsSync9(dir) || visited.has(dir)) {
|
|
1316
1585
|
return;
|
|
1317
1586
|
}
|
|
1318
1587
|
visited.add(dir);
|
|
1319
1588
|
try {
|
|
1320
1589
|
for (const entry of readdirSync3(dir, { withFileTypes: true })) {
|
|
1321
|
-
const fullPath =
|
|
1590
|
+
const fullPath = join9(dir, entry.name);
|
|
1322
1591
|
if (entry.isDirectory()) {
|
|
1323
1592
|
collectEventFiles(fullPath, results, visited);
|
|
1324
1593
|
continue;
|
|
@@ -1422,22 +1691,22 @@ var CopilotCliParser = class {
|
|
|
1422
1691
|
};
|
|
1423
1692
|
}
|
|
1424
1693
|
isInstalled() {
|
|
1425
|
-
return
|
|
1694
|
+
return existsSync9(ROOT_DIR);
|
|
1426
1695
|
}
|
|
1427
1696
|
};
|
|
1428
1697
|
registerParser(new CopilotCliParser());
|
|
1429
1698
|
|
|
1430
1699
|
// src/parsers/oh-my-pi.ts
|
|
1431
|
-
import { existsSync as
|
|
1432
|
-
import { homedir as
|
|
1433
|
-
import { join as
|
|
1434
|
-
var
|
|
1435
|
-
var
|
|
1436
|
-
var DEFAULT_SESSIONS_DIR2 =
|
|
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");
|
|
1437
1706
|
function createToolDefinition4(dataDir) {
|
|
1438
1707
|
return {
|
|
1439
|
-
id:
|
|
1440
|
-
name:
|
|
1708
|
+
id: TOOL_ID6,
|
|
1709
|
+
name: TOOL_NAME6,
|
|
1441
1710
|
dataDir
|
|
1442
1711
|
};
|
|
1443
1712
|
}
|
|
@@ -1445,7 +1714,7 @@ function toSafeNumber5(value) {
|
|
|
1445
1714
|
const numberValue = Number(value);
|
|
1446
1715
|
return Number.isFinite(numberValue) ? numberValue : 0;
|
|
1447
1716
|
}
|
|
1448
|
-
function
|
|
1717
|
+
function getPathLeaf4(value) {
|
|
1449
1718
|
const normalized = value.replace(/\\/g, "/").replace(/\/+$/, "");
|
|
1450
1719
|
const leaf = normalized.split("/").filter(Boolean).pop();
|
|
1451
1720
|
return leaf || "unknown";
|
|
@@ -1464,7 +1733,7 @@ function getUsageNumber2(usage, ...keys) {
|
|
|
1464
1733
|
return 0;
|
|
1465
1734
|
}
|
|
1466
1735
|
function extractOhMyPiProjectFromCwd(cwd) {
|
|
1467
|
-
return
|
|
1736
|
+
return getPathLeaf4(cwd);
|
|
1468
1737
|
}
|
|
1469
1738
|
function extractOhMyPiProjectFromDir(filePath, sessionsDir = DEFAULT_SESSIONS_DIR2) {
|
|
1470
1739
|
const normalizedFilePath = normalizeForPrefix2(filePath);
|
|
@@ -1481,7 +1750,7 @@ function extractOhMyPiProjectFromDir(filePath, sessionsDir = DEFAULT_SESSIONS_DI
|
|
|
1481
1750
|
try {
|
|
1482
1751
|
const decoded = decodeURIComponent(firstSegment);
|
|
1483
1752
|
if (decoded.includes("/") || decoded.includes("\\")) {
|
|
1484
|
-
return
|
|
1753
|
+
return getPathLeaf4(decoded);
|
|
1485
1754
|
}
|
|
1486
1755
|
} catch {
|
|
1487
1756
|
}
|
|
@@ -1531,7 +1800,7 @@ var OhMyPiParser = class {
|
|
|
1531
1800
|
if (message.role === "user" || message.role === "assistant") {
|
|
1532
1801
|
sessionEvents.push({
|
|
1533
1802
|
sessionId,
|
|
1534
|
-
source:
|
|
1803
|
+
source: TOOL_ID6,
|
|
1535
1804
|
project,
|
|
1536
1805
|
timestamp,
|
|
1537
1806
|
role: message.role
|
|
@@ -1563,7 +1832,7 @@ var OhMyPiParser = class {
|
|
|
1563
1832
|
}
|
|
1564
1833
|
entries.push({
|
|
1565
1834
|
sessionId,
|
|
1566
|
-
source:
|
|
1835
|
+
source: TOOL_ID6,
|
|
1567
1836
|
model: message.model || "unknown",
|
|
1568
1837
|
project,
|
|
1569
1838
|
timestamp,
|
|
@@ -1580,17 +1849,17 @@ var OhMyPiParser = class {
|
|
|
1580
1849
|
};
|
|
1581
1850
|
}
|
|
1582
1851
|
isInstalled() {
|
|
1583
|
-
return
|
|
1852
|
+
return existsSync10(this.sessionsDir);
|
|
1584
1853
|
}
|
|
1585
1854
|
};
|
|
1586
1855
|
registerParser(new OhMyPiParser());
|
|
1587
1856
|
|
|
1588
1857
|
// src/parsers/opencode.ts
|
|
1589
1858
|
import { execFileSync as execFileSync2 } from "child_process";
|
|
1590
|
-
import { existsSync as
|
|
1591
|
-
import { homedir as
|
|
1592
|
-
import { basename as basename4, join as
|
|
1593
|
-
var DEFAULT_DATA_DIR2 =
|
|
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");
|
|
1594
1863
|
var TOOL4 = {
|
|
1595
1864
|
id: "opencode",
|
|
1596
1865
|
name: "OpenCode",
|
|
@@ -1599,10 +1868,10 @@ var TOOL4 = {
|
|
|
1599
1868
|
function getOpenCodeDataDirs(env = process.env) {
|
|
1600
1869
|
const dirs = [
|
|
1601
1870
|
env.TOKEN_ARENA_OPENCODE_DIR,
|
|
1602
|
-
env.XDG_DATA_HOME ?
|
|
1871
|
+
env.XDG_DATA_HOME ? join11(env.XDG_DATA_HOME, "opencode") : void 0,
|
|
1603
1872
|
DEFAULT_DATA_DIR2,
|
|
1604
|
-
env.LOCALAPPDATA ?
|
|
1605
|
-
env.APPDATA ?
|
|
1873
|
+
env.LOCALAPPDATA ? join11(env.LOCALAPPDATA, "opencode") : void 0,
|
|
1874
|
+
env.APPDATA ? join11(env.APPDATA, "opencode") : void 0
|
|
1606
1875
|
].filter((value) => Boolean(value));
|
|
1607
1876
|
return Array.from(new Set(dirs));
|
|
1608
1877
|
}
|
|
@@ -1696,12 +1965,12 @@ var OpenCodeParser = class {
|
|
|
1696
1965
|
return { buckets, sessions };
|
|
1697
1966
|
}
|
|
1698
1967
|
isInstalled() {
|
|
1699
|
-
return this.resolveRoots().some((dir) =>
|
|
1968
|
+
return this.resolveRoots().some((dir) => existsSync11(dir));
|
|
1700
1969
|
}
|
|
1701
1970
|
async parseRoot(rootDir) {
|
|
1702
|
-
const dbPath =
|
|
1703
|
-
const messagesDir =
|
|
1704
|
-
if (
|
|
1971
|
+
const dbPath = join11(rootDir, "opencode.db");
|
|
1972
|
+
const messagesDir = join11(rootDir, "storage", "message");
|
|
1973
|
+
if (existsSync11(dbPath)) {
|
|
1705
1974
|
try {
|
|
1706
1975
|
return await this.parseFromSqlite(dbPath);
|
|
1707
1976
|
} catch (err) {
|
|
@@ -1768,7 +2037,7 @@ var OpenCodeParser = class {
|
|
|
1768
2037
|
};
|
|
1769
2038
|
}
|
|
1770
2039
|
parseFromJson(messagesDir) {
|
|
1771
|
-
if (!
|
|
2040
|
+
if (!existsSync11(messagesDir)) return { buckets: [], sessions: [] };
|
|
1772
2041
|
const entries = [];
|
|
1773
2042
|
const sessionEvents = [];
|
|
1774
2043
|
let sessionDirs;
|
|
@@ -1780,7 +2049,7 @@ var OpenCodeParser = class {
|
|
|
1780
2049
|
return { buckets: [], sessions: [] };
|
|
1781
2050
|
}
|
|
1782
2051
|
for (const sessionDir of sessionDirs) {
|
|
1783
|
-
const sessionPath =
|
|
2052
|
+
const sessionPath = join11(messagesDir, sessionDir.name);
|
|
1784
2053
|
let messageFiles;
|
|
1785
2054
|
try {
|
|
1786
2055
|
messageFiles = readdirSync4(sessionPath).filter(
|
|
@@ -1790,7 +2059,7 @@ var OpenCodeParser = class {
|
|
|
1790
2059
|
continue;
|
|
1791
2060
|
}
|
|
1792
2061
|
for (const file of messageFiles) {
|
|
1793
|
-
const filePath =
|
|
2062
|
+
const filePath = join11(sessionPath, file);
|
|
1794
2063
|
let data;
|
|
1795
2064
|
try {
|
|
1796
2065
|
data = JSON.parse(readFileSync4(filePath, "utf-8"));
|
|
@@ -1836,16 +2105,16 @@ var OpenCodeParser = class {
|
|
|
1836
2105
|
registerParser(new OpenCodeParser());
|
|
1837
2106
|
|
|
1838
2107
|
// src/parsers/openclaw.ts
|
|
1839
|
-
import { existsSync as
|
|
1840
|
-
import { homedir as
|
|
1841
|
-
import { join as
|
|
1842
|
-
var
|
|
1843
|
-
var
|
|
1844
|
-
var DEFAULT_DATA_DIR3 =
|
|
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");
|
|
1845
2114
|
var LEGACY_ROOT_NAMES = [".clawdbot", ".moltbot", ".moldbot"];
|
|
1846
2115
|
var TOOL5 = {
|
|
1847
|
-
id:
|
|
1848
|
-
name:
|
|
2116
|
+
id: TOOL_ID7,
|
|
2117
|
+
name: TOOL_NAME7,
|
|
1849
2118
|
dataDir: DEFAULT_DATA_DIR3
|
|
1850
2119
|
};
|
|
1851
2120
|
function getTokens(usage, ...keys) {
|
|
@@ -1855,16 +2124,16 @@ function getTokens(usage, ...keys) {
|
|
|
1855
2124
|
}
|
|
1856
2125
|
return 0;
|
|
1857
2126
|
}
|
|
1858
|
-
function getOpenClawRoots(homeDir =
|
|
1859
|
-
const roots = [
|
|
2127
|
+
function getOpenClawRoots(homeDir = homedir11()) {
|
|
2128
|
+
const roots = [join12(homeDir, ".openclaw")];
|
|
1860
2129
|
try {
|
|
1861
2130
|
const profileRoots = readdirSync5(homeDir, { withFileTypes: true }).filter(
|
|
1862
2131
|
(entry) => entry.isDirectory() && /^\.openclaw-.+/.test(entry.name)
|
|
1863
|
-
).map((entry) =>
|
|
2132
|
+
).map((entry) => join12(homeDir, entry.name)).sort((left, right) => left.localeCompare(right));
|
|
1864
2133
|
roots.push(...profileRoots);
|
|
1865
2134
|
} catch {
|
|
1866
2135
|
}
|
|
1867
|
-
roots.push(...LEGACY_ROOT_NAMES.map((name) =>
|
|
2136
|
+
roots.push(...LEGACY_ROOT_NAMES.map((name) => join12(homeDir, name)));
|
|
1868
2137
|
return Array.from(new Set(roots));
|
|
1869
2138
|
}
|
|
1870
2139
|
var OpenClawParser = class {
|
|
@@ -1877,8 +2146,8 @@ var OpenClawParser = class {
|
|
|
1877
2146
|
const entries = [];
|
|
1878
2147
|
const sessionEvents = [];
|
|
1879
2148
|
for (const root of this.resolveRoots()) {
|
|
1880
|
-
const agentsDir =
|
|
1881
|
-
if (!
|
|
2149
|
+
const agentsDir = join12(root, "agents");
|
|
2150
|
+
if (!existsSync12(agentsDir)) continue;
|
|
1882
2151
|
let agentDirs;
|
|
1883
2152
|
try {
|
|
1884
2153
|
agentDirs = readdirSync5(agentsDir, { withFileTypes: true }).filter(
|
|
@@ -1889,8 +2158,8 @@ var OpenClawParser = class {
|
|
|
1889
2158
|
}
|
|
1890
2159
|
for (const agentDir of agentDirs) {
|
|
1891
2160
|
const project = agentDir.name;
|
|
1892
|
-
const sessionsDir =
|
|
1893
|
-
if (!
|
|
2161
|
+
const sessionsDir = join12(agentsDir, agentDir.name, "sessions");
|
|
2162
|
+
if (!existsSync12(sessionsDir)) continue;
|
|
1894
2163
|
let files;
|
|
1895
2164
|
try {
|
|
1896
2165
|
files = readdirSync5(sessionsDir).filter((f) => f.endsWith(".jsonl"));
|
|
@@ -1898,7 +2167,7 @@ var OpenClawParser = class {
|
|
|
1898
2167
|
continue;
|
|
1899
2168
|
}
|
|
1900
2169
|
for (const file of files) {
|
|
1901
|
-
const filePath =
|
|
2170
|
+
const filePath = join12(sessionsDir, file);
|
|
1902
2171
|
let content;
|
|
1903
2172
|
try {
|
|
1904
2173
|
content = readFileSync5(filePath, "utf-8");
|
|
@@ -1921,7 +2190,7 @@ var OpenClawParser = class {
|
|
|
1921
2190
|
if (msg.role !== "user" && msg.role !== "assistant") continue;
|
|
1922
2191
|
sessionEvents.push({
|
|
1923
2192
|
sessionId: filePath,
|
|
1924
|
-
source:
|
|
2193
|
+
source: TOOL_ID7,
|
|
1925
2194
|
project,
|
|
1926
2195
|
timestamp: ts,
|
|
1927
2196
|
role: msg.role === "user" ? "user" : "assistant"
|
|
@@ -1931,7 +2200,7 @@ var OpenClawParser = class {
|
|
|
1931
2200
|
if (!usage) continue;
|
|
1932
2201
|
entries.push({
|
|
1933
2202
|
sessionId: filePath,
|
|
1934
|
-
source:
|
|
2203
|
+
source: TOOL_ID7,
|
|
1935
2204
|
model: msg.model || obj.model || "unknown",
|
|
1936
2205
|
project,
|
|
1937
2206
|
timestamp: ts,
|
|
@@ -1971,22 +2240,22 @@ var OpenClawParser = class {
|
|
|
1971
2240
|
};
|
|
1972
2241
|
}
|
|
1973
2242
|
isInstalled() {
|
|
1974
|
-
return this.resolveRoots().some((root) =>
|
|
2243
|
+
return this.resolveRoots().some((root) => existsSync12(join12(root, "agents")));
|
|
1975
2244
|
}
|
|
1976
2245
|
};
|
|
1977
2246
|
registerParser(new OpenClawParser());
|
|
1978
2247
|
|
|
1979
2248
|
// src/parsers/qwen-code.ts
|
|
1980
|
-
import { existsSync as
|
|
1981
|
-
import { homedir as
|
|
1982
|
-
import { join as
|
|
1983
|
-
var
|
|
1984
|
-
var
|
|
1985
|
-
var DEFAULT_DATA_DIR4 =
|
|
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");
|
|
1986
2255
|
function createToolDefinition5(dataDir) {
|
|
1987
2256
|
return {
|
|
1988
|
-
id:
|
|
1989
|
-
name:
|
|
2257
|
+
id: TOOL_ID8,
|
|
2258
|
+
name: TOOL_NAME8,
|
|
1990
2259
|
dataDir
|
|
1991
2260
|
};
|
|
1992
2261
|
}
|
|
@@ -1994,7 +2263,7 @@ function toSafeNumber6(value) {
|
|
|
1994
2263
|
const numberValue = Number(value);
|
|
1995
2264
|
return Number.isFinite(numberValue) ? numberValue : 0;
|
|
1996
2265
|
}
|
|
1997
|
-
function
|
|
2266
|
+
function getPathLeaf5(value) {
|
|
1998
2267
|
const normalized = value.replace(/\\/g, "/").replace(/\/+$/, "");
|
|
1999
2268
|
const leaf = normalized.split("/").filter(Boolean).pop();
|
|
2000
2269
|
return leaf || "unknown";
|
|
@@ -2004,16 +2273,16 @@ function normalizeForPrefix3(value) {
|
|
|
2004
2273
|
}
|
|
2005
2274
|
function findSessionFiles2(baseDir) {
|
|
2006
2275
|
const results = [];
|
|
2007
|
-
if (!
|
|
2276
|
+
if (!existsSync13(baseDir)) return results;
|
|
2008
2277
|
try {
|
|
2009
2278
|
for (const entry of readdirSync6(baseDir, { withFileTypes: true })) {
|
|
2010
2279
|
if (!entry.isDirectory()) continue;
|
|
2011
|
-
const chatsDir =
|
|
2012
|
-
if (!
|
|
2280
|
+
const chatsDir = join13(baseDir, entry.name, "chats");
|
|
2281
|
+
if (!existsSync13(chatsDir)) continue;
|
|
2013
2282
|
try {
|
|
2014
2283
|
for (const file of readdirSync6(chatsDir)) {
|
|
2015
2284
|
if (file.endsWith(".jsonl")) {
|
|
2016
|
-
results.push(
|
|
2285
|
+
results.push(join13(chatsDir, file));
|
|
2017
2286
|
}
|
|
2018
2287
|
}
|
|
2019
2288
|
} catch {
|
|
@@ -2026,7 +2295,7 @@ function findSessionFiles2(baseDir) {
|
|
|
2026
2295
|
}
|
|
2027
2296
|
function resolveQwenProject(cwd, filePath, dataDir = DEFAULT_DATA_DIR4) {
|
|
2028
2297
|
if (cwd) {
|
|
2029
|
-
return
|
|
2298
|
+
return getPathLeaf5(cwd);
|
|
2030
2299
|
}
|
|
2031
2300
|
const normalizedFilePath = normalizeForPrefix3(filePath);
|
|
2032
2301
|
const normalizedDataDir = normalizeForPrefix3(dataDir);
|
|
@@ -2068,7 +2337,7 @@ var QwenCodeParser = class {
|
|
|
2068
2337
|
if (obj.type === "user" || obj.type === "assistant") {
|
|
2069
2338
|
sessionEvents.push({
|
|
2070
2339
|
sessionId,
|
|
2071
|
-
source:
|
|
2340
|
+
source: TOOL_ID8,
|
|
2072
2341
|
project,
|
|
2073
2342
|
timestamp,
|
|
2074
2343
|
role: obj.type
|
|
@@ -2090,7 +2359,7 @@ var QwenCodeParser = class {
|
|
|
2090
2359
|
}
|
|
2091
2360
|
entries.push({
|
|
2092
2361
|
sessionId,
|
|
2093
|
-
source:
|
|
2362
|
+
source: TOOL_ID8,
|
|
2094
2363
|
model: obj.model || "unknown",
|
|
2095
2364
|
project,
|
|
2096
2365
|
timestamp,
|
|
@@ -2109,19 +2378,19 @@ var QwenCodeParser = class {
|
|
|
2109
2378
|
};
|
|
2110
2379
|
}
|
|
2111
2380
|
isInstalled() {
|
|
2112
|
-
return
|
|
2381
|
+
return existsSync13(this.dataDir);
|
|
2113
2382
|
}
|
|
2114
2383
|
};
|
|
2115
2384
|
registerParser(new QwenCodeParser());
|
|
2116
2385
|
|
|
2117
2386
|
// src/parsers/kimi-code.ts
|
|
2118
|
-
import { existsSync as
|
|
2119
|
-
import { homedir as
|
|
2120
|
-
import { join as
|
|
2121
|
-
var
|
|
2122
|
-
var
|
|
2123
|
-
var DEFAULT_SESSIONS_DIR3 =
|
|
2124
|
-
var DEFAULT_CONFIG_PATH =
|
|
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");
|
|
2125
2394
|
var USER_EVENT_TYPES = /* @__PURE__ */ new Set([
|
|
2126
2395
|
"UserMessage",
|
|
2127
2396
|
"user_message",
|
|
@@ -2137,8 +2406,8 @@ var ASSISTANT_EVENT_TYPES = /* @__PURE__ */ new Set([
|
|
|
2137
2406
|
]);
|
|
2138
2407
|
function createToolDefinition6(dataDir) {
|
|
2139
2408
|
return {
|
|
2140
|
-
id:
|
|
2141
|
-
name:
|
|
2409
|
+
id: TOOL_ID9,
|
|
2410
|
+
name: TOOL_NAME9,
|
|
2142
2411
|
dataDir
|
|
2143
2412
|
};
|
|
2144
2413
|
}
|
|
@@ -2146,36 +2415,36 @@ function toSafeNumber7(value) {
|
|
|
2146
2415
|
const numberValue = Number(value);
|
|
2147
2416
|
return Number.isFinite(numberValue) ? numberValue : 0;
|
|
2148
2417
|
}
|
|
2149
|
-
function
|
|
2418
|
+
function getPathLeaf6(value) {
|
|
2150
2419
|
const normalized = value.replace(/\\/g, "/").replace(/\/+$/, "");
|
|
2151
2420
|
const leaf = normalized.split("/").filter(Boolean).pop();
|
|
2152
2421
|
return leaf || "unknown";
|
|
2153
2422
|
}
|
|
2154
2423
|
function findWireFiles(baseDir) {
|
|
2155
2424
|
const results = [];
|
|
2156
|
-
if (!
|
|
2425
|
+
if (!existsSync14(baseDir)) return results;
|
|
2157
2426
|
try {
|
|
2158
2427
|
for (const workDir of readdirSync7(baseDir, { withFileTypes: true })) {
|
|
2159
2428
|
if (!workDir.isDirectory()) continue;
|
|
2160
|
-
const workDirPath =
|
|
2429
|
+
const workDirPath = join14(baseDir, workDir.name);
|
|
2161
2430
|
try {
|
|
2162
2431
|
for (const session of readdirSync7(workDirPath, {
|
|
2163
2432
|
withFileTypes: true
|
|
2164
2433
|
})) {
|
|
2165
2434
|
if (!session.isDirectory()) continue;
|
|
2166
|
-
const newWireFile =
|
|
2435
|
+
const newWireFile = join14(
|
|
2167
2436
|
workDirPath,
|
|
2168
2437
|
session.name,
|
|
2169
2438
|
"agents",
|
|
2170
2439
|
"main",
|
|
2171
2440
|
"wire.jsonl"
|
|
2172
2441
|
);
|
|
2173
|
-
if (
|
|
2442
|
+
if (existsSync14(newWireFile)) {
|
|
2174
2443
|
results.push({ filePath: newWireFile, workDirHash: workDir.name });
|
|
2175
2444
|
continue;
|
|
2176
2445
|
}
|
|
2177
|
-
const legacyWireFile =
|
|
2178
|
-
if (
|
|
2446
|
+
const legacyWireFile = join14(workDirPath, session.name, "wire.jsonl");
|
|
2447
|
+
if (existsSync14(legacyWireFile)) {
|
|
2179
2448
|
results.push({
|
|
2180
2449
|
filePath: legacyWireFile,
|
|
2181
2450
|
workDirHash: workDir.name
|
|
@@ -2225,7 +2494,7 @@ function loadProjectMap(configPath) {
|
|
|
2225
2494
|
pathValue = info.root || info.path || info.dir || void 0;
|
|
2226
2495
|
}
|
|
2227
2496
|
if (!pathValue) continue;
|
|
2228
|
-
const name = typeof info === "object" && info.name ? info.name :
|
|
2497
|
+
const name = typeof info === "object" && info.name ? info.name : getPathLeaf6(pathValue);
|
|
2229
2498
|
projectMap.set(hash, name);
|
|
2230
2499
|
}
|
|
2231
2500
|
} catch {
|
|
@@ -2283,14 +2552,14 @@ var KimiCodeParser = class {
|
|
|
2283
2552
|
}
|
|
2284
2553
|
sessionEvents.push({
|
|
2285
2554
|
sessionId,
|
|
2286
|
-
source:
|
|
2555
|
+
source: TOOL_ID9,
|
|
2287
2556
|
project,
|
|
2288
2557
|
timestamp: timestamp2,
|
|
2289
2558
|
role: "assistant"
|
|
2290
2559
|
});
|
|
2291
2560
|
entries.push({
|
|
2292
2561
|
sessionId,
|
|
2293
|
-
source:
|
|
2562
|
+
source: TOOL_ID9,
|
|
2294
2563
|
model: obj.model || currentModel,
|
|
2295
2564
|
project,
|
|
2296
2565
|
timestamp: timestamp2,
|
|
@@ -2317,7 +2586,7 @@ var KimiCodeParser = class {
|
|
|
2317
2586
|
if (role && timestamp) {
|
|
2318
2587
|
sessionEvents.push({
|
|
2319
2588
|
sessionId,
|
|
2320
|
-
source:
|
|
2589
|
+
source: TOOL_ID9,
|
|
2321
2590
|
project,
|
|
2322
2591
|
timestamp,
|
|
2323
2592
|
role
|
|
@@ -2340,7 +2609,7 @@ var KimiCodeParser = class {
|
|
|
2340
2609
|
if (!role) {
|
|
2341
2610
|
sessionEvents.push({
|
|
2342
2611
|
sessionId,
|
|
2343
|
-
source:
|
|
2612
|
+
source: TOOL_ID9,
|
|
2344
2613
|
project,
|
|
2345
2614
|
timestamp,
|
|
2346
2615
|
role: "assistant"
|
|
@@ -2348,7 +2617,7 @@ var KimiCodeParser = class {
|
|
|
2348
2617
|
}
|
|
2349
2618
|
entries.push({
|
|
2350
2619
|
sessionId,
|
|
2351
|
-
source:
|
|
2620
|
+
source: TOOL_ID9,
|
|
2352
2621
|
model: currentModel,
|
|
2353
2622
|
project,
|
|
2354
2623
|
timestamp,
|
|
@@ -2365,23 +2634,23 @@ var KimiCodeParser = class {
|
|
|
2365
2634
|
};
|
|
2366
2635
|
}
|
|
2367
2636
|
isInstalled() {
|
|
2368
|
-
return
|
|
2637
|
+
return existsSync14(this.sessionsDir);
|
|
2369
2638
|
}
|
|
2370
2639
|
};
|
|
2371
2640
|
registerParser(new KimiCodeParser());
|
|
2372
2641
|
|
|
2373
2642
|
// src/parsers/letcode.ts
|
|
2374
|
-
import { existsSync as
|
|
2375
|
-
import { homedir as
|
|
2376
|
-
import { basename as basename5, join as
|
|
2377
|
-
var
|
|
2378
|
-
var
|
|
2379
|
-
var DEFAULT_CONFIG_DIR =
|
|
2380
|
-
var DEFAULT_SESSIONS_DIR4 =
|
|
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");
|
|
2381
2650
|
function getLetcodeSessionsDirs(env = process.env) {
|
|
2382
2651
|
const dirs = [
|
|
2383
2652
|
env.TOKEN_ARENA_LETCODE_DIR,
|
|
2384
|
-
env.XDG_CONFIG_HOME ?
|
|
2653
|
+
env.XDG_CONFIG_HOME ? join15(env.XDG_CONFIG_HOME, "letcode", "sessions") : void 0,
|
|
2385
2654
|
DEFAULT_SESSIONS_DIR4
|
|
2386
2655
|
].filter((value) => Boolean(value));
|
|
2387
2656
|
return Array.from(new Set(dirs));
|
|
@@ -2435,8 +2704,8 @@ var LetcodeParser = class {
|
|
|
2435
2704
|
constructor(sessionsDir) {
|
|
2436
2705
|
this.sessionsDirs = sessionsDir ? [sessionsDir] : getLetcodeSessionsDirs();
|
|
2437
2706
|
this.tool = {
|
|
2438
|
-
id:
|
|
2439
|
-
name:
|
|
2707
|
+
id: TOOL_ID10,
|
|
2708
|
+
name: TOOL_NAME10,
|
|
2440
2709
|
dataDir: this.sessionsDirs[0] ?? DEFAULT_SESSIONS_DIR4
|
|
2441
2710
|
};
|
|
2442
2711
|
}
|
|
@@ -2459,7 +2728,7 @@ var LetcodeParser = class {
|
|
|
2459
2728
|
if (role) {
|
|
2460
2729
|
sessionEvents.push({
|
|
2461
2730
|
sessionId,
|
|
2462
|
-
source:
|
|
2731
|
+
source: TOOL_ID10,
|
|
2463
2732
|
project: "unknown",
|
|
2464
2733
|
timestamp,
|
|
2465
2734
|
role
|
|
@@ -2493,7 +2762,7 @@ var LetcodeParser = class {
|
|
|
2493
2762
|
seenEntryKeys.add(entryKey);
|
|
2494
2763
|
entries.push({
|
|
2495
2764
|
sessionId,
|
|
2496
|
-
source:
|
|
2765
|
+
source: TOOL_ID10,
|
|
2497
2766
|
model,
|
|
2498
2767
|
project: "unknown",
|
|
2499
2768
|
timestamp,
|
|
@@ -2511,31 +2780,31 @@ var LetcodeParser = class {
|
|
|
2511
2780
|
};
|
|
2512
2781
|
}
|
|
2513
2782
|
isInstalled() {
|
|
2514
|
-
return this.sessionsDirs.some((dir) =>
|
|
2783
|
+
return this.sessionsDirs.some((dir) => existsSync15(dir));
|
|
2515
2784
|
}
|
|
2516
2785
|
};
|
|
2517
2786
|
registerParser(new LetcodeParser());
|
|
2518
2787
|
|
|
2519
2788
|
// src/parsers/droid.ts
|
|
2520
|
-
import { existsSync as
|
|
2521
|
-
import { homedir as
|
|
2522
|
-
import { basename as basename6, dirname as dirname3, join as
|
|
2523
|
-
var
|
|
2524
|
-
var
|
|
2525
|
-
var DEFAULT_DATA_DIR5 =
|
|
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");
|
|
2526
2795
|
function createToolDefinition7(dataDir) {
|
|
2527
2796
|
return {
|
|
2528
|
-
id:
|
|
2529
|
-
name:
|
|
2797
|
+
id: TOOL_ID11,
|
|
2798
|
+
name: TOOL_NAME11,
|
|
2530
2799
|
dataDir
|
|
2531
2800
|
};
|
|
2532
2801
|
}
|
|
2533
2802
|
function findSessionFiles3(dir) {
|
|
2534
2803
|
const results = [];
|
|
2535
|
-
if (!
|
|
2804
|
+
if (!existsSync16(dir)) return results;
|
|
2536
2805
|
try {
|
|
2537
2806
|
for (const entry of readdirSync8(dir, { withFileTypes: true })) {
|
|
2538
|
-
const fullPath =
|
|
2807
|
+
const fullPath = join16(dir, entry.name);
|
|
2539
2808
|
if (entry.isDirectory()) {
|
|
2540
2809
|
results.push(...findSessionFiles3(fullPath));
|
|
2541
2810
|
} else if (entry.isFile() && entry.name.endsWith(".jsonl") && !entry.name.endsWith(".settings.json")) {
|
|
@@ -2592,13 +2861,13 @@ var DroidParser = class {
|
|
|
2592
2861
|
}
|
|
2593
2862
|
sessionEvents.push({
|
|
2594
2863
|
sessionId,
|
|
2595
|
-
source:
|
|
2864
|
+
source: TOOL_ID11,
|
|
2596
2865
|
project,
|
|
2597
2866
|
timestamp,
|
|
2598
2867
|
role
|
|
2599
2868
|
});
|
|
2600
2869
|
}
|
|
2601
|
-
const settingsPath =
|
|
2870
|
+
const settingsPath = join16(
|
|
2602
2871
|
dirname3(filePath),
|
|
2603
2872
|
`${basename6(filePath, ".jsonl")}.settings.json`
|
|
2604
2873
|
);
|
|
@@ -2627,7 +2896,7 @@ var DroidParser = class {
|
|
|
2627
2896
|
}
|
|
2628
2897
|
entries.push({
|
|
2629
2898
|
sessionId,
|
|
2630
|
-
source:
|
|
2899
|
+
source: TOOL_ID11,
|
|
2631
2900
|
model: settings.model || "unknown",
|
|
2632
2901
|
project,
|
|
2633
2902
|
timestamp: firstMessageTimestamp,
|
|
@@ -2643,22 +2912,22 @@ var DroidParser = class {
|
|
|
2643
2912
|
};
|
|
2644
2913
|
}
|
|
2645
2914
|
isInstalled() {
|
|
2646
|
-
return
|
|
2915
|
+
return existsSync16(this.dataDir);
|
|
2647
2916
|
}
|
|
2648
2917
|
};
|
|
2649
2918
|
registerParser(new DroidParser());
|
|
2650
2919
|
|
|
2651
2920
|
// src/parsers/pi-coding-agent.ts
|
|
2652
|
-
import { existsSync as
|
|
2653
|
-
import { homedir as
|
|
2654
|
-
import { join as
|
|
2655
|
-
var
|
|
2656
|
-
var
|
|
2657
|
-
var DEFAULT_SESSIONS_DIR5 =
|
|
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");
|
|
2658
2927
|
function createToolDefinition8(dataDir) {
|
|
2659
2928
|
return {
|
|
2660
|
-
id:
|
|
2661
|
-
name:
|
|
2929
|
+
id: TOOL_ID12,
|
|
2930
|
+
name: TOOL_NAME12,
|
|
2662
2931
|
dataDir
|
|
2663
2932
|
};
|
|
2664
2933
|
}
|
|
@@ -2666,7 +2935,7 @@ function toSafeNumber9(value) {
|
|
|
2666
2935
|
const numberValue = Number(value);
|
|
2667
2936
|
return Number.isFinite(numberValue) ? numberValue : 0;
|
|
2668
2937
|
}
|
|
2669
|
-
function
|
|
2938
|
+
function getPathLeaf7(value) {
|
|
2670
2939
|
const normalized = value.replace(/\\/g, "/").replace(/\/+$/, "");
|
|
2671
2940
|
const leaf = normalized.split("/").filter(Boolean).pop();
|
|
2672
2941
|
return leaf || "unknown";
|
|
@@ -2685,7 +2954,7 @@ function getUsageNumber3(usage, ...keys) {
|
|
|
2685
2954
|
return 0;
|
|
2686
2955
|
}
|
|
2687
2956
|
function extractPiProjectFromCwd(cwd) {
|
|
2688
|
-
return
|
|
2957
|
+
return getPathLeaf7(cwd);
|
|
2689
2958
|
}
|
|
2690
2959
|
function extractPiProjectFromDir(filePath, sessionsDir = DEFAULT_SESSIONS_DIR5) {
|
|
2691
2960
|
const normalizedFilePath = normalizeForPrefix4(filePath);
|
|
@@ -2702,7 +2971,7 @@ function extractPiProjectFromDir(filePath, sessionsDir = DEFAULT_SESSIONS_DIR5)
|
|
|
2702
2971
|
try {
|
|
2703
2972
|
const decoded = decodeURIComponent(firstSegment);
|
|
2704
2973
|
if (decoded.includes("/") || decoded.includes("\\")) {
|
|
2705
|
-
return
|
|
2974
|
+
return getPathLeaf7(decoded);
|
|
2706
2975
|
}
|
|
2707
2976
|
} catch {
|
|
2708
2977
|
}
|
|
@@ -2752,7 +3021,7 @@ var PiCodingAgentParser = class {
|
|
|
2752
3021
|
if (message.role === "user" || message.role === "assistant") {
|
|
2753
3022
|
sessionEvents.push({
|
|
2754
3023
|
sessionId,
|
|
2755
|
-
source:
|
|
3024
|
+
source: TOOL_ID12,
|
|
2756
3025
|
project,
|
|
2757
3026
|
timestamp,
|
|
2758
3027
|
role: message.role
|
|
@@ -2784,7 +3053,7 @@ var PiCodingAgentParser = class {
|
|
|
2784
3053
|
}
|
|
2785
3054
|
entries.push({
|
|
2786
3055
|
sessionId,
|
|
2787
|
-
source:
|
|
3056
|
+
source: TOOL_ID12,
|
|
2788
3057
|
model: message.model || "unknown",
|
|
2789
3058
|
project,
|
|
2790
3059
|
timestamp,
|
|
@@ -2801,23 +3070,23 @@ var PiCodingAgentParser = class {
|
|
|
2801
3070
|
};
|
|
2802
3071
|
}
|
|
2803
3072
|
isInstalled() {
|
|
2804
|
-
return
|
|
3073
|
+
return existsSync17(this.sessionsDir);
|
|
2805
3074
|
}
|
|
2806
3075
|
};
|
|
2807
3076
|
registerParser(new PiCodingAgentParser());
|
|
2808
3077
|
|
|
2809
3078
|
// src/parsers/qwenpaw.ts
|
|
2810
|
-
import { existsSync as
|
|
2811
|
-
import { homedir as
|
|
2812
|
-
import { join as
|
|
2813
|
-
var
|
|
2814
|
-
var
|
|
2815
|
-
var DEFAULT_USAGE_PATH =
|
|
2816
|
-
var DEFAULT_WORKSPACE_PATH =
|
|
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");
|
|
2817
3086
|
function createToolDefinition9(usagePath) {
|
|
2818
3087
|
return {
|
|
2819
|
-
id:
|
|
2820
|
-
name:
|
|
3088
|
+
id: TOOL_ID13,
|
|
3089
|
+
name: TOOL_NAME13,
|
|
2821
3090
|
dataDir: usagePath
|
|
2822
3091
|
};
|
|
2823
3092
|
}
|
|
@@ -2832,12 +3101,12 @@ function parseUsageDate(value) {
|
|
|
2832
3101
|
const timestamp = /* @__PURE__ */ new Date(`${value}T00:00:00.000Z`);
|
|
2833
3102
|
return Number.isNaN(timestamp.getTime()) ? null : timestamp;
|
|
2834
3103
|
}
|
|
2835
|
-
function
|
|
3104
|
+
function getString2(value) {
|
|
2836
3105
|
return typeof value === "string" && value.length > 0 ? value : null;
|
|
2837
3106
|
}
|
|
2838
3107
|
function resolveModel(recordKey, record) {
|
|
2839
|
-
const providerId =
|
|
2840
|
-
const modelName =
|
|
3108
|
+
const providerId = getString2(record.provider_id);
|
|
3109
|
+
const modelName = getString2(record.model_name);
|
|
2841
3110
|
if (providerId && modelName) {
|
|
2842
3111
|
return `${providerId}:${modelName}`;
|
|
2843
3112
|
}
|
|
@@ -2874,7 +3143,7 @@ var QwenPawParser = class {
|
|
|
2874
3143
|
continue;
|
|
2875
3144
|
}
|
|
2876
3145
|
entries.push({
|
|
2877
|
-
source:
|
|
3146
|
+
source: TOOL_ID13,
|
|
2878
3147
|
model: resolveModel(recordKey, record),
|
|
2879
3148
|
project: "unknown",
|
|
2880
3149
|
timestamp,
|
|
@@ -2897,15 +3166,15 @@ var QwenPawParser = class {
|
|
|
2897
3166
|
}
|
|
2898
3167
|
async parseWorkspaceSessions() {
|
|
2899
3168
|
const events = [];
|
|
2900
|
-
if (!
|
|
3169
|
+
if (!existsSync18(this.workspacePath)) {
|
|
2901
3170
|
return events;
|
|
2902
3171
|
}
|
|
2903
3172
|
try {
|
|
2904
3173
|
const workspaceDirs = readdirSync9(this.workspacePath);
|
|
2905
3174
|
for (const workspaceDir of workspaceDirs) {
|
|
2906
|
-
const workspacePath =
|
|
2907
|
-
const chatsPath =
|
|
2908
|
-
const sessionsPath =
|
|
3175
|
+
const workspacePath = join18(this.workspacePath, workspaceDir);
|
|
3176
|
+
const chatsPath = join18(workspacePath, "chats.json");
|
|
3177
|
+
const sessionsPath = join18(workspacePath, "sessions");
|
|
2909
3178
|
const chatsContent = readFileSafe(chatsPath);
|
|
2910
3179
|
if (!chatsContent) {
|
|
2911
3180
|
continue;
|
|
@@ -2933,7 +3202,7 @@ var QwenPawParser = class {
|
|
|
2933
3202
|
for (const msg of sessionMessages) {
|
|
2934
3203
|
events.push({
|
|
2935
3204
|
sessionId: chat.session_id,
|
|
2936
|
-
source:
|
|
3205
|
+
source: TOOL_ID13,
|
|
2937
3206
|
project: workspaceDir,
|
|
2938
3207
|
timestamp: new Date(msg.timestamp),
|
|
2939
3208
|
role: msg.role
|
|
@@ -2949,7 +3218,7 @@ var QwenPawParser = class {
|
|
|
2949
3218
|
}
|
|
2950
3219
|
getSessionFiles(sessionsPath) {
|
|
2951
3220
|
const files = /* @__PURE__ */ new Map();
|
|
2952
|
-
if (!
|
|
3221
|
+
if (!existsSync18(sessionsPath)) {
|
|
2953
3222
|
return files;
|
|
2954
3223
|
}
|
|
2955
3224
|
try {
|
|
@@ -2958,7 +3227,7 @@ var QwenPawParser = class {
|
|
|
2958
3227
|
if (!fileName.endsWith(".json")) {
|
|
2959
3228
|
continue;
|
|
2960
3229
|
}
|
|
2961
|
-
const filePath =
|
|
3230
|
+
const filePath = join18(sessionsPath, fileName);
|
|
2962
3231
|
const content = readFileSafe(filePath);
|
|
2963
3232
|
if (content) {
|
|
2964
3233
|
const sessionId = fileName.replace(/^[^_]+_/, "").replace(".json", "");
|
|
@@ -3034,7 +3303,7 @@ var QwenPawParser = class {
|
|
|
3034
3303
|
source: sessionData.source,
|
|
3035
3304
|
project: sessionData.project,
|
|
3036
3305
|
sessionHash,
|
|
3037
|
-
hostname:
|
|
3306
|
+
hostname: hostname4().replace(/\.local$/, ""),
|
|
3038
3307
|
firstMessageAt,
|
|
3039
3308
|
lastMessageAt,
|
|
3040
3309
|
durationSeconds,
|
|
@@ -3056,15 +3325,15 @@ var QwenPawParser = class {
|
|
|
3056
3325
|
});
|
|
3057
3326
|
}
|
|
3058
3327
|
isInstalled() {
|
|
3059
|
-
return
|
|
3328
|
+
return existsSync18(this.usagePath) || existsSync18(this.workspacePath);
|
|
3060
3329
|
}
|
|
3061
3330
|
};
|
|
3062
3331
|
registerParser(new QwenPawParser());
|
|
3063
3332
|
|
|
3064
3333
|
// src/parsers/cline.ts
|
|
3065
3334
|
import { readFileSync as readFileSync6, statSync } from "fs";
|
|
3066
|
-
import { homedir as
|
|
3067
|
-
import { basename as basename7, join as
|
|
3335
|
+
import { homedir as homedir18 } from "os";
|
|
3336
|
+
import { basename as basename7, join as join19 } from "path";
|
|
3068
3337
|
var EXTENSION_ID = "saoudrizwan.claude-dev";
|
|
3069
3338
|
var HOSTS = [
|
|
3070
3339
|
"Code",
|
|
@@ -3078,26 +3347,26 @@ var HOSTS = [
|
|
|
3078
3347
|
var TOOL6 = {
|
|
3079
3348
|
id: "cline",
|
|
3080
3349
|
name: "Cline",
|
|
3081
|
-
dataDir:
|
|
3350
|
+
dataDir: join19(homedir18(), ".cline")
|
|
3082
3351
|
};
|
|
3083
3352
|
function getHostRoots() {
|
|
3084
3353
|
const out = [];
|
|
3085
3354
|
if (process.platform === "darwin") {
|
|
3086
|
-
const base =
|
|
3087
|
-
for (const h of HOSTS) out.push(
|
|
3355
|
+
const base = join19(homedir18(), "Library", "Application Support");
|
|
3356
|
+
for (const h of HOSTS) out.push(join19(base, h));
|
|
3088
3357
|
} else if (process.platform === "win32") {
|
|
3089
|
-
const appData = process.env.APPDATA?.trim() ||
|
|
3090
|
-
for (const h of HOSTS) out.push(
|
|
3358
|
+
const appData = process.env.APPDATA?.trim() || join19(homedir18(), "AppData", "Roaming");
|
|
3359
|
+
for (const h of HOSTS) out.push(join19(appData, h));
|
|
3091
3360
|
} else {
|
|
3092
|
-
const xdg = process.env.XDG_CONFIG_HOME?.trim() ||
|
|
3093
|
-
for (const h of HOSTS) out.push(
|
|
3361
|
+
const xdg = process.env.XDG_CONFIG_HOME?.trim() || join19(homedir18(), ".config");
|
|
3362
|
+
for (const h of HOSTS) out.push(join19(xdg, h));
|
|
3094
3363
|
}
|
|
3095
3364
|
return out;
|
|
3096
3365
|
}
|
|
3097
3366
|
function findClineExtensionDirs() {
|
|
3098
3367
|
const dirs = [];
|
|
3099
3368
|
for (const root of getHostRoots()) {
|
|
3100
|
-
const ext =
|
|
3369
|
+
const ext = join19(root, "User", "globalStorage", EXTENSION_ID);
|
|
3101
3370
|
try {
|
|
3102
3371
|
if (statSync(ext).isDirectory()) dirs.push(ext);
|
|
3103
3372
|
} catch {
|
|
@@ -3129,7 +3398,7 @@ var ClineParser = class {
|
|
|
3129
3398
|
const entries = [];
|
|
3130
3399
|
const sessionEvents = [];
|
|
3131
3400
|
for (const extDir of extDirs) {
|
|
3132
|
-
const history = readJsonSafe(
|
|
3401
|
+
const history = readJsonSafe(join19(extDir, "state", "taskHistory.json"));
|
|
3133
3402
|
if (!Array.isArray(history)) continue;
|
|
3134
3403
|
for (const item of history) {
|
|
3135
3404
|
try {
|
|
@@ -3140,7 +3409,7 @@ var ClineParser = class {
|
|
|
3140
3409
|
);
|
|
3141
3410
|
const fallbackModel = item.modelId && String(item.modelId).trim() || "cline-unknown";
|
|
3142
3411
|
const messages = readJsonSafe(
|
|
3143
|
-
|
|
3412
|
+
join19(extDir, "tasks", taskId, "ui_messages.json")
|
|
3144
3413
|
);
|
|
3145
3414
|
if (!Array.isArray(messages)) continue;
|
|
3146
3415
|
for (const msg of messages) {
|
|
@@ -3211,20 +3480,20 @@ registerParser(new ClineParser());
|
|
|
3211
3480
|
import { execFileSync as execFileSync3 } from "child_process";
|
|
3212
3481
|
import {
|
|
3213
3482
|
copyFileSync,
|
|
3214
|
-
existsSync as
|
|
3483
|
+
existsSync as existsSync19,
|
|
3215
3484
|
mkdtempSync,
|
|
3216
3485
|
readdirSync as readdirSync10,
|
|
3217
3486
|
readFileSync as readFileSync7,
|
|
3218
3487
|
rmSync,
|
|
3219
3488
|
statSync as statSync2
|
|
3220
3489
|
} from "fs";
|
|
3221
|
-
import { homedir as
|
|
3222
|
-
import { join as
|
|
3223
|
-
var KIROAGENT_RELATIVE =
|
|
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");
|
|
3224
3493
|
function getDefaultBasePath() {
|
|
3225
3494
|
if (process.platform === "darwin") {
|
|
3226
|
-
return
|
|
3227
|
-
|
|
3495
|
+
return join20(
|
|
3496
|
+
homedir19(),
|
|
3228
3497
|
"Library",
|
|
3229
3498
|
"Application Support",
|
|
3230
3499
|
"Kiro",
|
|
@@ -3232,11 +3501,11 @@ function getDefaultBasePath() {
|
|
|
3232
3501
|
);
|
|
3233
3502
|
}
|
|
3234
3503
|
if (process.platform === "win32") {
|
|
3235
|
-
const appData = process.env.APPDATA?.trim() ||
|
|
3236
|
-
return
|
|
3504
|
+
const appData = process.env.APPDATA?.trim() || join20(homedir19(), "AppData", "Roaming");
|
|
3505
|
+
return join20(appData, "Kiro", KIROAGENT_RELATIVE);
|
|
3237
3506
|
}
|
|
3238
|
-
const xdgConfigHome = process.env.XDG_CONFIG_HOME?.trim() ||
|
|
3239
|
-
return
|
|
3507
|
+
const xdgConfigHome = process.env.XDG_CONFIG_HOME?.trim() || join20(homedir19(), ".config");
|
|
3508
|
+
return join20(xdgConfigHome, "Kiro", KIROAGENT_RELATIVE);
|
|
3240
3509
|
}
|
|
3241
3510
|
var TOOL7 = {
|
|
3242
3511
|
id: "kiro",
|
|
@@ -3247,10 +3516,10 @@ function getKiroBasePath() {
|
|
|
3247
3516
|
const explicit = process.env.KIRO_BASE_PATH?.trim();
|
|
3248
3517
|
if (explicit) {
|
|
3249
3518
|
const r = resolve(explicit);
|
|
3250
|
-
return
|
|
3519
|
+
return existsSync19(r) ? r : null;
|
|
3251
3520
|
}
|
|
3252
3521
|
const def = getDefaultBasePath();
|
|
3253
|
-
return
|
|
3522
|
+
return existsSync19(def) ? def : null;
|
|
3254
3523
|
}
|
|
3255
3524
|
function isLockError(err) {
|
|
3256
3525
|
return err instanceof Error && typeof err.message === "string" && /database is locked/i.test(err.message);
|
|
@@ -3271,12 +3540,12 @@ function readDb(dbPath) {
|
|
|
3271
3540
|
return queryDb(dbPath, TOKENS_SQL);
|
|
3272
3541
|
} catch (err) {
|
|
3273
3542
|
if (!isLockError(err)) throw err;
|
|
3274
|
-
const snapshotDir = mkdtempSync(
|
|
3275
|
-
const queryPath =
|
|
3543
|
+
const snapshotDir = mkdtempSync(join20(tmpdir(), "vibe-usage-kiro-"));
|
|
3544
|
+
const queryPath = join20(snapshotDir, "devdata.sqlite");
|
|
3276
3545
|
copyFileSync(dbPath, queryPath);
|
|
3277
3546
|
for (const suffix of ["-shm", "-wal"]) {
|
|
3278
3547
|
const companion = `${dbPath}${suffix}`;
|
|
3279
|
-
if (
|
|
3548
|
+
if (existsSync19(companion))
|
|
3280
3549
|
copyFileSync(companion, `${queryPath}${suffix}`);
|
|
3281
3550
|
}
|
|
3282
3551
|
try {
|
|
@@ -3328,7 +3597,7 @@ function buildModelTimeline(base) {
|
|
|
3328
3597
|
}
|
|
3329
3598
|
for (const entry of entries) {
|
|
3330
3599
|
if (!entry.isDirectory() || entry.name === "dev_data") continue;
|
|
3331
|
-
const dirPath =
|
|
3600
|
+
const dirPath = join20(base, entry.name);
|
|
3332
3601
|
let files;
|
|
3333
3602
|
try {
|
|
3334
3603
|
files = readdirSync10(dirPath).filter((f) => f.endsWith(".chat"));
|
|
@@ -3337,7 +3606,7 @@ function buildModelTimeline(base) {
|
|
|
3337
3606
|
}
|
|
3338
3607
|
for (const file of files) {
|
|
3339
3608
|
try {
|
|
3340
|
-
const data = JSON.parse(readFileSync7(
|
|
3609
|
+
const data = JSON.parse(readFileSync7(join20(dirPath, file), "utf-8"));
|
|
3341
3610
|
const meta = data?.metadata;
|
|
3342
3611
|
if (!meta?.modelId || !meta?.startTime) continue;
|
|
3343
3612
|
const startMs = Number(meta.startTime);
|
|
@@ -3386,13 +3655,13 @@ var KiroParser = class {
|
|
|
3386
3655
|
async parse() {
|
|
3387
3656
|
const base = getKiroBasePath();
|
|
3388
3657
|
if (!base) return { buckets: [], sessions: [] };
|
|
3389
|
-
const dbPath =
|
|
3390
|
-
const jsonlPath =
|
|
3658
|
+
const dbPath = join20(base, "dev_data", "devdata.sqlite");
|
|
3659
|
+
const jsonlPath = join20(base, "dev_data", "tokens_generated.jsonl");
|
|
3391
3660
|
let rows;
|
|
3392
3661
|
try {
|
|
3393
|
-
if (
|
|
3662
|
+
if (existsSync19(dbPath)) {
|
|
3394
3663
|
rows = readDb(dbPath);
|
|
3395
|
-
} else if (
|
|
3664
|
+
} else if (existsSync19(jsonlPath)) {
|
|
3396
3665
|
rows = readJsonl(jsonlPath);
|
|
3397
3666
|
} else {
|
|
3398
3667
|
return { buckets: [], sessions: [] };
|
|
@@ -3443,8 +3712,8 @@ registerParser(new KiroParser());
|
|
|
3443
3712
|
|
|
3444
3713
|
// src/parsers/roo-code.ts
|
|
3445
3714
|
import { readdirSync as readdirSync11, readFileSync as readFileSync8, statSync as statSync3 } from "fs";
|
|
3446
|
-
import { homedir as
|
|
3447
|
-
import { basename as basename8, join as
|
|
3715
|
+
import { homedir as homedir20 } from "os";
|
|
3716
|
+
import { basename as basename8, join as join21 } from "path";
|
|
3448
3717
|
var EXTENSION_ID2 = "rooveterinaryinc.roo-cline";
|
|
3449
3718
|
var HOSTS2 = [
|
|
3450
3719
|
"Code",
|
|
@@ -3459,17 +3728,17 @@ function getHostRoots2() {
|
|
|
3459
3728
|
const out = [];
|
|
3460
3729
|
let roots;
|
|
3461
3730
|
if (process.platform === "darwin") {
|
|
3462
|
-
roots = [
|
|
3731
|
+
roots = [join21(homedir20(), "Library", "Application Support")];
|
|
3463
3732
|
} else if (process.platform === "win32") {
|
|
3464
3733
|
roots = [
|
|
3465
|
-
process.env.APPDATA?.trim() ||
|
|
3734
|
+
process.env.APPDATA?.trim() || join21(homedir20(), "AppData", "Roaming")
|
|
3466
3735
|
];
|
|
3467
3736
|
} else {
|
|
3468
|
-
roots = [process.env.XDG_CONFIG_HOME?.trim() ||
|
|
3737
|
+
roots = [process.env.XDG_CONFIG_HOME?.trim() || join21(homedir20(), ".config")];
|
|
3469
3738
|
}
|
|
3470
3739
|
for (const root of roots) {
|
|
3471
3740
|
for (const h of HOSTS2) {
|
|
3472
|
-
out.push(
|
|
3741
|
+
out.push(join21(root, h));
|
|
3473
3742
|
}
|
|
3474
3743
|
}
|
|
3475
3744
|
return out;
|
|
@@ -3477,7 +3746,7 @@ function getHostRoots2() {
|
|
|
3477
3746
|
function findExtensionDirs() {
|
|
3478
3747
|
const dirs = [];
|
|
3479
3748
|
for (const root of getHostRoots2()) {
|
|
3480
|
-
const ext =
|
|
3749
|
+
const ext = join21(root, "User", "globalStorage", EXTENSION_ID2);
|
|
3481
3750
|
try {
|
|
3482
3751
|
if (statSync3(ext).isDirectory()) dirs.push(ext);
|
|
3483
3752
|
} catch {
|
|
@@ -3499,9 +3768,9 @@ function projectFromPath2(absPath) {
|
|
|
3499
3768
|
return name || "unknown";
|
|
3500
3769
|
}
|
|
3501
3770
|
function readHistoryItems(extDir) {
|
|
3502
|
-
const tasksDir =
|
|
3771
|
+
const tasksDir = join21(extDir, "tasks");
|
|
3503
3772
|
const index = readJsonSafe2(
|
|
3504
|
-
|
|
3773
|
+
join21(tasksDir, "_index.json")
|
|
3505
3774
|
);
|
|
3506
3775
|
if (index?.entries && Array.isArray(index.entries)) return index.entries;
|
|
3507
3776
|
const items = [];
|
|
@@ -3515,7 +3784,7 @@ function readHistoryItems(extDir) {
|
|
|
3515
3784
|
if (!entry.isDirectory() || entry.name.startsWith("_") || entry.name.startsWith("."))
|
|
3516
3785
|
continue;
|
|
3517
3786
|
const item = readJsonSafe2(
|
|
3518
|
-
|
|
3787
|
+
join21(tasksDir, entry.name, "history_item.json")
|
|
3519
3788
|
);
|
|
3520
3789
|
if (item && typeof item === "object") items.push(item);
|
|
3521
3790
|
}
|
|
@@ -3542,7 +3811,7 @@ var RooCodeParser = class {
|
|
|
3542
3811
|
const project = projectFromPath2(item.workspace);
|
|
3543
3812
|
const fallbackModel = item.apiConfigName && String(item.apiConfigName).trim() || "roo-unknown";
|
|
3544
3813
|
const messages = readJsonSafe2(
|
|
3545
|
-
|
|
3814
|
+
join21(extDir, "tasks", taskId, "ui_messages.json")
|
|
3546
3815
|
);
|
|
3547
3816
|
if (!Array.isArray(messages)) continue;
|
|
3548
3817
|
for (const msg of messages) {
|
|
@@ -3606,10 +3875,10 @@ var RooCodeParser = class {
|
|
|
3606
3875
|
registerParser(new RooCodeParser());
|
|
3607
3876
|
|
|
3608
3877
|
// src/parsers/snow.ts
|
|
3609
|
-
import { existsSync as
|
|
3610
|
-
import { homedir as
|
|
3611
|
-
import { join as
|
|
3612
|
-
var DEFAULT_DATA_DIR6 =
|
|
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");
|
|
3613
3882
|
function toNonNegativeNumber2(value) {
|
|
3614
3883
|
const numberValue = Number(value);
|
|
3615
3884
|
return Number.isFinite(numberValue) && numberValue >= 0 ? numberValue : 0;
|
|
@@ -3656,26 +3925,26 @@ var SnowParser = class {
|
|
|
3656
3925
|
return { buckets: aggregateToBuckets(entries), sessions: [] };
|
|
3657
3926
|
}
|
|
3658
3927
|
isInstalled() {
|
|
3659
|
-
return
|
|
3928
|
+
return existsSync20(this.dataDir);
|
|
3660
3929
|
}
|
|
3661
3930
|
};
|
|
3662
3931
|
registerParser(new SnowParser());
|
|
3663
3932
|
|
|
3664
3933
|
// src/parsers/cursor.ts
|
|
3665
3934
|
import { execFileSync as execFileSync4 } from "child_process";
|
|
3666
|
-
import { copyFileSync as copyFileSync2, existsSync as
|
|
3667
|
-
import { homedir as
|
|
3668
|
-
import { dirname as dirname4, join as
|
|
3669
|
-
var
|
|
3670
|
-
var
|
|
3671
|
-
var STATE_DB_RELATIVE =
|
|
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");
|
|
3672
3941
|
var ACCESS_TOKEN_KEY = "cursorAuth/accessToken";
|
|
3673
3942
|
var SESSION_COOKIE = "WorkosCursorSessionToken";
|
|
3674
3943
|
var FETCH_TIMEOUT_MS = 1e4;
|
|
3675
3944
|
function getDefaultStateDbPath() {
|
|
3676
3945
|
if (process.platform === "darwin") {
|
|
3677
|
-
return
|
|
3678
|
-
|
|
3946
|
+
return join23(
|
|
3947
|
+
homedir22(),
|
|
3679
3948
|
"Library",
|
|
3680
3949
|
"Application Support",
|
|
3681
3950
|
"Cursor",
|
|
@@ -3683,25 +3952,25 @@ function getDefaultStateDbPath() {
|
|
|
3683
3952
|
);
|
|
3684
3953
|
}
|
|
3685
3954
|
if (process.platform === "win32") {
|
|
3686
|
-
const appData = process.env.APPDATA?.trim() ||
|
|
3687
|
-
return
|
|
3955
|
+
const appData = process.env.APPDATA?.trim() || join23(homedir22(), "AppData", "Roaming");
|
|
3956
|
+
return join23(appData, "Cursor", STATE_DB_RELATIVE);
|
|
3688
3957
|
}
|
|
3689
|
-
const xdgConfigHome = process.env.XDG_CONFIG_HOME?.trim() ||
|
|
3690
|
-
return
|
|
3958
|
+
const xdgConfigHome = process.env.XDG_CONFIG_HOME?.trim() || join23(homedir22(), ".config");
|
|
3959
|
+
return join23(xdgConfigHome, "Cursor", STATE_DB_RELATIVE);
|
|
3691
3960
|
}
|
|
3692
3961
|
function getCursorStateDbPath() {
|
|
3693
3962
|
const explicit = process.env.CURSOR_STATE_DB_PATH?.trim();
|
|
3694
3963
|
if (explicit) {
|
|
3695
3964
|
const resolved = resolve2(explicit);
|
|
3696
|
-
return
|
|
3965
|
+
return existsSync21(resolved) ? resolved : null;
|
|
3697
3966
|
}
|
|
3698
3967
|
const configDirs = process.env.CURSOR_CONFIG_DIR?.trim();
|
|
3699
3968
|
const candidates = configDirs ? configDirs.split(",").map((v) => v.trim()).filter(Boolean).map((v) => {
|
|
3700
3969
|
const r = resolve2(v);
|
|
3701
|
-
return r.endsWith(".vscdb") ? r :
|
|
3970
|
+
return r.endsWith(".vscdb") ? r : join23(r, STATE_DB_RELATIVE);
|
|
3702
3971
|
}) : [getDefaultStateDbPath()];
|
|
3703
3972
|
for (const c of candidates) {
|
|
3704
|
-
if (
|
|
3973
|
+
if (existsSync21(c)) return c;
|
|
3705
3974
|
}
|
|
3706
3975
|
return null;
|
|
3707
3976
|
}
|
|
@@ -3741,13 +4010,13 @@ function readAccessToken(dbPath) {
|
|
|
3741
4010
|
return queryAccessToken(dbPath);
|
|
3742
4011
|
} catch (err) {
|
|
3743
4012
|
if (!isLockError2(err)) throw err;
|
|
3744
|
-
const snapshotDir = mkdtempSync2(
|
|
3745
|
-
const queryPath =
|
|
4013
|
+
const snapshotDir = mkdtempSync2(join23(tmpdir2(), "tokenarena-cursor-"));
|
|
4014
|
+
const queryPath = join23(snapshotDir, "state.vscdb");
|
|
3746
4015
|
try {
|
|
3747
4016
|
copyFileSync2(dbPath, queryPath);
|
|
3748
4017
|
for (const suffix of ["-shm", "-wal"]) {
|
|
3749
4018
|
const companion = `${dbPath}${suffix}`;
|
|
3750
|
-
if (
|
|
4019
|
+
if (existsSync21(companion))
|
|
3751
4020
|
copyFileSync2(companion, `${queryPath}${suffix}`);
|
|
3752
4021
|
}
|
|
3753
4022
|
return queryAccessToken(queryPath);
|
|
@@ -3875,8 +4144,8 @@ function parseInt0(value) {
|
|
|
3875
4144
|
}
|
|
3876
4145
|
function createToolDefinition10(dbPath) {
|
|
3877
4146
|
return {
|
|
3878
|
-
id:
|
|
3879
|
-
name:
|
|
4147
|
+
id: TOOL_ID14,
|
|
4148
|
+
name: TOOL_NAME14,
|
|
3880
4149
|
dataDir: dirname4(dbPath)
|
|
3881
4150
|
};
|
|
3882
4151
|
}
|
|
@@ -3892,7 +4161,7 @@ var CursorParser = class {
|
|
|
3892
4161
|
this.tool = createToolDefinition10(this.dbPath);
|
|
3893
4162
|
}
|
|
3894
4163
|
async parse() {
|
|
3895
|
-
if (!this.dbPath || !
|
|
4164
|
+
if (!this.dbPath || !existsSync21(this.dbPath)) {
|
|
3896
4165
|
return { buckets: [], sessions: [] };
|
|
3897
4166
|
}
|
|
3898
4167
|
let token;
|
|
@@ -3939,7 +4208,7 @@ var CursorParser = class {
|
|
|
3939
4208
|
const output = outputIdx >= 0 ? parseInt0(row[outputIdx]) : 0;
|
|
3940
4209
|
if (inputCacheWrite + inputNoCache + cacheRead + output === 0) continue;
|
|
3941
4210
|
entries.push({
|
|
3942
|
-
source:
|
|
4211
|
+
source: TOOL_ID14,
|
|
3943
4212
|
model,
|
|
3944
4213
|
project: "unknown",
|
|
3945
4214
|
timestamp,
|
|
@@ -3955,19 +4224,19 @@ var CursorParser = class {
|
|
|
3955
4224
|
};
|
|
3956
4225
|
}
|
|
3957
4226
|
isInstalled() {
|
|
3958
|
-
return
|
|
4227
|
+
return existsSync21(this.dbPath);
|
|
3959
4228
|
}
|
|
3960
4229
|
};
|
|
3961
4230
|
registerParser(new CursorParser());
|
|
3962
4231
|
|
|
3963
4232
|
// src/parsers/zcode.ts
|
|
3964
|
-
import { createHash as
|
|
3965
|
-
import { existsSync as
|
|
3966
|
-
import { homedir as
|
|
3967
|
-
import { dirname as dirname5, join as
|
|
3968
|
-
var
|
|
3969
|
-
var
|
|
3970
|
-
var DEFAULT_DB_PATH3 =
|
|
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");
|
|
3971
4240
|
var MODEL_USAGE_QUERY = `SELECT
|
|
3972
4241
|
model_usage.session_id as sessionId,
|
|
3973
4242
|
session.directory as directory,
|
|
@@ -4002,8 +4271,8 @@ var TURN_USAGE_QUERY = `SELECT
|
|
|
4002
4271
|
WHERE duration_ms IS NOT NULL`;
|
|
4003
4272
|
function createToolDefinition11(dbPath) {
|
|
4004
4273
|
return {
|
|
4005
|
-
id:
|
|
4006
|
-
name:
|
|
4274
|
+
id: TOOL_ID15,
|
|
4275
|
+
name: TOOL_NAME15,
|
|
4007
4276
|
dataDir: dirname5(dbPath)
|
|
4008
4277
|
};
|
|
4009
4278
|
}
|
|
@@ -4011,7 +4280,7 @@ function toSafeNumber11(value) {
|
|
|
4011
4280
|
const numberValue = Number(value);
|
|
4012
4281
|
return Number.isFinite(numberValue) && numberValue > 0 ? numberValue : 0;
|
|
4013
4282
|
}
|
|
4014
|
-
function
|
|
4283
|
+
function getString3(value) {
|
|
4015
4284
|
return typeof value === "string" && value.length > 0 ? value : null;
|
|
4016
4285
|
}
|
|
4017
4286
|
function parseUnixMillis(value) {
|
|
@@ -4022,7 +4291,7 @@ function parseUnixMillis(value) {
|
|
|
4022
4291
|
const timestamp = new Date(numberValue);
|
|
4023
4292
|
return Number.isNaN(timestamp.getTime()) ? null : timestamp;
|
|
4024
4293
|
}
|
|
4025
|
-
function
|
|
4294
|
+
function getPathLeaf8(value) {
|
|
4026
4295
|
if (!value) {
|
|
4027
4296
|
return "unknown";
|
|
4028
4297
|
}
|
|
@@ -4051,7 +4320,7 @@ function getOrCreateDraft(drafts, sessionId, project) {
|
|
|
4051
4320
|
}
|
|
4052
4321
|
const next = {
|
|
4053
4322
|
sessionId,
|
|
4054
|
-
source:
|
|
4323
|
+
source: TOOL_ID15,
|
|
4055
4324
|
project,
|
|
4056
4325
|
firstMessageAt: null,
|
|
4057
4326
|
lastMessageAt: null,
|
|
@@ -4065,7 +4334,7 @@ function getOrCreateDraft(drafts, sessionId, project) {
|
|
|
4065
4334
|
drafts.set(sessionId, next);
|
|
4066
4335
|
return next;
|
|
4067
4336
|
}
|
|
4068
|
-
function
|
|
4337
|
+
function buildSessionUsage3(entries) {
|
|
4069
4338
|
const usageBySession = /* @__PURE__ */ new Map();
|
|
4070
4339
|
for (const entry of entries) {
|
|
4071
4340
|
if (!entry.sessionId || hasInvalidTokenCounts(entry)) {
|
|
@@ -4097,23 +4366,23 @@ function buildSessionUsage2(entries) {
|
|
|
4097
4366
|
}
|
|
4098
4367
|
return usageBySession;
|
|
4099
4368
|
}
|
|
4100
|
-
function
|
|
4369
|
+
function buildSessions2(input2) {
|
|
4101
4370
|
const drafts = /* @__PURE__ */ new Map();
|
|
4102
4371
|
for (const row of input2.sessionRows) {
|
|
4103
|
-
const sessionId =
|
|
4372
|
+
const sessionId = getString3(row.id);
|
|
4104
4373
|
if (!sessionId) {
|
|
4105
4374
|
continue;
|
|
4106
4375
|
}
|
|
4107
4376
|
const draft = getOrCreateDraft(
|
|
4108
4377
|
drafts,
|
|
4109
4378
|
sessionId,
|
|
4110
|
-
|
|
4379
|
+
getPathLeaf8(getString3(row.directory))
|
|
4111
4380
|
);
|
|
4112
4381
|
draft.fallbackFirstAt = parseUnixMillis(row.timeCreated);
|
|
4113
4382
|
draft.fallbackLastAt = parseUnixMillis(row.timeUpdated);
|
|
4114
4383
|
}
|
|
4115
4384
|
for (const row of input2.messageRows) {
|
|
4116
|
-
const sessionId =
|
|
4385
|
+
const sessionId = getString3(row.sessionId);
|
|
4117
4386
|
if (!sessionId) {
|
|
4118
4387
|
continue;
|
|
4119
4388
|
}
|
|
@@ -4140,15 +4409,15 @@ function buildSessions(input2) {
|
|
|
4140
4409
|
}
|
|
4141
4410
|
}
|
|
4142
4411
|
for (const row of input2.turnRows) {
|
|
4143
|
-
const sessionId =
|
|
4412
|
+
const sessionId = getString3(row.sessionId);
|
|
4144
4413
|
if (!sessionId) {
|
|
4145
4414
|
continue;
|
|
4146
4415
|
}
|
|
4147
4416
|
const draft = getOrCreateDraft(drafts, sessionId, "unknown");
|
|
4148
4417
|
draft.activeSeconds += Math.round(toSafeNumber11(row.durationMs) / 1e3);
|
|
4149
4418
|
}
|
|
4150
|
-
const usageBySession =
|
|
4151
|
-
const host =
|
|
4419
|
+
const usageBySession = buildSessionUsage3(input2.entries);
|
|
4420
|
+
const host = hostname5().replace(/\.local$/, "");
|
|
4152
4421
|
return Array.from(drafts.values()).map((draft) => {
|
|
4153
4422
|
const firstMessageAt = draft.firstMessageAt ?? draft.fallbackFirstAt;
|
|
4154
4423
|
const lastMessageAt = draft.lastMessageAt ?? draft.fallbackLastAt ?? firstMessageAt;
|
|
@@ -4190,12 +4459,14 @@ function buildSessions(input2) {
|
|
|
4190
4459
|
return {
|
|
4191
4460
|
source: draft.source,
|
|
4192
4461
|
project: draft.project,
|
|
4193
|
-
sessionHash:
|
|
4462
|
+
sessionHash: createHash3("sha256").update(draft.sessionId).digest("hex").slice(0, 16),
|
|
4194
4463
|
hostname: host,
|
|
4195
4464
|
firstMessageAt: firstMessageAt.toISOString(),
|
|
4196
4465
|
lastMessageAt: lastMessageAt.toISOString(),
|
|
4197
4466
|
durationSeconds,
|
|
4198
|
-
|
|
4467
|
+
// Turn durations can overlap (parallel tool calls), so the sum may
|
|
4468
|
+
// exceed the wall-clock span of the session.
|
|
4469
|
+
activeSeconds: Math.min(draft.activeSeconds, durationSeconds),
|
|
4199
4470
|
messageCount: draft.messageCount,
|
|
4200
4471
|
userMessageCount: draft.userMessageCount,
|
|
4201
4472
|
userPromptHours: draft.userPromptHours,
|
|
@@ -4219,7 +4490,7 @@ var ZCodeParser = class {
|
|
|
4219
4490
|
this.tool = createToolDefinition11(this.dbPath);
|
|
4220
4491
|
}
|
|
4221
4492
|
async parse() {
|
|
4222
|
-
if (!
|
|
4493
|
+
if (!existsSync22(this.dbPath)) {
|
|
4223
4494
|
return { buckets: [], sessions: [] };
|
|
4224
4495
|
}
|
|
4225
4496
|
const usageRows = await this.queryRows(
|
|
@@ -4240,10 +4511,10 @@ var ZCodeParser = class {
|
|
|
4240
4511
|
continue;
|
|
4241
4512
|
}
|
|
4242
4513
|
entries.push({
|
|
4243
|
-
sessionId:
|
|
4244
|
-
source:
|
|
4245
|
-
model:
|
|
4246
|
-
project:
|
|
4514
|
+
sessionId: getString3(row.sessionId) ?? void 0,
|
|
4515
|
+
source: TOOL_ID15,
|
|
4516
|
+
model: getString3(row.model) ?? "unknown",
|
|
4517
|
+
project: getPathLeaf8(getString3(row.directory)),
|
|
4247
4518
|
timestamp,
|
|
4248
4519
|
inputTokens,
|
|
4249
4520
|
outputTokens,
|
|
@@ -4268,7 +4539,7 @@ var ZCodeParser = class {
|
|
|
4268
4539
|
}
|
|
4269
4540
|
return {
|
|
4270
4541
|
buckets: aggregateToBuckets(entries),
|
|
4271
|
-
sessions:
|
|
4542
|
+
sessions: buildSessions2({
|
|
4272
4543
|
sessionRows,
|
|
4273
4544
|
messageRows,
|
|
4274
4545
|
turnRows,
|
|
@@ -4277,27 +4548,27 @@ var ZCodeParser = class {
|
|
|
4277
4548
|
};
|
|
4278
4549
|
}
|
|
4279
4550
|
isInstalled() {
|
|
4280
|
-
return
|
|
4551
|
+
return existsSync22(this.dbPath);
|
|
4281
4552
|
}
|
|
4282
4553
|
};
|
|
4283
4554
|
registerParser(new ZCodeParser());
|
|
4284
4555
|
|
|
4285
4556
|
// src/parsers/qodercli.ts
|
|
4286
|
-
import { existsSync as
|
|
4287
|
-
import { homedir as
|
|
4288
|
-
import { basename as basename9, join as
|
|
4289
|
-
var
|
|
4290
|
-
var
|
|
4291
|
-
var DEFAULT_PROJECTS_DIR =
|
|
4292
|
-
var DEFAULT_LOGS_DIR =
|
|
4293
|
-
var DEFAULT_RUNS_DIR =
|
|
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");
|
|
4294
4565
|
var CLI_ENTRYPOINT = "cli";
|
|
4295
4566
|
var IDE_ENTRYPOINT = "acp";
|
|
4296
4567
|
var CREDIT_MODEL_FALLBACK = "credits";
|
|
4297
4568
|
function createToolDefinition12(projectsDir) {
|
|
4298
4569
|
return {
|
|
4299
|
-
id:
|
|
4300
|
-
name:
|
|
4570
|
+
id: TOOL_ID16,
|
|
4571
|
+
name: TOOL_NAME16,
|
|
4301
4572
|
dataDir: projectsDir
|
|
4302
4573
|
};
|
|
4303
4574
|
}
|
|
@@ -4336,13 +4607,13 @@ function classifyQoderEntrypoint(content) {
|
|
|
4336
4607
|
return "unknown";
|
|
4337
4608
|
}
|
|
4338
4609
|
function isQodercliBinaryPresent() {
|
|
4339
|
-
const home =
|
|
4610
|
+
const home = homedir24();
|
|
4340
4611
|
const candidates = [
|
|
4341
|
-
|
|
4342
|
-
|
|
4343
|
-
|
|
4612
|
+
join25(home, ".local", "bin", "qodercli"),
|
|
4613
|
+
join25(home, ".qoder", "bin", "qodercli"),
|
|
4614
|
+
join25(home, ".qoder-cli")
|
|
4344
4615
|
];
|
|
4345
|
-
return candidates.some((path) =>
|
|
4616
|
+
return candidates.some((path) => existsSync23(path));
|
|
4346
4617
|
}
|
|
4347
4618
|
function projectFromEncodedSlug(slug) {
|
|
4348
4619
|
const parts = slug.split("-").filter(Boolean);
|
|
@@ -4413,7 +4684,7 @@ function creditSnapshotsToEntries(snapshots) {
|
|
|
4413
4684
|
if (creditDelta > 0) {
|
|
4414
4685
|
entries.push({
|
|
4415
4686
|
sessionId: snap.sessionId,
|
|
4416
|
-
source:
|
|
4687
|
+
source: TOOL_ID16,
|
|
4417
4688
|
model: snap.model || CREDIT_MODEL_FALLBACK,
|
|
4418
4689
|
project: snap.project,
|
|
4419
4690
|
timestamp: snap.timestamp,
|
|
@@ -4451,7 +4722,7 @@ var QoderCliParser = class {
|
|
|
4451
4722
|
};
|
|
4452
4723
|
}
|
|
4453
4724
|
parseProjectSessions(sessionEvents) {
|
|
4454
|
-
if (!
|
|
4725
|
+
if (!existsSync23(this.projectsDir)) return;
|
|
4455
4726
|
for (const filePath of findJsonlFiles(this.projectsDir)) {
|
|
4456
4727
|
if (basename9(filePath).startsWith("verified-")) continue;
|
|
4457
4728
|
const content = readFileSafe(filePath);
|
|
@@ -4473,7 +4744,7 @@ var QoderCliParser = class {
|
|
|
4473
4744
|
if (Number.isNaN(ts.getTime())) continue;
|
|
4474
4745
|
sessionEvents.push({
|
|
4475
4746
|
sessionId,
|
|
4476
|
-
source:
|
|
4747
|
+
source: TOOL_ID16,
|
|
4477
4748
|
project,
|
|
4478
4749
|
timestamp: ts,
|
|
4479
4750
|
role: obj.type === "user" ? "user" : "assistant"
|
|
@@ -4488,7 +4759,7 @@ var QoderCliParser = class {
|
|
|
4488
4759
|
* There is no token data here — only quota/usage credit totals.
|
|
4489
4760
|
*/
|
|
4490
4761
|
parseCreditDeltas() {
|
|
4491
|
-
if (!
|
|
4762
|
+
if (!existsSync23(this.runsDir)) return [];
|
|
4492
4763
|
let runDirs;
|
|
4493
4764
|
try {
|
|
4494
4765
|
runDirs = readdirSync12(this.runsDir, { withFileTypes: true }).filter(
|
|
@@ -4499,15 +4770,15 @@ var QoderCliParser = class {
|
|
|
4499
4770
|
}
|
|
4500
4771
|
const allSnapshots = [];
|
|
4501
4772
|
for (const dir of runDirs) {
|
|
4502
|
-
const runPath =
|
|
4503
|
-
const logPath =
|
|
4504
|
-
if (!
|
|
4773
|
+
const runPath = join25(this.runsDir, dir.name);
|
|
4774
|
+
const logPath = join25(runPath, "qodercli.log");
|
|
4775
|
+
if (!existsSync23(logPath)) continue;
|
|
4505
4776
|
const logContent = readFileSafe(logPath);
|
|
4506
4777
|
if (!logContent?.includes("quota/usage response:")) {
|
|
4507
4778
|
continue;
|
|
4508
4779
|
}
|
|
4509
4780
|
const manifest = parseRunManifest(
|
|
4510
|
-
readFileSafe(
|
|
4781
|
+
readFileSafe(join25(runPath, "manifest.json"))
|
|
4511
4782
|
);
|
|
4512
4783
|
const project = manifest?.project_id ? projectFromEncodedSlug(manifest.project_id) : projectFromCwd(manifest?.cwd);
|
|
4513
4784
|
const snapshots = extractCreditSnapshotsFromLog(logContent, {
|
|
@@ -4519,22 +4790,22 @@ var QoderCliParser = class {
|
|
|
4519
4790
|
return creditSnapshotsToEntries(allSnapshots);
|
|
4520
4791
|
}
|
|
4521
4792
|
isInstalled() {
|
|
4522
|
-
return isQodercliBinaryPresent() ||
|
|
4793
|
+
return isQodercliBinaryPresent() || existsSync23(this.runsDir) || existsSync23(this.logsDir) || existsSync23(this.projectsDir);
|
|
4523
4794
|
}
|
|
4524
4795
|
};
|
|
4525
4796
|
registerParser(new QoderCliParser());
|
|
4526
4797
|
|
|
4527
4798
|
// src/parsers/grok-build.ts
|
|
4528
|
-
import { existsSync as
|
|
4529
|
-
import { homedir as
|
|
4530
|
-
import { basename as basename10, join as
|
|
4531
|
-
var
|
|
4532
|
-
var
|
|
4533
|
-
var DEFAULT_DATA_DIR7 =
|
|
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");
|
|
4534
4805
|
function createToolDefinition13(dataDir) {
|
|
4535
4806
|
return {
|
|
4536
|
-
id:
|
|
4537
|
-
name:
|
|
4807
|
+
id: TOOL_ID17,
|
|
4808
|
+
name: TOOL_NAME17,
|
|
4538
4809
|
dataDir
|
|
4539
4810
|
};
|
|
4540
4811
|
}
|
|
@@ -4581,7 +4852,7 @@ function pushUsageEntries(entries, args) {
|
|
|
4581
4852
|
}
|
|
4582
4853
|
entries.push({
|
|
4583
4854
|
sessionId,
|
|
4584
|
-
source:
|
|
4855
|
+
source: TOOL_ID17,
|
|
4585
4856
|
model: model || fallbackModel || "unknown",
|
|
4586
4857
|
project,
|
|
4587
4858
|
timestamp,
|
|
@@ -4594,7 +4865,7 @@ function pushUsageEntries(entries, args) {
|
|
|
4594
4865
|
}
|
|
4595
4866
|
function findSessionDirs(dataDir) {
|
|
4596
4867
|
const results = [];
|
|
4597
|
-
if (!
|
|
4868
|
+
if (!existsSync24(dataDir)) return results;
|
|
4598
4869
|
let projectDirs;
|
|
4599
4870
|
try {
|
|
4600
4871
|
projectDirs = readdirSync13(dataDir, { withFileTypes: true });
|
|
@@ -4604,7 +4875,7 @@ function findSessionDirs(dataDir) {
|
|
|
4604
4875
|
for (const projectEntry of projectDirs) {
|
|
4605
4876
|
if (!projectEntry.isDirectory()) continue;
|
|
4606
4877
|
if (projectEntry.name.endsWith(".sqlite")) continue;
|
|
4607
|
-
const projectDir =
|
|
4878
|
+
const projectDir = join26(dataDir, projectEntry.name);
|
|
4608
4879
|
const project = projectFromEncodedCwd(projectEntry.name);
|
|
4609
4880
|
let sessionEntries;
|
|
4610
4881
|
try {
|
|
@@ -4614,8 +4885,8 @@ function findSessionDirs(dataDir) {
|
|
|
4614
4885
|
}
|
|
4615
4886
|
for (const sessionEntry of sessionEntries) {
|
|
4616
4887
|
if (!sessionEntry.isDirectory()) continue;
|
|
4617
|
-
const sessionDir =
|
|
4618
|
-
if (!
|
|
4888
|
+
const sessionDir = join26(projectDir, sessionEntry.name);
|
|
4889
|
+
if (!existsSync24(join26(sessionDir, "updates.jsonl"))) continue;
|
|
4619
4890
|
results.push({
|
|
4620
4891
|
sessionDir,
|
|
4621
4892
|
project,
|
|
@@ -4626,7 +4897,7 @@ function findSessionDirs(dataDir) {
|
|
|
4626
4897
|
return results;
|
|
4627
4898
|
}
|
|
4628
4899
|
function readFallbackModel(sessionDir) {
|
|
4629
|
-
const summaryPath =
|
|
4900
|
+
const summaryPath = join26(sessionDir, "summary.json");
|
|
4630
4901
|
const content = readFileSafe(summaryPath);
|
|
4631
4902
|
if (!content) return "unknown";
|
|
4632
4903
|
try {
|
|
@@ -4648,7 +4919,7 @@ var GrokBuildParser = class {
|
|
|
4648
4919
|
const sessionEvents = [];
|
|
4649
4920
|
const sessions = findSessionDirs(this.dataDir);
|
|
4650
4921
|
for (const { sessionDir, project, sessionId } of sessions) {
|
|
4651
|
-
const updatesPath =
|
|
4922
|
+
const updatesPath = join26(sessionDir, "updates.jsonl");
|
|
4652
4923
|
const content = readFileSafe(updatesPath);
|
|
4653
4924
|
if (!content) continue;
|
|
4654
4925
|
const fallbackModel = readFallbackModel(sessionDir);
|
|
@@ -4675,7 +4946,7 @@ var GrokBuildParser = class {
|
|
|
4675
4946
|
seenUserPrompts.add(key);
|
|
4676
4947
|
sessionEvents.push({
|
|
4677
4948
|
sessionId: sid,
|
|
4678
|
-
source:
|
|
4949
|
+
source: TOOL_ID17,
|
|
4679
4950
|
project,
|
|
4680
4951
|
timestamp: ts,
|
|
4681
4952
|
role: "user"
|
|
@@ -4686,7 +4957,7 @@ var GrokBuildParser = class {
|
|
|
4686
4957
|
seenUserPrompts.delete(ANON_USER_OPEN);
|
|
4687
4958
|
sessionEvents.push({
|
|
4688
4959
|
sessionId: sid,
|
|
4689
|
-
source:
|
|
4960
|
+
source: TOOL_ID17,
|
|
4690
4961
|
project,
|
|
4691
4962
|
timestamp: ts,
|
|
4692
4963
|
role: "assistant"
|
|
@@ -4708,22 +4979,22 @@ var GrokBuildParser = class {
|
|
|
4708
4979
|
};
|
|
4709
4980
|
}
|
|
4710
4981
|
isInstalled() {
|
|
4711
|
-
return
|
|
4982
|
+
return existsSync24(this.dataDir) || existsSync24(join26(homedir25(), ".grok")) || existsSync24(join26(homedir25(), ".local", "bin", "grok"));
|
|
4712
4983
|
}
|
|
4713
4984
|
};
|
|
4714
4985
|
registerParser(new GrokBuildParser());
|
|
4715
4986
|
|
|
4716
4987
|
// src/parsers/atomcode.ts
|
|
4717
|
-
import { existsSync as
|
|
4718
|
-
import { homedir as
|
|
4719
|
-
import { basename as basename11, join as
|
|
4720
|
-
var
|
|
4721
|
-
var
|
|
4722
|
-
var DEFAULT_SESSIONS_DIR6 =
|
|
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");
|
|
4723
4994
|
function getAtomCodeSessionsDirs(env = process.env) {
|
|
4724
4995
|
const dirs = [
|
|
4725
4996
|
env.TOKEN_ARENA_ATOMCODE_DIR,
|
|
4726
|
-
env.ATOMCODE_HOME ?
|
|
4997
|
+
env.ATOMCODE_HOME ? join27(env.ATOMCODE_HOME, "sessions") : void 0,
|
|
4727
4998
|
DEFAULT_SESSIONS_DIR6
|
|
4728
4999
|
].filter((value) => Boolean(value));
|
|
4729
5000
|
return Array.from(new Set(dirs));
|
|
@@ -4781,8 +5052,8 @@ var AtomCodeParser = class {
|
|
|
4781
5052
|
constructor(sessionsDir) {
|
|
4782
5053
|
this.sessionsDirs = sessionsDir ? [sessionsDir] : getAtomCodeSessionsDirs();
|
|
4783
5054
|
this.tool = {
|
|
4784
|
-
id:
|
|
4785
|
-
name:
|
|
5055
|
+
id: TOOL_ID18,
|
|
5056
|
+
name: TOOL_NAME18,
|
|
4786
5057
|
dataDir: this.sessionsDirs[0] ?? DEFAULT_SESSIONS_DIR6
|
|
4787
5058
|
};
|
|
4788
5059
|
}
|
|
@@ -4809,7 +5080,7 @@ var AtomCodeParser = class {
|
|
|
4809
5080
|
if (row.user !== void 0 || row.assistant !== void 0) {
|
|
4810
5081
|
sessionEvents.push({
|
|
4811
5082
|
sessionId,
|
|
4812
|
-
source:
|
|
5083
|
+
source: TOOL_ID18,
|
|
4813
5084
|
project,
|
|
4814
5085
|
timestamp,
|
|
4815
5086
|
role: row.user !== void 0 ? "user" : "assistant"
|
|
@@ -4838,7 +5109,7 @@ var AtomCodeParser = class {
|
|
|
4838
5109
|
seenEntryKeys.add(entryKey);
|
|
4839
5110
|
entries.push({
|
|
4840
5111
|
sessionId,
|
|
4841
|
-
source:
|
|
5112
|
+
source: TOOL_ID18,
|
|
4842
5113
|
model,
|
|
4843
5114
|
project,
|
|
4844
5115
|
timestamp,
|
|
@@ -4856,24 +5127,24 @@ var AtomCodeParser = class {
|
|
|
4856
5127
|
};
|
|
4857
5128
|
}
|
|
4858
5129
|
isInstalled() {
|
|
4859
|
-
return this.sessionsDirs.some((dir) =>
|
|
5130
|
+
return this.sessionsDirs.some((dir) => existsSync25(dir));
|
|
4860
5131
|
}
|
|
4861
5132
|
};
|
|
4862
5133
|
registerParser(new AtomCodeParser());
|
|
4863
5134
|
|
|
4864
5135
|
// src/parsers/dsh.ts
|
|
4865
|
-
import { existsSync as
|
|
4866
|
-
import { homedir as
|
|
4867
|
-
import { basename as basename12, join as
|
|
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";
|
|
4868
5139
|
import * as zlib from "zlib";
|
|
4869
|
-
var
|
|
4870
|
-
var
|
|
4871
|
-
var DEFAULT_SESSIONS_DIR7 =
|
|
5140
|
+
var TOOL_ID19 = "dsh";
|
|
5141
|
+
var TOOL_NAME19 = "DeepSeek Harness";
|
|
5142
|
+
var DEFAULT_SESSIONS_DIR7 = join28(homedir27(), ".dsh", "sessions");
|
|
4872
5143
|
var LOG_BASENAME = "session";
|
|
4873
5144
|
function getDshSessionsDirs(env = process.env) {
|
|
4874
5145
|
const dirs = [
|
|
4875
5146
|
env.TOKEN_ARENA_DSH_DIR,
|
|
4876
|
-
env.DSH_HOME ?
|
|
5147
|
+
env.DSH_HOME ? join28(env.DSH_HOME, "sessions") : void 0,
|
|
4877
5148
|
DEFAULT_SESSIONS_DIR7
|
|
4878
5149
|
].filter((value) => Boolean(value));
|
|
4879
5150
|
return Array.from(new Set(dirs));
|
|
@@ -4962,10 +5233,10 @@ function readSessionLog(filePath) {
|
|
|
4962
5233
|
}
|
|
4963
5234
|
function findSessionLogs(dir) {
|
|
4964
5235
|
const results = [];
|
|
4965
|
-
if (!
|
|
5236
|
+
if (!existsSync26(dir)) return results;
|
|
4966
5237
|
try {
|
|
4967
5238
|
for (const entry of readdirSync14(dir, { withFileTypes: true })) {
|
|
4968
|
-
const fullPath =
|
|
5239
|
+
const fullPath = join28(dir, entry.name);
|
|
4969
5240
|
if (entry.isDirectory()) {
|
|
4970
5241
|
results.push(...findSessionLogs(fullPath));
|
|
4971
5242
|
} else if (entry.name === `${LOG_BASENAME}.jsonl` || entry.name === `${LOG_BASENAME}.jsonl.zstd`) {
|
|
@@ -4996,8 +5267,8 @@ var DshParser = class {
|
|
|
4996
5267
|
constructor(sessionsDir) {
|
|
4997
5268
|
this.sessionsDirs = sessionsDir ? [sessionsDir] : getDshSessionsDirs();
|
|
4998
5269
|
this.tool = {
|
|
4999
|
-
id:
|
|
5000
|
-
name:
|
|
5270
|
+
id: TOOL_ID19,
|
|
5271
|
+
name: TOOL_NAME19,
|
|
5001
5272
|
dataDir: this.sessionsDirs[0] ?? DEFAULT_SESSIONS_DIR7
|
|
5002
5273
|
};
|
|
5003
5274
|
}
|
|
@@ -5034,7 +5305,7 @@ var DshParser = class {
|
|
|
5034
5305
|
if (timestamp) {
|
|
5035
5306
|
sessionEvents.push({
|
|
5036
5307
|
sessionId,
|
|
5037
|
-
source:
|
|
5308
|
+
source: TOOL_ID19,
|
|
5038
5309
|
project,
|
|
5039
5310
|
timestamp,
|
|
5040
5311
|
role: "user"
|
|
@@ -5047,7 +5318,7 @@ var DshParser = class {
|
|
|
5047
5318
|
if (timestamp && !isCompaction) {
|
|
5048
5319
|
sessionEvents.push({
|
|
5049
5320
|
sessionId,
|
|
5050
|
-
source:
|
|
5321
|
+
source: TOOL_ID19,
|
|
5051
5322
|
project,
|
|
5052
5323
|
timestamp,
|
|
5053
5324
|
role: "assistant"
|
|
@@ -5078,7 +5349,7 @@ var DshParser = class {
|
|
|
5078
5349
|
seenEntryKeys.add(entryKey);
|
|
5079
5350
|
entries.push({
|
|
5080
5351
|
sessionId,
|
|
5081
|
-
source:
|
|
5352
|
+
source: TOOL_ID19,
|
|
5082
5353
|
model,
|
|
5083
5354
|
project,
|
|
5084
5355
|
timestamp,
|
|
@@ -5096,7 +5367,7 @@ var DshParser = class {
|
|
|
5096
5367
|
};
|
|
5097
5368
|
}
|
|
5098
5369
|
isInstalled() {
|
|
5099
|
-
return this.sessionsDirs.some((dir) =>
|
|
5370
|
+
return this.sessionsDirs.some((dir) => existsSync26(dir));
|
|
5100
5371
|
}
|
|
5101
5372
|
};
|
|
5102
5373
|
registerParser(new DshParser());
|
|
@@ -5107,31 +5378,31 @@ import { Command, Option } from "commander";
|
|
|
5107
5378
|
// src/infrastructure/config/manager.ts
|
|
5108
5379
|
import { randomUUID } from "crypto";
|
|
5109
5380
|
import {
|
|
5110
|
-
existsSync as
|
|
5381
|
+
existsSync as existsSync27,
|
|
5111
5382
|
mkdirSync,
|
|
5112
5383
|
readFileSync as readFileSync10,
|
|
5113
5384
|
unlinkSync,
|
|
5114
5385
|
writeFileSync
|
|
5115
5386
|
} from "fs";
|
|
5116
|
-
import { join as
|
|
5387
|
+
import { join as join30 } from "path";
|
|
5117
5388
|
|
|
5118
5389
|
// src/infrastructure/xdg.ts
|
|
5119
|
-
import { homedir as
|
|
5120
|
-
import { join as
|
|
5390
|
+
import { homedir as homedir28 } from "os";
|
|
5391
|
+
import { join as join29 } from "path";
|
|
5121
5392
|
function getConfigHome() {
|
|
5122
|
-
return process.env.XDG_CONFIG_HOME ||
|
|
5393
|
+
return process.env.XDG_CONFIG_HOME || join29(homedir28(), ".config");
|
|
5123
5394
|
}
|
|
5124
5395
|
function getStateHome() {
|
|
5125
|
-
return process.env.XDG_STATE_HOME ||
|
|
5396
|
+
return process.env.XDG_STATE_HOME || join29(homedir28(), ".local", "state");
|
|
5126
5397
|
}
|
|
5127
5398
|
function getRuntimeDir() {
|
|
5128
5399
|
return process.env.XDG_RUNTIME_DIR || getStateHome();
|
|
5129
5400
|
}
|
|
5130
5401
|
|
|
5131
5402
|
// src/infrastructure/config/manager.ts
|
|
5132
|
-
var CONFIG_DIR =
|
|
5403
|
+
var CONFIG_DIR = join30(getConfigHome(), "tokenarena");
|
|
5133
5404
|
var isDev = process.env.TOKEN_ARENA_DEV === "1";
|
|
5134
|
-
var CONFIG_FILE =
|
|
5405
|
+
var CONFIG_FILE = join30(CONFIG_DIR, isDev ? "config.dev.json" : "config.json");
|
|
5135
5406
|
var DEFAULT_API_URL = "https://token.guji.uno";
|
|
5136
5407
|
var VALID_CONFIG_KEYS = [
|
|
5137
5408
|
"apiKey",
|
|
@@ -5147,7 +5418,7 @@ function getConfigDir() {
|
|
|
5147
5418
|
return CONFIG_DIR;
|
|
5148
5419
|
}
|
|
5149
5420
|
function loadConfig() {
|
|
5150
|
-
if (!
|
|
5421
|
+
if (!existsSync27(CONFIG_FILE)) return null;
|
|
5151
5422
|
try {
|
|
5152
5423
|
const raw = readFileSync10(CONFIG_FILE, "utf-8");
|
|
5153
5424
|
const config = JSON.parse(raw);
|
|
@@ -5165,7 +5436,7 @@ function saveConfig(config) {
|
|
|
5165
5436
|
`, "utf-8");
|
|
5166
5437
|
}
|
|
5167
5438
|
function deleteConfig() {
|
|
5168
|
-
if (
|
|
5439
|
+
if (existsSync27(CONFIG_FILE)) {
|
|
5169
5440
|
unlinkSync(CONFIG_FILE);
|
|
5170
5441
|
}
|
|
5171
5442
|
}
|
|
@@ -5625,7 +5896,7 @@ async function handleConfig(args) {
|
|
|
5625
5896
|
}
|
|
5626
5897
|
|
|
5627
5898
|
// src/services/sync-service.ts
|
|
5628
|
-
import { hostname as
|
|
5899
|
+
import { hostname as hostname6 } from "os";
|
|
5629
5900
|
|
|
5630
5901
|
// src/domain/project-identity.ts
|
|
5631
5902
|
import { createHmac } from "crypto";
|
|
@@ -5644,11 +5915,11 @@ function toProjectIdentity(input2) {
|
|
|
5644
5915
|
}
|
|
5645
5916
|
|
|
5646
5917
|
// src/domain/upload-manifest.ts
|
|
5647
|
-
import { createHash as
|
|
5918
|
+
import { createHash as createHash4 } from "crypto";
|
|
5648
5919
|
var MANIFEST_VERSION = 1;
|
|
5649
5920
|
var SNAPSHOT_PROTOCOL_VERSION = 1;
|
|
5650
5921
|
function fingerprint(value) {
|
|
5651
|
-
return
|
|
5922
|
+
return createHash4("sha256").update(value).digest("hex").slice(0, 16);
|
|
5652
5923
|
}
|
|
5653
5924
|
function normalizeApiUrl(apiUrl) {
|
|
5654
5925
|
let end = apiUrl.length;
|
|
@@ -6027,7 +6298,7 @@ var ApiClient = class {
|
|
|
6027
6298
|
// src/infrastructure/runtime/lock.ts
|
|
6028
6299
|
import {
|
|
6029
6300
|
closeSync,
|
|
6030
|
-
existsSync as
|
|
6301
|
+
existsSync as existsSync28,
|
|
6031
6302
|
openSync,
|
|
6032
6303
|
readFileSync as readFileSync11,
|
|
6033
6304
|
rmSync as rmSync3,
|
|
@@ -6036,22 +6307,22 @@ import {
|
|
|
6036
6307
|
|
|
6037
6308
|
// src/infrastructure/runtime/paths.ts
|
|
6038
6309
|
import { mkdirSync as mkdirSync2 } from "fs";
|
|
6039
|
-
import { join as
|
|
6310
|
+
import { join as join31 } from "path";
|
|
6040
6311
|
var APP_NAME = "tokenarena";
|
|
6041
6312
|
function getRuntimeDirPath() {
|
|
6042
|
-
return
|
|
6313
|
+
return join31(getRuntimeDir(), APP_NAME);
|
|
6043
6314
|
}
|
|
6044
6315
|
function getStateDir() {
|
|
6045
|
-
return
|
|
6316
|
+
return join31(getStateHome(), APP_NAME);
|
|
6046
6317
|
}
|
|
6047
6318
|
function getSyncLockPath() {
|
|
6048
|
-
return
|
|
6319
|
+
return join31(getRuntimeDirPath(), "sync.lock");
|
|
6049
6320
|
}
|
|
6050
6321
|
function getSyncStatePath() {
|
|
6051
|
-
return
|
|
6322
|
+
return join31(getStateDir(), "status.json");
|
|
6052
6323
|
}
|
|
6053
6324
|
function getUploadManifestPath() {
|
|
6054
|
-
return
|
|
6325
|
+
return join31(getStateDir(), "upload-manifest.json");
|
|
6055
6326
|
}
|
|
6056
6327
|
function ensureAppDirs() {
|
|
6057
6328
|
mkdirSync2(getRuntimeDirPath(), { recursive: true });
|
|
@@ -6069,7 +6340,7 @@ function isProcessAlive(pid) {
|
|
|
6069
6340
|
}
|
|
6070
6341
|
}
|
|
6071
6342
|
function readLockMetadata(lockPath) {
|
|
6072
|
-
if (!
|
|
6343
|
+
if (!existsSync28(lockPath)) {
|
|
6073
6344
|
return null;
|
|
6074
6345
|
}
|
|
6075
6346
|
try {
|
|
@@ -6143,13 +6414,13 @@ function describeExistingSyncLock() {
|
|
|
6143
6414
|
}
|
|
6144
6415
|
|
|
6145
6416
|
// src/infrastructure/runtime/state.ts
|
|
6146
|
-
import { existsSync as
|
|
6417
|
+
import { existsSync as existsSync29, readFileSync as readFileSync12, writeFileSync as writeFileSync3 } from "fs";
|
|
6147
6418
|
function getDefaultState() {
|
|
6148
6419
|
return { status: "idle" };
|
|
6149
6420
|
}
|
|
6150
6421
|
function loadSyncState() {
|
|
6151
6422
|
const path = getSyncStatePath();
|
|
6152
|
-
if (!
|
|
6423
|
+
if (!existsSync29(path)) {
|
|
6153
6424
|
return getDefaultState();
|
|
6154
6425
|
}
|
|
6155
6426
|
try {
|
|
@@ -6210,7 +6481,7 @@ function markSyncFailed(source, error, status) {
|
|
|
6210
6481
|
}
|
|
6211
6482
|
|
|
6212
6483
|
// src/infrastructure/runtime/upload-manifest.ts
|
|
6213
|
-
import { existsSync as
|
|
6484
|
+
import { existsSync as existsSync30, readFileSync as readFileSync13, writeFileSync as writeFileSync4 } from "fs";
|
|
6214
6485
|
function isRecordOfStrings(value) {
|
|
6215
6486
|
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
6216
6487
|
return false;
|
|
@@ -6226,7 +6497,7 @@ function isUploadManifest(value) {
|
|
|
6226
6497
|
}
|
|
6227
6498
|
function loadUploadManifest() {
|
|
6228
6499
|
const path = getUploadManifestPath();
|
|
6229
|
-
if (!
|
|
6500
|
+
if (!existsSync30(path)) {
|
|
6230
6501
|
return null;
|
|
6231
6502
|
}
|
|
6232
6503
|
try {
|
|
@@ -6348,7 +6619,7 @@ function persistUploadManifest(manifest, quiet) {
|
|
|
6348
6619
|
function toDeviceMetadata(config) {
|
|
6349
6620
|
return {
|
|
6350
6621
|
deviceId: getOrCreateDeviceId(config),
|
|
6351
|
-
hostname:
|
|
6622
|
+
hostname: hostname6().replace(/\.local$/, "")
|
|
6352
6623
|
};
|
|
6353
6624
|
}
|
|
6354
6625
|
function toUploadBuckets(buckets, settings, device) {
|
|
@@ -6766,18 +7037,18 @@ View your dashboard at: ${apiUrl}/usage`);
|
|
|
6766
7037
|
|
|
6767
7038
|
// src/commands/init.ts
|
|
6768
7039
|
import { execFileSync as execFileSync7, spawn } from "child_process";
|
|
6769
|
-
import { existsSync as
|
|
7040
|
+
import { existsSync as existsSync33 } from "fs";
|
|
6770
7041
|
import { appendFile, mkdir, readFile } from "fs/promises";
|
|
6771
|
-
import { homedir as
|
|
6772
|
-
import { dirname as dirname6, join as
|
|
7042
|
+
import { homedir as homedir31, platform as platform5 } from "os";
|
|
7043
|
+
import { dirname as dirname6, join as join32, posix as posix3, win32 } from "path";
|
|
6773
7044
|
|
|
6774
7045
|
// src/infrastructure/service/index.ts
|
|
6775
7046
|
import { platform as platform4 } from "os";
|
|
6776
7047
|
|
|
6777
7048
|
// src/infrastructure/service/linux-systemd.ts
|
|
6778
7049
|
import { execFileSync as execFileSync5 } from "child_process";
|
|
6779
|
-
import { existsSync as
|
|
6780
|
-
import { homedir as
|
|
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";
|
|
6781
7052
|
import { posix } from "path";
|
|
6782
7053
|
|
|
6783
7054
|
// src/utils/command.ts
|
|
@@ -6846,10 +7117,10 @@ function escapeXml(value) {
|
|
|
6846
7117
|
|
|
6847
7118
|
// src/infrastructure/service/linux-systemd.ts
|
|
6848
7119
|
var SYSTEMD_SERVICE_NAME = "tokenarena";
|
|
6849
|
-
function getLinuxSystemdServiceDir(homePath =
|
|
7120
|
+
function getLinuxSystemdServiceDir(homePath = homedir29()) {
|
|
6850
7121
|
return posix.join(homePath, ".config", "systemd", "user");
|
|
6851
7122
|
}
|
|
6852
|
-
function getLinuxSystemdServiceFile(homePath =
|
|
7123
|
+
function getLinuxSystemdServiceFile(homePath = homedir29()) {
|
|
6853
7124
|
return posix.join(
|
|
6854
7125
|
getLinuxSystemdServiceDir(homePath),
|
|
6855
7126
|
`${SYSTEMD_SERVICE_NAME}.service`
|
|
@@ -6906,7 +7177,7 @@ function ensureSystemdAvailable() {
|
|
|
6906
7177
|
}
|
|
6907
7178
|
function createLinuxSystemdServiceBackend() {
|
|
6908
7179
|
function isInstalled() {
|
|
6909
|
-
return
|
|
7180
|
+
return existsSync31(getLinuxSystemdServiceFile());
|
|
6910
7181
|
}
|
|
6911
7182
|
async function setup(skipPrompt = false) {
|
|
6912
7183
|
if (!ensureSystemdAvailable()) {
|
|
@@ -7031,7 +7302,7 @@ function createLinuxSystemdServiceBackend() {
|
|
|
7031
7302
|
}
|
|
7032
7303
|
async function uninstall(skipPrompt = false) {
|
|
7033
7304
|
const serviceFile = getLinuxSystemdServiceFile();
|
|
7034
|
-
if (!
|
|
7305
|
+
if (!existsSync31(serviceFile)) {
|
|
7035
7306
|
logger.info(formatBullet("\u670D\u52A1\u6587\u4EF6\u4E0D\u5B58\u5728\u3002", "warning"));
|
|
7036
7307
|
return;
|
|
7037
7308
|
}
|
|
@@ -7092,17 +7363,17 @@ function createLinuxSystemdServiceBackend() {
|
|
|
7092
7363
|
|
|
7093
7364
|
// src/infrastructure/service/macos-launchd.ts
|
|
7094
7365
|
import { execFileSync as execFileSync6 } from "child_process";
|
|
7095
|
-
import { existsSync as
|
|
7096
|
-
import { homedir as
|
|
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";
|
|
7097
7368
|
import { posix as posix2 } from "path";
|
|
7098
7369
|
var MACOS_LAUNCHD_LABEL = "com.guji.tokenarena";
|
|
7099
7370
|
function getCurrentUid() {
|
|
7100
7371
|
return typeof process.getuid === "function" ? process.getuid() : null;
|
|
7101
7372
|
}
|
|
7102
|
-
function getMacosLaunchAgentDir(homePath =
|
|
7373
|
+
function getMacosLaunchAgentDir(homePath = homedir30()) {
|
|
7103
7374
|
return posix2.join(homePath, "Library", "LaunchAgents");
|
|
7104
7375
|
}
|
|
7105
|
-
function getMacosLaunchAgentFile(homePath =
|
|
7376
|
+
function getMacosLaunchAgentFile(homePath = homedir30()) {
|
|
7106
7377
|
return posix2.join(
|
|
7107
7378
|
getMacosLaunchAgentDir(homePath),
|
|
7108
7379
|
`${MACOS_LAUNCHD_LABEL}.plist`
|
|
@@ -7229,7 +7500,7 @@ function writeLaunchAgentPlist() {
|
|
|
7229
7500
|
label: MACOS_LAUNCHD_LABEL,
|
|
7230
7501
|
programArguments: [command.execPath, ...command.args],
|
|
7231
7502
|
environment: getManagedServiceEnvironment(),
|
|
7232
|
-
workingDirectory:
|
|
7503
|
+
workingDirectory: homedir30(),
|
|
7233
7504
|
standardOutPath: stdoutPath,
|
|
7234
7505
|
standardErrorPath: stderrPath
|
|
7235
7506
|
});
|
|
@@ -7254,7 +7525,7 @@ function bootstrapLaunchAgent() {
|
|
|
7254
7525
|
}
|
|
7255
7526
|
function createMacosLaunchdServiceBackend() {
|
|
7256
7527
|
function isInstalled() {
|
|
7257
|
-
return
|
|
7528
|
+
return existsSync32(getMacosLaunchAgentFile());
|
|
7258
7529
|
}
|
|
7259
7530
|
async function setup(skipPrompt = false) {
|
|
7260
7531
|
if (!ensureLaunchctlAvailable()) {
|
|
@@ -7395,7 +7666,7 @@ function createMacosLaunchdServiceBackend() {
|
|
|
7395
7666
|
}
|
|
7396
7667
|
async function uninstall(skipPrompt = false) {
|
|
7397
7668
|
const plistFile = getMacosLaunchAgentFile();
|
|
7398
|
-
if (!
|
|
7669
|
+
if (!existsSync32(plistFile)) {
|
|
7399
7670
|
logger.info(formatBullet("\u670D\u52A1\u6587\u4EF6\u4E0D\u5B58\u5728\u3002", "warning"));
|
|
7400
7671
|
return;
|
|
7401
7672
|
}
|
|
@@ -7506,7 +7777,7 @@ function resolvePowerShellProfilePath() {
|
|
|
7506
7777
|
const systemRoot = process.env.SYSTEMROOT || "C:\\Windows";
|
|
7507
7778
|
const candidates = [
|
|
7508
7779
|
"pwsh.exe",
|
|
7509
|
-
|
|
7780
|
+
join32(systemRoot, "System32", "WindowsPowerShell", "v1.0", "powershell.exe")
|
|
7510
7781
|
];
|
|
7511
7782
|
for (const command of candidates) {
|
|
7512
7783
|
try {
|
|
@@ -7535,8 +7806,8 @@ function resolvePowerShellProfilePath() {
|
|
|
7535
7806
|
function resolveShellAliasSetup(options = {}) {
|
|
7536
7807
|
const currentPlatform = options.currentPlatform ?? platform5();
|
|
7537
7808
|
const env = options.env ?? process.env;
|
|
7538
|
-
const homeDir = options.homeDir ??
|
|
7539
|
-
const pathExists = options.exists ??
|
|
7809
|
+
const homeDir = options.homeDir ?? homedir31();
|
|
7810
|
+
const pathExists = options.exists ?? existsSync33;
|
|
7540
7811
|
const shellFromEnv = env.SHELL ? basenameLikeShell(env.SHELL).toLowerCase() : "";
|
|
7541
7812
|
const shellName = shellFromEnv || (currentPlatform === "win32" ? "powershell" : "");
|
|
7542
7813
|
const aliasName = "ta";
|
|
@@ -7733,7 +8004,7 @@ async function setupShellAlias() {
|
|
|
7733
8004
|
try {
|
|
7734
8005
|
await mkdir(dirname6(setup.configFile), { recursive: true });
|
|
7735
8006
|
let existingContent = "";
|
|
7736
|
-
if (
|
|
8007
|
+
if (existsSync33(setup.configFile)) {
|
|
7737
8008
|
existingContent = await readFile(setup.configFile, "utf-8");
|
|
7738
8009
|
}
|
|
7739
8010
|
const normalizedContent = existingContent.toLowerCase();
|
|
@@ -7992,7 +8263,7 @@ function buildLocalUsageDashboardData(input2) {
|
|
|
7992
8263
|
|
|
7993
8264
|
// src/infrastructure/runtime/cli-version.ts
|
|
7994
8265
|
import { readFileSync as readFileSync14 } from "fs";
|
|
7995
|
-
import { dirname as dirname7, join as
|
|
8266
|
+
import { dirname as dirname7, join as join33 } from "path";
|
|
7996
8267
|
import { fileURLToPath } from "url";
|
|
7997
8268
|
var FALLBACK_VERSION = "0.0.0";
|
|
7998
8269
|
var cachedVersion;
|
|
@@ -8000,7 +8271,7 @@ function getCliVersion(metaUrl = import.meta.url) {
|
|
|
8000
8271
|
if (cachedVersion) {
|
|
8001
8272
|
return cachedVersion;
|
|
8002
8273
|
}
|
|
8003
|
-
const packageJsonPath =
|
|
8274
|
+
const packageJsonPath = join33(
|
|
8004
8275
|
dirname7(fileURLToPath(metaUrl)),
|
|
8005
8276
|
"..",
|
|
8006
8277
|
"package.json"
|
|
@@ -8411,8 +8682,8 @@ async function runSyncCommand(opts = {}) {
|
|
|
8411
8682
|
}
|
|
8412
8683
|
|
|
8413
8684
|
// src/commands/uninstall.ts
|
|
8414
|
-
import { existsSync as
|
|
8415
|
-
import { homedir as
|
|
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";
|
|
8416
8687
|
function removeShellAlias() {
|
|
8417
8688
|
const shell = process.env.SHELL;
|
|
8418
8689
|
if (!shell) return;
|
|
@@ -8421,22 +8692,22 @@ function removeShellAlias() {
|
|
|
8421
8692
|
let configFile;
|
|
8422
8693
|
switch (shellName) {
|
|
8423
8694
|
case "zsh":
|
|
8424
|
-
configFile = `${
|
|
8695
|
+
configFile = `${homedir32()}/.zshrc`;
|
|
8425
8696
|
break;
|
|
8426
8697
|
case "bash":
|
|
8427
|
-
if (platform6() === "darwin" &&
|
|
8428
|
-
configFile = `${
|
|
8698
|
+
if (platform6() === "darwin" && existsSync34(`${homedir32()}/.bash_profile`)) {
|
|
8699
|
+
configFile = `${homedir32()}/.bash_profile`;
|
|
8429
8700
|
} else {
|
|
8430
|
-
configFile = `${
|
|
8701
|
+
configFile = `${homedir32()}/.bashrc`;
|
|
8431
8702
|
}
|
|
8432
8703
|
break;
|
|
8433
8704
|
case "fish":
|
|
8434
|
-
configFile = `${
|
|
8705
|
+
configFile = `${homedir32()}/.config/fish/config.fish`;
|
|
8435
8706
|
break;
|
|
8436
8707
|
default:
|
|
8437
8708
|
return;
|
|
8438
8709
|
}
|
|
8439
|
-
if (!
|
|
8710
|
+
if (!existsSync34(configFile)) return;
|
|
8440
8711
|
try {
|
|
8441
8712
|
let content = readFileSync15(configFile, "utf-8");
|
|
8442
8713
|
const aliasPatterns = [
|
|
@@ -8475,7 +8746,7 @@ async function runUninstall() {
|
|
|
8475
8746
|
const runtimeDir = getRuntimeDirPath();
|
|
8476
8747
|
const serviceBackend = getServiceBackend();
|
|
8477
8748
|
const hasInstalledService = serviceBackend?.isInstalled() ?? false;
|
|
8478
|
-
const hasLocalArtifacts =
|
|
8749
|
+
const hasLocalArtifacts = existsSync34(configPath) || existsSync34(configDir) || existsSync34(stateDir) || existsSync34(runtimeDir) || hasInstalledService;
|
|
8479
8750
|
if (!hasLocalArtifacts) {
|
|
8480
8751
|
logger.info(formatHeader("\u5378\u8F7D TokenArena"));
|
|
8481
8752
|
logger.info(formatBullet("\u672A\u53D1\u73B0\u672C\u5730\u914D\u7F6E\uFF0C\u65E0\u9700\u5378\u8F7D\u3002"));
|
|
@@ -8519,22 +8790,22 @@ async function runUninstall() {
|
|
|
8519
8790
|
}
|
|
8520
8791
|
}
|
|
8521
8792
|
logger.info(formatSection("\u6267\u884C\u7ED3\u679C"));
|
|
8522
|
-
if (
|
|
8793
|
+
if (existsSync34(configPath)) {
|
|
8523
8794
|
deleteConfig();
|
|
8524
8795
|
logger.info(formatBullet("\u5DF2\u5220\u9664\u914D\u7F6E\u6587\u4EF6\u3002", "success"));
|
|
8525
8796
|
}
|
|
8526
|
-
if (
|
|
8797
|
+
if (existsSync34(configDir)) {
|
|
8527
8798
|
try {
|
|
8528
8799
|
rmSync6(configDir, { recursive: false, force: true });
|
|
8529
8800
|
logger.info(formatBullet("\u5DF2\u5220\u9664\u914D\u7F6E\u76EE\u5F55\u3002", "success"));
|
|
8530
8801
|
} catch {
|
|
8531
8802
|
}
|
|
8532
8803
|
}
|
|
8533
|
-
if (
|
|
8804
|
+
if (existsSync34(stateDir)) {
|
|
8534
8805
|
rmSync6(stateDir, { recursive: true, force: true });
|
|
8535
8806
|
logger.info(formatBullet("\u5DF2\u5220\u9664\u72B6\u6001\u6570\u636E\u3002", "success"));
|
|
8536
8807
|
}
|
|
8537
|
-
if (
|
|
8808
|
+
if (existsSync34(runtimeDir)) {
|
|
8538
8809
|
rmSync6(runtimeDir, { recursive: true, force: true });
|
|
8539
8810
|
logger.info(formatBullet("\u5DF2\u5220\u9664\u8FD0\u884C\u65F6\u6570\u636E\u3002", "success"));
|
|
8540
8811
|
}
|
|
@@ -8765,7 +9036,7 @@ function createCli() {
|
|
|
8765
9036
|
}
|
|
8766
9037
|
|
|
8767
9038
|
// src/infrastructure/runtime/main-module.ts
|
|
8768
|
-
import { existsSync as
|
|
9039
|
+
import { existsSync as existsSync35, realpathSync as realpathSync2 } from "fs";
|
|
8769
9040
|
import { resolve as resolve3 } from "path";
|
|
8770
9041
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
8771
9042
|
function isMainModule(argvEntry = process.argv[1], metaUrl = import.meta.url) {
|
|
@@ -8776,7 +9047,7 @@ function isMainModule(argvEntry = process.argv[1], metaUrl = import.meta.url) {
|
|
|
8776
9047
|
try {
|
|
8777
9048
|
return realpathSync2(argvEntry) === realpathSync2(currentModulePath);
|
|
8778
9049
|
} catch {
|
|
8779
|
-
if (!
|
|
9050
|
+
if (!existsSync35(argvEntry)) {
|
|
8780
9051
|
return false;
|
|
8781
9052
|
}
|
|
8782
9053
|
return resolve3(argvEntry) === resolve3(currentModulePath);
|