@tokscale/cli 1.0.17 → 1.0.18

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.
Files changed (108) hide show
  1. package/dist/cli.js +214 -91
  2. package/dist/cli.js.map +1 -1
  3. package/dist/graph-types.d.ts +1 -1
  4. package/dist/graph-types.d.ts.map +1 -1
  5. package/dist/native-runner.js +5 -5
  6. package/dist/native-runner.js.map +1 -1
  7. package/dist/native.d.ts +9 -30
  8. package/dist/native.d.ts.map +1 -1
  9. package/dist/native.js +18 -134
  10. package/dist/native.js.map +1 -1
  11. package/dist/sessions/types.d.ts +1 -1
  12. package/dist/sessions/types.d.ts.map +1 -1
  13. package/dist/submit.d.ts +2 -0
  14. package/dist/submit.d.ts.map +1 -1
  15. package/dist/submit.js +32 -16
  16. package/dist/submit.js.map +1 -1
  17. package/dist/tui/App.d.ts.map +1 -1
  18. package/dist/tui/App.js +13 -6
  19. package/dist/tui/App.js.map +1 -1
  20. package/dist/tui/components/DailyView.d.ts.map +1 -1
  21. package/dist/tui/components/DailyView.js +25 -8
  22. package/dist/tui/components/DailyView.js.map +1 -1
  23. package/dist/tui/components/DateBreakdownPanel.js +2 -2
  24. package/dist/tui/components/DateBreakdownPanel.js.map +1 -1
  25. package/dist/tui/components/Footer.d.ts.map +1 -1
  26. package/dist/tui/components/Footer.js +2 -3
  27. package/dist/tui/components/Footer.js.map +1 -1
  28. package/dist/tui/components/LoadingSpinner.d.ts.map +1 -1
  29. package/dist/tui/components/LoadingSpinner.js +1 -2
  30. package/dist/tui/components/LoadingSpinner.js.map +1 -1
  31. package/dist/tui/components/ModelView.js +2 -2
  32. package/dist/tui/components/ModelView.js.map +1 -1
  33. package/dist/tui/config/settings.d.ts +4 -4
  34. package/dist/tui/config/settings.d.ts.map +1 -1
  35. package/dist/tui/config/settings.js +11 -4
  36. package/dist/tui/config/settings.js.map +1 -1
  37. package/dist/tui/hooks/useData.d.ts.map +1 -1
  38. package/dist/tui/hooks/useData.js +29 -42
  39. package/dist/tui/hooks/useData.js.map +1 -1
  40. package/dist/tui/types/index.d.ts +2 -2
  41. package/dist/tui/types/index.d.ts.map +1 -1
  42. package/dist/tui/types/index.js +3 -1
  43. package/dist/tui/types/index.js.map +1 -1
  44. package/dist/tui/utils/colors.d.ts +1 -0
  45. package/dist/tui/utils/colors.d.ts.map +1 -1
  46. package/dist/tui/utils/colors.js +7 -0
  47. package/dist/tui/utils/colors.js.map +1 -1
  48. package/dist/wrapped.d.ts.map +1 -1
  49. package/dist/wrapped.js +20 -48
  50. package/dist/wrapped.js.map +1 -1
  51. package/package.json +2 -2
  52. package/src/cli.ts +232 -97
  53. package/src/graph-types.ts +1 -1
  54. package/src/native-runner.ts +5 -5
  55. package/src/native.ts +35 -200
  56. package/src/sessions/types.ts +1 -1
  57. package/src/submit.ts +36 -22
  58. package/src/tui/App.tsx +9 -6
  59. package/src/tui/components/DailyView.tsx +29 -11
  60. package/src/tui/components/DateBreakdownPanel.tsx +2 -2
  61. package/src/tui/components/Footer.tsx +7 -2
  62. package/src/tui/components/LoadingSpinner.tsx +1 -2
  63. package/src/tui/components/ModelView.tsx +2 -2
  64. package/src/tui/config/settings.ts +18 -9
  65. package/src/tui/hooks/useData.ts +36 -47
  66. package/src/tui/types/index.ts +5 -4
  67. package/src/tui/utils/colors.ts +7 -0
  68. package/src/wrapped.ts +21 -54
  69. package/dist/graph.d.ts +0 -29
  70. package/dist/graph.d.ts.map +0 -1
  71. package/dist/graph.js +0 -383
  72. package/dist/graph.js.map +0 -1
  73. package/dist/pricing.d.ts +0 -58
  74. package/dist/pricing.d.ts.map +0 -1
  75. package/dist/pricing.js +0 -232
  76. package/dist/pricing.js.map +0 -1
  77. package/dist/sessions/claudecode.d.ts +0 -8
  78. package/dist/sessions/claudecode.d.ts.map +0 -1
  79. package/dist/sessions/claudecode.js +0 -84
  80. package/dist/sessions/claudecode.js.map +0 -1
  81. package/dist/sessions/codex.d.ts +0 -8
  82. package/dist/sessions/codex.d.ts.map +0 -1
  83. package/dist/sessions/codex.js +0 -158
  84. package/dist/sessions/codex.js.map +0 -1
  85. package/dist/sessions/gemini.d.ts +0 -8
  86. package/dist/sessions/gemini.d.ts.map +0 -1
  87. package/dist/sessions/gemini.js +0 -66
  88. package/dist/sessions/gemini.js.map +0 -1
  89. package/dist/sessions/index.d.ts +0 -32
  90. package/dist/sessions/index.d.ts.map +0 -1
  91. package/dist/sessions/index.js +0 -96
  92. package/dist/sessions/index.js.map +0 -1
  93. package/dist/sessions/opencode.d.ts +0 -9
  94. package/dist/sessions/opencode.d.ts.map +0 -1
  95. package/dist/sessions/opencode.js +0 -69
  96. package/dist/sessions/opencode.js.map +0 -1
  97. package/dist/sessions/reports.d.ts +0 -58
  98. package/dist/sessions/reports.d.ts.map +0 -1
  99. package/dist/sessions/reports.js +0 -337
  100. package/dist/sessions/reports.js.map +0 -1
  101. package/src/graph.ts +0 -485
  102. package/src/pricing.ts +0 -309
  103. package/src/sessions/claudecode.ts +0 -119
  104. package/src/sessions/codex.ts +0 -227
  105. package/src/sessions/gemini.ts +0 -108
  106. package/src/sessions/index.ts +0 -126
  107. package/src/sessions/opencode.ts +0 -117
  108. package/src/sessions/reports.ts +0 -475
