linkshell-cli 0.5.15 → 0.5.17

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.
@@ -0,0 +1,34 @@
1
+ export interface UsageTotals {
2
+ inputTokens: number;
3
+ outputTokens: number;
4
+ cacheReadTokens: number;
5
+ cacheWriteTokens: number;
6
+ totalTokens: number;
7
+ calls: number;
8
+ }
9
+ export interface UsageBucket extends UsageTotals {
10
+ key: string;
11
+ }
12
+ export interface UsageReport {
13
+ totals: UsageTotals;
14
+ sessions: number;
15
+ /** Highest single-day token total. */
16
+ peakDayTokens: number;
17
+ /** Longest single session span (first→last activity), milliseconds. */
18
+ longestTaskMs: number;
19
+ /** Consecutive active days ending at the most recent active day. */
20
+ currentStreakDays: number;
21
+ /** Longest run of consecutive active days ever. */
22
+ longestStreakDays: number;
23
+ byDay: UsageBucket[];
24
+ byHourWeekday: {
25
+ weekday: number;
26
+ hour: number;
27
+ tokens: number;
28
+ }[];
29
+ byTool: UsageBucket[];
30
+ byModel: UsageBucket[];
31
+ byProject: UsageBucket[];
32
+ generatedAt: number;
33
+ }
34
+ export declare function aggregateUsage(): UsageReport;
@@ -0,0 +1,332 @@
1
+ // Host-side usage aggregator. Scans local agent transcripts on disk and rolls
2
+ // them up into the dimensions a usage dashboard needs (cumulative total, peak
3
+ // day, activity heatmap by day, streaks, longest task). Fully DECOUPLED from any
4
+ // live LinkShell turn — it reads what the agents already wrote to disk, so
5
+ // history and externally-started sessions (any process, not just LinkShell) are
6
+ // all counted, the same way ccusage / vibe-usage / CodeIsland work.
7
+ //
8
+ // Counting convention (matches ccusage): sum usage PER API CALL — context is
9
+ // re-counted every turn, which is why totals reach billions. This is the usage
10
+ // view, the opposite of the single-snapshot "current context occupancy" meter.
11
+ import { readdirSync, readFileSync, statSync, existsSync } from "node:fs";
12
+ import { homedir } from "node:os";
13
+ import { join, basename } from "node:path";
14
+ function emptyTotals() {
15
+ return {
16
+ inputTokens: 0,
17
+ outputTokens: 0,
18
+ cacheReadTokens: 0,
19
+ cacheWriteTokens: 0,
20
+ totalTokens: 0,
21
+ calls: 0,
22
+ };
23
+ }
24
+ function dayKeyOf(ts) {
25
+ const d = new Date(ts);
26
+ return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, "0")}-${String(d.getDate()).padStart(2, "0")}`;
27
+ }
28
+ class Accumulator {
29
+ totals = emptyTotals();
30
+ day = new Map();
31
+ hw = new Map(); // "weekday:hour" → tokens
32
+ tool = new Map();
33
+ model = new Map();
34
+ project = new Map();
35
+ // Per-session activity timestamps, for longest-continuous-task duration.
36
+ sessionTimes = new Map();
37
+ bump(map, key, s, tokens) {
38
+ let t = map.get(key);
39
+ if (!t) {
40
+ t = emptyTotals();
41
+ map.set(key, t);
42
+ }
43
+ t.inputTokens += s.input;
44
+ t.outputTokens += s.output;
45
+ t.cacheReadTokens += s.cacheRead;
46
+ t.cacheWriteTokens += s.cacheWrite;
47
+ t.totalTokens += tokens;
48
+ t.calls += 1;
49
+ }
50
+ add(s) {
51
+ const tokens = s.input + s.output + s.cacheRead + s.cacheWrite;
52
+ if (tokens <= 0)
53
+ return;
54
+ this.totals.inputTokens += s.input;
55
+ this.totals.outputTokens += s.output;
56
+ this.totals.cacheReadTokens += s.cacheRead;
57
+ this.totals.cacheWriteTokens += s.cacheWrite;
58
+ this.totals.totalTokens += tokens;
59
+ this.totals.calls += 1;
60
+ this.bump(this.day, dayKeyOf(s.ts), s, tokens);
61
+ const d = new Date(s.ts);
62
+ const hwKey = `${d.getDay()}:${d.getHours()}`;
63
+ this.hw.set(hwKey, (this.hw.get(hwKey) ?? 0) + tokens);
64
+ this.bump(this.tool, s.tool, s, tokens);
65
+ this.bump(this.model, s.model || "(unknown)", s, tokens);
66
+ this.bump(this.project, s.project || "(unknown)", s, tokens);
67
+ const times = this.sessionTimes.get(s.sessionId);
68
+ if (!times)
69
+ this.sessionTimes.set(s.sessionId, [s.ts]);
70
+ else
71
+ times.push(s.ts);
72
+ }
73
+ toBuckets(map) {
74
+ return [...map.entries()]
75
+ .map(([key, t]) => ({ key, ...t }))
76
+ .sort((a, b) => b.totalTokens - a.totalTokens);
77
+ }
78
+ finish(sessions, generatedAt) {
79
+ const byDay = [...this.day.entries()]
80
+ .map(([key, t]) => ({ key, ...t }))
81
+ .sort((a, b) => a.key.localeCompare(b.key));
82
+ const peakDayTokens = byDay.reduce((m, d) => Math.max(m, d.totalTokens), 0);
83
+ // Longest CONTINUOUS work segment across all sessions. A Claude session
84
+ // file can be resumed days later, so first→last would absurdly count idle
85
+ // days. Instead, sort each session's call timestamps and split whenever the
86
+ // gap exceeds IDLE_SPLIT_MS; the longest unbroken segment is the task length.
87
+ const IDLE_SPLIT_MS = 30 * 60_000;
88
+ let longestTaskMs = 0;
89
+ for (const times of this.sessionTimes.values()) {
90
+ if (times.length === 0)
91
+ continue;
92
+ times.sort((a, b) => a - b);
93
+ let segStart = times[0];
94
+ let prev = times[0];
95
+ for (let i = 1; i < times.length; i++) {
96
+ const cur = times[i];
97
+ if (cur - prev > IDLE_SPLIT_MS) {
98
+ longestTaskMs = Math.max(longestTaskMs, prev - segStart);
99
+ segStart = cur;
100
+ }
101
+ prev = cur;
102
+ }
103
+ longestTaskMs = Math.max(longestTaskMs, prev - segStart);
104
+ }
105
+ const { currentStreakDays, longestStreakDays } = computeStreaks(byDay.map((d) => d.key), generatedAt);
106
+ const byHourWeekday = [...this.hw.entries()].map(([k, tokens]) => {
107
+ const parts = k.split(":");
108
+ return { weekday: Number(parts[0]), hour: Number(parts[1]), tokens };
109
+ });
110
+ return {
111
+ totals: this.totals,
112
+ sessions,
113
+ peakDayTokens,
114
+ longestTaskMs,
115
+ currentStreakDays,
116
+ longestStreakDays,
117
+ byDay,
118
+ byHourWeekday,
119
+ byTool: this.toBuckets(this.tool),
120
+ byModel: this.toBuckets(this.model),
121
+ byProject: this.toBuckets(this.project),
122
+ generatedAt,
123
+ };
124
+ }
125
+ }
126
+ // Streaks over a sorted set of active day-keys (YYYY-MM-DD). Current streak
127
+ // counts back from today (or yesterday — a gap of "today not yet active" still
128
+ // keeps an unbroken run alive). Uses UTC-noon to step days, dodging DST edges.
129
+ function computeStreaks(dayKeys, now) {
130
+ if (dayKeys.length === 0)
131
+ return { currentStreakDays: 0, longestStreakDays: 0 };
132
+ const set = new Set(dayKeys);
133
+ const dayMs = 86_400_000;
134
+ const toKey = (ms) => dayKeyOf(ms);
135
+ // Longest run.
136
+ let longest = 1;
137
+ let run = 1;
138
+ const sorted = [...dayKeys].sort();
139
+ for (let i = 1; i < sorted.length; i++) {
140
+ const prev = new Date(sorted[i - 1] + "T12:00:00").getTime();
141
+ const cur = new Date(sorted[i] + "T12:00:00").getTime();
142
+ const gapDays = Math.round((cur - prev) / dayMs);
143
+ if (gapDays === 1)
144
+ run += 1;
145
+ else
146
+ run = 1;
147
+ longest = Math.max(longest, run);
148
+ }
149
+ // Current run: walk backwards from today; if today isn't active, allow
150
+ // starting from yesterday (today simply hasn't happened yet).
151
+ let cursor = new Date(toKey(now) + "T12:00:00").getTime();
152
+ if (!set.has(toKey(cursor)))
153
+ cursor -= dayMs; // today inactive → start at yesterday
154
+ let current = 0;
155
+ while (set.has(toKey(cursor))) {
156
+ current += 1;
157
+ cursor -= dayMs;
158
+ }
159
+ return { currentStreakDays: current, longestStreakDays: longest };
160
+ }
161
+ function parseTs(value) {
162
+ if (typeof value === "number" && Number.isFinite(value)) {
163
+ return value > 10_000_000_000 ? value : value * 1000;
164
+ }
165
+ if (typeof value === "string" && value.trim()) {
166
+ const p = Date.parse(value);
167
+ return Number.isNaN(p) ? undefined : p;
168
+ }
169
+ return undefined;
170
+ }
171
+ function walkJsonl(dir, onFile) {
172
+ let entries;
173
+ try {
174
+ entries = readdirSync(dir);
175
+ }
176
+ catch {
177
+ return;
178
+ }
179
+ for (const entry of entries) {
180
+ const full = join(dir, entry);
181
+ let st;
182
+ try {
183
+ st = statSync(full);
184
+ }
185
+ catch {
186
+ continue;
187
+ }
188
+ if (st.isDirectory())
189
+ walkJsonl(full, onFile);
190
+ else if (entry.endsWith(".jsonl"))
191
+ onFile(full);
192
+ }
193
+ }
194
+ // Claude: ~/.claude/projects/**/*.jsonl — each assistant line carries
195
+ // message.usage. Skip <synthetic> (internal, no real usage).
196
+ function ingestClaude(acc) {
197
+ const root = join(homedir(), ".claude", "projects");
198
+ if (!existsSync(root))
199
+ return 0;
200
+ let sessions = 0;
201
+ walkJsonl(root, (path) => {
202
+ sessions += 1;
203
+ const sessionId = basename(path, ".jsonl");
204
+ let text;
205
+ try {
206
+ text = readFileSync(path, "utf8");
207
+ }
208
+ catch {
209
+ return;
210
+ }
211
+ let fileCwd = "";
212
+ for (const line of text.split(/\r?\n/)) {
213
+ if (!line.trim())
214
+ continue;
215
+ let o;
216
+ try {
217
+ o = JSON.parse(line);
218
+ }
219
+ catch {
220
+ continue;
221
+ }
222
+ if (typeof o?.cwd === "string" && !fileCwd)
223
+ fileCwd = o.cwd;
224
+ if (o?.type !== "assistant")
225
+ continue;
226
+ const msg = o.message;
227
+ const usage = msg?.usage;
228
+ const model = typeof msg?.model === "string" ? msg.model : "";
229
+ if (!usage || model === "<synthetic>" || !model)
230
+ continue;
231
+ const ts = parseTs(o.timestamp);
232
+ if (ts === undefined)
233
+ continue;
234
+ acc.add({
235
+ ts,
236
+ sessionId,
237
+ tool: "claude-code",
238
+ model,
239
+ project: basename(o.cwd || fileCwd || "(unknown)"),
240
+ input: usage.input_tokens || 0,
241
+ output: usage.output_tokens || 0,
242
+ cacheRead: usage.cache_read_input_tokens || 0,
243
+ cacheWrite: usage.cache_creation_input_tokens || 0,
244
+ });
245
+ }
246
+ });
247
+ return sessions;
248
+ }
249
+ // Codex: ~/.codex/sessions/**/rollout-*.jsonl — token_count events carry
250
+ // info.last_token_usage (per-turn delta; total_token_usage is cumulative and
251
+ // would double-count). cached_input_tokens is a subset of input_tokens.
252
+ function ingestCodex(acc) {
253
+ const root = join(homedir(), ".codex", "sessions");
254
+ if (!existsSync(root))
255
+ return 0;
256
+ let sessions = 0;
257
+ walkJsonl(root, (path) => {
258
+ if (!basename(path).startsWith("rollout-"))
259
+ return;
260
+ sessions += 1;
261
+ const sessionId = basename(path, ".jsonl");
262
+ let text;
263
+ try {
264
+ text = readFileSync(path, "utf8");
265
+ }
266
+ catch {
267
+ return;
268
+ }
269
+ let model = "";
270
+ let cwd = "";
271
+ for (const line of text.split(/\r?\n/)) {
272
+ if (!line.trim())
273
+ continue;
274
+ let o;
275
+ try {
276
+ o = JSON.parse(line);
277
+ }
278
+ catch {
279
+ continue;
280
+ }
281
+ const p = o?.payload ?? {};
282
+ const type = p.type ?? o?.type;
283
+ if (type === "session_meta") {
284
+ if (typeof p.cwd === "string")
285
+ cwd = p.cwd;
286
+ if (typeof p.model === "string")
287
+ model = p.model;
288
+ continue;
289
+ }
290
+ if (type === "turn_context") {
291
+ if (typeof p.model === "string")
292
+ model = p.model;
293
+ continue;
294
+ }
295
+ if (type !== "token_count")
296
+ continue;
297
+ const last = p.info?.last_token_usage;
298
+ if (!last)
299
+ continue;
300
+ const ts = parseTs(o.timestamp);
301
+ if (ts === undefined)
302
+ continue;
303
+ const cacheRead = last.cached_input_tokens || 0;
304
+ const rawInput = last.input_tokens || 0;
305
+ acc.add({
306
+ ts,
307
+ sessionId,
308
+ tool: "codex",
309
+ model: model || "gpt-5",
310
+ project: basename(cwd || "(unknown)"),
311
+ input: Math.max(0, rawInput - cacheRead),
312
+ output: (last.output_tokens || 0) + (last.reasoning_output_tokens || 0),
313
+ cacheRead,
314
+ cacheWrite: 0,
315
+ });
316
+ }
317
+ });
318
+ return sessions;
319
+ }
320
+ let _cachedReport = null;
321
+ let _cachedAt = 0;
322
+ export function aggregateUsage() {
323
+ const now = Date.now();
324
+ if (_cachedReport && now - _cachedAt < 60_000)
325
+ return _cachedReport;
326
+ const acc = new Accumulator();
327
+ const sessions = ingestClaude(acc) + ingestCodex(acc);
328
+ _cachedReport = acc.finish(sessions, now);
329
+ _cachedAt = now;
330
+ return _cachedReport;
331
+ }
332
+ //# sourceMappingURL=usage-report.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"usage-report.js","sourceRoot":"","sources":["../../../../src/runtime/usage-report.ts"],"names":[],"mappings":"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"}