@yishiguji/tokenarena 0.10.0 → 0.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -4713,37 +4713,425 @@ var GrokBuildParser = class {
4713
4713
  };
4714
4714
  registerParser(new GrokBuildParser());
4715
4715
 
4716
+ // src/parsers/atomcode.ts
4717
+ import { existsSync as existsSync24 } from "fs";
4718
+ import { homedir as homedir25 } from "os";
4719
+ import { basename as basename11, join as join26 } from "path";
4720
+ var TOOL_ID17 = "atomcode";
4721
+ var TOOL_NAME17 = "AtomCode";
4722
+ var DEFAULT_SESSIONS_DIR6 = join26(homedir25(), ".atomcode", "sessions");
4723
+ function getAtomCodeSessionsDirs(env = process.env) {
4724
+ const dirs = [
4725
+ env.TOKEN_ARENA_ATOMCODE_DIR,
4726
+ env.ATOMCODE_HOME ? join26(env.ATOMCODE_HOME, "sessions") : void 0,
4727
+ DEFAULT_SESSIONS_DIR6
4728
+ ].filter((value) => Boolean(value));
4729
+ return Array.from(new Set(dirs));
4730
+ }
4731
+ function toNonNegativeNumber3(value) {
4732
+ const numberValue = Number(value);
4733
+ return Number.isFinite(numberValue) && numberValue >= 0 ? numberValue : 0;
4734
+ }
4735
+ function parseTimestamp3(value) {
4736
+ if (typeof value === "number" && Number.isFinite(value)) {
4737
+ const timestamp = new Date(value);
4738
+ return Number.isNaN(timestamp.getTime()) ? null : timestamp;
4739
+ }
4740
+ if (typeof value === "string" && value.trim()) {
4741
+ const asNumber = Number(value);
4742
+ if (Number.isFinite(asNumber)) {
4743
+ const timestamp2 = new Date(asNumber);
4744
+ if (!Number.isNaN(timestamp2.getTime())) {
4745
+ return timestamp2;
4746
+ }
4747
+ }
4748
+ const timestamp = new Date(value);
4749
+ return Number.isNaN(timestamp.getTime()) ? null : timestamp;
4750
+ }
4751
+ return null;
4752
+ }
4753
+ function parseMeta(content) {
4754
+ if (!content) return null;
4755
+ try {
4756
+ const parsed = JSON.parse(content);
4757
+ return parsed && typeof parsed === "object" ? parsed : null;
4758
+ } catch {
4759
+ return null;
4760
+ }
4761
+ }
4762
+ function getMetaModel(meta) {
4763
+ for (const turn of meta?.turn_stats ?? []) {
4764
+ for (const usage of turn.model_usage ?? []) {
4765
+ if (typeof usage.model_id === "string" && usage.model_id) {
4766
+ return usage.model_id;
4767
+ }
4768
+ }
4769
+ }
4770
+ return "unknown";
4771
+ }
4772
+ function getMetaProject(meta) {
4773
+ if (typeof meta?.working_dir === "string" && meta.working_dir) {
4774
+ return basename11(meta.working_dir) || "unknown";
4775
+ }
4776
+ return "unknown";
4777
+ }
4778
+ var AtomCodeParser = class {
4779
+ tool;
4780
+ sessionsDirs;
4781
+ constructor(sessionsDir) {
4782
+ this.sessionsDirs = sessionsDir ? [sessionsDir] : getAtomCodeSessionsDirs();
4783
+ this.tool = {
4784
+ id: TOOL_ID17,
4785
+ name: TOOL_NAME17,
4786
+ dataDir: this.sessionsDirs[0] ?? DEFAULT_SESSIONS_DIR6
4787
+ };
4788
+ }
4789
+ async parse() {
4790
+ const entries = [];
4791
+ const sessionEvents = [];
4792
+ const seenEntryKeys = /* @__PURE__ */ new Set();
4793
+ for (const sessionsDir of this.sessionsDirs) {
4794
+ for (const filePath of findJsonlFiles(sessionsDir)) {
4795
+ const content = readFileSafe(filePath);
4796
+ if (!content) continue;
4797
+ const rows = parseJsonl(content);
4798
+ if (rows.length === 0) continue;
4799
+ const fallbackSessionId = extractSessionId(filePath);
4800
+ const meta = parseMeta(
4801
+ readFileSafe(filePath.replace(/\.jsonl$/, ".meta"))
4802
+ );
4803
+ const project = getMetaProject(meta);
4804
+ const model = getMetaModel(meta);
4805
+ for (const row of rows) {
4806
+ const sessionId = typeof row.session_id === "string" && row.session_id ? row.session_id : fallbackSessionId;
4807
+ const timestamp = parseTimestamp3(row.ts);
4808
+ if (!timestamp) continue;
4809
+ if (row.user !== void 0 || row.assistant !== void 0) {
4810
+ sessionEvents.push({
4811
+ sessionId,
4812
+ source: TOOL_ID17,
4813
+ project,
4814
+ timestamp,
4815
+ role: row.user !== void 0 ? "user" : "assistant"
4816
+ });
4817
+ }
4818
+ const usage = row.usage;
4819
+ if (!usage) continue;
4820
+ const prompt = toNonNegativeNumber3(usage.prompt);
4821
+ const completion = toNonNegativeNumber3(usage.completion);
4822
+ const cached = toNonNegativeNumber3(usage.cached);
4823
+ const inputTokens = Math.max(0, prompt - cached);
4824
+ if (inputTokens + completion + cached === 0) {
4825
+ continue;
4826
+ }
4827
+ const entryKey = [
4828
+ sessionId,
4829
+ timestamp.toISOString(),
4830
+ model,
4831
+ inputTokens,
4832
+ completion,
4833
+ cached
4834
+ ].join("|");
4835
+ if (seenEntryKeys.has(entryKey)) {
4836
+ continue;
4837
+ }
4838
+ seenEntryKeys.add(entryKey);
4839
+ entries.push({
4840
+ sessionId,
4841
+ source: TOOL_ID17,
4842
+ model,
4843
+ project,
4844
+ timestamp,
4845
+ inputTokens,
4846
+ outputTokens: completion,
4847
+ reasoningTokens: 0,
4848
+ cachedTokens: cached
4849
+ });
4850
+ }
4851
+ }
4852
+ }
4853
+ return {
4854
+ buckets: aggregateToBuckets(entries),
4855
+ sessions: extractSessions(sessionEvents, entries)
4856
+ };
4857
+ }
4858
+ isInstalled() {
4859
+ return this.sessionsDirs.some((dir) => existsSync24(dir));
4860
+ }
4861
+ };
4862
+ registerParser(new AtomCodeParser());
4863
+
4864
+ // src/parsers/dsh.ts
4865
+ import { existsSync as existsSync25, readdirSync as readdirSync14, readFileSync as readFileSync9 } from "fs";
4866
+ import { homedir as homedir26 } from "os";
4867
+ import { basename as basename12, join as join27 } from "path";
4868
+ import * as zlib from "zlib";
4869
+ var TOOL_ID18 = "dsh";
4870
+ var TOOL_NAME18 = "DeepSeek Harness";
4871
+ var DEFAULT_SESSIONS_DIR7 = join27(homedir26(), ".dsh", "sessions");
4872
+ var LOG_BASENAME = "session";
4873
+ function getDshSessionsDirs(env = process.env) {
4874
+ const dirs = [
4875
+ env.TOKEN_ARENA_DSH_DIR,
4876
+ env.DSH_HOME ? join27(env.DSH_HOME, "sessions") : void 0,
4877
+ DEFAULT_SESSIONS_DIR7
4878
+ ].filter((value) => Boolean(value));
4879
+ return Array.from(new Set(dirs));
4880
+ }
4881
+ function toNonNegativeNumber4(value) {
4882
+ const numberValue = Number(value);
4883
+ return Number.isFinite(numberValue) && numberValue >= 0 ? numberValue : 0;
4884
+ }
4885
+ function scanZstdFrames(buffer) {
4886
+ const ZSTD_MAGIC = 4247762216;
4887
+ const frames = [];
4888
+ let offset = 0;
4889
+ while (offset < buffer.length) {
4890
+ const start = offset;
4891
+ if (buffer.length - offset < 4) break;
4892
+ if (buffer.readUInt32LE(offset) !== ZSTD_MAGIC) break;
4893
+ offset += 4;
4894
+ if (offset === buffer.length) break;
4895
+ const descriptor = buffer.readUInt8(offset);
4896
+ offset += 1;
4897
+ if ((descriptor & 24) !== 0) break;
4898
+ const contentSizeFlag = descriptor >>> 6;
4899
+ const singleSegment = (descriptor & 32) !== 0;
4900
+ const checksum = (descriptor & 4) !== 0;
4901
+ const dictionaryFlag = descriptor & 3;
4902
+ const dictionaryBytes = dictionaryFlag === 3 ? 4 : dictionaryFlag;
4903
+ const contentSizeBytes = contentSizeFlag === 0 ? singleSegment ? 1 : 0 : 1 << contentSizeFlag;
4904
+ const remainingHeaderBytes = (singleSegment ? 0 : 1) + dictionaryBytes + contentSizeBytes;
4905
+ if (buffer.length - offset < remainingHeaderBytes) break;
4906
+ offset += remainingHeaderBytes;
4907
+ let complete = true;
4908
+ for (; ; ) {
4909
+ if (buffer.length - offset < 3) {
4910
+ complete = false;
4911
+ break;
4912
+ }
4913
+ const blockHeader = buffer.readUIntLE(offset, 3);
4914
+ offset += 3;
4915
+ const lastBlock = (blockHeader & 1) !== 0;
4916
+ const blockType = blockHeader >>> 1 & 3;
4917
+ const blockSize = blockHeader >>> 3;
4918
+ if (blockType === 3) {
4919
+ complete = false;
4920
+ break;
4921
+ }
4922
+ const payloadBytes = blockType === 1 ? 1 : blockSize;
4923
+ if (buffer.length - offset < payloadBytes) {
4924
+ complete = false;
4925
+ break;
4926
+ }
4927
+ offset += payloadBytes;
4928
+ if (lastBlock) break;
4929
+ }
4930
+ if (!complete) break;
4931
+ if (checksum) {
4932
+ if (buffer.length - offset < 4) break;
4933
+ offset += 4;
4934
+ }
4935
+ frames.push([start, offset]);
4936
+ }
4937
+ return frames;
4938
+ }
4939
+ function decompressZstdLog(buffer) {
4940
+ if (typeof zlib.zstdDecompressSync !== "function") return null;
4941
+ const chunks = [];
4942
+ for (const [start, end] of scanZstdFrames(buffer)) {
4943
+ try {
4944
+ chunks.push(zlib.zstdDecompressSync(buffer.subarray(start, end)));
4945
+ } catch {
4946
+ }
4947
+ }
4948
+ if (chunks.length === 0) return null;
4949
+ return Buffer.concat(chunks).toString("utf-8");
4950
+ }
4951
+ function readSessionLog(filePath) {
4952
+ let buffer;
4953
+ try {
4954
+ buffer = readFileSync9(filePath);
4955
+ } catch {
4956
+ return null;
4957
+ }
4958
+ if (filePath.endsWith(".zstd")) {
4959
+ return decompressZstdLog(buffer);
4960
+ }
4961
+ return buffer.toString("utf-8");
4962
+ }
4963
+ function findSessionLogs(dir) {
4964
+ const results = [];
4965
+ if (!existsSync25(dir)) return results;
4966
+ try {
4967
+ for (const entry of readdirSync14(dir, { withFileTypes: true })) {
4968
+ const fullPath = join27(dir, entry.name);
4969
+ if (entry.isDirectory()) {
4970
+ results.push(...findSessionLogs(fullPath));
4971
+ } else if (entry.name === `${LOG_BASENAME}.jsonl` || entry.name === `${LOG_BASENAME}.jsonl.zstd`) {
4972
+ results.push(fullPath);
4973
+ }
4974
+ }
4975
+ } catch {
4976
+ }
4977
+ return results;
4978
+ }
4979
+ function decodeSegment(segment) {
4980
+ return segment.replace(
4981
+ /~([0-9A-F]{4})/g,
4982
+ (_, hex) => String.fromCodePoint(Number.parseInt(hex, 16))
4983
+ );
4984
+ }
4985
+ function projectFromDirName(name) {
4986
+ if (name === "_no-cwd") return "unknown";
4987
+ const slug = name.replace(/^-+/, "").replace(/-+$/, "");
4988
+ if (!slug) return "unknown";
4989
+ const parts = slug.split("-").filter(Boolean);
4990
+ const last = parts[parts.length - 1];
4991
+ return last ? decodeSegment(last) || "unknown" : "unknown";
4992
+ }
4993
+ var DshParser = class {
4994
+ tool;
4995
+ sessionsDirs;
4996
+ constructor(sessionsDir) {
4997
+ this.sessionsDirs = sessionsDir ? [sessionsDir] : getDshSessionsDirs();
4998
+ this.tool = {
4999
+ id: TOOL_ID18,
5000
+ name: TOOL_NAME18,
5001
+ dataDir: this.sessionsDirs[0] ?? DEFAULT_SESSIONS_DIR7
5002
+ };
5003
+ }
5004
+ async parse() {
5005
+ const entries = [];
5006
+ const sessionEvents = [];
5007
+ const seenEntryKeys = /* @__PURE__ */ new Set();
5008
+ for (const sessionsDir of this.sessionsDirs) {
5009
+ for (const filePath of findSessionLogs(sessionsDir)) {
5010
+ const content = readSessionLog(filePath);
5011
+ if (!content) continue;
5012
+ const rows = parseJsonl(content);
5013
+ if (rows.length === 0) continue;
5014
+ const relativeParts = filePath.slice(sessionsDir.length + 1).split(/[\\/]/);
5015
+ const header = rows[0]?.type === "session" ? rows[0] : void 0;
5016
+ const sessionId = (header?.id ?? decodeSegment(relativeParts[1] ?? "")) || "unknown";
5017
+ const project = typeof header?.cwd === "string" && header.cwd ? basename12(header.cwd) || "unknown" : projectFromDirName(relativeParts[0] ?? "");
5018
+ let currentModel = "unknown";
5019
+ for (const row of rows) {
5020
+ if (row.type === "request/context") {
5021
+ const model2 = row.data?.model;
5022
+ if (typeof model2 === "string" && model2) currentModel = model2;
5023
+ continue;
5024
+ }
5025
+ if (row.type === "request/header") {
5026
+ const model2 = row.data?.header?.config?.model;
5027
+ if (typeof model2 === "string" && model2) currentModel = model2;
5028
+ continue;
5029
+ }
5030
+ const timestamp = typeof row.time === "number" && Number.isFinite(row.time) ? new Date(row.time) : null;
5031
+ if (row.type === "user/message") {
5032
+ const sourceKind = row.data?.source?.kind ?? row.data?.message?.source?.kind;
5033
+ if (sourceKind !== "user") continue;
5034
+ if (timestamp) {
5035
+ sessionEvents.push({
5036
+ sessionId,
5037
+ source: TOOL_ID18,
5038
+ project,
5039
+ timestamp,
5040
+ role: "user"
5041
+ });
5042
+ }
5043
+ continue;
5044
+ }
5045
+ const isCompaction = row.type === "compaction/summary";
5046
+ if (row.type !== "assistant/message" && !isCompaction) continue;
5047
+ if (timestamp && !isCompaction) {
5048
+ sessionEvents.push({
5049
+ sessionId,
5050
+ source: TOOL_ID18,
5051
+ project,
5052
+ timestamp,
5053
+ role: "assistant"
5054
+ });
5055
+ }
5056
+ const usage = row.data?.usage;
5057
+ if (!usage || timestamp === null) continue;
5058
+ const model = (isCompaction && typeof row.data?.model === "string" ? row.data.model : "") || currentModel;
5059
+ const inputTokens = toNonNegativeNumber4(usage.inputTokens);
5060
+ const cachedTokens = toNonNegativeNumber4(usage.cacheReadTokens) + toNonNegativeNumber4(usage.cacheWriteTokens);
5061
+ const reasoningTokens = toNonNegativeNumber4(usage.reasoningTokens);
5062
+ const outputTokens = Math.max(
5063
+ 0,
5064
+ toNonNegativeNumber4(usage.outputTokens) - reasoningTokens
5065
+ );
5066
+ if (inputTokens + outputTokens + cachedTokens + reasoningTokens === 0)
5067
+ continue;
5068
+ const entryKey = [
5069
+ sessionId,
5070
+ timestamp.toISOString(),
5071
+ model,
5072
+ inputTokens,
5073
+ outputTokens,
5074
+ cachedTokens,
5075
+ reasoningTokens
5076
+ ].join("|");
5077
+ if (seenEntryKeys.has(entryKey)) continue;
5078
+ seenEntryKeys.add(entryKey);
5079
+ entries.push({
5080
+ sessionId,
5081
+ source: TOOL_ID18,
5082
+ model,
5083
+ project,
5084
+ timestamp,
5085
+ inputTokens,
5086
+ outputTokens,
5087
+ reasoningTokens,
5088
+ cachedTokens
5089
+ });
5090
+ }
5091
+ }
5092
+ }
5093
+ return {
5094
+ buckets: aggregateToBuckets(entries),
5095
+ sessions: extractSessions(sessionEvents, entries)
5096
+ };
5097
+ }
5098
+ isInstalled() {
5099
+ return this.sessionsDirs.some((dir) => existsSync25(dir));
5100
+ }
5101
+ };
5102
+ registerParser(new DshParser());
5103
+
4716
5104
  // src/cli.ts