package/dist/pricing.js DELETED
@@ -1,232 +0,0 @@
1
- /**
2
- * Pricing data fetcher using LiteLLM as source
3
- * Features disk caching with 1-hour TTL
4
- */
5
- import * as fs from "node:fs";
6
- import * as path from "node:path";
7
- import * as os from "node:os";
8
- function escapeRegex(str) {
9
- return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
10
- }
11
- export function normalizeModelName(modelId) {
12
- const lower = modelId.toLowerCase();
13
- if (lower.includes("opus")) {
14
- if (lower.includes("4.5") || lower.includes("4-5")) {
15
- return "opus-4-5";
16
- }
17
- else if (lower.includes("4")) {
18
- return "opus-4";
19
- }
20
- }
21
- if (lower.includes("sonnet")) {
22
- if (lower.includes("4.5") || lower.includes("4-5")) {
23
- return "sonnet-4-5";
24
- }
25
- else if (lower.includes("4")) {
26
- return "sonnet-4";
27
- }
28
- else if (lower.includes("3.7") || lower.includes("3-7")) {
29
- return "sonnet-3-7";
30
- }
31
- else if (lower.includes("3.5") || lower.includes("3-5")) {
32
- return "sonnet-3-5";
33
- }
34
- }
35
- if (lower.includes("haiku") && (lower.includes("4.5") || lower.includes("4-5"))) {
36
- return "haiku-4-5";
37
- }
38
- if (lower === "o3") {
39
- return "o3";
40
- }
41
- if (lower.startsWith("gpt-4o") || lower === "gpt-4o") {
42
- return "gpt-4o";
43
- }
44
- if (lower.startsWith("gpt-4.1") || lower.includes("gpt-4.1")) {
45
- return "gpt-4.1";
46
- }
47
- if (lower.includes("gemini-2.5-pro")) {
48
- return "gemini-2.5-pro";
49
- }
50
- if (lower.includes("gemini-2.5-flash")) {
51
- return "gemini-2.5-flash";
52
- }
53
- return null;
54
- }
55
- export function isWordBoundaryMatch(haystack, needle) {
56
- const pos = haystack.indexOf(needle);
57
- if (pos === -1)
58
- return false;
59
- const beforeOk = pos === 0 || !/[a-zA-Z0-9]/.test(haystack[pos - 1]);
60
- const afterOk = pos + needle.length === haystack.length ||
61
- !/[a-zA-Z0-9]/.test(haystack[pos + needle.length]);
62
- return beforeOk && afterOk;
63
- }
64
- const LITELLM_PRICING_URL = "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json";
65
- const CACHE_TTL_MS = 60 * 60 * 1000; // 1 hour
66
- function getCacheDir() {
67
- const cacheHome = process.env.XDG_CACHE_HOME || path.join(os.homedir(), ".cache");
68
- return path.join(cacheHome, "tokscale");
69
- }
70
- function getCachePath() {
71
- return path.join(getCacheDir(), "pricing.json");
72
- }
73
- function loadCachedPricing() {
74
- try {
75
- const cachePath = getCachePath();
76
- if (!fs.existsSync(cachePath)) {
77
- return null;
78
- }
79
- const content = fs.readFileSync(cachePath, "utf-8");
80
- const cached = JSON.parse(content);
81
- // Check TTL
82
- const age = Date.now() - cached.timestamp;
83
- if (age > CACHE_TTL_MS) {
84
- return null; // Cache expired
85
- }
86
- return cached;
87
- }
88
- catch {
89
- return null;
90
- }
91
- }
92
- function saveCachedPricing(data) {
93
- try {
94
- const cacheDir = getCacheDir();
95
- if (!fs.existsSync(cacheDir)) {
96
- fs.mkdirSync(cacheDir, { recursive: true });
97
- }
98
- const cached = {
99
- timestamp: Date.now(),
100
- data,
101
- };
102
- fs.writeFileSync(getCachePath(), JSON.stringify(cached), "utf-8");
103
- }
104
- catch {
105
- // Ignore cache write errors
106
- }
107
- }
108
- export class PricingFetcher {
109
- pricingData = null;
110
- /**
111
- * Fetch pricing data (with disk cache, 1-hour TTL)
112
- */
113
- async fetchPricing() {
114
- if (this.pricingData)
115
- return this.pricingData;
116
- // Try to load from cache first
117
- const cached = loadCachedPricing();
118
- if (cached) {
119
- this.pricingData = cached.data;
120
- return this.pricingData;
121
- }
122
- const controller = new AbortController();
123
- const timeoutId = setTimeout(() => controller.abort(), 15000);
124
- let response;
125
- try {
126
- response = await fetch(LITELLM_PRICING_URL, { signal: controller.signal });
127
- }
128
- finally {
129
- clearTimeout(timeoutId);
130
- }
131
- if (!response.ok) {
132
- throw new Error(`Failed to fetch pricing: ${response.status}`);
133
- }
134
- this.pricingData = (await response.json());
135
- // Save to cache
136
- saveCachedPricing(this.pricingData);
137
- return this.pricingData;
138
- }
139
- /**
140
- * Get raw pricing dataset
141
- */
142
- getPricingData() {
143
- return this.pricingData;
144
- }
145
- /**
146
- * Convert pricing data to format expected by Rust native module
147
- */
148
- toPricingEntries() {
149
- if (!this.pricingData)
150
- return [];
151
- return Object.entries(this.pricingData).map(([modelId, pricing]) => ({
152
- modelId,
153
- pricing: {
154
- inputCostPerToken: pricing.input_cost_per_token ?? 0,
155
- outputCostPerToken: pricing.output_cost_per_token ?? 0,
156
- // napi-rs expects undefined (not null) for Option<T> fields
157
- cacheReadInputTokenCost: pricing.cache_read_input_token_cost,
158
- cacheCreationInputTokenCost: pricing.cache_creation_input_token_cost,
159
- },
160
- }));
161
- }
162
- getModelPricing(modelID) {
163
- if (!this.pricingData)
164
- return null;
165
- // Direct lookup
166
- if (this.pricingData[modelID]) {
167
- return this.pricingData[modelID];
168
- }
169
- // Try with provider prefix
170
- const prefixes = ["anthropic/", "openai/", "google/", "bedrock/"];
171
- for (const prefix of prefixes) {
172
- if (this.pricingData[prefix + modelID]) {
173
- return this.pricingData[prefix + modelID];
174
- }
175
- }
176
- const normalized = normalizeModelName(modelID);
177
- if (normalized) {
178
- if (this.pricingData[normalized]) {
179
- return this.pricingData[normalized];
180
- }
181
- for (const prefix of prefixes) {
182
- if (this.pricingData[prefix + normalized]) {
183
- return this.pricingData[prefix + normalized];
184
- }
185
- }
186
- }
187
- const lowerModelID = modelID.toLowerCase();
188
- const lowerNormalized = normalized?.toLowerCase();
189
- const sortedKeys = Object.keys(this.pricingData).sort();
190
- for (const key of sortedKeys) {
191
- const lowerKey = key.toLowerCase();
192
- if (isWordBoundaryMatch(lowerKey, lowerModelID)) {
193
- return this.pricingData[key];
194
- }
195
- if (lowerNormalized && isWordBoundaryMatch(lowerKey, lowerNormalized)) {
196
- return this.pricingData[key];
197
- }
198
- }
199
- for (const key of sortedKeys) {
200
- const lowerKey = key.toLowerCase();
201
- if (isWordBoundaryMatch(lowerModelID, lowerKey)) {
202
- return this.pricingData[key];
203
- }
204
- if (lowerNormalized && isWordBoundaryMatch(lowerNormalized, lowerKey)) {
205
- return this.pricingData[key];
206
- }
207
- }
208
- return null;
209
- }
210
- calculateCost(tokens, pricing) {
211
- const inputCost = tokens.input * (pricing.input_cost_per_token ?? 0);
212
- const outputCost = (tokens.output + (tokens.reasoning ?? 0)) * (pricing.output_cost_per_token ?? 0);
213
- const cacheWriteCost = tokens.cacheWrite * (pricing.cache_creation_input_token_cost ?? 0);
214
- const cacheReadCost = tokens.cacheRead * (pricing.cache_read_input_token_cost ?? 0);
215
- return inputCost + outputCost + cacheWriteCost + cacheReadCost;
216
- }
217
- }
218
- /**
219
- * Clear pricing cache (for testing or forced refresh)
220
- */
221
- export function clearPricingCache() {
222
- try {
223
- const cachePath = getCachePath();
224
- if (fs.existsSync(cachePath)) {
225
- fs.unlinkSync(cachePath);
226
- }
227
- }
228
- catch {
229
- // Ignore errors
230
- }
231
- }
232
- //# sourceMappingURL=pricing.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"pricing.js","sourceRoot":"","sources":["../src/pricing.ts"],"names":[],"mappings":"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"}
@@ -1,8 +0,0 @@
1
- /**
2
- * Claude Code (Anthropic official) session parser
3
- * Reads from ~/.claude/projects/
4
- */
5
- import { type UnifiedMessage } from "./types.js";
6
- export declare function getClaudeCodeProjectsPath(): string;
7
- export declare function parseClaudeCodeMessages(): UnifiedMessage[];
8
- //# sourceMappingURL=claudecode.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"claudecode.d.ts","sourceRoot":"","sources":["../../src/sessions/claudecode.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,OAAO,EAAwB,KAAK,cAAc,EAAuB,MAAM,YAAY,CAAC;AAgB5F,wBAAgB,yBAAyB,IAAI,MAAM,CAElD;AAyBD,wBAAgB,uBAAuB,IAAI,cAAc,EAAE,CAmE1D"}
@@ -1,84 +0,0 @@
1
- /**
2
- * Claude Code (Anthropic official) session parser
3
- * Reads from ~/.claude/projects/
4
- */
5
- import * as fs from "node:fs";
6
- import * as path from "node:path";
7
- import * as os from "node:os";
8
- import { createUnifiedMessage } from "./types.js";
9
- export function getClaudeCodeProjectsPath() {
10
- return path.join(os.homedir(), ".claude", "projects");
11
- }
12
- function findJsonlFiles(dir) {
13
- const files = [];
14
- function walk(currentDir) {
15
- try {
16
- const entries = fs.readdirSync(currentDir, { withFileTypes: true });
17
- for (const entry of entries) {
18
- const fullPath = path.join(currentDir, entry.name);
19
- if (entry.isDirectory()) {
20
- walk(fullPath);
21
- }
22
- else if (entry.isFile() && entry.name.endsWith(".jsonl")) {
23
- files.push(fullPath);
24
- }
25
- }
26
- }
27
- catch {
28
- // Skip inaccessible directories
29
- }
30
- }
31
- walk(dir);
32
- return files;
33
- }
34
- export function parseClaudeCodeMessages() {
35
- const projectsPath = getClaudeCodeProjectsPath();
36
- if (!fs.existsSync(projectsPath)) {
37
- return [];
38
- }
39
- const messages = [];
40
- const files = findJsonlFiles(projectsPath);
41
- for (const file of files) {
42
- // Use file path as session ID
43
- const sessionId = path.relative(projectsPath, file).replace(/\.jsonl$/, "");
44
- try {
45
- const content = fs.readFileSync(file, "utf-8");
46
- const lines = content.split(/\r?\n/);
47
- for (const line of lines) {
48
- const trimmed = line.trim();
49
- if (!trimmed)
50
- continue;
51
- try {
52
- const entry = JSON.parse(trimmed);
53
- // Process assistant messages with usage data and timestamp
54
- if (entry.type === "assistant" &&
55
- entry.message?.usage &&
56
- entry.timestamp) {
57
- const model = entry.message.model || "unknown";
58
- const usage = entry.message.usage;
59
- const timestamp = new Date(entry.timestamp).getTime();
60
- // Skip invalid timestamps
61
- if (isNaN(timestamp))
62
- continue;
63
- const tokens = {
64
- input: usage.input_tokens || 0,
65
- output: usage.output_tokens || 0,
66
- cacheRead: usage.cache_read_input_tokens || 0,
67
- cacheWrite: usage.cache_creation_input_tokens || 0,
68
- reasoning: 0,
69
- };
70
- messages.push(createUnifiedMessage("claude", model, "anthropic", sessionId, timestamp, tokens));
71
- }
72
- }
73
- catch {
74
- // Skip malformed lines
75
- }
76
- }
77
- }
78
- catch {
79
- // Skip unreadable files
80
- }
81
- }
82
- return messages;
83
- }
84
- //# sourceMappingURL=claudecode.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"claudecode.js","sourceRoot":"","sources":["../../src/sessions/claudecode.ts"],"names":[],"mappings":"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"}
@@ -1,8 +0,0 @@
1
- /**
2
- * Codex CLI (OpenAI) session parser
3
- * Reads from ~/.codex/sessions/
4
- */
5
- import { type UnifiedMessage } from "./types.js";
6
- export declare function getCodexSessionsPath(): string;
7
- export declare function parseCodexMessages(): UnifiedMessage[];
8
- //# sourceMappingURL=codex.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"codex.d.ts","sourceRoot":"","sources":["../../src/sessions/codex.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,OAAO,EAAwB,KAAK,cAAc,EAAuB,MAAM,YAAY,CAAC;AAmC5F,wBAAgB,oBAAoB,IAAI,MAAM,CAG7C;AAkDD,wBAAgB,kBAAkB,IAAI,cAAc,EAAE,CAkIrD"}
@@ -1,158 +0,0 @@
1
- /**
2
- * Codex CLI (OpenAI) session parser
3
- * Reads from ~/.codex/sessions/
4
- */
5
- import * as fs from "node:fs";
6
- import * as path from "node:path";
7
- import * as os from "node:os";
8
- import { createUnifiedMessage } from "./types.js";
9
- export function getCodexSessionsPath() {
10
- const codexHome = process.env.CODEX_HOME || path.join(os.homedir(), ".codex");
11
- return path.join(codexHome, "sessions");
12
- }
13
- function findJsonlFiles(dir) {
14
- const files = [];
15
- function walk(currentDir) {
16
- try {
17
- const entries = fs.readdirSync(currentDir, { withFileTypes: true });
18
- for (const entry of entries) {
19
- const fullPath = path.join(currentDir, entry.name);
20
- if (entry.isDirectory()) {
21
- walk(fullPath);
22
- }
23
- else if (entry.isFile() && entry.name.endsWith(".jsonl")) {
24
- files.push(fullPath);
25
- }
26
- }
27
- }
28
- catch {
29
- // Skip inaccessible directories
30
- }
31
- }
32
- walk(dir);
33
- return files;
34
- }
35
- function extractModel(payload) {
36
- // Direct model field
37
- if (typeof payload.model === "string" && payload.model.trim()) {
38
- return payload.model.trim();
39
- }
40
- // model_name field
41
- if (typeof payload.model_name === "string" && payload.model_name.trim()) {
42
- return payload.model_name.trim();
43
- }
44
- // Nested in info
45
- const info = payload.info;
46
- if (info) {
47
- if (typeof info.model === "string" && info.model.trim()) {
48
- return info.model.trim();
49
- }
50
- if (typeof info.model_name === "string" && info.model_name.trim()) {
51
- return info.model_name.trim();
52
- }
53
- }
54
- return undefined;
55
- }
56
- export function parseCodexMessages() {
57
- const sessionsPath = getCodexSessionsPath();
58
- if (!fs.existsSync(sessionsPath)) {
59
- return [];
60
- }
61
- const messages = [];
62
- const files = findJsonlFiles(sessionsPath);
63
- for (const file of files) {
64
- // Use file path as session ID
65
- const sessionId = path.relative(sessionsPath, file).replace(/\.jsonl$/, "");
66
- try {
67
- const content = fs.readFileSync(file, "utf-8");
68
- const lines = content.split(/\r?\n/);
69
- let currentModel;
70
- let previousTotals = null;
71
- for (const line of lines) {
72
- const trimmed = line.trim();
73
- if (!trimmed)
74
- continue;
75
- try {
76
- const entry = JSON.parse(trimmed);
77
- // Extract model from turn_context
78
- if (entry.type === "turn_context" && entry.payload) {
79
- const model = extractModel(entry.payload);
80
- if (model)
81
- currentModel = model;
82
- continue;
83
- }
84
- // Process token_count events with timestamp
85
- if (entry.type === "event_msg" && entry.payload?.type === "token_count") {
86
- const info = entry.payload.info;
87
- if (!info)
88
- continue;
89
- // Extract model from payload
90
- const payloadModel = extractModel(entry.payload);
91
- if (payloadModel)
92
- currentModel = payloadModel;
93
- const model = currentModel || "unknown";
94
- // Extract timestamp
95
- const timestamp = entry.timestamp
96
- ? new Date(entry.timestamp).getTime()
97
- : entry.payload?.timestamp
98
- ? new Date(entry.payload.timestamp).getTime()
99
- : Date.now();
100
- // Skip invalid timestamps
101
- if (isNaN(timestamp))
102
- continue;
103
- // Get usage data
104
- const lastUsage = info.last_token_usage;
105
- const totalUsage = info.total_token_usage;
106
- let delta = {
107
- input: 0,
108
- cached: 0,
109
- output: 0,
110
- };
111
- if (lastUsage) {
112
- delta = {
113
- input: lastUsage.input_tokens || 0,
114
- cached: lastUsage.cached_input_tokens || lastUsage.cache_read_input_tokens || 0,
115
- output: lastUsage.output_tokens || 0,
116
- };
117
- }
118
- else if (totalUsage && previousTotals) {
119
- delta = {
120
- input: Math.max((totalUsage.input_tokens || 0) - previousTotals.input, 0),
121
- cached: Math.max((totalUsage.cached_input_tokens || totalUsage.cache_read_input_tokens || 0) -
122
- previousTotals.cached, 0),
123
- output: Math.max((totalUsage.output_tokens || 0) - previousTotals.output, 0),
124
- };
125
- }
126
- if (totalUsage) {
127
- previousTotals = {
128
- input: totalUsage.input_tokens || 0,
129
- cached: totalUsage.cached_input_tokens || totalUsage.cache_read_input_tokens || 0,
130
- output: totalUsage.output_tokens || 0,
131
- };
132
- }
133
- // Skip empty deltas
134
- if (delta.input === 0 && delta.cached === 0 && delta.output === 0) {
135
- continue;
136
- }
137
- const tokens = {
138
- input: delta.input,
139
- output: delta.output,
140
- cacheRead: delta.cached,
141
- cacheWrite: 0, // Codex doesn't track cache write
142
- reasoning: 0,
143
- };
144
- messages.push(createUnifiedMessage("codex", model, "openai", sessionId, timestamp, tokens));
145
- }
146
- }
147
- catch {
148
- // Skip malformed lines
149
- }
150
- }
151
- }
152
- catch {
153
- // Skip unreadable files
154
- }
155
- }
156
- return messages;
157
- }
158
- //# sourceMappingURL=codex.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"codex.js","sourceRoot":"","sources":["../../src/sessions/codex.ts"],"names":[],"mappings":"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"}
@@ -1,8 +0,0 @@
1
- /**
2
- * Gemini CLI session parser
3
- * Reads from ~/.gemini/tmp/{projectHash}/chats/session-*.json
4
- */
5
- import { type UnifiedMessage } from "./types.js";
6
- export declare function getGeminiBasePath(): string;
7
- export declare function parseGeminiMessages(): UnifiedMessage[];
8
- //# sourceMappingURL=gemini.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"gemini.d.ts","sourceRoot":"","sources":["../../src/sessions/gemini.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,OAAO,EAAwB,KAAK,cAAc,EAAuB,MAAM,YAAY,CAAC;AA0B5F,wBAAgB,iBAAiB,IAAI,MAAM,CAE1C;AAED,wBAAgB,mBAAmB,IAAI,cAAc,EAAE,CAqEtD"}
@@ -1,66 +0,0 @@
1
- /**
2
- * Gemini CLI session parser
3
- * Reads from ~/.gemini/tmp/{projectHash}/chats/session-*.json
4
- */
5
- import * as fs from "node:fs";
6
- import * as path from "node:path";
7
- import * as os from "node:os";
8
- import { createUnifiedMessage } from "./types.js";
9
- export function getGeminiBasePath() {
10
- return path.join(os.homedir(), ".gemini");
11
- }
12
- export function parseGeminiMessages() {
13
- const basePath = getGeminiBasePath();
14
- const tmpPath = path.join(basePath, "tmp");
15
- if (!fs.existsSync(tmpPath)) {
16
- return [];
17
- }
18
- const messages = [];
19
- try {
20
- // Find all project directories
21
- const projectDirs = fs
22
- .readdirSync(tmpPath, { withFileTypes: true })
23
- .filter((d) => d.isDirectory())
24
- .map((d) => path.join(tmpPath, d.name));
25
- for (const projectDir of projectDirs) {
26
- const chatsDir = path.join(projectDir, "chats");
27
- if (!fs.existsSync(chatsDir))
28
- continue;
29
- // Find all session JSON files
30
- const sessionFiles = fs
31
- .readdirSync(chatsDir)
32
- .filter((f) => f.startsWith("session-") && f.endsWith(".json"));
33
- for (const sessionFile of sessionFiles) {
34
- try {
35
- const content = fs.readFileSync(path.join(chatsDir, sessionFile), "utf-8");
36
- const session = JSON.parse(content);
37
- for (const msg of session.messages) {
38
- // Only process gemini messages with token data and timestamp
39
- if (msg.type !== "gemini" || !msg.tokens || !msg.model || !msg.timestamp)
40
- continue;
41
- const timestamp = new Date(msg.timestamp).getTime();
42
- // Skip invalid timestamps
43
- if (isNaN(timestamp))
44
- continue;
45
- const tokens = {
46
- input: msg.tokens.input || 0,
47
- output: msg.tokens.output || 0,
48
- cacheRead: msg.tokens.cached || 0,
49
- cacheWrite: 0, // Gemini doesn't track cache write
50
- reasoning: msg.tokens.thoughts || 0,
51
- };
52
- messages.push(createUnifiedMessage("gemini", msg.model, "google", session.sessionId, timestamp, tokens));
53
- }
54
- }
55
- catch {
56
- // Skip malformed files
57
- }
58
- }
59
- }
60
- }
61
- catch {
62
- // Skip inaccessible directories
63
- }
64
- return messages;
65
- }
66
- //# sourceMappingURL=gemini.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"gemini.js","sourceRoot":"","sources":["../../src/sessions/gemini.ts"],"names":[],"mappings":"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"}
@@ -1,32 +0,0 @@
1
- /**
2
- * Session parsers for different AI coding assistant formats
3
- *
4
- * This module provides TypeScript fallback parsers that match the Rust
5
- * implementations in packages/core/src/sessions/. Used when native module
6
- * is not available.
7
- */
8
- export * from "./types.js";
9
- export { parseOpenCodeMessages, getOpenCodeStoragePath } from "./opencode.js";
10
- export { parseClaudeCodeMessages, getClaudeCodeProjectsPath } from "./claudecode.js";
11
- export { parseCodexMessages, getCodexSessionsPath } from "./codex.js";
12
- export { parseGeminiMessages, getGeminiBasePath } from "./gemini.js";
13
- import type { UnifiedMessage, SourceType } from "./types.js";
14
- export interface ParsedMessages {
15
- messages: UnifiedMessage[];
16
- opencodeCount: number;
17
- claudeCount: number;
18
- codexCount: number;
19
- geminiCount: number;
20
- processingTimeMs: number;
21
- }
22
- export interface ParseOptions {
23
- sources?: SourceType[];
24
- since?: string;
25
- until?: string;
26
- year?: string;
27
- }
28
- /**
29
- * Parse all local session sources using TypeScript fallback parsers
30
- */
31
- export declare function parseLocalSources(options?: ParseOptions): ParsedMessages;
32
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/sessions/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,cAAc,YAAY,CAAC;AAC3B,OAAO,EAAE,qBAAqB,EAAE,sBAAsB,EAAE,MAAM,eAAe,CAAC;AAC9E,OAAO,EAAE,uBAAuB,EAAE,yBAAyB,EAAE,MAAM,iBAAiB,CAAC;AACrF,OAAO,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AACtE,OAAO,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAErE,OAAO,KAAK,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAM7D,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,cAAc,EAAE,CAAC;IAC3B,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,CAAC,EAAE,UAAU,EAAE,CAAC;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAwBD;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,GAAE,YAAiB,GAAG,cAAc,CAgE5E"}