whoburnedmore 0.9.12 → 0.9.14
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 +223 -58
- package/package.json +3 -4
package/dist/index.js
CHANGED
|
@@ -8,10 +8,10 @@ var __export = (target, all) => {
|
|
|
8
8
|
// src/index.ts
|
|
9
9
|
import { spawn } from "node:child_process";
|
|
10
10
|
import { createHash } from "node:crypto";
|
|
11
|
-
import { mkdirSync as
|
|
11
|
+
import { mkdirSync as mkdirSync4, writeFileSync as writeFileSync4 } from "node:fs";
|
|
12
12
|
import { createRequire as createRequire4 } from "node:module";
|
|
13
13
|
import { platform as platform3 } from "node:os";
|
|
14
|
-
import { join as
|
|
14
|
+
import { join as join11 } from "node:path";
|
|
15
15
|
import { createInterface } from "node:readline/promises";
|
|
16
16
|
import pc2 from "picocolors";
|
|
17
17
|
|
|
@@ -786,7 +786,7 @@ async function daemonLoop(deps) {
|
|
|
786
786
|
// src/collect.ts
|
|
787
787
|
import { execFile } from "node:child_process";
|
|
788
788
|
import { createRequire as createRequire3 } from "node:module";
|
|
789
|
-
import { dirname as
|
|
789
|
+
import { dirname as dirname5, join as join10 } from "node:path";
|
|
790
790
|
import { promisify } from "node:util";
|
|
791
791
|
|
|
792
792
|
// src/attribution.ts
|
|
@@ -1155,7 +1155,10 @@ function collectCursorViaTokscale(lookbackDays = LOOKBACK_DAYS) {
|
|
|
1155
1155
|
const bin = resolveTokscaleBin();
|
|
1156
1156
|
if (!bin) return [];
|
|
1157
1157
|
const today = /* @__PURE__ */ new Date();
|
|
1158
|
-
const day = (offset) =>
|
|
1158
|
+
const day = (offset) => {
|
|
1159
|
+
const d = new Date(today.getTime() - offset * 864e5);
|
|
1160
|
+
return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, "0")}-${String(d.getDate()).padStart(2, "0")}`;
|
|
1161
|
+
};
|
|
1159
1162
|
if (mapTokscaleDay(day(0), runTokscaleDay(bin, day(0))).length === 0) {
|
|
1160
1163
|
if (mapTokscaleDay(day(1), runTokscaleDay(bin, day(1))).length === 0) {
|
|
1161
1164
|
return [];
|
|
@@ -1224,7 +1227,7 @@ function mapCursorEvents(events) {
|
|
|
1224
1227
|
const ms = Number(e.timestamp);
|
|
1225
1228
|
if (!tu || !Number.isFinite(ms)) continue;
|
|
1226
1229
|
const d = new Date(ms);
|
|
1227
|
-
const date = d.
|
|
1230
|
+
const date = `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, "0")}-${String(d.getDate()).padStart(2, "0")}`;
|
|
1228
1231
|
const model = e.model || "cursor";
|
|
1229
1232
|
const input = num2(tu.inputTokens);
|
|
1230
1233
|
const output = num2(tu.outputTokens);
|
|
@@ -1314,9 +1317,9 @@ async function collectCursor() {
|
|
|
1314
1317
|
}
|
|
1315
1318
|
|
|
1316
1319
|
// src/native/claude.ts
|
|
1317
|
-
import { readdir, readFile } from "node:fs/promises";
|
|
1320
|
+
import { readdir, readFile as readFile2 } from "node:fs/promises";
|
|
1318
1321
|
import { homedir as homedir5 } from "node:os";
|
|
1319
|
-
import { join as
|
|
1322
|
+
import { join as join7 } from "node:path";
|
|
1320
1323
|
|
|
1321
1324
|
// ../../node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/external.js
|
|
1322
1325
|
var external_exports = {};
|
|
@@ -6761,7 +6764,8 @@ var ConnectorProvider = external_exports.enum([
|
|
|
6761
6764
|
"openai-api",
|
|
6762
6765
|
"openrouter",
|
|
6763
6766
|
"google-api",
|
|
6764
|
-
"cursor"
|
|
6767
|
+
"cursor",
|
|
6768
|
+
"azure-foundry"
|
|
6765
6769
|
]);
|
|
6766
6770
|
var UsageOrigin = external_exports.enum([
|
|
6767
6771
|
"cli",
|
|
@@ -6770,6 +6774,7 @@ var UsageOrigin = external_exports.enum([
|
|
|
6770
6774
|
"openrouter",
|
|
6771
6775
|
"google-api",
|
|
6772
6776
|
"cursor",
|
|
6777
|
+
"azure-foundry",
|
|
6773
6778
|
"import"
|
|
6774
6779
|
]);
|
|
6775
6780
|
var DailyUsageEntry = external_exports.object({
|
|
@@ -7062,6 +7067,76 @@ var OrgJoinInput = external_exports.object({
|
|
|
7062
7067
|
code: external_exports.string().min(1).max(64).optional()
|
|
7063
7068
|
});
|
|
7064
7069
|
|
|
7070
|
+
// src/native/file-cache.ts
|
|
7071
|
+
import { mkdirSync as mkdirSync3, renameSync as renameSync3, writeFileSync as writeFileSync3 } from "node:fs";
|
|
7072
|
+
import { readFile, stat } from "node:fs/promises";
|
|
7073
|
+
import { dirname as dirname3, join as join6 } from "node:path";
|
|
7074
|
+
function nativeCachePath(reader, env = process.env) {
|
|
7075
|
+
const override = env.WHOBURNEDMORE_CONFIG_DIR?.trim();
|
|
7076
|
+
const dir = override || defaultConfigDir();
|
|
7077
|
+
return join6(dir, `native-cache-${reader}.json`);
|
|
7078
|
+
}
|
|
7079
|
+
async function loadCache(path, version) {
|
|
7080
|
+
try {
|
|
7081
|
+
const raw = await readFile(path, "utf8");
|
|
7082
|
+
const parsed = JSON.parse(raw);
|
|
7083
|
+
if (parsed && parsed.v === version && parsed.files && typeof parsed.files === "object") {
|
|
7084
|
+
return parsed.files;
|
|
7085
|
+
}
|
|
7086
|
+
} catch {
|
|
7087
|
+
}
|
|
7088
|
+
return {};
|
|
7089
|
+
}
|
|
7090
|
+
function saveCache(path, version, files) {
|
|
7091
|
+
try {
|
|
7092
|
+
mkdirSync3(dirname3(path), { recursive: true });
|
|
7093
|
+
const tmp = `${path}.tmp-${process.pid}`;
|
|
7094
|
+
writeFileSync3(tmp, JSON.stringify({ v: version, files }));
|
|
7095
|
+
renameSync3(tmp, path);
|
|
7096
|
+
} catch {
|
|
7097
|
+
}
|
|
7098
|
+
}
|
|
7099
|
+
async function readFilesWithCache(opts) {
|
|
7100
|
+
const now = opts.now ?? Date.now;
|
|
7101
|
+
const cached = await loadCache(opts.cachePath, opts.version);
|
|
7102
|
+
const fresh = {};
|
|
7103
|
+
const itemsByFile = [];
|
|
7104
|
+
let filesRead = 0;
|
|
7105
|
+
for (const f of opts.files) {
|
|
7106
|
+
let size;
|
|
7107
|
+
let mtimeMs;
|
|
7108
|
+
try {
|
|
7109
|
+
const s = await stat(f);
|
|
7110
|
+
size = s.size;
|
|
7111
|
+
mtimeMs = s.mtimeMs;
|
|
7112
|
+
} catch {
|
|
7113
|
+
continue;
|
|
7114
|
+
}
|
|
7115
|
+
const hit = cached[f];
|
|
7116
|
+
if (hit && hit.size === size && hit.mtimeMs === mtimeMs) {
|
|
7117
|
+
fresh[f] = hit;
|
|
7118
|
+
itemsByFile.push(hit.items);
|
|
7119
|
+
continue;
|
|
7120
|
+
}
|
|
7121
|
+
if (now() > opts.deadline) {
|
|
7122
|
+
saveCache(opts.cachePath, opts.version, { ...cached, ...fresh });
|
|
7123
|
+
return { itemsByFile: null, filesRead, timedOut: true };
|
|
7124
|
+
}
|
|
7125
|
+
let content;
|
|
7126
|
+
try {
|
|
7127
|
+
content = await readFile(f, "utf8");
|
|
7128
|
+
} catch {
|
|
7129
|
+
continue;
|
|
7130
|
+
}
|
|
7131
|
+
const items = opts.parseFile(content, f);
|
|
7132
|
+
fresh[f] = { size, mtimeMs, items };
|
|
7133
|
+
itemsByFile.push(items);
|
|
7134
|
+
filesRead += 1;
|
|
7135
|
+
}
|
|
7136
|
+
saveCache(opts.cachePath, opts.version, fresh);
|
|
7137
|
+
return { itemsByFile, filesRead, timedOut: false };
|
|
7138
|
+
}
|
|
7139
|
+
|
|
7065
7140
|
// src/native/claude.ts
|
|
7066
7141
|
function num3(n) {
|
|
7067
7142
|
const v = Math.round(Number(n));
|
|
@@ -7167,10 +7242,10 @@ function finalizeClaudeEntries(acc) {
|
|
|
7167
7242
|
}
|
|
7168
7243
|
function resolveClaudeConfigRoots(env = process.env) {
|
|
7169
7244
|
const override = env.CLAUDE_CONFIG_DIR;
|
|
7170
|
-
return override ? override.split(",").map((s) => s.trim()).filter(Boolean) : [
|
|
7245
|
+
return override ? override.split(",").map((s) => s.trim()).filter(Boolean) : [join7(homedir5(), ".claude"), join7(homedir5(), ".config", "claude")];
|
|
7171
7246
|
}
|
|
7172
7247
|
function resolveClaudeProjectDirs(env = process.env) {
|
|
7173
|
-
return resolveClaudeConfigRoots(env).map((r) =>
|
|
7248
|
+
return resolveClaudeConfigRoots(env).map((r) => join7(r, "projects"));
|
|
7174
7249
|
}
|
|
7175
7250
|
async function listJsonl(dir) {
|
|
7176
7251
|
let dirents;
|
|
@@ -7181,7 +7256,7 @@ async function listJsonl(dir) {
|
|
|
7181
7256
|
}
|
|
7182
7257
|
const out = [];
|
|
7183
7258
|
for (const d of dirents) {
|
|
7184
|
-
const full =
|
|
7259
|
+
const full = join7(dir, d.name);
|
|
7185
7260
|
if (d.isDirectory()) {
|
|
7186
7261
|
out.push(...await listJsonl(full));
|
|
7187
7262
|
} else if (d.isFile() && d.name.endsWith(".jsonl")) {
|
|
@@ -7190,7 +7265,43 @@ async function listJsonl(dir) {
|
|
|
7190
7265
|
}
|
|
7191
7266
|
return out;
|
|
7192
7267
|
}
|
|
7193
|
-
var NATIVE_READ_BUDGET_MS =
|
|
7268
|
+
var NATIVE_READ_BUDGET_MS = 45e3;
|
|
7269
|
+
var CLAUDE_CACHE_VERSION = 1;
|
|
7270
|
+
function toCached(r) {
|
|
7271
|
+
return [
|
|
7272
|
+
r.key,
|
|
7273
|
+
r.hasRealId ? 1 : 0,
|
|
7274
|
+
r.date,
|
|
7275
|
+
r.model,
|
|
7276
|
+
r.inputTokens,
|
|
7277
|
+
r.outputTokens,
|
|
7278
|
+
r.cacheCreationTokens,
|
|
7279
|
+
r.cacheReadTokens
|
|
7280
|
+
];
|
|
7281
|
+
}
|
|
7282
|
+
function fromCached(t) {
|
|
7283
|
+
return {
|
|
7284
|
+
key: t[0],
|
|
7285
|
+
hasRealId: t[1] === 1,
|
|
7286
|
+
date: t[2],
|
|
7287
|
+
ts: 0,
|
|
7288
|
+
model: t[3],
|
|
7289
|
+
inputTokens: t[4],
|
|
7290
|
+
outputTokens: t[5],
|
|
7291
|
+
cacheCreationTokens: t[6],
|
|
7292
|
+
cacheReadTokens: t[7]
|
|
7293
|
+
};
|
|
7294
|
+
}
|
|
7295
|
+
function parseFileToCache(content, path) {
|
|
7296
|
+
const acc = /* @__PURE__ */ new Map();
|
|
7297
|
+
accumulateClaudeLines(acc, splitLines(content));
|
|
7298
|
+
let synIndex = 0;
|
|
7299
|
+
return [...acc.values()].map(
|
|
7300
|
+
(r) => toCached(
|
|
7301
|
+
r.hasRealId ? r : { ...r, key: `synthetic|${path}|${synIndex += 1}` }
|
|
7302
|
+
)
|
|
7303
|
+
);
|
|
7304
|
+
}
|
|
7194
7305
|
function* splitLines(content) {
|
|
7195
7306
|
let start = 0;
|
|
7196
7307
|
for (let i = 0; i < content.length; i++) {
|
|
@@ -7207,23 +7318,35 @@ async function collectClaudeNative(env = process.env, opts = {}) {
|
|
|
7207
7318
|
for (const dir of dirs) files.push(...await listJsonl(dir));
|
|
7208
7319
|
if (files.length === 0) return { entries: [], found: false, filesScanned: 0 };
|
|
7209
7320
|
const now = opts.now ?? Date.now;
|
|
7210
|
-
const
|
|
7321
|
+
const res = await readFilesWithCache({
|
|
7322
|
+
files,
|
|
7323
|
+
cachePath: opts.cachePath ?? nativeCachePath("claude", env),
|
|
7324
|
+
version: CLAUDE_CACHE_VERSION,
|
|
7325
|
+
parseFile: parseFileToCache,
|
|
7326
|
+
deadline: now() + (opts.budgetMs ?? NATIVE_READ_BUDGET_MS),
|
|
7327
|
+
now
|
|
7328
|
+
});
|
|
7329
|
+
if (!res.itemsByFile) {
|
|
7330
|
+
return {
|
|
7331
|
+
entries: [],
|
|
7332
|
+
found: false,
|
|
7333
|
+
filesScanned: res.filesRead,
|
|
7334
|
+
timedOut: true
|
|
7335
|
+
};
|
|
7336
|
+
}
|
|
7211
7337
|
const acc = /* @__PURE__ */ new Map();
|
|
7212
|
-
|
|
7213
|
-
|
|
7214
|
-
|
|
7215
|
-
|
|
7216
|
-
|
|
7217
|
-
let content;
|
|
7218
|
-
try {
|
|
7219
|
-
content = await readFile(f, "utf8");
|
|
7220
|
-
} catch {
|
|
7221
|
-
continue;
|
|
7338
|
+
for (const items of res.itemsByFile) {
|
|
7339
|
+
for (const t of items) {
|
|
7340
|
+
const r = fromCached(t);
|
|
7341
|
+
const prev = acc.get(r.key);
|
|
7342
|
+
if (!prev || reqTokens(r) > reqTokens(prev)) acc.set(r.key, r);
|
|
7222
7343
|
}
|
|
7223
|
-
accumulateClaudeLines(acc, splitLines(content));
|
|
7224
|
-
scanned += 1;
|
|
7225
7344
|
}
|
|
7226
|
-
return {
|
|
7345
|
+
return {
|
|
7346
|
+
entries: finalizeClaudeEntries(acc),
|
|
7347
|
+
found: true,
|
|
7348
|
+
filesScanned: res.filesRead
|
|
7349
|
+
};
|
|
7227
7350
|
}
|
|
7228
7351
|
async function collectClaudeRequests(env = process.env, opts = {}) {
|
|
7229
7352
|
const dirs = resolveClaudeProjectDirs(env);
|
|
@@ -7239,7 +7362,7 @@ async function collectClaudeRequests(env = process.env, opts = {}) {
|
|
|
7239
7362
|
}
|
|
7240
7363
|
let content;
|
|
7241
7364
|
try {
|
|
7242
|
-
content = await
|
|
7365
|
+
content = await readFile2(f, "utf8");
|
|
7243
7366
|
} catch {
|
|
7244
7367
|
continue;
|
|
7245
7368
|
}
|
|
@@ -7249,9 +7372,9 @@ async function collectClaudeRequests(env = process.env, opts = {}) {
|
|
|
7249
7372
|
}
|
|
7250
7373
|
|
|
7251
7374
|
// src/native/codex.ts
|
|
7252
|
-
import { readdir as readdir2
|
|
7375
|
+
import { readdir as readdir2 } from "node:fs/promises";
|
|
7253
7376
|
import { homedir as homedir6 } from "node:os";
|
|
7254
|
-
import { join as
|
|
7377
|
+
import { join as join8 } from "node:path";
|
|
7255
7378
|
function num4(n) {
|
|
7256
7379
|
const v = Math.round(Number(n));
|
|
7257
7380
|
return Number.isFinite(v) && v > 0 ? v : 0;
|
|
@@ -7340,8 +7463,8 @@ function parseCodexRollout(lines) {
|
|
|
7340
7463
|
}
|
|
7341
7464
|
return out;
|
|
7342
7465
|
}
|
|
7343
|
-
function
|
|
7344
|
-
for (const s of
|
|
7466
|
+
function foldCodexSessions(acc, sessions) {
|
|
7467
|
+
for (const s of sessions) {
|
|
7345
7468
|
const k = `${s.date}|${s.model}`;
|
|
7346
7469
|
let b = acc.get(k);
|
|
7347
7470
|
if (!b) {
|
|
@@ -7383,8 +7506,8 @@ function finalizeCodexEntries(acc) {
|
|
|
7383
7506
|
return entries;
|
|
7384
7507
|
}
|
|
7385
7508
|
function resolveCodexSessionsDir(env = process.env) {
|
|
7386
|
-
const home = env.CODEX_HOME && env.CODEX_HOME.trim() ? env.CODEX_HOME.trim() :
|
|
7387
|
-
return
|
|
7509
|
+
const home = env.CODEX_HOME && env.CODEX_HOME.trim() ? env.CODEX_HOME.trim() : join8(homedir6(), ".codex");
|
|
7510
|
+
return join8(home, "sessions");
|
|
7388
7511
|
}
|
|
7389
7512
|
async function listJsonl2(dir) {
|
|
7390
7513
|
let dirents;
|
|
@@ -7395,7 +7518,7 @@ async function listJsonl2(dir) {
|
|
|
7395
7518
|
}
|
|
7396
7519
|
const out = [];
|
|
7397
7520
|
for (const d of dirents) {
|
|
7398
|
-
const full =
|
|
7521
|
+
const full = join8(dir, d.name);
|
|
7399
7522
|
if (d.isDirectory()) out.push(...await listJsonl2(full));
|
|
7400
7523
|
else if (d.isFile() && d.name.endsWith(".jsonl")) out.push(full);
|
|
7401
7524
|
}
|
|
@@ -7411,38 +7534,69 @@ function* splitLines2(content) {
|
|
|
7411
7534
|
}
|
|
7412
7535
|
if (start < content.length) yield content.slice(start);
|
|
7413
7536
|
}
|
|
7414
|
-
var NATIVE_READ_BUDGET_MS2 =
|
|
7537
|
+
var NATIVE_READ_BUDGET_MS2 = 45e3;
|
|
7538
|
+
var CODEX_CACHE_VERSION = 1;
|
|
7539
|
+
function toCachedSession(s) {
|
|
7540
|
+
return [
|
|
7541
|
+
s.date,
|
|
7542
|
+
s.model,
|
|
7543
|
+
s.inputTokens,
|
|
7544
|
+
s.outputTokens,
|
|
7545
|
+
s.cacheCreationTokens,
|
|
7546
|
+
s.cacheReadTokens,
|
|
7547
|
+
s.turnCount
|
|
7548
|
+
];
|
|
7549
|
+
}
|
|
7550
|
+
function fromCachedSession(t) {
|
|
7551
|
+
return {
|
|
7552
|
+
date: t[0],
|
|
7553
|
+
model: t[1],
|
|
7554
|
+
inputTokens: t[2],
|
|
7555
|
+
outputTokens: t[3],
|
|
7556
|
+
cacheCreationTokens: t[4],
|
|
7557
|
+
cacheReadTokens: t[5],
|
|
7558
|
+
turnCount: t[6]
|
|
7559
|
+
};
|
|
7560
|
+
}
|
|
7415
7561
|
async function collectCodexNative(env = process.env, opts = {}) {
|
|
7416
7562
|
const dir = resolveCodexSessionsDir(env);
|
|
7417
7563
|
const files = await listJsonl2(dir);
|
|
7418
7564
|
if (files.length === 0) return { entries: [], found: false, filesScanned: 0 };
|
|
7419
7565
|
const now = opts.now ?? Date.now;
|
|
7420
|
-
const
|
|
7566
|
+
const res = await readFilesWithCache({
|
|
7567
|
+
files,
|
|
7568
|
+
cachePath: opts.cachePath ?? nativeCachePath("codex", env),
|
|
7569
|
+
version: CODEX_CACHE_VERSION,
|
|
7570
|
+
parseFile: (content) => parseCodexRollout(splitLines2(content)).map(toCachedSession),
|
|
7571
|
+
deadline: now() + (opts.budgetMs ?? NATIVE_READ_BUDGET_MS2),
|
|
7572
|
+
now
|
|
7573
|
+
});
|
|
7574
|
+
if (!res.itemsByFile) {
|
|
7575
|
+
return {
|
|
7576
|
+
entries: [],
|
|
7577
|
+
found: false,
|
|
7578
|
+
filesScanned: res.filesRead,
|
|
7579
|
+
timedOut: true
|
|
7580
|
+
};
|
|
7581
|
+
}
|
|
7421
7582
|
const acc = /* @__PURE__ */ new Map();
|
|
7422
|
-
|
|
7423
|
-
|
|
7424
|
-
if (now() > deadline) {
|
|
7425
|
-
return { entries: [], found: false, filesScanned: scanned, timedOut: true };
|
|
7426
|
-
}
|
|
7427
|
-
let content;
|
|
7428
|
-
try {
|
|
7429
|
-
content = await readFile2(f, "utf8");
|
|
7430
|
-
} catch {
|
|
7431
|
-
continue;
|
|
7432
|
-
}
|
|
7433
|
-
accumulateCodexSession(acc, splitLines2(content));
|
|
7434
|
-
scanned += 1;
|
|
7583
|
+
for (const items of res.itemsByFile) {
|
|
7584
|
+
foldCodexSessions(acc, items.map(fromCachedSession));
|
|
7435
7585
|
}
|
|
7436
|
-
return {
|
|
7586
|
+
return {
|
|
7587
|
+
entries: finalizeCodexEntries(acc),
|
|
7588
|
+
found: true,
|
|
7589
|
+
filesScanned: res.filesRead
|
|
7590
|
+
};
|
|
7437
7591
|
}
|
|
7438
7592
|
|
|
7439
7593
|
// src/pricing-live.ts
|
|
7440
7594
|
import { mkdir, readFile as readFile3, rename, writeFile } from "node:fs/promises";
|
|
7441
|
-
import { dirname as
|
|
7595
|
+
import { dirname as dirname4, join as join9 } from "node:path";
|
|
7442
7596
|
var CACHE_TTL_MS = 24 * 60 * 60 * 1e3;
|
|
7443
7597
|
var FETCH_TIMEOUT_MS = 5e3;
|
|
7444
7598
|
function pricingCachePath(dir = defaultConfigDir()) {
|
|
7445
|
-
return
|
|
7599
|
+
return join9(dir, "pricing-cache.json");
|
|
7446
7600
|
}
|
|
7447
7601
|
async function readCache(path) {
|
|
7448
7602
|
try {
|
|
@@ -7478,7 +7632,7 @@ async function loadLivePricing(env = process.env, now = Date.now, cachePath = pr
|
|
|
7478
7632
|
if (live) {
|
|
7479
7633
|
setLivePricing(live);
|
|
7480
7634
|
try {
|
|
7481
|
-
await mkdir(
|
|
7635
|
+
await mkdir(dirname4(path), { recursive: true });
|
|
7482
7636
|
const tmp = `${path}.${process.pid}.tmp`;
|
|
7483
7637
|
await writeFile(tmp, JSON.stringify({ fetchedAt: now(), table: live }));
|
|
7484
7638
|
await rename(tmp, path);
|
|
@@ -7633,7 +7787,7 @@ function resolveCcusageBin() {
|
|
|
7633
7787
|
const pkgPath = require3.resolve("ccusage/package.json");
|
|
7634
7788
|
const pkg = require3("ccusage/package.json");
|
|
7635
7789
|
const rel = typeof pkg.bin === "string" ? pkg.bin : pkg.bin?.ccusage ?? "ccusage";
|
|
7636
|
-
const binPath =
|
|
7790
|
+
const binPath = join10(dirname5(pkgPath), rel);
|
|
7637
7791
|
if (/\.(c|m)?js$/.test(binPath)) {
|
|
7638
7792
|
return { cmd: process.execPath, prefixArgs: [binPath] };
|
|
7639
7793
|
}
|
|
@@ -8221,9 +8375,9 @@ async function confirm(question) {
|
|
|
8221
8375
|
}
|
|
8222
8376
|
function showLocalDashboard(payload) {
|
|
8223
8377
|
const dir = defaultConfigDir();
|
|
8224
|
-
|
|
8225
|
-
const file =
|
|
8226
|
-
|
|
8378
|
+
mkdirSync4(dir, { recursive: true });
|
|
8379
|
+
const file = join11(dir, "dashboard.html");
|
|
8380
|
+
writeFileSync4(
|
|
8227
8381
|
file,
|
|
8228
8382
|
renderDashboardHtml(payload.entries, /* @__PURE__ */ new Date(), { webBaseUrl: webBase() })
|
|
8229
8383
|
);
|
|
@@ -8474,7 +8628,13 @@ async function submitSignedIn(token, payload, flags, interactive) {
|
|
|
8474
8628
|
afterSubmitChores(flags);
|
|
8475
8629
|
}
|
|
8476
8630
|
function afterSubmitChores(flags) {
|
|
8477
|
-
if (flags.quiet)
|
|
8631
|
+
if (flags.quiet) {
|
|
8632
|
+
try {
|
|
8633
|
+
if (autoSyncInstalled()) reconcileAutoSync();
|
|
8634
|
+
} catch {
|
|
8635
|
+
}
|
|
8636
|
+
return;
|
|
8637
|
+
}
|
|
8478
8638
|
try {
|
|
8479
8639
|
reconcileAutoSync();
|
|
8480
8640
|
} catch {
|
|
@@ -8562,6 +8722,11 @@ async function runDaemon() {
|
|
|
8562
8722
|
runOnce: async () => {
|
|
8563
8723
|
rotateLogIfLarge();
|
|
8564
8724
|
await run({ dryRun: false, noSubmit: false, local: false, quiet: true });
|
|
8725
|
+
if (!loadConfig()?.cliToken) {
|
|
8726
|
+
throw new Error(
|
|
8727
|
+
"not linked \u2014 nothing submitted (run `npx whoburnedmore link --token=\u2026` from your signed-in profile first)"
|
|
8728
|
+
);
|
|
8729
|
+
}
|
|
8565
8730
|
}
|
|
8566
8731
|
});
|
|
8567
8732
|
console.log();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "whoburnedmore",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.14",
|
|
4
4
|
"description": "Find out who burned more — submit your AI coding-agent token usage to the public leaderboard at whoburnedmore.com",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -38,11 +38,10 @@
|
|
|
38
38
|
"homepage": "https://whoburnedmore.com",
|
|
39
39
|
"repository": {
|
|
40
40
|
"type": "git",
|
|
41
|
-
"url": "git+https://github.com/
|
|
42
|
-
"directory": "packages/cli"
|
|
41
|
+
"url": "git+https://github.com/arhxam/whoburnedmore.git"
|
|
43
42
|
},
|
|
44
43
|
"bugs": {
|
|
45
|
-
"url": "https://github.com/
|
|
44
|
+
"url": "https://github.com/arhxam/whoburnedmore/issues"
|
|
46
45
|
},
|
|
47
46
|
"keywords": [
|
|
48
47
|
"ai",
|