@tokz/cli 0.2.1 → 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.
|
@@ -16,7 +16,7 @@ import {
|
|
|
16
16
|
sanitizeProjectPath,
|
|
17
17
|
shortModel,
|
|
18
18
|
usd
|
|
19
|
-
} from "./chunk-
|
|
19
|
+
} from "./chunk-JAZOB7NC.js";
|
|
20
20
|
|
|
21
21
|
// src/ui/Root.tsx
|
|
22
22
|
import { useEffect as useEffect2, useState as useState6 } from "react";
|
|
@@ -147,7 +147,7 @@ async function loadProjects(home = homedir(), onProgress) {
|
|
|
147
147
|
byDir.set(dir, list);
|
|
148
148
|
}
|
|
149
149
|
const realMap = await realPathsBySanitized(home);
|
|
150
|
-
const seenMessageIds = /* @__PURE__ */ new
|
|
150
|
+
const seenMessageIds = /* @__PURE__ */ new Map();
|
|
151
151
|
const seenToolIds = /* @__PURE__ */ new Set();
|
|
152
152
|
let parsed = 0;
|
|
153
153
|
const out = [];
|
|
@@ -7,7 +7,8 @@ var PRICES = {
|
|
|
7
7
|
"claude-opus-4-8": { inputPerMTok: 5, outputPerMTok: 25 },
|
|
8
8
|
"claude-opus-4-7": { inputPerMTok: 5, outputPerMTok: 25 },
|
|
9
9
|
"claude-opus-4-6": { inputPerMTok: 5, outputPerMTok: 25 },
|
|
10
|
-
|
|
10
|
+
// introductory pricing ($2/$10) through 2026-08-31; sticker is $3/$15 after
|
|
11
|
+
"claude-sonnet-5": { inputPerMTok: 2, outputPerMTok: 10 },
|
|
11
12
|
"claude-sonnet-4-6": { inputPerMTok: 3, outputPerMTok: 15 },
|
|
12
13
|
"claude-haiku-4-5": { inputPerMTok: 1, outputPerMTok: 5 },
|
|
13
14
|
// OpenAI (no cache-write charge; cached input 0.1x)
|
|
@@ -43,13 +44,16 @@ function resolvePrice(modelId) {
|
|
|
43
44
|
function emptyUsage() {
|
|
44
45
|
return { inputTokens: 0, cacheReadTokens: 0, cacheCreationTokens: 0, outputTokens: 0, turns: 0 };
|
|
45
46
|
}
|
|
47
|
+
var CACHE_WRITE_1H_MULT = 2;
|
|
46
48
|
function costUsd(usage, modelId) {
|
|
47
49
|
const p = resolvePrice(modelId);
|
|
48
50
|
const readMult = p.cacheReadMult ?? DEFAULT_CACHE_READ_MULT;
|
|
49
51
|
const writeMult = p.cacheWriteMult ?? DEFAULT_CACHE_WRITE_MULT;
|
|
50
52
|
const input = usage.inputTokens / 1e6 * p.inputPerMTok;
|
|
51
53
|
const cacheRead = usage.cacheReadTokens / 1e6 * p.inputPerMTok * readMult;
|
|
52
|
-
const
|
|
54
|
+
const write1h = Math.min(usage.cacheCreation1hTokens ?? 0, usage.cacheCreationTokens);
|
|
55
|
+
const write5m = usage.cacheCreationTokens - write1h;
|
|
56
|
+
const cacheWrite = write5m / 1e6 * p.inputPerMTok * writeMult + write1h / 1e6 * p.inputPerMTok * (p.cacheWriteMult ?? CACHE_WRITE_1H_MULT);
|
|
53
57
|
const output = usage.outputTokens / 1e6 * p.outputPerMTok;
|
|
54
58
|
return { input, cacheRead, cacheWrite, output, total: input + cacheRead + cacheWrite + output };
|
|
55
59
|
}
|
|
@@ -60,6 +64,7 @@ function addUsage(acc, u) {
|
|
|
60
64
|
acc.inputTokens += u.inputTokens;
|
|
61
65
|
acc.cacheReadTokens += u.cacheReadTokens;
|
|
62
66
|
acc.cacheCreationTokens += u.cacheCreationTokens;
|
|
67
|
+
acc.cacheCreation1hTokens = (acc.cacheCreation1hTokens ?? 0) + (u.cacheCreation1hTokens ?? 0);
|
|
63
68
|
acc.outputTokens += u.outputTokens;
|
|
64
69
|
acc.turns += u.turns;
|
|
65
70
|
}
|
|
@@ -279,12 +284,16 @@ var AssistantLine = z.object({
|
|
|
279
284
|
input_tokens: z.number().catch(0).default(0),
|
|
280
285
|
cache_creation_input_tokens: z.number().catch(0).default(0),
|
|
281
286
|
cache_read_input_tokens: z.number().catch(0).default(0),
|
|
282
|
-
output_tokens: z.number().catch(0).default(0)
|
|
287
|
+
output_tokens: z.number().catch(0).default(0),
|
|
288
|
+
cache_creation: z.object({
|
|
289
|
+
ephemeral_5m_input_tokens: z.number().catch(0).default(0),
|
|
290
|
+
ephemeral_1h_input_tokens: z.number().catch(0).default(0)
|
|
291
|
+
}).nullish()
|
|
283
292
|
}).optional(),
|
|
284
293
|
content: z.array(z.object({ type: z.string(), id: z.string().optional(), name: z.string().optional() }).passthrough()).optional()
|
|
285
294
|
})
|
|
286
295
|
});
|
|
287
|
-
async function parseTranscript(file,
|
|
296
|
+
async function parseTranscript(file, seenMessages = /* @__PURE__ */ new Map(), seenToolIds = /* @__PURE__ */ new Set()) {
|
|
288
297
|
const stats = { file, usageByModel: {}, toolCalls: {}, toolCostUsd: {}, dailyUsage: {} };
|
|
289
298
|
const rl = createInterface({ input: createReadStream(file, "utf8"), crlfDelay: Infinity });
|
|
290
299
|
for await (const line of rl) {
|
|
@@ -304,32 +313,51 @@ async function parseTranscript(file, seenMessageIds = /* @__PURE__ */ new Set(),
|
|
|
304
313
|
stats.lastTs = timestamp;
|
|
305
314
|
}
|
|
306
315
|
const model = message.model ?? "unknown";
|
|
307
|
-
const firstSeen = !message.id || !seenMessageIds.has(message.id);
|
|
308
|
-
if (message.id) seenMessageIds.add(message.id);
|
|
309
316
|
let turnCost = 0;
|
|
310
|
-
if (message.usage &&
|
|
311
|
-
const
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
317
|
+
if (message.usage && model !== "<synthetic>") {
|
|
318
|
+
const u = message.usage;
|
|
319
|
+
const cur = {
|
|
320
|
+
input: u.input_tokens,
|
|
321
|
+
cacheRead: u.cache_read_input_tokens,
|
|
322
|
+
cacheWrite: u.cache_creation_input_tokens,
|
|
323
|
+
cacheWrite1h: u.cache_creation?.ephemeral_1h_input_tokens ?? 0,
|
|
324
|
+
output: u.output_tokens
|
|
325
|
+
};
|
|
326
|
+
const prev = message.id ? seenMessages.get(message.id) : void 0;
|
|
327
|
+
const delta = {
|
|
328
|
+
inputTokens: Math.max(0, cur.input - (prev?.input ?? 0)),
|
|
329
|
+
cacheReadTokens: Math.max(0, cur.cacheRead - (prev?.cacheRead ?? 0)),
|
|
330
|
+
cacheCreationTokens: Math.max(0, cur.cacheWrite - (prev?.cacheWrite ?? 0)),
|
|
331
|
+
cacheCreation1hTokens: Math.max(0, cur.cacheWrite1h - (prev?.cacheWrite1h ?? 0)),
|
|
332
|
+
outputTokens: Math.max(0, cur.output - (prev?.output ?? 0)),
|
|
333
|
+
turns: prev ? 0 : 1
|
|
334
|
+
};
|
|
335
|
+
if (message.id) {
|
|
336
|
+
seenMessages.set(message.id, {
|
|
337
|
+
input: Math.max(cur.input, prev?.input ?? 0),
|
|
338
|
+
cacheRead: Math.max(cur.cacheRead, prev?.cacheRead ?? 0),
|
|
339
|
+
cacheWrite: Math.max(cur.cacheWrite, prev?.cacheWrite ?? 0),
|
|
340
|
+
cacheWrite1h: Math.max(cur.cacheWrite1h, prev?.cacheWrite1h ?? 0),
|
|
341
|
+
output: Math.max(cur.output, prev?.output ?? 0)
|
|
342
|
+
});
|
|
315
343
|
}
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
344
|
+
const hasDelta = delta.inputTokens + delta.cacheReadTokens + delta.cacheCreationTokens + delta.outputTokens > 0 || delta.turns > 0;
|
|
345
|
+
if (hasDelta) {
|
|
346
|
+
const accs = [stats.usageByModel[model] ??= emptyUsage()];
|
|
347
|
+
if (timestamp) {
|
|
348
|
+
const day = stats.dailyUsage[timestamp.slice(0, 10)] ??= {};
|
|
349
|
+
accs.push(day[model] ??= emptyUsage());
|
|
350
|
+
}
|
|
351
|
+
for (const acc of accs) {
|
|
352
|
+
acc.inputTokens += delta.inputTokens;
|
|
353
|
+
acc.cacheReadTokens += delta.cacheReadTokens;
|
|
354
|
+
acc.cacheCreationTokens += delta.cacheCreationTokens;
|
|
355
|
+
acc.cacheCreation1hTokens = (acc.cacheCreation1hTokens ?? 0) + (delta.cacheCreation1hTokens ?? 0);
|
|
356
|
+
acc.outputTokens += delta.outputTokens;
|
|
357
|
+
acc.turns += delta.turns;
|
|
358
|
+
}
|
|
359
|
+
turnCost = costUsd(delta, model).total;
|
|
322
360
|
}
|
|
323
|
-
turnCost = costUsd(
|
|
324
|
-
{
|
|
325
|
-
inputTokens: message.usage.input_tokens,
|
|
326
|
-
cacheCreationTokens: message.usage.cache_creation_input_tokens,
|
|
327
|
-
cacheReadTokens: message.usage.cache_read_input_tokens,
|
|
328
|
-
outputTokens: message.usage.output_tokens,
|
|
329
|
-
turns: 1
|
|
330
|
-
},
|
|
331
|
-
model
|
|
332
|
-
).total;
|
|
333
361
|
}
|
|
334
362
|
const turnTools = [];
|
|
335
363
|
for (const block of message.content ?? []) {
|
package/dist/cli.js
CHANGED
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
pct1,
|
|
8
8
|
tok,
|
|
9
9
|
usd
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-JAZOB7NC.js";
|
|
11
11
|
|
|
12
12
|
// src/cli.ts
|
|
13
13
|
import { createRequire } from "module";
|
|
@@ -71,7 +71,7 @@ program.command("audit").argument("[project]", "project path (default: current d
|
|
|
71
71
|
process.exitCode = 1;
|
|
72
72
|
return;
|
|
73
73
|
}
|
|
74
|
-
const seenMessageIds = /* @__PURE__ */ new
|
|
74
|
+
const seenMessageIds = /* @__PURE__ */ new Map();
|
|
75
75
|
const seenToolIds = /* @__PURE__ */ new Set();
|
|
76
76
|
const sessions = await Promise.all(
|
|
77
77
|
transcripts.map((f) => parseTranscript(f, seenMessageIds, seenToolIds))
|
|
@@ -91,7 +91,7 @@ program.action(async () => {
|
|
|
91
91
|
process.exitCode = 1;
|
|
92
92
|
return;
|
|
93
93
|
}
|
|
94
|
-
const seenMessageIds = /* @__PURE__ */ new
|
|
94
|
+
const seenMessageIds = /* @__PURE__ */ new Map();
|
|
95
95
|
const seenToolIds = /* @__PURE__ */ new Set();
|
|
96
96
|
const sessions = await Promise.all(
|
|
97
97
|
transcripts.map((f) => parseTranscript(f, seenMessageIds, seenToolIds))
|
|
@@ -102,7 +102,7 @@ program.action(async () => {
|
|
|
102
102
|
const [{ render }, React, { Root }, { Fullscreen }] = await Promise.all([
|
|
103
103
|
import("ink"),
|
|
104
104
|
import("react"),
|
|
105
|
-
import("./Root-
|
|
105
|
+
import("./Root-6SZ5FQDN.js"),
|
|
106
106
|
import("./Fullscreen-GK2ZYXHV.js")
|
|
107
107
|
]);
|
|
108
108
|
render(React.createElement(Fullscreen, null, React.createElement(Root)));
|