@poco-ai/tokenarena 0.2.2-beta.2 → 0.2.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 CHANGED
@@ -1,4 +1,21 @@
1
1
  #!/usr/bin/env node
2
+ import {
3
+ formatBullet,
4
+ formatHeader,
5
+ formatKeyValue,
6
+ formatMutedPath,
7
+ formatSection,
8
+ formatStatusBadge,
9
+ isCommandAvailable,
10
+ isInteractiveTerminal,
11
+ logger,
12
+ maskSecret,
13
+ promptConfirm,
14
+ promptPassword,
15
+ promptSelect,
16
+ promptText,
17
+ runInstallService
18
+ } from "./chunk-XJKRJ3K2.js";
2
19
 
3
20
  // src/parsers/claude-code.ts
4
21
  import { existsSync as existsSync3 } from "fs";
@@ -1813,150 +1830,6 @@ function getDefaultApiUrl() {
1813
1830
  return process.env.TOKEN_ARENA_API_URL || DEFAULT_API_URL;
1814
1831
  }
1815
1832
 
1816
- // src/infrastructure/ui/format.ts
1817
- var hasColor = Boolean(process.stdout.isTTY && process.env.NO_COLOR !== "1");
1818
- function withCode(code, value) {
1819
- if (!hasColor) return value;
1820
- return `\x1B[${code}m${value}\x1B[0m`;
1821
- }
1822
- function bold(value) {
1823
- return withCode("1", value);
1824
- }
1825
- function dim(value) {
1826
- return withCode("2", value);
1827
- }
1828
- function cyan(value) {
1829
- return withCode("36", value);
1830
- }
1831
- function green(value) {
1832
- return withCode("32", value);
1833
- }
1834
- function yellow(value) {
1835
- return withCode("33", value);
1836
- }
1837
- function red(value) {
1838
- return withCode("31", value);
1839
- }
1840
- function magenta(value) {
1841
- return withCode("35", value);
1842
- }
1843
- function formatHeader(title, subtitle) {
1844
- const lines = [`${cyan("\u25C8")} ${bold(title)}`];
1845
- if (subtitle) {
1846
- lines.push(dim(subtitle));
1847
- }
1848
- return `
1849
- ${lines.join("\n")}`;
1850
- }
1851
- function formatSection(title) {
1852
- return `
1853
- ${bold(title)}`;
1854
- }
1855
- function formatKeyValue(label, value) {
1856
- return ` ${dim(label.padEnd(14, " "))} ${value}`;
1857
- }
1858
- function formatBullet(value, tone = "neutral") {
1859
- const icon = tone === "success" ? green("\u2714") : tone === "warning" ? yellow("!") : tone === "danger" ? red("\u2716") : cyan("\u2022");
1860
- return ` ${icon} ${value}`;
1861
- }
1862
- function formatMutedPath(path) {
1863
- return dim(path);
1864
- }
1865
- function maskSecret(value, visible = 8) {
1866
- if (!value) return "(empty)";
1867
- if (value.length <= visible) return value;
1868
- return `${value.slice(0, visible)}\u2026`;
1869
- }
1870
- function formatStatusBadge(label, tone = "neutral") {
1871
- if (tone === "success") return green(label);
1872
- if (tone === "warning") return yellow(label);
1873
- if (tone === "danger") return red(label);
1874
- return magenta(label);
1875
- }
1876
-
1877
- // src/infrastructure/ui/prompts.ts
1878
- import {
1879
- confirm,
1880
- input,
1881
- password,
1882
- select
1883
- } from "@inquirer/prompts";
1884
- function isInteractiveTerminal() {
1885
- return Boolean(process.stdin.isTTY && process.stdout.isTTY);
1886
- }
1887
- async function promptConfirm(options) {
1888
- return confirm({
1889
- message: options.message,
1890
- default: options.defaultValue
1891
- });
1892
- }
1893
- async function promptText(options) {
1894
- return input({
1895
- message: options.message,
1896
- default: options.defaultValue,
1897
- validate: options.validate
1898
- });
1899
- }
1900
- async function promptPassword(options) {
1901
- return password({
1902
- message: options.message,
1903
- mask: options.mask ?? "*",
1904
- validate: options.validate
1905
- });
1906
- }
1907
- async function promptSelect(options) {
1908
- return select({
1909
- message: options.message,
1910
- choices: [...options.choices],
1911
- pageSize: Math.min(Math.max(options.choices.length, 6), 10)
1912
- });
1913
- }
1914
-
1915
- // src/utils/logger.ts
1916
- var LOG_LEVELS = {
1917
- debug: 0,
1918
- info: 1,
1919
- warn: 2,
1920
- error: 3
1921
- };
1922
- var Logger = class {
1923
- level;
1924
- constructor(level = "info") {
1925
- this.level = level;
1926
- }
1927
- setLevel(level) {
1928
- this.level = level;
1929
- }
1930
- debug(msg) {
1931
- if (LOG_LEVELS[this.level] <= LOG_LEVELS.debug) {
1932
- process.stderr.write(`[debug] ${msg}
1933
- `);
1934
- }
1935
- }
1936
- info(msg) {
1937
- if (LOG_LEVELS[this.level] <= LOG_LEVELS.info) {
1938
- process.stdout.write(`${msg}
1939
- `);
1940
- }
1941
- }
1942
- warn(msg) {
1943
- if (LOG_LEVELS[this.level] <= LOG_LEVELS.warn) {
1944
- process.stderr.write(`warn: ${msg}
1945
- `);
1946
- }
1947
- }
1948
- error(msg) {
1949
- if (LOG_LEVELS[this.level] <= LOG_LEVELS.error) {
1950
- process.stderr.write(`error: ${msg}
1951
- `);
1952
- }
1953
- }
1954
- log(msg) {
1955
- this.info(msg);
1956
- }
1957
- };
1958
- var logger = new Logger();
1959
-
1960
1833
  // src/commands/config.ts