4717
5105
  import { Command, Option } from "commander";
4718
5106
 
4719
5107
  // src/infrastructure/config/manager.ts
4720
5108
  import { randomUUID } from "crypto";
4721
5109
  import {
4722
- existsSync as existsSync24,
5110
+ existsSync as existsSync26,
4723
5111
  mkdirSync,
4724
- readFileSync as readFileSync9,
5112
+ readFileSync as readFileSync10,
4725
5113
  unlinkSync,
4726
5114
  writeFileSync
4727
5115
  } from "fs";
4728
- import { join as join27 } from "path";
5116
+ import { join as join29 } from "path";
4729
5117
 
4730
5118
  // src/infrastructure/xdg.ts
4731
- import { homedir as homedir25 } from "os";
4732
- import { join as join26 } from "path";
5119
+ import { homedir as homedir27 } from "os";
5120
+ import { join as join28 } from "path";
4733
5121
  function getConfigHome() {
4734
- return process.env.XDG_CONFIG_HOME || join26(homedir25(), ".config");
5122
+ return process.env.XDG_CONFIG_HOME || join28(homedir27(), ".config");
4735
5123
  }
4736
5124
  function getStateHome() {
4737
- return process.env.XDG_STATE_HOME || join26(homedir25(), ".local", "state");
5125
+ return process.env.XDG_STATE_HOME || join28(homedir27(), ".local", "state");
4738
5126
  }
