@yishiguji/tokenarena 0.11.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 +308 -68
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -4861,37 +4861,277 @@ var AtomCodeParser = class {
|
|
|
4861
4861
|
};
|
|
4862
4862
|
registerParser(new AtomCodeParser());
|
|
4863
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
|
+
|
|
4864
5104
|
// src/cli.ts
|
|
4865
5105
|
import { Command, Option } from "commander";
|
|
4866
5106
|
|
|
4867
5107
|
// src/infrastructure/config/manager.ts
|
|
4868
5108
|
import { randomUUID } from "crypto";
|
|
4869
5109
|
import {
|
|
4870
|
-
existsSync as
|
|
5110
|
+
existsSync as existsSync26,
|
|
4871
5111
|
mkdirSync,
|
|
4872
|
-
readFileSync as
|
|
5112
|
+
readFileSync as readFileSync10,
|
|
4873
5113
|
unlinkSync,
|
|
4874
5114
|
writeFileSync
|
|
4875
5115
|
} from "fs";
|
|
4876
|
-
import { join as
|
|
5116
|
+
import { join as join29 } from "path";
|
|
4877
5117
|
|
|
4878
5118
|
// src/infrastructure/xdg.ts
|
|
4879
|
-
import { homedir as
|
|
4880
|
-
import { join as
|
|
5119
|
+
import { homedir as homedir27 } from "os";
|
|
5120
|
+
import { join as join28 } from "path";
|
|
4881
5121
|
function getConfigHome() {
|
|
4882
|
-
return process.env.XDG_CONFIG_HOME ||
|
|
5122
|
+
return process.env.XDG_CONFIG_HOME || join28(homedir27(), ".config");
|
|
4883
5123
|
}
|
|
4884
5124
|
function getStateHome() {
|
|
4885
|
-
return process.env.XDG_STATE_HOME ||
|
|
5125
|
+
return process.env.XDG_STATE_HOME || join28(homedir27(), ".local", "state");
|
|
4886
5126
|
}
|
|
4887
5127
|
function getRuntimeDir() {
|
|
4888
5128
|
return process.env.XDG_RUNTIME_DIR || getStateHome();
|
|
4889
5129
|
}
|
|
4890
5130
|
|
|
4891
5131
|
// src/infrastructure/config/manager.ts
|
|
4892
|
-
var CONFIG_DIR =
|
|
5132
|
+
var CONFIG_DIR = join29(getConfigHome(), "tokenarena");
|
|
4893
5133
|
var isDev = process.env.TOKEN_ARENA_DEV === "1";
|
|
4894
|
-
var CONFIG_FILE =
|
|
5134
|
+
var CONFIG_FILE = join29(CONFIG_DIR, isDev ? "config.dev.json" : "config.json");
|
|
4895
5135
|
var DEFAULT_API_URL = "https://token.guji.uno";
|
|
4896
5136
|
var VALID_CONFIG_KEYS = [
|
|
4897
5137
|
"apiKey",
|
|
@@ -4907,9 +5147,9 @@ function getConfigDir() {
|
|
|
4907
5147
|
return CONFIG_DIR;
|
|
4908
5148
|
}
|
|
4909
5149
|
function loadConfig() {
|
|
4910
|
-
if (!
|
|
5150
|
+
if (!existsSync26(CONFIG_FILE)) return null;
|
|
4911
5151
|
try {
|
|
4912
|
-
const raw =
|
|
5152
|
+
const raw = readFileSync10(CONFIG_FILE, "utf-8");
|
|
4913
5153
|
const config = JSON.parse(raw);
|
|
4914
5154
|
if (!config.apiUrl) {
|
|
4915
5155
|
config.apiUrl = DEFAULT_API_URL;
|
|
@@ -4925,7 +5165,7 @@ function saveConfig(config) {
|
|
|
4925
5165
|
`, "utf-8");
|
|
4926
5166
|
}
|
|
4927
5167
|
function deleteConfig() {
|
|
4928
|
-
if (
|
|
5168
|
+
if (existsSync26(CONFIG_FILE)) {
|
|
4929
5169
|
unlinkSync(CONFIG_FILE);
|
|
4930
5170
|
}
|
|
4931
5171
|
}
|
|
@@ -5787,31 +6027,31 @@ var ApiClient = class {
|
|
|
5787
6027
|
// src/infrastructure/runtime/lock.ts
|
|
5788
6028
|
import {
|
|
5789
6029
|
closeSync,
|
|
5790
|
-
existsSync as
|
|
6030
|
+
existsSync as existsSync27,
|
|
5791
6031
|
openSync,
|
|
5792
|
-
readFileSync as
|
|
6032
|
+
readFileSync as readFileSync11,
|
|
5793
6033
|
rmSync as rmSync3,
|
|
5794
6034
|
writeFileSync as writeFileSync2
|
|
5795
6035
|
} from "fs";
|
|
5796
6036
|
|
|
5797
6037
|
// src/infrastructure/runtime/paths.ts
|
|
5798
6038
|
import { mkdirSync as mkdirSync2 } from "fs";
|
|
5799
|
-
import { join as
|
|
6039
|
+
import { join as join30 } from "path";
|
|
5800
6040
|
var APP_NAME = "tokenarena";
|
|
5801
6041
|
function getRuntimeDirPath() {
|
|
5802
|
-
return
|
|
6042
|
+
return join30(getRuntimeDir(), APP_NAME);
|
|
5803
6043
|
}
|
|
5804
6044
|
function getStateDir() {
|
|
5805
|
-
return
|
|
6045
|
+
return join30(getStateHome(), APP_NAME);
|
|
5806
6046
|
}
|
|
5807
6047
|
function getSyncLockPath() {
|
|
5808
|
-
return
|
|
6048
|
+
return join30(getRuntimeDirPath(), "sync.lock");
|
|
5809
6049
|
}
|
|
5810
6050
|
function getSyncStatePath() {
|
|
5811
|
-
return
|
|
6051
|
+
return join30(getStateDir(), "status.json");
|
|
5812
6052
|
}
|
|
5813
6053
|
function getUploadManifestPath() {
|
|
5814
|
-
return
|
|
6054
|
+
return join30(getStateDir(), "upload-manifest.json");
|
|
5815
6055
|
}
|
|
5816
6056
|
function ensureAppDirs() {
|
|
5817
6057
|
mkdirSync2(getRuntimeDirPath(), { recursive: true });
|
|
@@ -5829,11 +6069,11 @@ function isProcessAlive(pid) {
|
|
|
5829
6069
|
}
|
|
5830
6070
|
}
|
|
5831
6071
|
function readLockMetadata(lockPath) {
|
|
5832
|
-
if (!
|
|
6072
|
+
if (!existsSync27(lockPath)) {
|
|
5833
6073
|
return null;
|
|
5834
6074
|
}
|
|
5835
6075
|
try {
|
|
5836
|
-
return JSON.parse(
|
|
6076
|
+
return JSON.parse(readFileSync11(lockPath, "utf-8"));
|
|
5837
6077
|
} catch {
|
|
5838
6078
|
return null;
|
|
5839
6079
|
}
|
|
@@ -5903,19 +6143,19 @@ function describeExistingSyncLock() {
|
|
|
5903
6143
|
}
|
|
5904
6144
|
|
|
5905
6145
|
// src/infrastructure/runtime/state.ts
|
|
5906
|
-
import { existsSync as
|
|
6146
|
+
import { existsSync as existsSync28, readFileSync as readFileSync12, writeFileSync as writeFileSync3 } from "fs";
|
|
5907
6147
|
function getDefaultState() {
|
|
5908
6148
|
return { status: "idle" };
|
|
5909
6149
|
}
|
|
5910
6150
|
function loadSyncState() {
|
|
5911
6151
|
const path = getSyncStatePath();
|
|
5912
|
-
if (!
|
|
6152
|
+
if (!existsSync28(path)) {
|
|
5913
6153
|
return getDefaultState();
|
|
5914
6154
|
}
|
|
5915
6155
|
try {
|
|
5916
6156
|
return {
|
|
5917
6157
|
...getDefaultState(),
|
|
5918
|
-
...JSON.parse(
|
|
6158
|
+
...JSON.parse(readFileSync12(path, "utf-8"))
|
|
5919
6159
|
};
|
|
5920
6160
|
} catch {
|
|
5921
6161
|
return getDefaultState();
|
|
@@ -5970,7 +6210,7 @@ function markSyncFailed(source, error, status) {
|
|
|
5970
6210
|
}
|
|
5971
6211
|
|
|
5972
6212
|
// src/infrastructure/runtime/upload-manifest.ts
|
|
5973
|
-
import { existsSync as
|
|
6213
|
+
import { existsSync as existsSync29, readFileSync as readFileSync13, writeFileSync as writeFileSync4 } from "fs";
|
|
5974
6214
|
function isRecordOfStrings(value) {
|
|
5975
6215
|
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
5976
6216
|
return false;
|
|
@@ -5986,11 +6226,11 @@ function isUploadManifest(value) {
|
|
|
5986
6226
|
}
|
|
5987
6227
|
function loadUploadManifest() {
|
|
5988
6228
|
const path = getUploadManifestPath();
|
|
5989
|
-
if (!
|
|
6229
|
+
if (!existsSync29(path)) {
|
|
5990
6230
|
return null;
|
|
5991
6231
|
}
|
|
5992
6232
|
try {
|
|
5993
|
-
const parsed = JSON.parse(
|
|
6233
|
+
const parsed = JSON.parse(readFileSync13(path, "utf-8"));
|
|
5994
6234
|
if (!isUploadManifest(parsed)) {
|
|
5995
6235
|
return null;
|
|
5996
6236
|
}
|
|
@@ -6526,18 +6766,18 @@ View your dashboard at: ${apiUrl}/usage`);
|
|
|
6526
6766
|
|
|
6527
6767
|
// src/commands/init.ts
|
|
6528
6768
|
import { execFileSync as execFileSync7, spawn } from "child_process";
|
|
6529
|
-
import { existsSync as
|
|
6769
|
+
import { existsSync as existsSync32 } from "fs";
|
|
6530
6770
|
import { appendFile, mkdir, readFile } from "fs/promises";
|
|
6531
|
-
import { homedir as
|
|
6532
|
-
import { dirname as dirname6, join as
|
|
6771
|
+
import { homedir as homedir30, platform as platform5 } from "os";
|
|
6772
|
+
import { dirname as dirname6, join as join31, posix as posix3, win32 } from "path";
|
|
6533
6773
|
|
|
6534
6774
|
// src/infrastructure/service/index.ts
|
|
6535
6775
|
import { platform as platform4 } from "os";
|
|
6536
6776
|
|
|
6537
6777
|
// src/infrastructure/service/linux-systemd.ts
|
|
6538
6778
|
import { execFileSync as execFileSync5 } from "child_process";
|
|
6539
|
-
import { existsSync as
|
|
6540
|
-
import { homedir as
|
|
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";
|
|
6541
6781
|
import { posix } from "path";
|
|
6542
6782
|
|
|
6543
6783
|
// src/utils/command.ts
|
|
@@ -6606,10 +6846,10 @@ function escapeXml(value) {
|
|
|
6606
6846
|
|
|
6607
6847
|
// src/infrastructure/service/linux-systemd.ts
|
|
6608
6848
|
var SYSTEMD_SERVICE_NAME = "tokenarena";
|
|
6609
|
-
function getLinuxSystemdServiceDir(homePath =
|
|
6849
|
+
function getLinuxSystemdServiceDir(homePath = homedir28()) {
|
|
6610
6850
|
return posix.join(homePath, ".config", "systemd", "user");
|
|
6611
6851
|
}
|
|
6612
|
-
function getLinuxSystemdServiceFile(homePath =
|
|
6852
|
+
function getLinuxSystemdServiceFile(homePath = homedir28()) {
|
|
6613
6853
|
return posix.join(
|
|
6614
6854
|
getLinuxSystemdServiceDir(homePath),
|
|
6615
6855
|
`${SYSTEMD_SERVICE_NAME}.service`
|
|
@@ -6666,7 +6906,7 @@ function ensureSystemdAvailable() {
|
|
|
6666
6906
|
}
|
|
6667
6907
|
function createLinuxSystemdServiceBackend() {
|
|
6668
6908
|
function isInstalled() {
|
|
6669
|
-
return
|
|
6909
|
+
return existsSync30(getLinuxSystemdServiceFile());
|
|
6670
6910
|
}
|
|
6671
6911
|
async function setup(skipPrompt = false) {
|
|
6672
6912
|
if (!ensureSystemdAvailable()) {
|
|
@@ -6791,7 +7031,7 @@ function createLinuxSystemdServiceBackend() {
|
|
|
6791
7031
|
}
|
|
6792
7032
|
async function uninstall(skipPrompt = false) {
|
|
6793
7033
|
const serviceFile = getLinuxSystemdServiceFile();
|
|
6794
|
-
if (!
|
|
7034
|
+
if (!existsSync30(serviceFile)) {
|
|
6795
7035
|
logger.info(formatBullet("\u670D\u52A1\u6587\u4EF6\u4E0D\u5B58\u5728\u3002", "warning"));
|
|
6796
7036
|
return;
|
|
6797
7037
|
}
|
|
@@ -6852,17 +7092,17 @@ function createLinuxSystemdServiceBackend() {
|
|
|
6852
7092
|
|
|
6853
7093
|
// src/infrastructure/service/macos-launchd.ts
|
|
6854
7094
|
import { execFileSync as execFileSync6 } from "child_process";
|
|
6855
|
-
import { existsSync as
|
|
6856
|
-
import { homedir as
|
|
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";
|
|
6857
7097
|
import { posix as posix2 } from "path";
|
|
6858
7098
|
var MACOS_LAUNCHD_LABEL = "com.guji.tokenarena";
|
|
6859
7099
|
function getCurrentUid() {
|
|
6860
7100
|
return typeof process.getuid === "function" ? process.getuid() : null;
|
|
6861
7101
|
}
|
|
6862
|
-
function getMacosLaunchAgentDir(homePath =
|
|
7102
|
+
function getMacosLaunchAgentDir(homePath = homedir29()) {
|
|
6863
7103
|
return posix2.join(homePath, "Library", "LaunchAgents");
|
|
6864
7104
|
}
|
|
6865
|
-
function getMacosLaunchAgentFile(homePath =
|
|
7105
|
+
function getMacosLaunchAgentFile(homePath = homedir29()) {
|
|
6866
7106
|
return posix2.join(
|
|
6867
7107
|
getMacosLaunchAgentDir(homePath),
|
|
6868
7108
|
`${MACOS_LAUNCHD_LABEL}.plist`
|
|
@@ -6989,7 +7229,7 @@ function writeLaunchAgentPlist() {
|
|
|
6989
7229
|
label: MACOS_LAUNCHD_LABEL,
|
|
6990
7230
|
programArguments: [command.execPath, ...command.args],
|
|
6991
7231
|
environment: getManagedServiceEnvironment(),
|
|
6992
|
-
workingDirectory:
|
|
7232
|
+
workingDirectory: homedir29(),
|
|
6993
7233
|
standardOutPath: stdoutPath,
|
|
6994
7234
|
standardErrorPath: stderrPath
|
|
6995
7235
|
});
|
|
@@ -7014,7 +7254,7 @@ function bootstrapLaunchAgent() {
|
|
|
7014
7254
|
}
|
|
7015
7255
|
function createMacosLaunchdServiceBackend() {
|
|
7016
7256
|
function isInstalled() {
|
|
7017
|
-
return
|
|
7257
|
+
return existsSync31(getMacosLaunchAgentFile());
|
|
7018
7258
|
}
|
|
7019
7259
|
async function setup(skipPrompt = false) {
|
|
7020
7260
|
if (!ensureLaunchctlAvailable()) {
|
|
@@ -7155,7 +7395,7 @@ function createMacosLaunchdServiceBackend() {
|
|
|
7155
7395
|
}
|
|
7156
7396
|
async function uninstall(skipPrompt = false) {
|
|
7157
7397
|
const plistFile = getMacosLaunchAgentFile();
|
|
7158
|
-
if (!
|
|
7398
|
+
if (!existsSync31(plistFile)) {
|
|
7159
7399
|
logger.info(formatBullet("\u670D\u52A1\u6587\u4EF6\u4E0D\u5B58\u5728\u3002", "warning"));
|
|
7160
7400
|
return;
|
|
7161
7401
|
}
|
|
@@ -7266,7 +7506,7 @@ function resolvePowerShellProfilePath() {
|
|
|
7266
7506
|
const systemRoot = process.env.SYSTEMROOT || "C:\\Windows";
|
|
7267
7507
|
const candidates = [
|
|
7268
7508
|
"pwsh.exe",
|
|
7269
|
-
|
|
7509
|
+
join31(systemRoot, "System32", "WindowsPowerShell", "v1.0", "powershell.exe")
|
|
7270
7510
|
];
|
|
7271
7511
|
for (const command of candidates) {
|
|
7272
7512
|
try {
|
|
@@ -7295,8 +7535,8 @@ function resolvePowerShellProfilePath() {
|
|
|
7295
7535
|
function resolveShellAliasSetup(options = {}) {
|
|
7296
7536
|
const currentPlatform = options.currentPlatform ?? platform5();
|
|
7297
7537
|
const env = options.env ?? process.env;
|
|
7298
|
-
const homeDir = options.homeDir ??
|
|
7299
|
-
const pathExists = options.exists ??
|
|
7538
|
+
const homeDir = options.homeDir ?? homedir30();
|
|
7539
|
+
const pathExists = options.exists ?? existsSync32;
|
|
7300
7540
|
const shellFromEnv = env.SHELL ? basenameLikeShell(env.SHELL).toLowerCase() : "";
|
|
7301
7541
|
const shellName = shellFromEnv || (currentPlatform === "win32" ? "powershell" : "");
|
|
7302
7542
|
const aliasName = "ta";
|
|
@@ -7493,7 +7733,7 @@ async function setupShellAlias() {
|
|
|
7493
7733
|
try {
|
|
7494
7734
|
await mkdir(dirname6(setup.configFile), { recursive: true });
|
|
7495
7735
|
let existingContent = "";
|
|
7496
|
-
if (
|
|
7736
|
+
if (existsSync32(setup.configFile)) {
|
|
7497
7737
|
existingContent = await readFile(setup.configFile, "utf-8");
|
|
7498
7738
|
}
|
|
7499
7739
|
const normalizedContent = existingContent.toLowerCase();
|
|
@@ -7751,8 +7991,8 @@ function buildLocalUsageDashboardData(input2) {
|
|
|
7751
7991
|
}
|
|
7752
7992
|
|
|
7753
7993
|
// src/infrastructure/runtime/cli-version.ts
|
|
7754
|
-
import { readFileSync as
|
|
7755
|
-
import { dirname as dirname7, join as
|
|
7994
|
+
import { readFileSync as readFileSync14 } from "fs";
|
|
7995
|
+
import { dirname as dirname7, join as join32 } from "path";
|
|
7756
7996
|
import { fileURLToPath } from "url";
|
|
7757
7997
|
var FALLBACK_VERSION = "0.0.0";
|
|
7758
7998
|
var cachedVersion;
|
|
@@ -7760,13 +8000,13 @@ function getCliVersion(metaUrl = import.meta.url) {
|
|
|
7760
8000
|
if (cachedVersion) {
|
|
7761
8001
|
return cachedVersion;
|
|
7762
8002
|
}
|
|
7763
|
-
const packageJsonPath =
|
|
8003
|
+
const packageJsonPath = join32(
|
|
7764
8004
|
dirname7(fileURLToPath(metaUrl)),
|
|
7765
8005
|
"..",
|
|
7766
8006
|
"package.json"
|
|
7767
8007
|
);
|
|
7768
8008
|
try {
|
|
7769
|
-
const packageJson = JSON.parse(
|
|
8009
|
+
const packageJson = JSON.parse(readFileSync14(packageJsonPath, "utf-8"));
|
|
7770
8010
|
cachedVersion = typeof packageJson.version === "string" ? packageJson.version : FALLBACK_VERSION;
|
|
7771
8011
|
} catch {
|
|
7772
8012
|
cachedVersion = FALLBACK_VERSION;
|
|
@@ -8171,8 +8411,8 @@ async function runSyncCommand(opts = {}) {
|
|
|
8171
8411
|
}
|
|
8172
8412
|
|
|
8173
8413
|
// src/commands/uninstall.ts
|
|
8174
|
-
import { existsSync as
|
|
8175
|
-
import { homedir as
|
|
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";
|
|
8176
8416
|
function removeShellAlias() {
|
|
8177
8417
|
const shell = process.env.SHELL;
|
|
8178
8418
|
if (!shell) return;
|
|
@@ -8181,24 +8421,24 @@ function removeShellAlias() {
|
|
|
8181
8421
|
let configFile;
|
|
8182
8422
|
switch (shellName) {
|
|
8183
8423
|
case "zsh":
|
|
8184
|
-
configFile = `${
|
|
8424
|
+
configFile = `${homedir31()}/.zshrc`;
|
|
8185
8425
|
break;
|
|
8186
8426
|
case "bash":
|
|
8187
|
-
if (platform6() === "darwin" &&
|
|
8188
|
-
configFile = `${
|
|
8427
|
+
if (platform6() === "darwin" && existsSync33(`${homedir31()}/.bash_profile`)) {
|
|
8428
|
+
configFile = `${homedir31()}/.bash_profile`;
|
|
8189
8429
|
} else {
|
|
8190
|
-
configFile = `${
|
|
8430
|
+
configFile = `${homedir31()}/.bashrc`;
|
|
8191
8431
|
}
|
|
8192
8432
|
break;
|
|
8193
8433
|
case "fish":
|
|
8194
|
-
configFile = `${
|
|
8434
|
+
configFile = `${homedir31()}/.config/fish/config.fish`;
|
|
8195
8435
|
break;
|
|
8196
8436
|
default:
|
|
8197
8437
|
return;
|
|
8198
8438
|
}
|
|
8199
|
-
if (!
|
|
8439
|
+
if (!existsSync33(configFile)) return;
|
|
8200
8440
|
try {
|
|
8201
|
-
let content =
|
|
8441
|
+
let content = readFileSync15(configFile, "utf-8");
|
|
8202
8442
|
const aliasPatterns = [
|
|
8203
8443
|
// zsh / bash format: alias ta="tokenarena"
|
|
8204
8444
|
new RegExp(
|
|
@@ -8235,7 +8475,7 @@ async function runUninstall() {
|
|
|
8235
8475
|
const runtimeDir = getRuntimeDirPath();
|
|
8236
8476
|
const serviceBackend = getServiceBackend();
|
|
8237
8477
|
const hasInstalledService = serviceBackend?.isInstalled() ?? false;
|
|
8238
|
-
const hasLocalArtifacts =
|
|
8478
|
+
const hasLocalArtifacts = existsSync33(configPath) || existsSync33(configDir) || existsSync33(stateDir) || existsSync33(runtimeDir) || hasInstalledService;
|
|
8239
8479
|
if (!hasLocalArtifacts) {
|
|
8240
8480
|
logger.info(formatHeader("\u5378\u8F7D TokenArena"));
|
|
8241
8481
|
logger.info(formatBullet("\u672A\u53D1\u73B0\u672C\u5730\u914D\u7F6E\uFF0C\u65E0\u9700\u5378\u8F7D\u3002"));
|
|
@@ -8279,22 +8519,22 @@ async function runUninstall() {
|
|
|
8279
8519
|
}
|
|
8280
8520
|
}
|
|
8281
8521
|
logger.info(formatSection("\u6267\u884C\u7ED3\u679C"));
|
|
8282
|
-
if (
|
|
8522
|
+
if (existsSync33(configPath)) {
|
|
8283
8523
|
deleteConfig();
|
|
8284
8524
|
logger.info(formatBullet("\u5DF2\u5220\u9664\u914D\u7F6E\u6587\u4EF6\u3002", "success"));
|
|
8285
8525
|
}
|
|
8286
|
-
if (
|
|
8526
|
+
if (existsSync33(configDir)) {
|
|
8287
8527
|
try {
|
|
8288
8528
|
rmSync6(configDir, { recursive: false, force: true });
|
|
8289
8529
|
logger.info(formatBullet("\u5DF2\u5220\u9664\u914D\u7F6E\u76EE\u5F55\u3002", "success"));
|
|
8290
8530
|
} catch {
|
|
8291
8531
|
}
|
|
8292
8532
|
}
|
|
8293
|
-
if (
|
|
8533
|
+
if (existsSync33(stateDir)) {
|
|
8294
8534
|
rmSync6(stateDir, { recursive: true, force: true });
|
|
8295
8535
|
logger.info(formatBullet("\u5DF2\u5220\u9664\u72B6\u6001\u6570\u636E\u3002", "success"));
|
|
8296
8536
|
}
|
|
8297
|
-
if (
|
|
8537
|
+
if (existsSync33(runtimeDir)) {
|
|
8298
8538
|
rmSync6(runtimeDir, { recursive: true, force: true });
|
|
8299
8539
|
logger.info(formatBullet("\u5DF2\u5220\u9664\u8FD0\u884C\u65F6\u6570\u636E\u3002", "success"));
|
|
8300
8540
|
}
|
|
@@ -8525,7 +8765,7 @@ function createCli() {
|
|
|
8525
8765
|
}
|
|
8526
8766
|
|
|
8527
8767
|
// src/infrastructure/runtime/main-module.ts
|
|
8528
|
-
import { existsSync as
|
|
8768
|
+
import { existsSync as existsSync34, realpathSync as realpathSync2 } from "fs";
|
|
8529
8769
|
import { resolve as resolve3 } from "path";
|
|
8530
8770
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
8531
8771
|
function isMainModule(argvEntry = process.argv[1], metaUrl = import.meta.url) {
|
|
@@ -8536,7 +8776,7 @@ function isMainModule(argvEntry = process.argv[1], metaUrl = import.meta.url) {
|
|
|
8536
8776
|
try {
|
|
8537
8777
|
return realpathSync2(argvEntry) === realpathSync2(currentModulePath);
|
|
8538
8778
|
} catch {
|
|
8539
|
-
if (!
|
|
8779
|
+
if (!existsSync34(argvEntry)) {
|
|
8540
8780
|
return false;
|
|
8541
8781
|
}
|
|
8542
8782
|
return resolve3(argvEntry) === resolve3(currentModulePath);
|