1961
1834
  var VALID_KEYS = ["apiKey", "apiUrl", "syncInterval", "logLevel"];
1962
1835
  function isConfigKey(value) {
@@ -2262,14 +2135,14 @@ import { hostname as hostname3 } from "os";
2262
2135
 
2263
2136
  // src/domain/project-identity.ts
2264
2137
  import { createHmac } from "crypto";
2265
- function toProjectIdentity(input2) {
2266
- if (input2.mode === "disabled") {
2138
+ function toProjectIdentity(input) {
2139
+ if (input.mode === "disabled") {
2267
2140
  return { projectKey: "unknown", projectLabel: "Unknown Project" };
2268
2141
  }
2269
- if (input2.mode === "raw") {
2270
- return { projectKey: input2.project, projectLabel: input2.project };
2142
+ if (input.mode === "raw") {
2143
+ return { projectKey: input.project, projectLabel: input.project };
2271
2144
  }
2272
- const projectKey = createHmac("sha256", input2.salt).update(input2.project).digest("hex").slice(0, 16);
2145
+ const projectKey = createHmac("sha256", input.salt).update(input.project).digest("hex").slice(0, 16);
2273
2146
  return {
2274
2147
  projectKey,
2275
2148
  projectLabel: `Project ${projectKey.slice(0, 6)}`
@@ -2285,13 +2158,13 @@ function shortHash(value) {
2285
2158
  function normalizeApiUrl(apiUrl) {
2286
2159
  return apiUrl.replace(/\/+$/, "");
2287
2160
  }
2288
- function buildUploadManifestScope(input2) {
2161
+ function buildUploadManifestScope(input) {
2289
2162
  return {
2290
- apiKeyHash: shortHash(input2.apiKey),
2291
- apiUrl: normalizeApiUrl(input2.apiUrl),
2292
- deviceId: input2.deviceId,
2293
- projectHashSaltHash: shortHash(input2.settings.projectHashSalt),
2294
- projectMode: input2.settings.projectMode
2163
+ apiKeyHash: shortHash(input.apiKey),
2164
+ apiUrl: normalizeApiUrl(input.apiUrl),
2165
+ deviceId: input.deviceId,
2166
+ projectHashSaltHash: shortHash(input.settings.projectHashSalt),
2167
+ projectMode: input.settings.projectMode
2295
2168
  };
2296
2169
  }
2297
2170
  function describeUploadManifestScopeChanges(previous, current) {
@@ -2361,20 +2234,20 @@ function buildRecordHashes(items, getKey, getHash) {
2361
2234
  }
2362
2235
  return hashes;
2363
2236
  }
2364
- function createUploadManifest(input2) {
2237
+ function createUploadManifest(input) {
2365
2238
  return {
2366
2239
  buckets: buildRecordHashes(
2367
- input2.buckets,
2240
+ input.buckets,
2368
2241
  getUploadBucketManifestKey,
2369
2242
  getUploadBucketContentHash
2370
2243
  ),
2371
- scope: input2.scope,
2244
+ scope: input.scope,
2372
2245
  sessions: buildRecordHashes(
2373
- input2.sessions,
2246
+ input.sessions,
2374
2247
  getUploadSessionManifestKey,
2375
2248
  getUploadSessionContentHash
2376
2249
  ),
2377
- updatedAt: input2.updatedAt ?? (/* @__PURE__ */ new Date()).toISOString(),
2250
+ updatedAt: input.updatedAt ?? (/* @__PURE__ */ new Date()).toISOString(),
2378
2251
  version: MANIFEST_VERSION
2379
2252
  };
2380
2253
  }
@@ -2387,21 +2260,21 @@ function countRemovedRecords(previous, current) {
2387
2260
  }
2388
2261
  return removed;
2389
2262
  }
2390
- function diffUploadManifest(input2) {
2263
+ function diffUploadManifest(input) {
2391
2264
  const nextManifest = createUploadManifest({
2392
- buckets: input2.buckets,
2393
- scope: input2.scope,
2394
- sessions: input2.sessions,
2395
- updatedAt: input2.updatedAt
2265
+ buckets: input.buckets,
2266
+ scope: input.scope,
2267
+ sessions: input.sessions,
2268
+ updatedAt: input.updatedAt
2396
2269
  });
2397
- const scopeChangedReasons = input2.previous ? describeUploadManifestScopeChanges(input2.previous.scope, input2.scope) : [];
2398
- const previousBuckets = input2.previous && scopeChangedReasons.length === 0 ? input2.previous.buckets : {};
2399
- const previousSessions = input2.previous && scopeChangedReasons.length === 0 ? input2.previous.sessions : {};
2400
- const bucketsToUpload = input2.buckets.filter((bucket) => {
2270
+ const scopeChangedReasons = input.previous ? describeUploadManifestScopeChanges(input.previous.scope, input.scope) : [];
2271
+ const previousBuckets = input.previous && scopeChangedReasons.length === 0 ? input.previous.buckets : {};
2272
+ const previousSessions = input.previous && scopeChangedReasons.length === 0 ? input.previous.sessions : {};
2273
+ const bucketsToUpload = input.buckets.filter((bucket) => {
2401
2274
  const key = getUploadBucketManifestKey(bucket);
2402
2275
  return previousBuckets[key] !== nextManifest.buckets[key];
2403
2276
  });
2404
- const sessionsToUpload = input2.sessions.filter((session) => {
2277
+ const sessionsToUpload = input.sessions.filter((session) => {
2405
2278
  const key = getUploadSessionManifestKey(session);
2406
2279
  return previousSessions[key] !== nextManifest.sessions[key];
2407
2280
  });
@@ -2415,8 +2288,8 @@ function diffUploadManifest(input2) {
2415
2288
  ),
2416
2289
  scopeChangedReasons,
2417
2290
  sessionsToUpload,
2418
- unchangedBuckets: input2.buckets.length - bucketsToUpload.length,
2419
- unchangedSessions: input2.sessions.length - sessionsToUpload.length
2291
+ unchangedBuckets: input.buckets.length - bucketsToUpload.length,
2292
+ unchangedSessions: input.sessions.length - sessionsToUpload.length
2420
2293
  };
2421
2294
  }
2422
2295
 
@@ -3284,8 +3157,8 @@ import { dirname as dirname3, join as join15, posix, win32 } from "path";
3284
3157
  function joinForPlatform(currentPlatform, ...parts) {
3285
3158
  return currentPlatform === "win32" ? win32.join(...parts) : posix.join(...parts);
3286
3159
  }
3287
- function basenameLikeShell(input2) {
3288
- return input2.split(/[\\/]+/).pop()?.replace(/\.exe$/i, "") ?? input2;
3160
+ function basenameLikeShell(input) {
3161
+ return input.split(/[\\/]+/).pop()?.replace(/\.exe$/i, "") ?? input;
3289
3162
  }
3290
3163
  function getBrowserLaunchCommand(url, currentPlatform = platform()) {
3291
3164
  switch (currentPlatform) {
@@ -3510,6 +3383,30 @@ async function runInit(opts = {}) {
3510
3383
  logger.info(formatBullet("TokenArena \u5DF2\u51C6\u5907\u5C31\u7EEA\u3002", "success"));
3511
3384
  logger.info(formatKeyValue("\u63A7\u5236\u53F0", `${apiUrl}/usage`));
3512
3385
  await setupShellAlias();
3386
+ await setupSystemdService();
3387
+ }
3388
+ async function setupSystemdService() {
3389
+ const currentPlatform = platform();
3390
+ if (currentPlatform !== "linux") {
3391
+ return;
3392
+ }
3393
+ if (!isCommandAvailable("systemctl")) {
3394
+ return;
3395
+ }
3396
+ const shouldSetup = await promptConfirm({
3397
+ message: "\u662F\u5426\u8BBE\u7F6E systemd \u670D\u52A1\u4EE5\u81EA\u52A8\u8FD0\u884C daemon\uFF1F",
3398
+ defaultValue: true
3399
+ });
3400
+ if (!shouldSetup) {
3401
+ logger.info(formatBullet("\u5DF2\u8DF3\u8FC7 systemd \u670D\u52A1\u8BBE\u7F6E\u3002"));
3402
+ return;
3403
+ }
3404
+ try {
3405
+ const { runInstallService: runInstallService2 } = await import("./service-4U7K4DKW.js");
3406
+ await runInstallService2({ action: "setup", skipPrompt: true });
3407
+ } catch (err) {
3408
+ logger.warn(`systemd \u670D\u52A1\u8BBE\u7F6E\u5931\u8D25: ${err.message}`);
3409
+ }
3513
3410
  }
3514
3411
  async function setupShellAlias() {
3515
3412
  const setup = resolveShellAliasSetup();
@@ -3994,6 +3891,11 @@ function createCli() {
3994
3891
  program.command("daemon").description("Run continuous sync (every 5 minutes by default)").option("--interval <ms>", "Sync interval in milliseconds", parseInt).action(async (opts) => {
3995
3892
  await runDaemon(opts);
3996
3893
  });
3894
+ program.command("service [action]").description(
3895
+ "Manage systemd user service (setup|start|stop|restart|status|uninstall)"
3896
+ ).action(async (action) => {
3897
+ await runInstallService({ action });
3898
+ });
3997
3899
  program.command("status").description("Show configuration and detected tools").action(async () => {
3998
3900
  await runStatus();
3999
3901
  });