@yishiguji/tokenarena 0.16.3 → 0.16.5

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
@@ -645,13 +645,15 @@ function readRollout(path) {
645
645
  let latestTimestampOrder = 0n;
646
646
  let minLineTimestampOrder = null;
647
647
  let line = 0;
648
- let lineCount = 0;
648
+ let maxOrdinal = null;
649
649
  for (const text of content.split("\n")) {
650
650
  line++;
651
651
  if (!text.trim()) continue;
652
- lineCount++;
653
652
  try {
654
653
  const event = JSON.parse(text);
654
+ if (typeof event.ordinal === "number" && Number.isSafeInteger(event.ordinal) && event.ordinal >= 0 && (maxOrdinal === null || event.ordinal > maxOrdinal)) {
655
+ maxOrdinal = event.ordinal;
656
+ }
655
657
  const timestamp = readTimestamp(event.timestamp);
656
658
  const order = timestampOrder(event.timestamp, timestamp);
657
659
  if (order !== null) {
@@ -702,7 +704,7 @@ function readRollout(path) {
702
704
  forkedFrom && spawnedFrom && forkedFrom !== spawnedFrom
703
705
  ),
704
706
  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,
707
+ maxOrdinal,
706
708
  rootTimestampOrder: timestampOrder(
707
709
  rootMeta?.timestamp,
708
710
  readTimestamp(rootMeta?.timestamp)
@@ -809,13 +811,11 @@ var CodexParser = class {
809
811
  if (file.parentConflict || file.parentId) {
810
812
  const parent = file.parentId ? threadIndex.get(file.parentId) : void 0;
811
813
  const cutoff = file.rootTimestampOrder;
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 秒,或父内容完全早于截止点
814
+ const parentMaxOrdinal = parent ? parent.files.reduce(
815
+ (max, rollout) => rollout.maxOrdinal !== null && (max === null || rollout.maxOrdinal > max) ? rollout.maxOrdinal : max,
816
+ null
817
+ ) : null;
818
+ const coverageOk = parent ? file.forkOrdinalExclusive !== null && parentMaxOrdinal !== null ? parentMaxOrdinal >= file.forkOrdinalExclusive - 1 : cutoff !== null && // 父最大时间戳落后不超过 1 秒,或父内容完全早于截止点
819
819
  // 且父最早行时间戳也早于截止点(父在截止前已停止写入)。
820
820
  (parent.latestTimestampOrder >= cutoff - 1000000n || parent.minLineTimestampOrder !== null && parent.minLineTimestampOrder < cutoff) : false;
821
821
  if (file.parentConflict || !parent || parent === thread || cutoff === null || !processThread(parent) || parent.invalidTokenTimestamp || !coverageOk) {
@@ -1282,7 +1282,15 @@ import { dirname, join as join6 } from "path";
1282
1282
  import { execFileSync } from "child_process";
1283
1283
  import { statSync } from "fs";
1284
1284
  import { pathToFileURL } from "url";
1285
- function withSuppressedSqliteWarning(fn) {
1285
+ var warningScope = Promise.resolve();
1286
+ async function withSuppressedSqliteWarning(fn) {
1287
+ const previousScope = warningScope;
1288
+ let releaseScope = () => {
1289
+ };
1290
+ warningScope = new Promise((resolve5) => {
1291
+ releaseScope = resolve5;
1292
+ });
1293
+ await previousScope;
1286
1294
  const originalEmitWarning = process.emitWarning;
1287
1295
  process.emitWarning = ((warning, ...args) => {
1288
1296
  const warningName = typeof warning === "string" ? typeof args[0] === "string" ? args[0] : "" : warning.name;
@@ -1292,9 +1300,12 @@ function withSuppressedSqliteWarning(fn) {
1292
1300
  }
1293
1301
  originalEmitWarning.call(process, warning, ...args);
1294
1302
  });
1295
- return fn().finally(() => {
1303
+ try {
1304
+ return await fn();
1305
+ } finally {
1296
1306
  process.emitWarning = originalEmitWarning;
1297
- });
1307
+ releaseScope();
1308
+ }
1298
1309
  }
1299
1310
  function warnWhenWalSkipped(dbPath) {
1300
1311
  try {
@@ -2375,25 +2386,9 @@ function getOpenCodeDataDirs(env = process.env) {
2375
2386
  ].filter((value) => Boolean(value));
2376
2387
  return Array.from(new Set(dirs));
2377
2388
  }
2378
- async function withSuppressedSqliteWarning2(fn) {
2379
- const originalEmitWarning = process.emitWarning;
2380
- process.emitWarning = ((warning, ...args) => {
2381
- const warningName = typeof warning === "string" ? typeof args[0] === "string" ? args[0] : "" : warning.name;
2382
- const warningMessage = typeof warning === "string" ? warning : warning.message;
2383
- if (warningName === "ExperimentalWarning" && warningMessage.includes("SQLite")) {
2384
- return;
2385
- }
2386
- originalEmitWarning.call(process, warning, ...args);
2387
- });
2388
- try {
2389
- return await fn();
2390
- } finally {
2391
- process.emitWarning = originalEmitWarning;
2392
- }
2393
- }
2394
2389
  async function readSqliteRowsWithBuiltin2(dbPath, query) {
2395
2390
  try {
2396
- return await withSuppressedSqliteWarning2(async () => {
2391
+ return await withSuppressedSqliteWarning(async () => {
2397
2392
  const sqliteModuleId = "node:sqlite";
2398
2393
  const sqlite = await import(sqliteModuleId);
2399
2394
  const db = new sqlite.DatabaseSync(dbPath);
@@ -7421,13 +7416,13 @@ function saveCachedParseResult(toolId, fingerprint2, result) {
7421
7416
  // src/services/parser-service.ts
7422
7417
  var PARSER_CONCURRENCY = 8;
7423
7418
  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
7419
  try {
7420
+ const files = parser.listSourceFiles?.();
7421
+ const fingerprint2 = files ? computeScanFingerprint(files) : null;
7422
+ const cached = loadCachedParseResult(parser.tool.id, fingerprint2);
7423
+ if (cached) {
7424
+ return { status: "ok", result: cached, cached: true };
7425
+ }
7431
7426
  const result = await parser.parse();
7432
7427
  saveCachedParseResult(parser.tool.id, fingerprint2, result);
7433
7428
  return { status: "ok", result, cached: false };
@@ -7564,14 +7559,28 @@ function toDeviceMetadata(config) {
7564
7559
  hostname: hostname7().replace(/\.local$/, "")
7565
7560
  };
7566
7561
  }
7567
- function toUploadBuckets(buckets, settings, device) {
7562
+ function createProjectIdentityResolver(settings) {
7563
+ const identities = /* @__PURE__ */ new Map();
7564
+ return (project) => {
7565
+ const name = project || "unknown";
7566
+ let identity = identities.get(name);
7567
+ if (!identity) {
7568
+ identity = toProjectIdentity({
7569
+ project: name,
7570
+ mode: settings.projectMode,
7571
+ salt: settings.projectHashSalt
7572
+ });
7573
+ identities.set(name, identity);
7574
+ }
7575
+ return identity;
7576
+ };
7577
+ }
7578
+ function toUploadBuckets(buckets, settings, device, resolveProject = createProjectIdentityResolver(
7579
+ settings
7580
+ )) {
7568
7581
  const aggregated = /* @__PURE__ */ new Map();
7569
7582
  for (const bucket of buckets) {
7570
- const project = toProjectIdentity({
7571
- project: bucket.project || "unknown",
7572
- mode: settings.projectMode,
7573
- salt: settings.projectHashSalt
7574
- });
7583
+ const project = resolveProject(bucket.project);
7575
7584
  const key = [
7576
7585
  bucket.source,
7577
7586
  bucket.model,
@@ -7607,13 +7616,11 @@ function toUploadBuckets(buckets, settings, device) {
7607
7616
  }
7608
7617
  return Array.from(aggregated.values());
7609
7618
  }
7610
- function toUploadSessions(sessions, settings, device) {
7619
+ function toUploadSessions(sessions, settings, device, resolveProject = createProjectIdentityResolver(
7620
+ settings
7621
+ )) {
7611
7622
  return sessions.map((session) => {
7612
- const project = toProjectIdentity({
7613
- project: session.project || "unknown",
7614
- mode: settings.projectMode,
7615
- salt: settings.projectHashSalt
7616
- });
7623
+ const project = resolveProject(session.project);
7617
7624
  return {
7618
7625
  source: session.source,
7619
7626
  projectKey: project.projectKey,
@@ -7792,8 +7799,19 @@ async function runSync(config, opts = {}) {
7792
7799
  deviceId: device.deviceId,
7793
7800
  settings
7794
7801
  });
7795
- const uploadBuckets = toUploadBuckets(allBuckets, settings, device);
7796
- const uploadSessions = toUploadSessions(allSessions, settings, device);
7802
+ const resolveProject = createProjectIdentityResolver(settings);
7803
+ const uploadBuckets = toUploadBuckets(
7804
+ allBuckets,
7805
+ settings,
7806
+ device,
7807
+ resolveProject
7808
+ );
7809
+ const uploadSessions = toUploadSessions(
7810
+ allSessions,
7811
+ settings,
7812
+ device,
7813
+ resolveProject
7814
+ );
7797
7815
  const previousManifest = loadUploadManifest();
7798
7816
  const uploadDiff = diffUploadManifest({
7799
7817
  buckets: uploadBuckets,
@@ -7846,7 +7864,9 @@ async function runSync(config, opts = {}) {
7846
7864
  skippedParts.length > 0 ? `No new or updated usage data to upload. Skipped ${skippedParts.join(" + ")}.` : "No new or updated usage data to upload."
7847
7865
  );
7848
7866
  }
7849
- persistUploadManifest(uploadDiff.nextManifest, quiet);
7867
+ if (uploadDiff.removedBuckets > 0 || uploadDiff.removedSessions > 0) {
7868
+ persistUploadManifest(uploadDiff.nextManifest, quiet);
7869
+ }
7850
7870
  markSyncSucceeded(source, { buckets: 0, sessions: 0 });
7851
7871
  return { buckets: 0, sessions: 0 };
7852
7872
  }
@@ -8009,7 +8029,7 @@ View your dashboard at: ${apiUrl}/usage`);
8009
8029
  }
8010
8030
 
8011
8031
  // src/commands/init.ts
8012
- import { execFileSync as execFileSync7, spawn } from "child_process";
8032
+ import { execFileSync as execFileSync8, spawn } from "child_process";
8013
8033
  import { existsSync as existsSync36 } from "fs";
8014
8034
  import { appendFile, mkdir, readFile } from "fs/promises";
8015
8035
  import { homedir as homedir33, platform as platform5 } from "os";
@@ -8019,18 +8039,24 @@ import { dirname as dirname8, join as join36, posix as posix3, win32 } from "pat
8019
8039
  import { platform as platform4 } from "os";
8020
8040
 
8021
8041
  // src/infrastructure/service/linux-systemd.ts
8022
- import { execFileSync as execFileSync5 } from "child_process";
8042
+ import { execFileSync as execFileSync6 } from "child_process";
8023
8043
  import { existsSync as existsSync34, mkdirSync as mkdirSync4, rmSync as rmSync4, writeFileSync as writeFileSync6 } from "fs";
8024
8044
  import { homedir as homedir31, platform as platform2 } from "os";
8025
8045
  import { posix } from "path";
8026
8046
 
8027
8047
  // src/utils/command.ts
8028
- import { execSync } from "child_process";
8048
+ import { execFileSync as execFileSync5 } from "child_process";
8029
8049
  import { platform } from "os";
8050
+ function getCommandCheck(command, currentPlatform = platform()) {
8051
+ if (currentPlatform === "win32") {
8052
+ return { command: "where", args: [command] };
8053
+ }
8054
+ return { command: "/bin/sh", args: ["-c", 'command -v "$1"', "sh", command] };
8055
+ }
8030
8056
  function isCommandAvailable(command) {
8057
+ const check = getCommandCheck(command);
8031
8058
  try {
8032
- const check = platform() === "win32" ? `where ${command}` : `command -v ${command}`;
8033
- execSync(check, { stdio: "ignore", timeout: 5e3 });
8059
+ execFileSync5(check.command, check.args, { stdio: "ignore", timeout: 5e3 });
8034
8060
  return true;
8035
8061
  } catch {
8036
8062
  return false;
@@ -8142,7 +8168,7 @@ function getSystemdSupport() {
8142
8168
  return { ok: true };
8143
8169
  }
8144
8170
  function execSystemctl(args) {
8145
- execFileSync5("systemctl", ["--user", ...args], {
8171
+ execFileSync6("systemctl", ["--user", ...args], {
8146
8172
  stdio: "inherit"
8147
8173
  });
8148
8174
  }
@@ -8341,7 +8367,7 @@ function createLinuxSystemdServiceBackend() {
8341
8367
  }
8342
8368
 
8343
8369
  // src/infrastructure/service/macos-launchd.ts
8344
- import { execFileSync as execFileSync6 } from "child_process";
8370
+ import { execFileSync as execFileSync7 } from "child_process";
8345
8371
  import { existsSync as existsSync35, mkdirSync as mkdirSync5, rmSync as rmSync5, writeFileSync as writeFileSync7 } from "fs";
8346
8372
  import { homedir as homedir32, platform as platform3 } from "os";
8347
8373
  import { posix as posix2 } from "path";
@@ -8439,7 +8465,7 @@ function getLaunchctlSupport() {
8439
8465
  };
8440
8466
  }
8441
8467
  try {
8442
- execFileSync6("launchctl", ["print", getMacosLaunchdDomain(uid)], {
8468
+ execFileSync7("launchctl", ["print", getMacosLaunchdDomain(uid)], {
8443
8469
  stdio: "ignore"
8444
8470
  });
8445
8471
  return { ok: true };
@@ -8451,7 +8477,7 @@ function getLaunchctlSupport() {
8451
8477
  }
8452
8478
  }
8453
8479
  function execLaunchctl(args, inherit = true) {
8454
- execFileSync6("launchctl", args, {
8480
+ execFileSync7("launchctl", args, {
8455
8481
  stdio: inherit ? "inherit" : "ignore"
8456
8482
  });
8457
8483
  }
@@ -8760,7 +8786,7 @@ function resolvePowerShellProfilePath() {
8760
8786
  ];
8761
8787
  for (const command of candidates) {
8762
8788
  try {
8763
- const output = execFileSync7(
8789
+ const output = execFileSync8(
8764
8790
  command,
8765
8791
  [
8766
8792
  "-NoLogo",