@yishiguji/tokenarena 0.16.1 → 0.16.3
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 +226 -77
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -367,8 +367,25 @@ function selectSnapshot(current, candidate) {
|
|
|
367
367
|
}
|
|
368
368
|
};
|
|
369
369
|
}
|
|
370
|
+
function getScanDirectories() {
|
|
371
|
+
const directories = [];
|
|
372
|
+
for (const root of getClaudeRoots()) {
|
|
373
|
+
directories.push(join2(root, "projects"));
|
|
374
|
+
}
|
|
375
|
+
for (const root of getClaudeRoots()) {
|
|
376
|
+
for (const directory of ["transcripts", "sessions"]) {
|
|
377
|
+
directories.push(join2(root, directory));
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
return directories;
|
|
381
|
+
}
|
|
370
382
|
var ClaudeCodeParser = class {
|
|
371
383
|
tool = TOOL;
|
|
384
|
+
listSourceFiles() {
|
|
385
|
+
return getScanDirectories().flatMap(
|
|
386
|
+
(directory) => findJsonlFiles(directory)
|
|
387
|
+
);
|
|
388
|
+
}
|
|
372
389
|
async parse() {
|
|
373
390
|
const snapshots = /* @__PURE__ */ new Map();
|
|
374
391
|
const sessionEvents = /* @__PURE__ */ new Map();
|
|
@@ -626,16 +643,22 @@ function readRollout(path) {
|
|
|
626
643
|
let rootMeta = null;
|
|
627
644
|
let model = "unknown";
|
|
628
645
|
let latestTimestampOrder = 0n;
|
|
646
|
+
let minLineTimestampOrder = null;
|
|
629
647
|
let line = 0;
|
|
648
|
+
let lineCount = 0;
|
|
630
649
|
for (const text of content.split("\n")) {
|
|
631
650
|
line++;
|
|
632
651
|
if (!text.trim()) continue;
|
|
652
|
+
lineCount++;
|
|
633
653
|
try {
|
|
634
654
|
const event = JSON.parse(text);
|
|
635
655
|
const timestamp = readTimestamp(event.timestamp);
|
|
636
656
|
const order = timestampOrder(event.timestamp, timestamp);
|
|
637
|
-
if (order !== null
|
|
638
|
-
latestTimestampOrder = order;
|
|
657
|
+
if (order !== null) {
|
|
658
|
+
if (order > latestTimestampOrder) latestTimestampOrder = order;
|
|
659
|
+
if (minLineTimestampOrder === null || order < minLineTimestampOrder)
|
|
660
|
+
minLineTimestampOrder = order;
|
|
661
|
+
}
|
|
639
662
|
if (event.type === "session_meta" && !rootMeta) rootMeta = event;
|
|
640
663
|
if (event.type === "turn_context") {
|
|
641
664
|
model = readId(event.payload?.model) || readId(event.payload?.info?.model) || model;
|
|
@@ -678,11 +701,14 @@ function readRollout(path) {
|
|
|
678
701
|
parentConflict: Boolean(
|
|
679
702
|
forkedFrom && spawnedFrom && forkedFrom !== spawnedFrom
|
|
680
703
|
),
|
|
704
|
+
forkOrdinalExclusive: typeof meta?.forked_from_ordinal_exclusive === "number" && Number.isSafeInteger(meta.forked_from_ordinal_exclusive) && meta.forked_from_ordinal_exclusive > 0 ? meta.forked_from_ordinal_exclusive : null,
|
|
705
|
+
lineCount,
|
|
681
706
|
rootTimestampOrder: timestampOrder(
|
|
682
707
|
rootMeta?.timestamp,
|
|
683
708
|
readTimestamp(rootMeta?.timestamp)
|
|
684
709
|
),
|
|
685
710
|
latestTimestampOrder,
|
|
711
|
+
minLineTimestampOrder,
|
|
686
712
|
tokens,
|
|
687
713
|
prompts
|
|
688
714
|
};
|
|
@@ -728,12 +754,16 @@ var CodexParser = class {
|
|
|
728
754
|
isInstalled() {
|
|
729
755
|
return this.dataDirs.some((directory) => existsSync4(directory));
|
|
730
756
|
}
|
|
757
|
+
/** The same list `parse()` reads, so the two can never drift apart. */
|
|
758
|
+
listSourceFiles() {
|
|
759
|
+
return [...new Set(this.dataDirs.flatMap(findJsonlFiles))].sort();
|
|
760
|
+
}
|
|
731
761
|
async parse() {
|
|
732
762
|
const entries = [];
|
|
733
763
|
const sessionEvents = [];
|
|
734
764
|
const threads = /* @__PURE__ */ new Map();
|
|
735
765
|
const threadIndex = /* @__PURE__ */ new Map();
|
|
736
|
-
const files =
|
|
766
|
+
const files = this.listSourceFiles();
|
|
737
767
|
for (const path of files) {
|
|
738
768
|
const file = readRollout(path);
|
|
739
769
|
if (!file) continue;
|
|
@@ -743,6 +773,7 @@ var CodexParser = class {
|
|
|
743
773
|
files: [],
|
|
744
774
|
timeline: [],
|
|
745
775
|
latestTimestampOrder: 0n,
|
|
776
|
+
minLineTimestampOrder: null,
|
|
746
777
|
invalidTokenTimestamp: false,
|
|
747
778
|
status: "new"
|
|
748
779
|
};
|
|
@@ -751,6 +782,8 @@ var CodexParser = class {
|
|
|
751
782
|
thread.files.push(file);
|
|
752
783
|
if (file.latestTimestampOrder > thread.latestTimestampOrder)
|
|
753
784
|
thread.latestTimestampOrder = file.latestTimestampOrder;
|
|
785
|
+
if (file.minLineTimestampOrder !== null && (thread.minLineTimestampOrder === null || file.minLineTimestampOrder < thread.minLineTimestampOrder))
|
|
786
|
+
thread.minLineTimestampOrder = file.minLineTimestampOrder;
|
|
754
787
|
thread.invalidTokenTimestamp ||= file.tokens.some(
|
|
755
788
|
(token) => !token.timestamp
|
|
756
789
|
);
|
|
@@ -776,7 +809,16 @@ var CodexParser = class {
|
|
|
776
809
|
if (file.parentConflict || file.parentId) {
|
|
777
810
|
const parent = file.parentId ? threadIndex.get(file.parentId) : void 0;
|
|
778
811
|
const cutoff = file.rootTimestampOrder;
|
|
779
|
-
|
|
812
|
+
const coverageOk = parent ? file.forkOrdinalExclusive !== null ? (
|
|
813
|
+
// 多文件父线程按最新文件(通常就是产生该 fork 的 rollout)
|
|
814
|
+
// 的行数核验;其余文件属于同一线程的历史分段。
|
|
815
|
+
parent.files.some(
|
|
816
|
+
(rollout) => rollout.lineCount >= (file.forkOrdinalExclusive ?? 0)
|
|
817
|
+
)
|
|
818
|
+
) : cutoff !== null && // 父最大时间戳落后不超过 1 秒,或父内容完全早于截止点
|
|
819
|
+
// 且父最早行时间戳也早于截止点(父在截止前已停止写入)。
|
|
820
|
+
(parent.latestTimestampOrder >= cutoff - 1000000n || parent.minLineTimestampOrder !== null && parent.minLineTimestampOrder < cutoff) : false;
|
|
821
|
+
if (file.parentConflict || !parent || parent === thread || cutoff === null || !processThread(parent) || parent.invalidTokenTimestamp || !coverageOk) {
|
|
780
822
|
logger.warn(
|
|
781
823
|
"Codex fork replay could not be verified; skipping " + basename2(file.path)
|
|
782
824
|
);
|
|
@@ -6640,7 +6682,7 @@ async function handleConfig(args) {
|
|
|
6640
6682
|
}
|
|
6641
6683
|
|
|
6642
6684
|
// src/services/sync-service.ts
|
|
6643
|
-
import { hostname as
|
|
6685
|
+
import { hostname as hostname7 } from "os";
|
|
6644
6686
|
|
|
6645
6687
|
// src/domain/project-identity.ts
|
|
6646
6688
|
import { createHmac } from "crypto";
|
|
@@ -7272,38 +7314,179 @@ function saveUploadManifest(manifest) {
|
|
|
7272
7314
|
);
|
|
7273
7315
|
}
|
|
7274
7316
|
|
|
7317
|
+
// src/services/parse-cache.ts
|
|
7318
|
+
import { createHash as createHash7 } from "crypto";
|
|
7319
|
+
import { mkdirSync as mkdirSync3, readFileSync as readFileSync14, statSync as statSync6, writeFileSync as writeFileSync5 } from "fs";
|
|
7320
|
+
import { hostname as hostname6 } from "os";
|
|
7321
|
+
import { join as join35 } from "path";
|
|
7322
|
+
|
|
7323
|
+
// src/infrastructure/runtime/cli-version.ts
|
|
7324
|
+
import { dirname as dirname7, join as join34 } from "path";
|
|
7325
|
+
import { fileURLToPath } from "url";
|
|
7326
|
+
var FALLBACK_VERSION = "0.0.0";
|
|
7327
|
+
var versionCache = /* @__PURE__ */ new Map();
|
|
7328
|
+
function readPackageVersion(startDir) {
|
|
7329
|
+
let dir = startDir;
|
|
7330
|
+
while (true) {
|
|
7331
|
+
const contents = readFileSafe(join34(dir, "package.json"));
|
|
7332
|
+
if (contents !== null) {
|
|
7333
|
+
try {
|
|
7334
|
+
const { version } = JSON.parse(contents);
|
|
7335
|
+
return typeof version === "string" && version.length > 0 ? version : void 0;
|
|
7336
|
+
} catch {
|
|
7337
|
+
return void 0;
|
|
7338
|
+
}
|
|
7339
|
+
}
|
|
7340
|
+
const parent = dirname7(dir);
|
|
7341
|
+
if (parent === dir) {
|
|
7342
|
+
return void 0;
|
|
7343
|
+
}
|
|
7344
|
+
dir = parent;
|
|
7345
|
+
}
|
|
7346
|
+
}
|
|
7347
|
+
function getCliVersion(metaUrl = import.meta.url) {
|
|
7348
|
+
const startDir = dirname7(fileURLToPath(metaUrl));
|
|
7349
|
+
const cached = versionCache.get(startDir);
|
|
7350
|
+
if (cached !== void 0) {
|
|
7351
|
+
return cached;
|
|
7352
|
+
}
|
|
7353
|
+
const version = readPackageVersion(startDir) ?? FALLBACK_VERSION;
|
|
7354
|
+
versionCache.set(startDir, version);
|
|
7355
|
+
return version;
|
|
7356
|
+
}
|
|
7357
|
+
|
|
7358
|
+
// src/services/parse-cache.ts
|
|
7359
|
+
var CACHE_FORMAT_VERSION = 1;
|
|
7360
|
+
var SETTLE_MS = 5e3;
|
|
7361
|
+
function getParseCacheDir() {
|
|
7362
|
+
return join35(getStateDir(), "parse-cache");
|
|
7363
|
+
}
|
|
7364
|
+
function getParseCachePath(toolId) {
|
|
7365
|
+
return join35(getParseCacheDir(), `${toolId}.json`);
|
|
7366
|
+
}
|
|
7367
|
+
function computeScanFingerprint(files, now = Date.now()) {
|
|
7368
|
+
const hash = createHash7("sha256");
|
|
7369
|
+
hash.update(`v${CACHE_FORMAT_VERSION}\0`);
|
|
7370
|
+
hash.update(`${getCliVersion()}\0`);
|
|
7371
|
+
hash.update(`${hostname6()}\0`);
|
|
7372
|
+
for (const file of [...files].sort()) {
|
|
7373
|
+
let stats;
|
|
7374
|
+
try {
|
|
7375
|
+
stats = statSync6(file);
|
|
7376
|
+
} catch {
|
|
7377
|
+
return null;
|
|
7378
|
+
}
|
|
7379
|
+
if (now - stats.mtimeMs < SETTLE_MS) {
|
|
7380
|
+
return null;
|
|
7381
|
+
}
|
|
7382
|
+
hash.update(`${file}\0${stats.mtimeMs}\0${stats.size}\0`);
|
|
7383
|
+
}
|
|
7384
|
+
return hash.digest("hex");
|
|
7385
|
+
}
|
|
7386
|
+
function loadCachedParseResult(toolId, fingerprint2) {
|
|
7387
|
+
if (!fingerprint2) {
|
|
7388
|
+
return null;
|
|
7389
|
+
}
|
|
7390
|
+
try {
|
|
7391
|
+
const envelope = JSON.parse(
|
|
7392
|
+
readFileSync14(getParseCachePath(toolId), "utf-8")
|
|
7393
|
+
);
|
|
7394
|
+
if (envelope.formatVersion !== CACHE_FORMAT_VERSION || envelope.fingerprint !== fingerprint2 || !Array.isArray(envelope.result?.buckets) || !Array.isArray(envelope.result?.sessions)) {
|
|
7395
|
+
return null;
|
|
7396
|
+
}
|
|
7397
|
+
return {
|
|
7398
|
+
buckets: envelope.result.buckets,
|
|
7399
|
+
sessions: envelope.result.sessions
|
|
7400
|
+
};
|
|
7401
|
+
} catch {
|
|
7402
|
+
return null;
|
|
7403
|
+
}
|
|
7404
|
+
}
|
|
7405
|
+
function saveCachedParseResult(toolId, fingerprint2, result) {
|
|
7406
|
+
if (!fingerprint2 || result.incomplete) {
|
|
7407
|
+
return;
|
|
7408
|
+
}
|
|
7409
|
+
const envelope = {
|
|
7410
|
+
formatVersion: CACHE_FORMAT_VERSION,
|
|
7411
|
+
fingerprint: fingerprint2,
|
|
7412
|
+
result: { buckets: result.buckets, sessions: result.sessions }
|
|
7413
|
+
};
|
|
7414
|
+
try {
|
|
7415
|
+
mkdirSync3(getParseCacheDir(), { recursive: true });
|
|
7416
|
+
writeFileSync5(getParseCachePath(toolId), JSON.stringify(envelope), "utf-8");
|
|
7417
|
+
} catch {
|
|
7418
|
+
}
|
|
7419
|
+
}
|
|
7420
|
+
|
|
7275
7421
|
// src/services/parser-service.ts
|
|
7422
|
+
var PARSER_CONCURRENCY = 8;
|
|
7423
|
+
async function parseWithCache(parser) {
|
|
7424
|
+
const files = parser.listSourceFiles?.();
|
|
7425
|
+
const fingerprint2 = files ? computeScanFingerprint(files) : null;
|
|
7426
|
+
const cached = loadCachedParseResult(parser.tool.id, fingerprint2);
|
|
7427
|
+
if (cached) {
|
|
7428
|
+
return { status: "ok", result: cached, cached: true };
|
|
7429
|
+
}
|
|
7430
|
+
try {
|
|
7431
|
+
const result = await parser.parse();
|
|
7432
|
+
saveCachedParseResult(parser.tool.id, fingerprint2, result);
|
|
7433
|
+
return { status: "ok", result, cached: false };
|
|
7434
|
+
} catch (err) {
|
|
7435
|
+
return {
|
|
7436
|
+
status: "failed",
|
|
7437
|
+
message: err instanceof Error ? err.message : String(err)
|
|
7438
|
+
};
|
|
7439
|
+
}
|
|
7440
|
+
}
|
|
7441
|
+
async function mapWithConcurrency(items, limit, run2) {
|
|
7442
|
+
const results = new Array(items.length);
|
|
7443
|
+
let cursor = 0;
|
|
7444
|
+
async function worker() {
|
|
7445
|
+
while (cursor < items.length) {
|
|
7446
|
+
const index = cursor++;
|
|
7447
|
+
results[index] = await run2(items[index]);
|
|
7448
|
+
}
|
|
7449
|
+
}
|
|
7450
|
+
await Promise.all(
|
|
7451
|
+
Array.from({ length: Math.min(limit, items.length) }, () => worker())
|
|
7452
|
+
);
|
|
7453
|
+
return results;
|
|
7454
|
+
}
|
|
7276
7455
|
async function runAllParsers() {
|
|
7277
7456
|
const allBuckets = [];
|
|
7278
7457
|
const allSessions = [];
|
|
7279
7458
|
const parserResults = [];
|
|
7280
7459
|
const failedSources = /* @__PURE__ */ new Set();
|
|
7281
|
-
|
|
7282
|
-
|
|
7283
|
-
|
|
7284
|
-
|
|
7285
|
-
|
|
7286
|
-
|
|
7287
|
-
|
|
7288
|
-
|
|
7289
|
-
|
|
7290
|
-
|
|
7291
|
-
|
|
7292
|
-
|
|
7293
|
-
|
|
7294
|
-
|
|
7295
|
-
|
|
7296
|
-
parserResults.push({
|
|
7297
|
-
source: parser.tool.id,
|
|
7298
|
-
buckets: buckets.length,
|
|
7299
|
-
sessions: sessions.length
|
|
7300
|
-
});
|
|
7301
|
-
}
|
|
7302
|
-
} catch (err) {
|
|
7460
|
+
const parsers2 = getAllParsers();
|
|
7461
|
+
const settled = await mapWithConcurrency(
|
|
7462
|
+
parsers2,
|
|
7463
|
+
PARSER_CONCURRENCY,
|
|
7464
|
+
parseWithCache
|
|
7465
|
+
);
|
|
7466
|
+
for (const [index, parser] of parsers2.entries()) {
|
|
7467
|
+
const outcome = settled[index];
|
|
7468
|
+
if (outcome.status === "failed") {
|
|
7469
|
+
failedSources.add(parser.tool.id);
|
|
7470
|
+
logger.warn(`${parser.tool.id} parser failed: ${outcome.message}`);
|
|
7471
|
+
continue;
|
|
7472
|
+
}
|
|
7473
|
+
const { buckets, sessions, incomplete } = outcome.result;
|
|
7474
|
+
if (incomplete) {
|
|
7303
7475
|
failedSources.add(parser.tool.id);
|
|
7304
7476
|
logger.warn(
|
|
7305
|
-
`${parser.tool.id} parser
|
|
7477
|
+
`${parser.tool.id} parser reported an incomplete scan; preserving its remote history.`
|
|
7306
7478
|
);
|
|
7479
|
+
continue;
|
|
7480
|
+
}
|
|
7481
|
+
if (buckets.length > 0) allBuckets.push(...buckets);
|
|
7482
|
+
if (sessions.length > 0) allSessions.push(...sessions);
|
|
7483
|
+
if (buckets.length > 0 || sessions.length > 0) {
|
|
7484
|
+
parserResults.push({
|
|
7485
|
+
source: parser.tool.id,
|
|
7486
|
+
buckets: buckets.length,
|
|
7487
|
+
sessions: sessions.length,
|
|
7488
|
+
...outcome.cached ? { cached: true } : {}
|
|
7489
|
+
});
|
|
7307
7490
|
}
|
|
7308
7491
|
}
|
|
7309
7492
|
return {
|
|
@@ -7378,7 +7561,7 @@ function persistUploadManifest(manifest, quiet) {
|
|
|
7378
7561
|
function toDeviceMetadata(config) {
|
|
7379
7562
|
return {
|
|
7380
7563
|
deviceId: getOrCreateDeviceId(config),
|
|
7381
|
-
hostname:
|
|
7564
|
+
hostname: hostname7().replace(/\.local$/, "")
|
|
7382
7565
|
};
|
|
7383
7566
|
}
|
|
7384
7567
|
function toUploadBuckets(buckets, settings, device) {
|
|
@@ -7577,7 +7760,8 @@ async function runSync(config, opts = {}) {
|
|
|
7577
7760
|
const parts = [];
|
|
7578
7761
|
if (p.buckets > 0) parts.push(`${p.buckets} buckets`);
|
|
7579
7762
|
if (p.sessions > 0) parts.push(`${p.sessions} sessions`);
|
|
7580
|
-
|
|
7763
|
+
const suffix = p.cached ? " (unchanged)" : "";
|
|
7764
|
+
logger.info(` ${p.source}: ${parts.join(", ")}${suffix}`);
|
|
7581
7765
|
}
|
|
7582
7766
|
}
|
|
7583
7767
|
const apiUrl = config.apiUrl || "https://token.guji.uno";
|
|
@@ -7829,14 +8013,14 @@ import { execFileSync as execFileSync7, spawn } from "child_process";
|
|
|
7829
8013
|
import { existsSync as existsSync36 } from "fs";
|
|
7830
8014
|
import { appendFile, mkdir, readFile } from "fs/promises";
|
|
7831
8015
|
import { homedir as homedir33, platform as platform5 } from "os";
|
|
7832
|
-
import { dirname as
|
|
8016
|
+
import { dirname as dirname8, join as join36, posix as posix3, win32 } from "path";
|
|
7833
8017
|
|
|
7834
8018
|
// src/infrastructure/service/index.ts
|
|
7835
8019
|
import { platform as platform4 } from "os";
|
|
7836
8020
|
|
|
7837
8021
|
// src/infrastructure/service/linux-systemd.ts
|
|
7838
8022
|
import { execFileSync as execFileSync5 } from "child_process";
|
|
7839
|
-
import { existsSync as existsSync34, mkdirSync as
|
|
8023
|
+
import { existsSync as existsSync34, mkdirSync as mkdirSync4, rmSync as rmSync4, writeFileSync as writeFileSync6 } from "fs";
|
|
7840
8024
|
import { homedir as homedir31, platform as platform2 } from "os";
|
|
7841
8025
|
import { posix } from "path";
|
|
7842
8026
|
|
|
@@ -7998,8 +8182,8 @@ function createLinuxSystemdServiceBackend() {
|
|
|
7998
8182
|
execPath: command.execPath,
|
|
7999
8183
|
args: command.args
|
|
8000
8184
|
});
|
|
8001
|
-
|
|
8002
|
-
|
|
8185
|
+
mkdirSync4(serviceDir, { recursive: true });
|
|
8186
|
+
writeFileSync6(serviceFile, content, "utf-8");
|
|
8003
8187
|
execSystemctl(["daemon-reload"]);
|
|
8004
8188
|
execSystemctl(["enable", SYSTEMD_SERVICE_NAME]);
|
|
8005
8189
|
execSystemctl(["start", SYSTEMD_SERVICE_NAME]);
|
|
@@ -8158,7 +8342,7 @@ function createLinuxSystemdServiceBackend() {
|
|
|
8158
8342
|
|
|
8159
8343
|
// src/infrastructure/service/macos-launchd.ts
|
|
8160
8344
|
import { execFileSync as execFileSync6 } from "child_process";
|
|
8161
|
-
import { existsSync as existsSync35, mkdirSync as
|
|
8345
|
+
import { existsSync as existsSync35, mkdirSync as mkdirSync5, rmSync as rmSync5, writeFileSync as writeFileSync7 } from "fs";
|
|
8162
8346
|
import { homedir as homedir32, platform as platform3 } from "os";
|
|
8163
8347
|
import { posix as posix2 } from "path";
|
|
8164
8348
|
var MACOS_LAUNCHD_LABEL = "com.guji.tokenarena";
|
|
@@ -8300,8 +8484,8 @@ function writeLaunchAgentPlist() {
|
|
|
8300
8484
|
standardErrorPath: stderrPath
|
|
8301
8485
|
});
|
|
8302
8486
|
ensureAppDirs();
|
|
8303
|
-
|
|
8304
|
-
|
|
8487
|
+
mkdirSync5(getMacosLaunchAgentDir(), { recursive: true });
|
|
8488
|
+
writeFileSync7(plistFile, plist, "utf-8");
|
|
8305
8489
|
return plistFile;
|
|
8306
8490
|
}
|
|
8307
8491
|
function bootstrapLaunchAgent() {
|
|
@@ -8572,7 +8756,7 @@ function resolvePowerShellProfilePath() {
|
|
|
8572
8756
|
const systemRoot = process.env.SYSTEMROOT || "C:\\Windows";
|
|
8573
8757
|
const candidates = [
|
|
8574
8758
|
"pwsh.exe",
|
|
8575
|
-
|
|
8759
|
+
join36(systemRoot, "System32", "WindowsPowerShell", "v1.0", "powershell.exe")
|
|
8576
8760
|
];
|
|
8577
8761
|
for (const command of candidates) {
|
|
8578
8762
|
try {
|
|
@@ -8797,7 +8981,7 @@ async function setupShellAlias() {
|
|
|
8797
8981
|
return;
|
|
8798
8982
|
}
|
|
8799
8983
|
try {
|
|
8800
|
-
await mkdir(
|
|
8984
|
+
await mkdir(dirname8(setup.configFile), { recursive: true });
|
|
8801
8985
|
let existingContent = "";
|
|
8802
8986
|
if (existsSync36(setup.configFile)) {
|
|
8803
8987
|
existingContent = await readFile(setup.configFile, "utf-8");
|
|
@@ -9062,41 +9246,6 @@ function buildLocalUsageDashboardData(input2) {
|
|
|
9062
9246
|
};
|
|
9063
9247
|
}
|
|
9064
9248
|
|
|
9065
|
-
// src/infrastructure/runtime/cli-version.ts
|
|
9066
|
-
import { dirname as dirname8, join as join35 } from "path";
|
|
9067
|
-
import { fileURLToPath } from "url";
|
|
9068
|
-
var FALLBACK_VERSION = "0.0.0";
|
|
9069
|
-
var versionCache = /* @__PURE__ */ new Map();
|
|
9070
|
-
function readPackageVersion(startDir) {
|
|
9071
|
-
let dir = startDir;
|
|
9072
|
-
while (true) {
|
|
9073
|
-
const contents = readFileSafe(join35(dir, "package.json"));
|
|
9074
|
-
if (contents !== null) {
|
|
9075
|
-
try {
|
|
9076
|
-
const { version } = JSON.parse(contents);
|
|
9077
|
-
return typeof version === "string" && version.length > 0 ? version : void 0;
|
|
9078
|
-
} catch {
|
|
9079
|
-
return void 0;
|
|
9080
|
-
}
|
|
9081
|
-
}
|
|
9082
|
-
const parent = dirname8(dir);
|
|
9083
|
-
if (parent === dir) {
|
|
9084
|
-
return void 0;
|
|
9085
|
-
}
|
|
9086
|
-
dir = parent;
|
|
9087
|
-
}
|
|
9088
|
-
}
|
|
9089
|
-
function getCliVersion(metaUrl = import.meta.url) {
|
|
9090
|
-
const startDir = dirname8(fileURLToPath(metaUrl));
|
|
9091
|
-
const cached = versionCache.get(startDir);
|
|
9092
|
-
if (cached !== void 0) {
|
|
9093
|
-
return cached;
|
|
9094
|
-
}
|
|
9095
|
-
const version = readPackageVersion(startDir) ?? FALLBACK_VERSION;
|
|
9096
|
-
versionCache.set(startDir, version);
|
|
9097
|
-
return version;
|
|
9098
|
-
}
|
|
9099
|
-
|
|
9100
9249
|
// src/infrastructure/ui/local-usage-dashboard.ts
|
|
9101
9250
|
var MAX_RANK_ROWS = 6;
|
|
9102
9251
|
var MAX_SESSION_ROWS = 6;
|
|
@@ -9495,7 +9644,7 @@ async function runSyncCommand(opts = {}) {
|
|
|
9495
9644
|
}
|
|
9496
9645
|
|
|
9497
9646
|
// src/commands/uninstall.ts
|
|
9498
|
-
import { existsSync as existsSync37, readFileSync as
|
|
9647
|
+
import { existsSync as existsSync37, readFileSync as readFileSync15, rmSync as rmSync6, writeFileSync as writeFileSync8 } from "fs";
|
|
9499
9648
|
import { homedir as homedir34, platform as platform6 } from "os";
|
|
9500
9649
|
function removeShellAlias() {
|
|
9501
9650
|
const shell = process.env.SHELL;
|
|
@@ -9522,7 +9671,7 @@ function removeShellAlias() {
|
|
|
9522
9671
|
}
|
|
9523
9672
|
if (!existsSync37(configFile)) return;
|
|
9524
9673
|
try {
|
|
9525
|
-
let content =
|
|
9674
|
+
let content = readFileSync15(configFile, "utf-8");
|
|
9526
9675
|
const aliasPatterns = [
|
|
9527
9676
|
// zsh / bash format: alias ta="tokenarena"
|
|
9528
9677
|
new RegExp(
|
|
@@ -9544,7 +9693,7 @@ function removeShellAlias() {
|
|
|
9544
9693
|
content = next;
|
|
9545
9694
|
}
|
|
9546
9695
|
}
|
|
9547
|
-
|
|
9696
|
+
writeFileSync8(configFile, content, "utf-8");
|
|
9548
9697
|
logger.info(`Removed shell alias from ${configFile}`);
|
|
9549
9698
|
} catch (err) {
|
|
9550
9699
|
logger.warn(
|