4739
5127
  function getRuntimeDir() {
4740
5128
  return process.env.XDG_RUNTIME_DIR || getStateHome();
4741
5129
  }
4742
5130
 
4743
5131
  // src/infrastructure/config/manager.ts
4744
- var CONFIG_DIR = join27(getConfigHome(), "tokenarena");
5132
+ var CONFIG_DIR = join29(getConfigHome(), "tokenarena");
4745
5133
  var isDev = process.env.TOKEN_ARENA_DEV === "1";
4746
- var CONFIG_FILE = join27(CONFIG_DIR, isDev ? "config.dev.json" : "config.json");
5134
+ var CONFIG_FILE = join29(CONFIG_DIR, isDev ? "config.dev.json" : "config.json");
4747
5135
  var DEFAULT_API_URL = "https://token.guji.uno";
4748
5136
  var VALID_CONFIG_KEYS = [
4749
5137
  "apiKey",
@@ -4759,9 +5147,9 @@ function getConfigDir() {
4759
5147
  return CONFIG_DIR;
4760
5148
  }
4761
5149
  function loadConfig() {
4762
- if (!existsSync24(CONFIG_FILE)) return null;
5150
+ if (!existsSync26(CONFIG_FILE)) return null;
4763
5151
  try {
4764
- const raw = readFileSync9(CONFIG_FILE, "utf-8");
5152
+ const raw = readFileSync10(CONFIG_FILE, "utf-8");
4765
5153
  const config = JSON.parse(raw);
4766
5154
  if (!config.apiUrl) {
4767
5155
  config.apiUrl = DEFAULT_API_URL;
@@ -4777,7 +5165,7 @@ function saveConfig(config) {
4777
5165
  `, "utf-8");
4778
5166
  }
4779
5167
  function deleteConfig() {
4780
- if (existsSync24(CONFIG_FILE)) {
5168
+ if (existsSync26(CONFIG_FILE)) {
4781
5169
  unlinkSync(CONFIG_FILE);
4782
5170
  }
4783
5171
  }
@@ -5639,31 +6027,31 @@ var ApiClient = class {
5639
6027
  // src/infrastructure/runtime/lock.ts
5640
6028
  import {
5641
6029
  closeSync,
5642
- existsSync as existsSync25,
6030
+ existsSync as existsSync27,
5643
6031
  openSync,
5644
- readFileSync as readFileSync10,
6032
+ readFileSync as readFileSync11,
5645
6033
  rmSync as rmSync3,
5646
6034
  writeFileSync as writeFileSync2
5647
6035
  } from "fs";
5648
6036
 
5649
6037
  // src/infrastructure/runtime/paths.ts
5650
6038
  import { mkdirSync as mkdirSync2 } from "fs";
5651
- import { join as join28 } from "path";
6039
+ import { join as join30 } from "path";
5652
6040
  var APP_NAME = "tokenarena";
5653
6041
  function getRuntimeDirPath() {
5654
- return join28(getRuntimeDir(), APP_NAME);
6042
+ return join30(getRuntimeDir(), APP_NAME);
5655
6043
  }
5656
6044
  function getStateDir() {
5657
- return join28(getStateHome(), APP_NAME);
6045
+ return join30(getStateHome(), APP_NAME);
5658
6046
  }
5659
6047
  function getSyncLockPath() {
5660
- return join28(getRuntimeDirPath(), "sync.lock");
6048
+ return join30(getRuntimeDirPath(), "sync.lock");
5661
6049
  }
5662
6050
  function getSyncStatePath() {
5663
- return join28(getStateDir(), "status.json");
6051
+ return join30(getStateDir(), "status.json");
5664
6052
  }
5665
6053
  function getUploadManifestPath() {
5666
- return join28(getStateDir(), "upload-manifest.json");
6054
+ return join30(getStateDir(), "upload-manifest.json");
5667
6055
  }
5668
6056
  function ensureAppDirs() {
5669
6057
  mkdirSync2(getRuntimeDirPath(), { recursive: true });
@@ -5681,11 +6069,11 @@ function isProcessAlive(pid) {
5681
6069
  }
5682
6070
  }
5683
6071
  function readLockMetadata(lockPath) {
5684
- if (!existsSync25(lockPath)) {
6072
+ if (!existsSync27(lockPath)) {
5685
6073
  return null;
5686
6074
  }
5687
6075
  try {
5688
- return JSON.parse(readFileSync10(lockPath, "utf-8"));
6076
+ return JSON.parse(readFileSync11(lockPath, "utf-8"));
5689
6077
  } catch {
5690
6078
  return null;
5691
6079
  }
@@ -5755,19 +6143,19 @@ function describeExistingSyncLock() {
5755
6143
  }
5756
6144
 
5757
6145
  // src/infrastructure/runtime/state.ts
5758
- import { existsSync as existsSync26, readFileSync as readFileSync11, writeFileSync as writeFileSync3 } from "fs";
6146
+ import { existsSync as existsSync28, readFileSync as readFileSync12, writeFileSync as writeFileSync3 } from "fs";
5759
6147
  function getDefaultState() {
5760
6148
  return { status: "idle" };
5761
6149
  }
5762
6150
  function loadSyncState() {
5763
6151
  const path = getSyncStatePath();
5764
- if (!existsSync26(path)) {
6152
+ if (!existsSync28(path)) {
5765
6153
  return getDefaultState();
5766
6154
  }
5767
6155
  try {
5768
6156
  return {
5769
6157
  ...getDefaultState(),
5770
- ...JSON.parse(readFileSync11(path, "utf-8"))
6158
+ ...JSON.parse(readFileSync12(path, "utf-8"))
5771
6159
  };
5772
6160
  } catch {
5773
6161
  return getDefaultState();
@@ -5822,7 +6210,7 @@ function markSyncFailed(source, error, status) {
5822
6210
  }
5823
6211
 
5824
6212
  // src/infrastructure/runtime/upload-manifest.ts
5825
- import { existsSync as existsSync27, readFileSync as readFileSync12, writeFileSync as writeFileSync4 } from "fs";
6213
+ import { existsSync as existsSync29, readFileSync as readFileSync13, writeFileSync as writeFileSync4 } from "fs";
5826
6214
  function isRecordOfStrings(value) {
5827
6215
  if (!value || typeof value !== "object" || Array.isArray(value)) {
5828
6216
  return false;
@@ -5838,11 +6226,11 @@ function isUploadManifest(value) {
5838
6226
  }
5839
6227
  function loadUploadManifest() {
5840
6228
  const path = getUploadManifestPath();
5841
- if (!existsSync27(path)) {
6229
+ if (!existsSync29(path)) {
5842
6230
  return null;
5843
6231
  }
5844
6232
  try {
5845
- const parsed = JSON.parse(readFileSync12(path, "utf-8"));
6233
+ const parsed = JSON.parse(readFileSync13(path, "utf-8"));
5846
6234
  if (!isUploadManifest(parsed)) {
5847
6235
  return null;
5848
6236
  }
@@ -6378,18 +6766,18 @@ View your dashboard at: ${apiUrl}/usage`);
6378
6766
 
6379
6767
  // src/commands/init.ts
6380
6768
  import { execFileSync as execFileSync7, spawn } from "child_process";
6381
- import { existsSync as existsSync30 } from "fs";
6769
+ import { existsSync as existsSync32 } from "fs";
6382
6770
  import { appendFile, mkdir, readFile } from "fs/promises";
6383
- import { homedir as homedir28, platform as platform5 } from "os";
6384
- import { dirname as dirname6, join as join29, posix as posix3, win32 } from "path";
6771
+ import { homedir as homedir30, platform as platform5 } from "os";
6772
+ import { dirname as dirname6, join as join31, posix as posix3, win32 } from "path";
6385
6773
 
6386
6774
  // src/infrastructure/service/index.ts
6387
6775
  import { platform as platform4 } from "os";
6388
6776
 
6389
6777
  // src/infrastructure/service/linux-systemd.ts
6390
6778
  import { execFileSync as execFileSync5 } from "child_process";
6391
- import { existsSync as existsSync28, mkdirSync as mkdirSync3, rmSync as rmSync4, writeFileSync as writeFileSync5 } from "fs";
6392
- import { homedir as homedir26, platform as platform2 } from "os";
6779
+ import { existsSync as existsSync30, mkdirSync as mkdirSync3, rmSync as rmSync4, writeFileSync as writeFileSync5 } from "fs";
6780
+ import { homedir as homedir28, platform as platform2 } from "os";
6393
6781
  import { posix } from "path";
6394
6782
 
6395
6783
  // src/utils/command.ts
@@ -6458,10 +6846,10 @@ function escapeXml(value) {
6458
6846
 
6459
6847
  // src/infrastructure/service/linux-systemd.ts
6460
6848
  var SYSTEMD_SERVICE_NAME = "tokenarena";
6461
- function getLinuxSystemdServiceDir(homePath = homedir26()) {
6849
+ function getLinuxSystemdServiceDir(homePath = homedir28()) {
6462
6850
  return posix.join(homePath, ".config", "systemd", "user");
6463
6851
  }
6464
- function getLinuxSystemdServiceFile(homePath = homedir26()) {
6852
+ function getLinuxSystemdServiceFile(homePath = homedir28()) {
6465
6853
  return posix.join(
6466
6854
  getLinuxSystemdServiceDir(homePath),
6467
6855
  `${SYSTEMD_SERVICE_NAME}.service`
@@ -6518,7 +6906,7 @@ function ensureSystemdAvailable() {
6518
6906
  }
6519
6907
  function createLinuxSystemdServiceBackend() {
6520
6908
  function isInstalled() {
6521
- return existsSync28(getLinuxSystemdServiceFile());
6909
+ return existsSync30(getLinuxSystemdServiceFile());
6522
6910
  }
6523
6911
  async function setup(skipPrompt = false) {
6524
6912
  if (!ensureSystemdAvailable()) {
@@ -6643,7 +7031,7 @@ function createLinuxSystemdServiceBackend() {
6643
7031
  }
6644
7032
  async function uninstall(skipPrompt = false) {
6645
7033
  const serviceFile = getLinuxSystemdServiceFile();
6646
- if (!existsSync28(serviceFile)) {
7034
+ if (!existsSync30(serviceFile)) {
6647
7035
  logger.info(formatBullet("\u670D\u52A1\u6587\u4EF6\u4E0D\u5B58\u5728\u3002", "warning"));
6648
7036
  return;
6649
7037
  }
@@ -6704,17 +7092,17 @@ function createLinuxSystemdServiceBackend() {
6704
7092
 
6705
7093
  // src/infrastructure/service/macos-launchd.ts
6706
7094
  import { execFileSync as execFileSync6 } from "child_process";
6707
- import { existsSync as existsSync29, mkdirSync as mkdirSync4, rmSync as rmSync5, writeFileSync as writeFileSync6 } from "fs";
6708
- import { homedir as homedir27, platform as platform3 } from "os";
7095
+ import { existsSync as existsSync31, mkdirSync as mkdirSync4, rmSync as rmSync5, writeFileSync as writeFileSync6 } from "fs";
7096
+ import { homedir as homedir29, platform as platform3 } from "os";
6709
7097
  import { posix as posix2 } from "path";
6710
7098
  var MACOS_LAUNCHD_LABEL = "com.guji.tokenarena";
6711
7099
  function getCurrentUid() {
6712
7100
  return typeof process.getuid === "function" ? process.getuid() : null;
6713
7101
  }
6714
- function getMacosLaunchAgentDir(homePath = homedir27()) {
7102
+ function getMacosLaunchAgentDir(homePath = homedir29()) {
6715
7103
  return posix2.join(homePath, "Library", "LaunchAgents");
6716
7104
  }
6717
- function getMacosLaunchAgentFile(homePath = homedir27()) {
7105
+ function getMacosLaunchAgentFile(homePath = homedir29()) {
6718
7106
  return posix2.join(
6719
7107
  getMacosLaunchAgentDir(homePath),
6720
7108
  `${MACOS_LAUNCHD_LABEL}.plist`
@@ -6841,7 +7229,7 @@ function writeLaunchAgentPlist() {
6841
7229
  label: MACOS_LAUNCHD_LABEL,
6842
7230
  programArguments: [command.execPath, ...command.args],
6843
7231
  environment: getManagedServiceEnvironment(),
6844
- workingDirectory: homedir27(),
7232
+ workingDirectory: homedir29(),
6845
7233
  standardOutPath: stdoutPath,
6846
7234
  standardErrorPath: stderrPath
6847
7235
  });
@@ -6866,7 +7254,7 @@ function bootstrapLaunchAgent() {
6866
7254
  }
6867
7255
  function createMacosLaunchdServiceBackend() {
6868
7256
  function isInstalled() {
6869
- return existsSync29(getMacosLaunchAgentFile());
7257
+ return existsSync31(getMacosLaunchAgentFile());
6870
7258
  }
6871
7259
  async function setup(skipPrompt = false) {
6872
7260
  if (!ensureLaunchctlAvailable()) {
@@ -7007,7 +7395,7 @@ function createMacosLaunchdServiceBackend() {
7007
7395
  }
7008
7396
  async function uninstall(skipPrompt = false) {
7009
7397
  const plistFile = getMacosLaunchAgentFile();
7010
- if (!existsSync29(plistFile)) {
7398
+ if (!existsSync31(plistFile)) {
7011
7399
  logger.info(formatBullet("\u670D\u52A1\u6587\u4EF6\u4E0D\u5B58\u5728\u3002", "warning"));
7012
7400
  return;
7013
7401
  }
@@ -7118,7 +7506,7 @@ function resolvePowerShellProfilePath() {
7118
7506
  const systemRoot = process.env.SYSTEMROOT || "C:\\Windows";
7119
7507
  const candidates = [
7120
7508
  "pwsh.exe",
7121
- join29(systemRoot, "System32", "WindowsPowerShell", "v1.0", "powershell.exe")
7509
+ join31(systemRoot, "System32", "WindowsPowerShell", "v1.0", "powershell.exe")
7122
7510
  ];
7123
7511
  for (const command of candidates) {
7124
7512
  try {
@@ -7147,8 +7535,8 @@ function resolvePowerShellProfilePath() {
7147
7535
  function resolveShellAliasSetup(options = {}) {
7148
7536
  const currentPlatform = options.currentPlatform ?? platform5();
7149
7537
  const env = options.env ?? process.env;
7150
- const homeDir = options.homeDir ?? homedir28();
7151
- const pathExists = options.exists ?? existsSync30;
7538
+ const homeDir = options.homeDir ?? homedir30();
7539
+ const pathExists = options.exists ?? existsSync32;
7152
7540
  const shellFromEnv = env.SHELL ? basenameLikeShell(env.SHELL).toLowerCase() : "";
7153
7541
  const shellName = shellFromEnv || (currentPlatform === "win32" ? "powershell" : "");
7154
7542
  const aliasName = "ta";
@@ -7345,7 +7733,7 @@ async function setupShellAlias() {
7345
7733
  try {
7346
7734
  await mkdir(dirname6(setup.configFile), { recursive: true });
7347
7735
  let existingContent = "";
7348
- if (existsSync30(setup.configFile)) {
7736
+ if (existsSync32(setup.configFile)) {
7349
7737
  existingContent = await readFile(setup.configFile, "utf-8");
7350
7738
  }
7351
7739
  const normalizedContent = existingContent.toLowerCase();
@@ -7603,8 +7991,8 @@ function buildLocalUsageDashboardData(input2) {
7603
7991
  }
7604
7992
 
7605
7993
  // src/infrastructure/runtime/cli-version.ts
7606
- import { readFileSync as readFileSync13 } from "fs";
7607
- import { dirname as dirname7, join as join30 } from "path";
7994
+ import { readFileSync as readFileSync14 } from "fs";
7995
+ import { dirname as dirname7, join as join32 } from "path";
7608
7996
  import { fileURLToPath } from "url";
7609
7997
  var FALLBACK_VERSION = "0.0.0";
7610
7998
  var cachedVersion;
@@ -7612,13 +8000,13 @@ function getCliVersion(metaUrl = import.meta.url) {
7612
8000
  if (cachedVersion) {
7613
8001
  return cachedVersion;
7614
8002
  }
7615
- const packageJsonPath = join30(
8003
+ const packageJsonPath = join32(
7616
8004
  dirname7(fileURLToPath(metaUrl)),
7617
8005
  "..",
7618
8006
  "package.json"
7619
8007
  );
7620
8008
  try {
7621
- const packageJson = JSON.parse(readFileSync13(packageJsonPath, "utf-8"));
8009
+ const packageJson = JSON.parse(readFileSync14(packageJsonPath, "utf-8"));
7622
8010
  cachedVersion = typeof packageJson.version === "string" ? packageJson.version : FALLBACK_VERSION;
7623
8011
  } catch {
7624
8012
  cachedVersion = FALLBACK_VERSION;
@@ -8023,8 +8411,8 @@ async function runSyncCommand(opts = {}) {
8023
8411
  }
8024
8412
 
8025
8413
  // src/commands/uninstall.ts
8026
- import { existsSync as existsSync31, readFileSync as readFileSync14, rmSync as rmSync6, writeFileSync as writeFileSync7 } from "fs";
8027
- import { homedir as homedir29, platform as platform6 } from "os";
8414
+ import { existsSync as existsSync33, readFileSync as readFileSync15, rmSync as rmSync6, writeFileSync as writeFileSync7 } from "fs";
8415
+ import { homedir as homedir31, platform as platform6 } from "os";
8028
8416
  function removeShellAlias() {
8029
8417
  const shell = process.env.SHELL;
8030
8418
  if (!shell) return;
@@ -8033,24 +8421,24 @@ function removeShellAlias() {
8033
8421
  let configFile;
8034
8422
  switch (shellName) {
8035
8423
  case "zsh":
8036
- configFile = `${homedir29()}/.zshrc`;
8424
+ configFile = `${homedir31()}/.zshrc`;
8037
8425
  break;
8038
8426
  case "bash":
8039
- if (platform6() === "darwin" && existsSync31(`${homedir29()}/.bash_profile`)) {
8040
- configFile = `${homedir29()}/.bash_profile`;
8427
+ if (platform6() === "darwin" && existsSync33(`${homedir31()}/.bash_profile`)) {
8428
+ configFile = `${homedir31()}/.bash_profile`;
8041
8429
  } else {
8042
- configFile = `${homedir29()}/.bashrc`;
8430
+ configFile = `${homedir31()}/.bashrc`;
8043
8431
  }
8044
8432
  break;
8045
8433
  case "fish":
8046
- configFile = `${homedir29()}/.config/fish/config.fish`;
8434
+ configFile = `${homedir31()}/.config/fish/config.fish`;
8047
8435
  break;
8048
8436
  default:
8049
8437
  return;
8050
8438
  }
8051
- if (!existsSync31(configFile)) return;
8439
+ if (!existsSync33(configFile)) return;
8052
8440
  try {
8053
- let content = readFileSync14(configFile, "utf-8");
8441
+ let content = readFileSync15(configFile, "utf-8");
8054
8442
  const aliasPatterns = [
8055
8443
  // zsh / bash format: alias ta="tokenarena"
8056
8444
  new RegExp(
@@ -8087,7 +8475,7 @@ async function runUninstall() {
8087
8475
  const runtimeDir = getRuntimeDirPath();
8088
8476
  const serviceBackend = getServiceBackend();
8089
8477
  const hasInstalledService = serviceBackend?.isInstalled() ?? false;
8090
- const hasLocalArtifacts = existsSync31(configPath) || existsSync31(configDir) || existsSync31(stateDir) || existsSync31(runtimeDir) || hasInstalledService;
8478
+ const hasLocalArtifacts = existsSync33(configPath) || existsSync33(configDir) || existsSync33(stateDir) || existsSync33(runtimeDir) || hasInstalledService;
8091
8479
  if (!hasLocalArtifacts) {
8092
8480
  logger.info(formatHeader("\u5378\u8F7D TokenArena"));
8093
8481
  logger.info(formatBullet("\u672A\u53D1\u73B0\u672C\u5730\u914D\u7F6E\uFF0C\u65E0\u9700\u5378\u8F7D\u3002"));
@@ -8131,22 +8519,22 @@ async function runUninstall() {
8131
8519
  }
8132
8520
  }
8133
8521
  logger.info(formatSection("\u6267\u884C\u7ED3\u679C"));
8134
- if (existsSync31(configPath)) {
8522
+ if (existsSync33(configPath)) {
8135
8523
  deleteConfig();
8136
8524
  logger.info(formatBullet("\u5DF2\u5220\u9664\u914D\u7F6E\u6587\u4EF6\u3002", "success"));
8137
8525
  }
8138
- if (existsSync31(configDir)) {
8526
+ if (existsSync33(configDir)) {
8139
8527
  try {
8140
8528
  rmSync6(configDir, { recursive: false, force: true });
8141
8529
  logger.info(formatBullet("\u5DF2\u5220\u9664\u914D\u7F6E\u76EE\u5F55\u3002", "success"));
8142
8530
  } catch {
8143
8531
  }
8144
8532
  }
8145
- if (existsSync31(stateDir)) {
8533
+ if (existsSync33(stateDir)) {
8146
8534
  rmSync6(stateDir, { recursive: true, force: true });
8147
8535
  logger.info(formatBullet("\u5DF2\u5220\u9664\u72B6\u6001\u6570\u636E\u3002", "success"));
8148
8536
  }
8149
- if (existsSync31(runtimeDir)) {
8537
+ if (existsSync33(runtimeDir)) {
8150
8538
  rmSync6(runtimeDir, { recursive: true, force: true });
8151
8539
  logger.info(formatBullet("\u5DF2\u5220\u9664\u8FD0\u884C\u65F6\u6570\u636E\u3002", "success"));
8152
8540
  }
@@ -8377,7 +8765,7 @@ function createCli() {
8377
8765
  }
8378
8766
 
8379
8767
  // src/infrastructure/runtime/main-module.ts
8380
- import { existsSync as existsSync32, realpathSync as realpathSync2 } from "fs";
8768
+ import { existsSync as existsSync34, realpathSync as realpathSync2 } from "fs";
8381
8769
  import { resolve as resolve3 } from "path";
8382
8770
  import { fileURLToPath as fileURLToPath2 } from "url";
8383
8771
  function isMainModule(argvEntry = process.argv[1], metaUrl = import.meta.url) {
@@ -8388,7 +8776,7 @@ function isMainModule(argvEntry = process.argv[1], metaUrl = import.meta.url) {
8388
8776
  try {
8389
8777
  return realpathSync2(argvEntry) === realpathSync2(currentModulePath);
8390
8778
  } catch {
8391
- if (!existsSync32(argvEntry)) {
8779
+ if (!existsSync34(argvEntry)) {
8392
8780
  return false;
8393
8781
  }
8394
8782
  return resolve3(argvEntry) === resolve3(currentModulePath);