@tokscale/cli 1.4.3 → 2.0.1
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.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +128 -0
- package/dist/index.js.map +1 -0
- package/package.json +19 -26
- package/dist/auth.d.ts +0 -17
- package/dist/auth.d.ts.map +0 -1
- package/dist/auth.js +0 -162
- package/dist/auth.js.map +0 -1
- package/dist/cli.d.ts +0 -9
- package/dist/cli.d.ts.map +0 -1
- package/dist/cli.js +0 -1550
- package/dist/cli.js.map +0 -1
- package/dist/credentials.d.ts +0 -50
- package/dist/credentials.d.ts.map +0 -1
- package/dist/credentials.js +0 -151
- package/dist/credentials.js.map +0 -1
- package/dist/cursor.d.ts +0 -167
- package/dist/cursor.d.ts.map +0 -1
- package/dist/cursor.js +0 -906
- package/dist/cursor.js.map +0 -1
- package/dist/date-utils.d.ts +0 -10
- package/dist/date-utils.d.ts.map +0 -1
- package/dist/date-utils.js +0 -47
- package/dist/date-utils.js.map +0 -1
- package/dist/graph-types.d.ts +0 -142
- package/dist/graph-types.d.ts.map +0 -1
- package/dist/graph-types.js +0 -6
- package/dist/graph-types.js.map +0 -1
- package/dist/native-runner.d.ts +0 -11
- package/dist/native-runner.d.ts.map +0 -1
- package/dist/native-runner.js +0 -77
- package/dist/native-runner.js.map +0 -1
- package/dist/native.d.ts +0 -106
- package/dist/native.d.ts.map +0 -1
- package/dist/native.js +0 -302
- package/dist/native.js.map +0 -1
- package/dist/sessions/types.d.ts +0 -28
- package/dist/sessions/types.d.ts.map +0 -1
- package/dist/sessions/types.js +0 -27
- package/dist/sessions/types.js.map +0 -1
- package/dist/spinner.d.ts +0 -75
- package/dist/spinner.d.ts.map +0 -1
- package/dist/spinner.js +0 -203
- package/dist/spinner.js.map +0 -1
- package/dist/submit.d.ts +0 -23
- package/dist/submit.d.ts.map +0 -1
- package/dist/submit.js +0 -294
- package/dist/submit.js.map +0 -1
- package/dist/table.d.ts +0 -42
- package/dist/table.d.ts.map +0 -1
- package/dist/table.js +0 -181
- package/dist/table.js.map +0 -1
- package/dist/tui/App.d.ts +0 -4
- package/dist/tui/App.d.ts.map +0 -1
- package/dist/tui/App.js +0 -333
- package/dist/tui/App.js.map +0 -1
- package/dist/tui/components/BarChart.d.ts +0 -17
- package/dist/tui/components/BarChart.d.ts.map +0 -1
- package/dist/tui/components/BarChart.js +0 -146
- package/dist/tui/components/BarChart.js.map +0 -1
- package/dist/tui/components/DailyView.d.ts +0 -13
- package/dist/tui/components/DailyView.d.ts.map +0 -1
- package/dist/tui/components/DailyView.js +0 -86
- package/dist/tui/components/DailyView.js.map +0 -1
- package/dist/tui/components/DateBreakdownPanel.d.ts +0 -7
- package/dist/tui/components/DateBreakdownPanel.d.ts.map +0 -1
- package/dist/tui/components/DateBreakdownPanel.js +0 -36
- package/dist/tui/components/DateBreakdownPanel.js.map +0 -1
- package/dist/tui/components/Footer.d.ts +0 -28
- package/dist/tui/components/Footer.d.ts.map +0 -1
- package/dist/tui/components/Footer.js +0 -130
- package/dist/tui/components/Footer.js.map +0 -1
- package/dist/tui/components/Header.d.ts +0 -9
- package/dist/tui/components/Header.d.ts.map +0 -1
- package/dist/tui/components/Header.js +0 -20
- package/dist/tui/components/Header.js.map +0 -1
- package/dist/tui/components/Legend.d.ts +0 -7
- package/dist/tui/components/Legend.d.ts.map +0 -1
- package/dist/tui/components/Legend.js +0 -16
- package/dist/tui/components/Legend.js.map +0 -1
- package/dist/tui/components/LoadingSpinner.d.ts +0 -8
- package/dist/tui/components/LoadingSpinner.d.ts.map +0 -1
- package/dist/tui/components/LoadingSpinner.js +0 -55
- package/dist/tui/components/LoadingSpinner.js.map +0 -1
- package/dist/tui/components/ModelRow.d.ts +0 -13
- package/dist/tui/components/ModelRow.d.ts.map +0 -1
- package/dist/tui/components/ModelRow.js +0 -15
- package/dist/tui/components/ModelRow.js.map +0 -1
- package/dist/tui/components/ModelView.d.ts +0 -13
- package/dist/tui/components/ModelView.d.ts.map +0 -1
- package/dist/tui/components/ModelView.js +0 -96
- package/dist/tui/components/ModelView.js.map +0 -1
- package/dist/tui/components/OverviewView.d.ts +0 -14
- package/dist/tui/components/OverviewView.d.ts.map +0 -1
- package/dist/tui/components/OverviewView.js +0 -65
- package/dist/tui/components/OverviewView.js.map +0 -1
- package/dist/tui/components/StatsView.d.ts +0 -14
- package/dist/tui/components/StatsView.d.ts.map +0 -1
- package/dist/tui/components/StatsView.js +0 -102
- package/dist/tui/components/StatsView.js.map +0 -1
- package/dist/tui/components/TokenBreakdown.d.ts +0 -14
- package/dist/tui/components/TokenBreakdown.d.ts.map +0 -1
- package/dist/tui/components/TokenBreakdown.js +0 -10
- package/dist/tui/components/TokenBreakdown.js.map +0 -1
- package/dist/tui/components/index.d.ts +0 -16
- package/dist/tui/components/index.d.ts.map +0 -1
- package/dist/tui/components/index.js +0 -13
- package/dist/tui/components/index.js.map +0 -1
- package/dist/tui/config/settings.d.ts +0 -15
- package/dist/tui/config/settings.d.ts.map +0 -1
- package/dist/tui/config/settings.js +0 -147
- package/dist/tui/config/settings.js.map +0 -1
- package/dist/tui/config/themes.d.ts +0 -15
- package/dist/tui/config/themes.d.ts.map +0 -1
- package/dist/tui/config/themes.js +0 -82
- package/dist/tui/config/themes.js.map +0 -1
- package/dist/tui/hooks/useData.d.ts +0 -19
- package/dist/tui/hooks/useData.d.ts.map +0 -1
- package/dist/tui/hooks/useData.js +0 -468
- package/dist/tui/hooks/useData.js.map +0 -1
- package/dist/tui/index.d.ts +0 -4
- package/dist/tui/index.d.ts.map +0 -1
- package/dist/tui/index.js +0 -36
- package/dist/tui/index.js.map +0 -1
- package/dist/tui/types/index.d.ts +0 -137
- package/dist/tui/types/index.d.ts.map +0 -1
- package/dist/tui/types/index.js +0 -26
- package/dist/tui/types/index.js.map +0 -1
- package/dist/tui/utils/cleanup.d.ts +0 -22
- package/dist/tui/utils/cleanup.d.ts.map +0 -1
- package/dist/tui/utils/cleanup.js +0 -59
- package/dist/tui/utils/cleanup.js.map +0 -1
- package/dist/tui/utils/colors.d.ts +0 -19
- package/dist/tui/utils/colors.d.ts.map +0 -1
- package/dist/tui/utils/colors.js +0 -71
- package/dist/tui/utils/colors.js.map +0 -1
- package/dist/tui/utils/format.d.ts +0 -7
- package/dist/tui/utils/format.d.ts.map +0 -1
- package/dist/tui/utils/format.js +0 -45
- package/dist/tui/utils/format.js.map +0 -1
- package/dist/tui/utils/responsive.d.ts +0 -5
- package/dist/tui/utils/responsive.d.ts.map +0 -1
- package/dist/tui/utils/responsive.js +0 -5
- package/dist/tui/utils/responsive.js.map +0 -1
- package/dist/wrapped.d.ts +0 -43
- package/dist/wrapped.d.ts.map +0 -1
- package/dist/wrapped.js +0 -719
- package/dist/wrapped.js.map +0 -1
- package/src/auth.ts +0 -211
- package/src/cli.ts +0 -1892
- package/src/credentials.ts +0 -176
- package/src/cursor.ts +0 -1044
- package/src/date-utils.ts +0 -51
- package/src/graph-types.ts +0 -175
- package/src/native-runner.js +0 -4
- package/src/native-runner.ts +0 -91
- package/src/native.ts +0 -633
- package/src/sessions/types.ts +0 -59
- package/src/spinner.ts +0 -283
- package/src/submit.ts +0 -360
- package/src/table.ts +0 -233
- package/src/tui/App.tsx +0 -453
- package/src/tui/components/BarChart.tsx +0 -205
- package/src/tui/components/DailyView.tsx +0 -132
- package/src/tui/components/DateBreakdownPanel.tsx +0 -79
- package/src/tui/components/Footer.tsx +0 -380
- package/src/tui/components/Header.tsx +0 -68
- package/src/tui/components/Legend.tsx +0 -39
- package/src/tui/components/LoadingSpinner.tsx +0 -81
- package/src/tui/components/ModelRow.tsx +0 -47
- package/src/tui/components/ModelView.tsx +0 -147
- package/src/tui/components/OverviewView.tsx +0 -121
- package/src/tui/components/StatsView.tsx +0 -249
- package/src/tui/components/TokenBreakdown.tsx +0 -46
- package/src/tui/components/index.ts +0 -15
- package/src/tui/config/settings.ts +0 -183
- package/src/tui/config/themes.ts +0 -115
- package/src/tui/hooks/useData.ts +0 -558
- package/src/tui/index.tsx +0 -44
- package/src/tui/opentui.d.ts +0 -166
- package/src/tui/types/index.ts +0 -173
- package/src/tui/utils/cleanup.ts +0 -65
- package/src/tui/utils/colors.ts +0 -78
- package/src/tui/utils/format.ts +0 -36
- package/src/tui/utils/responsive.ts +0 -8
- package/src/types.d.ts +0 -28
- package/src/wrapped.ts +0 -848
package/src/native.ts
DELETED
|
@@ -1,633 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Native module loader for Rust core
|
|
3
|
-
*
|
|
4
|
-
* Exposes all Rust functions with proper TypeScript types.
|
|
5
|
-
* Native module is REQUIRED - no TypeScript fallback.
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
import type {
|
|
9
|
-
TokenContributionData,
|
|
10
|
-
SourceType,
|
|
11
|
-
} from "./graph-types.js";
|
|
12
|
-
import { loadSettings } from "./tui/config/settings.js";
|
|
13
|
-
|
|
14
|
-
// =============================================================================
|
|
15
|
-
// Types matching Rust exports
|
|
16
|
-
// =============================================================================
|
|
17
|
-
|
|
18
|
-
interface NativeTokenBreakdown {
|
|
19
|
-
input: number;
|
|
20
|
-
output: number;
|
|
21
|
-
cacheRead: number;
|
|
22
|
-
cacheWrite: number;
|
|
23
|
-
reasoning: number;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
interface NativeDailyTotals {
|
|
27
|
-
tokens: number;
|
|
28
|
-
cost: number;
|
|
29
|
-
messages: number;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
interface NativeSourceContribution {
|
|
33
|
-
source: string;
|
|
34
|
-
modelId: string;
|
|
35
|
-
providerId: string;
|
|
36
|
-
tokens: NativeTokenBreakdown;
|
|
37
|
-
cost: number;
|
|
38
|
-
messages: number;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
interface NativeDailyContribution {
|
|
42
|
-
date: string;
|
|
43
|
-
timestampMs?: number;
|
|
44
|
-
totals: NativeDailyTotals;
|
|
45
|
-
intensity: number;
|
|
46
|
-
tokenBreakdown: NativeTokenBreakdown;
|
|
47
|
-
sources: NativeSourceContribution[];
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
interface NativeYearSummary {
|
|
51
|
-
year: string;
|
|
52
|
-
totalTokens: number;
|
|
53
|
-
totalCost: number;
|
|
54
|
-
rangeStart: string;
|
|
55
|
-
rangeEnd: string;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
interface NativeDataSummary {
|
|
59
|
-
totalTokens: number;
|
|
60
|
-
totalCost: number;
|
|
61
|
-
totalDays: number;
|
|
62
|
-
activeDays: number;
|
|
63
|
-
averagePerDay: number;
|
|
64
|
-
maxCostInSingleDay: number;
|
|
65
|
-
sources: string[];
|
|
66
|
-
models: string[];
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
interface NativeGraphMeta {
|
|
70
|
-
generatedAt: string;
|
|
71
|
-
version: string;
|
|
72
|
-
dateRangeStart: string;
|
|
73
|
-
dateRangeEnd: string;
|
|
74
|
-
processingTimeMs: number;
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
interface NativeGraphResult {
|
|
78
|
-
meta: NativeGraphMeta;
|
|
79
|
-
summary: NativeDataSummary;
|
|
80
|
-
years: NativeYearSummary[];
|
|
81
|
-
contributions: NativeDailyContribution[];
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
interface NativeModelUsage {
|
|
85
|
-
source: string;
|
|
86
|
-
model: string;
|
|
87
|
-
provider: string;
|
|
88
|
-
input: number;
|
|
89
|
-
output: number;
|
|
90
|
-
cacheRead: number;
|
|
91
|
-
cacheWrite: number;
|
|
92
|
-
reasoning: number;
|
|
93
|
-
messageCount: number;
|
|
94
|
-
cost: number;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
interface NativeModelReport {
|
|
98
|
-
entries: NativeModelUsage[];
|
|
99
|
-
totalInput: number;
|
|
100
|
-
totalOutput: number;
|
|
101
|
-
totalCacheRead: number;
|
|
102
|
-
totalCacheWrite: number;
|
|
103
|
-
totalMessages: number;
|
|
104
|
-
totalCost: number;
|
|
105
|
-
processingTimeMs: number;
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
interface NativeMonthlyUsage {
|
|
109
|
-
month: string;
|
|
110
|
-
models: string[];
|
|
111
|
-
input: number;
|
|
112
|
-
output: number;
|
|
113
|
-
cacheRead: number;
|
|
114
|
-
cacheWrite: number;
|
|
115
|
-
messageCount: number;
|
|
116
|
-
cost: number;
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
interface NativeMonthlyReport {
|
|
120
|
-
entries: NativeMonthlyUsage[];
|
|
121
|
-
totalCost: number;
|
|
122
|
-
processingTimeMs: number;
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
// Types for two-phase processing (parallel optimization)
|
|
126
|
-
interface NativeParsedMessage {
|
|
127
|
-
source: string;
|
|
128
|
-
modelId: string;
|
|
129
|
-
providerId: string;
|
|
130
|
-
timestamp: number;
|
|
131
|
-
date: string;
|
|
132
|
-
input: number;
|
|
133
|
-
output: number;
|
|
134
|
-
cacheRead: number;
|
|
135
|
-
cacheWrite: number;
|
|
136
|
-
reasoning: number;
|
|
137
|
-
sessionId: string;
|
|
138
|
-
agent?: string;
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
interface NativeParsedMessages {
|
|
142
|
-
messages: NativeParsedMessage[];
|
|
143
|
-
opencodeCount: number;
|
|
144
|
-
claudeCount: number;
|
|
145
|
-
codexCount: number;
|
|
146
|
-
geminiCount: number;
|
|
147
|
-
ampCount: number;
|
|
148
|
-
droidCount: number;
|
|
149
|
-
openclawCount: number;
|
|
150
|
-
piCount: number;
|
|
151
|
-
kimiCount: number;
|
|
152
|
-
processingTimeMs: number;
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
interface NativeLocalParseOptions {
|
|
156
|
-
homeDir?: string;
|
|
157
|
-
sources?: string[];
|
|
158
|
-
since?: string;
|
|
159
|
-
until?: string;
|
|
160
|
-
year?: string;
|
|
161
|
-
sinceTs?: number;
|
|
162
|
-
untilTs?: number;
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
interface NativeFinalizeReportOptions {
|
|
166
|
-
homeDir?: string;
|
|
167
|
-
localMessages: NativeParsedMessages;
|
|
168
|
-
includeCursor: boolean;
|
|
169
|
-
since?: string;
|
|
170
|
-
until?: string;
|
|
171
|
-
year?: string;
|
|
172
|
-
sinceTs?: number;
|
|
173
|
-
untilTs?: number;
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
interface NativeCore {
|
|
177
|
-
version(): string;
|
|
178
|
-
parseLocalSources(options: NativeLocalParseOptions): NativeParsedMessages;
|
|
179
|
-
finalizeReport(options: NativeFinalizeReportOptions): NativeModelReport;
|
|
180
|
-
finalizeMonthlyReport(options: NativeFinalizeReportOptions): NativeMonthlyReport;
|
|
181
|
-
finalizeGraph(options: NativeFinalizeReportOptions): NativeGraphResult;
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
// =============================================================================
|
|
185
|
-
// Module loading
|
|
186
|
-
// =============================================================================
|
|
187
|
-
|
|
188
|
-
let nativeCore: NativeCore | null = null;
|
|
189
|
-
|
|
190
|
-
try {
|
|
191
|
-
// Type assertion needed because dynamic import returns module namespace
|
|
192
|
-
// nativeCore.version() is called directly, async functions go through subprocess
|
|
193
|
-
nativeCore = await import("@tokscale/core").then(
|
|
194
|
-
(m) => (m.default || m) as unknown as NativeCore
|
|
195
|
-
);
|
|
196
|
-
} catch (e) {
|
|
197
|
-
void e;
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
// =============================================================================
|
|
201
|
-
// Public API
|
|
202
|
-
// =============================================================================
|
|
203
|
-
|
|
204
|
-
/**
|
|
205
|
-
* Check if native module is available
|
|
206
|
-
*/
|
|
207
|
-
export function isNativeAvailable(): boolean {
|
|
208
|
-
return nativeCore !== null;
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
/**
|
|
212
|
-
* Get native module version
|
|
213
|
-
*/
|
|
214
|
-
export function getNativeVersion(): string | null {
|
|
215
|
-
return nativeCore?.version() ?? null;
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
/**
|
|
219
|
-
* Convert native result to TypeScript format
|
|
220
|
-
*/
|
|
221
|
-
function fromNativeResult(result: NativeGraphResult): TokenContributionData {
|
|
222
|
-
return {
|
|
223
|
-
meta: {
|
|
224
|
-
generatedAt: result.meta.generatedAt,
|
|
225
|
-
version: result.meta.version,
|
|
226
|
-
dateRange: {
|
|
227
|
-
start: result.meta.dateRangeStart,
|
|
228
|
-
end: result.meta.dateRangeEnd,
|
|
229
|
-
},
|
|
230
|
-
},
|
|
231
|
-
summary: {
|
|
232
|
-
totalTokens: result.summary.totalTokens,
|
|
233
|
-
totalCost: result.summary.totalCost,
|
|
234
|
-
totalDays: result.summary.totalDays,
|
|
235
|
-
activeDays: result.summary.activeDays,
|
|
236
|
-
averagePerDay: result.summary.averagePerDay,
|
|
237
|
-
maxCostInSingleDay: result.summary.maxCostInSingleDay,
|
|
238
|
-
sources: result.summary.sources as SourceType[],
|
|
239
|
-
models: result.summary.models,
|
|
240
|
-
},
|
|
241
|
-
years: result.years.map((y) => ({
|
|
242
|
-
year: y.year,
|
|
243
|
-
totalTokens: y.totalTokens,
|
|
244
|
-
totalCost: y.totalCost,
|
|
245
|
-
range: {
|
|
246
|
-
start: y.rangeStart,
|
|
247
|
-
end: y.rangeEnd,
|
|
248
|
-
},
|
|
249
|
-
})),
|
|
250
|
-
contributions: result.contributions.map((c) => ({
|
|
251
|
-
date: c.date,
|
|
252
|
-
timestampMs: c.timestampMs ?? undefined,
|
|
253
|
-
totals: {
|
|
254
|
-
tokens: c.totals.tokens,
|
|
255
|
-
cost: c.totals.cost,
|
|
256
|
-
messages: c.totals.messages,
|
|
257
|
-
},
|
|
258
|
-
intensity: c.intensity as 0 | 1 | 2 | 3 | 4,
|
|
259
|
-
tokenBreakdown: {
|
|
260
|
-
input: c.tokenBreakdown.input,
|
|
261
|
-
output: c.tokenBreakdown.output,
|
|
262
|
-
cacheRead: c.tokenBreakdown.cacheRead,
|
|
263
|
-
cacheWrite: c.tokenBreakdown.cacheWrite,
|
|
264
|
-
reasoning: c.tokenBreakdown.reasoning,
|
|
265
|
-
},
|
|
266
|
-
sources: c.sources.map((s) => ({
|
|
267
|
-
source: s.source as SourceType,
|
|
268
|
-
modelId: s.modelId,
|
|
269
|
-
providerId: s.providerId,
|
|
270
|
-
tokens: {
|
|
271
|
-
input: s.tokens.input,
|
|
272
|
-
output: s.tokens.output,
|
|
273
|
-
cacheRead: s.tokens.cacheRead,
|
|
274
|
-
cacheWrite: s.tokens.cacheWrite,
|
|
275
|
-
reasoning: s.tokens.reasoning,
|
|
276
|
-
},
|
|
277
|
-
cost: s.cost,
|
|
278
|
-
messages: s.messages,
|
|
279
|
-
})),
|
|
280
|
-
})),
|
|
281
|
-
};
|
|
282
|
-
}
|
|
283
|
-
|
|
284
|
-
// =============================================================================
|
|
285
|
-
// Reports
|
|
286
|
-
// =============================================================================
|
|
287
|
-
|
|
288
|
-
export interface ModelUsage {
|
|
289
|
-
source: string;
|
|
290
|
-
model: string;
|
|
291
|
-
provider: string;
|
|
292
|
-
input: number;
|
|
293
|
-
output: number;
|
|
294
|
-
cacheRead: number;
|
|
295
|
-
cacheWrite: number;
|
|
296
|
-
reasoning: number;
|
|
297
|
-
messageCount: number;
|
|
298
|
-
cost: number;
|
|
299
|
-
}
|
|
300
|
-
|
|
301
|
-
export interface ModelReport {
|
|
302
|
-
entries: ModelUsage[];
|
|
303
|
-
totalInput: number;
|
|
304
|
-
totalOutput: number;
|
|
305
|
-
totalCacheRead: number;
|
|
306
|
-
totalCacheWrite: number;
|
|
307
|
-
totalMessages: number;
|
|
308
|
-
totalCost: number;
|
|
309
|
-
processingTimeMs: number;
|
|
310
|
-
}
|
|
311
|
-
|
|
312
|
-
export interface MonthlyUsage {
|
|
313
|
-
month: string;
|
|
314
|
-
models: string[];
|
|
315
|
-
input: number;
|
|
316
|
-
output: number;
|
|
317
|
-
cacheRead: number;
|
|
318
|
-
cacheWrite: number;
|
|
319
|
-
messageCount: number;
|
|
320
|
-
cost: number;
|
|
321
|
-
}
|
|
322
|
-
|
|
323
|
-
export interface MonthlyReport {
|
|
324
|
-
entries: MonthlyUsage[];
|
|
325
|
-
totalCost: number;
|
|
326
|
-
processingTimeMs: number;
|
|
327
|
-
}
|
|
328
|
-
|
|
329
|
-
// =============================================================================
|
|
330
|
-
// Two-Phase Processing (Parallel Optimization)
|
|
331
|
-
// =============================================================================
|
|
332
|
-
|
|
333
|
-
export interface ParsedMessages {
|
|
334
|
-
messages: Array<{
|
|
335
|
-
source: string;
|
|
336
|
-
modelId: string;
|
|
337
|
-
providerId: string;
|
|
338
|
-
timestamp: number;
|
|
339
|
-
date: string;
|
|
340
|
-
input: number;
|
|
341
|
-
output: number;
|
|
342
|
-
cacheRead: number;
|
|
343
|
-
cacheWrite: number;
|
|
344
|
-
reasoning: number;
|
|
345
|
-
sessionId: string;
|
|
346
|
-
agent?: string;
|
|
347
|
-
}>;
|
|
348
|
-
opencodeCount: number;
|
|
349
|
-
claudeCount: number;
|
|
350
|
-
codexCount: number;
|
|
351
|
-
geminiCount: number;
|
|
352
|
-
ampCount: number;
|
|
353
|
-
droidCount: number;
|
|
354
|
-
openclawCount: number;
|
|
355
|
-
piCount: number;
|
|
356
|
-
kimiCount: number;
|
|
357
|
-
processingTimeMs: number;
|
|
358
|
-
}
|
|
359
|
-
|
|
360
|
-
export interface LocalParseOptions {
|
|
361
|
-
homeDir?: string;
|
|
362
|
-
sources?: SourceType[];
|
|
363
|
-
since?: string;
|
|
364
|
-
until?: string;
|
|
365
|
-
year?: string;
|
|
366
|
-
sinceTs?: number;
|
|
367
|
-
untilTs?: number;
|
|
368
|
-
}
|
|
369
|
-
|
|
370
|
-
export interface FinalizeOptions {
|
|
371
|
-
localMessages: ParsedMessages;
|
|
372
|
-
includeCursor: boolean;
|
|
373
|
-
since?: string;
|
|
374
|
-
until?: string;
|
|
375
|
-
year?: string;
|
|
376
|
-
sinceTs?: number;
|
|
377
|
-
untilTs?: number;
|
|
378
|
-
}
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
// =============================================================================
|
|
383
|
-
// Async Subprocess Wrappers (Non-blocking for UI)
|
|
384
|
-
// =============================================================================
|
|
385
|
-
|
|
386
|
-
import { fileURLToPath } from "node:url";
|
|
387
|
-
import { dirname, join } from "node:path";
|
|
388
|
-
import { writeFileSync, readFileSync, unlinkSync, mkdirSync, existsSync } from "node:fs";
|
|
389
|
-
import { tmpdir } from "node:os";
|
|
390
|
-
import { randomUUID } from "node:crypto";
|
|
391
|
-
|
|
392
|
-
const __filename = fileURLToPath(import.meta.url);
|
|
393
|
-
const __dirname = dirname(__filename);
|
|
394
|
-
|
|
395
|
-
const SIGKILL_GRACE_MS = 500;
|
|
396
|
-
|
|
397
|
-
function getNativeTimeoutMs(): number {
|
|
398
|
-
const settings = loadSettings();
|
|
399
|
-
return process.env.TOKSCALE_NATIVE_TIMEOUT_MS
|
|
400
|
-
? parseInt(process.env.TOKSCALE_NATIVE_TIMEOUT_MS, 10)
|
|
401
|
-
: (settings.nativeTimeoutMs ?? 300_000);
|
|
402
|
-
}
|
|
403
|
-
|
|
404
|
-
interface BunSubprocess {
|
|
405
|
-
stdout: { text: () => Promise<string> };
|
|
406
|
-
stderr: { text: () => Promise<string> };
|
|
407
|
-
exited: Promise<number>;
|
|
408
|
-
signalCode: string | null;
|
|
409
|
-
killed: boolean;
|
|
410
|
-
kill: (signal?: string) => void;
|
|
411
|
-
}
|
|
412
|
-
|
|
413
|
-
interface BunSpawnOptions {
|
|
414
|
-
stdout: "pipe" | "ignore";
|
|
415
|
-
stderr: "pipe" | "ignore";
|
|
416
|
-
}
|
|
417
|
-
|
|
418
|
-
interface BunGlobalType {
|
|
419
|
-
spawn: (cmd: string[], opts: BunSpawnOptions) => BunSubprocess;
|
|
420
|
-
}
|
|
421
|
-
|
|
422
|
-
function safeKill(proc: unknown, signal?: string): void {
|
|
423
|
-
try {
|
|
424
|
-
(proc as { kill: (signal?: string) => void }).kill(signal);
|
|
425
|
-
} catch {}
|
|
426
|
-
}
|
|
427
|
-
|
|
428
|
-
async function runInSubprocess<T>(method: string, args: unknown[]): Promise<T> {
|
|
429
|
-
const NATIVE_TIMEOUT_MS = getNativeTimeoutMs();
|
|
430
|
-
const runnerPath = join(__dirname, "native-runner.js");
|
|
431
|
-
const input = JSON.stringify({ method, args });
|
|
432
|
-
|
|
433
|
-
const tmpDir = join(tmpdir(), "tokscale");
|
|
434
|
-
mkdirSync(tmpDir, { recursive: true });
|
|
435
|
-
const id = randomUUID();
|
|
436
|
-
const inputFile = join(tmpDir, `input-${id}.json`);
|
|
437
|
-
const outputFile = join(tmpDir, `output-${id}.json`);
|
|
438
|
-
|
|
439
|
-
writeFileSync(inputFile, input, "utf-8");
|
|
440
|
-
|
|
441
|
-
const BunGlobal = (globalThis as Record<string, unknown>).Bun as BunGlobalType;
|
|
442
|
-
|
|
443
|
-
let proc: BunSubprocess;
|
|
444
|
-
try {
|
|
445
|
-
proc = BunGlobal.spawn([process.execPath, runnerPath, inputFile, outputFile], {
|
|
446
|
-
stdout: "ignore",
|
|
447
|
-
stderr: "pipe",
|
|
448
|
-
});
|
|
449
|
-
} catch (e) {
|
|
450
|
-
try { unlinkSync(inputFile); } catch {}
|
|
451
|
-
throw new Error(`Failed to spawn subprocess: ${(e as Error).message}`);
|
|
452
|
-
}
|
|
453
|
-
|
|
454
|
-
let timeoutId: ReturnType<typeof setTimeout> | null = null;
|
|
455
|
-
let sigkillId: ReturnType<typeof setTimeout> | null = null;
|
|
456
|
-
let weInitiatedKill = false;
|
|
457
|
-
|
|
458
|
-
const cleanup = async () => {
|
|
459
|
-
if (timeoutId) clearTimeout(timeoutId);
|
|
460
|
-
if (sigkillId) clearTimeout(sigkillId);
|
|
461
|
-
try { unlinkSync(inputFile); } catch {}
|
|
462
|
-
try { unlinkSync(outputFile); } catch {}
|
|
463
|
-
};
|
|
464
|
-
|
|
465
|
-
try {
|
|
466
|
-
const timeoutPromise = new Promise<never>((_, reject) => {
|
|
467
|
-
timeoutId = setTimeout(() => {
|
|
468
|
-
weInitiatedKill = true;
|
|
469
|
-
safeKill(proc, "SIGTERM");
|
|
470
|
-
sigkillId = setTimeout(() => {
|
|
471
|
-
safeKill(proc, "SIGKILL");
|
|
472
|
-
reject(new Error(
|
|
473
|
-
`Subprocess '${method}' timed out after ${NATIVE_TIMEOUT_MS}ms (hard kill)`
|
|
474
|
-
));
|
|
475
|
-
}, SIGKILL_GRACE_MS);
|
|
476
|
-
}, NATIVE_TIMEOUT_MS);
|
|
477
|
-
});
|
|
478
|
-
|
|
479
|
-
const exitCode = await Promise.race([proc.exited, timeoutPromise]);
|
|
480
|
-
|
|
481
|
-
if (timeoutId) clearTimeout(timeoutId);
|
|
482
|
-
|
|
483
|
-
if (weInitiatedKill || proc.signalCode) {
|
|
484
|
-
throw new Error(
|
|
485
|
-
`Subprocess '${method}' was killed (signal: ${proc.signalCode || "SIGTERM"})`
|
|
486
|
-
);
|
|
487
|
-
}
|
|
488
|
-
|
|
489
|
-
if (exitCode !== 0) {
|
|
490
|
-
const stderr = await proc.stderr.text();
|
|
491
|
-
let errorMsg = `Process exited with code ${exitCode}`;
|
|
492
|
-
if (stderr) {
|
|
493
|
-
try {
|
|
494
|
-
const parsed = JSON.parse(stderr);
|
|
495
|
-
if (parsed.error) {
|
|
496
|
-
errorMsg = parsed.error;
|
|
497
|
-
} else {
|
|
498
|
-
errorMsg = stderr;
|
|
499
|
-
}
|
|
500
|
-
} catch {
|
|
501
|
-
// Not JSON — include raw stderr so the user sees the actual error
|
|
502
|
-
// (e.g. dynamic linker errors on NixOS, missing shared libraries, etc.)
|
|
503
|
-
errorMsg = stderr;
|
|
504
|
-
}
|
|
505
|
-
}
|
|
506
|
-
throw new Error(`Subprocess '${method}' failed: ${errorMsg}`);
|
|
507
|
-
}
|
|
508
|
-
|
|
509
|
-
if (!existsSync(outputFile)) {
|
|
510
|
-
throw new Error(`Subprocess '${method}' did not produce output file`);
|
|
511
|
-
}
|
|
512
|
-
|
|
513
|
-
try {
|
|
514
|
-
const output = readFileSync(outputFile, "utf-8");
|
|
515
|
-
return JSON.parse(output) as T;
|
|
516
|
-
} catch (e) {
|
|
517
|
-
throw new Error(
|
|
518
|
-
`Failed to parse subprocess output: ${(e as Error).message}`
|
|
519
|
-
);
|
|
520
|
-
}
|
|
521
|
-
} finally {
|
|
522
|
-
await cleanup();
|
|
523
|
-
}
|
|
524
|
-
}
|
|
525
|
-
|
|
526
|
-
export async function parseLocalSourcesAsync(options: LocalParseOptions): Promise<ParsedMessages> {
|
|
527
|
-
if (!isNativeAvailable()) {
|
|
528
|
-
throw new Error("Native module required. Run: bun run build:core");
|
|
529
|
-
}
|
|
530
|
-
|
|
531
|
-
const nativeOptions: NativeLocalParseOptions = {
|
|
532
|
-
homeDir: options.homeDir,
|
|
533
|
-
sources: options.sources,
|
|
534
|
-
since: options.since,
|
|
535
|
-
until: options.until,
|
|
536
|
-
year: options.year,
|
|
537
|
-
sinceTs: options.sinceTs,
|
|
538
|
-
untilTs: options.untilTs,
|
|
539
|
-
};
|
|
540
|
-
|
|
541
|
-
return runInSubprocess<ParsedMessages>("parseLocalSources", [nativeOptions]);
|
|
542
|
-
}
|
|
543
|
-
|
|
544
|
-
export async function finalizeReportAsync(options: FinalizeOptions): Promise<ModelReport> {
|
|
545
|
-
if (!isNativeAvailable()) {
|
|
546
|
-
throw new Error("Native module required. Run: bun run build:core");
|
|
547
|
-
}
|
|
548
|
-
|
|
549
|
-
const nativeOptions: NativeFinalizeReportOptions = {
|
|
550
|
-
homeDir: undefined,
|
|
551
|
-
localMessages: options.localMessages,
|
|
552
|
-
includeCursor: options.includeCursor,
|
|
553
|
-
since: options.since,
|
|
554
|
-
until: options.until,
|
|
555
|
-
year: options.year,
|
|
556
|
-
sinceTs: options.sinceTs,
|
|
557
|
-
untilTs: options.untilTs,
|
|
558
|
-
};
|
|
559
|
-
|
|
560
|
-
return runInSubprocess<ModelReport>("finalizeReport", [nativeOptions]);
|
|
561
|
-
}
|
|
562
|
-
|
|
563
|
-
export async function finalizeMonthlyReportAsync(options: FinalizeOptions): Promise<MonthlyReport> {
|
|
564
|
-
if (!isNativeAvailable()) {
|
|
565
|
-
throw new Error("Native module required. Run: bun run build:core");
|
|
566
|
-
}
|
|
567
|
-
|
|
568
|
-
const nativeOptions: NativeFinalizeReportOptions = {
|
|
569
|
-
homeDir: undefined,
|
|
570
|
-
localMessages: options.localMessages,
|
|
571
|
-
includeCursor: options.includeCursor,
|
|
572
|
-
since: options.since,
|
|
573
|
-
until: options.until,
|
|
574
|
-
year: options.year,
|
|
575
|
-
sinceTs: options.sinceTs,
|
|
576
|
-
untilTs: options.untilTs,
|
|
577
|
-
};
|
|
578
|
-
|
|
579
|
-
return runInSubprocess<MonthlyReport>("finalizeMonthlyReport", [nativeOptions]);
|
|
580
|
-
}
|
|
581
|
-
|
|
582
|
-
export async function finalizeGraphAsync(options: FinalizeOptions): Promise<TokenContributionData> {
|
|
583
|
-
if (!isNativeAvailable()) {
|
|
584
|
-
throw new Error("Native module required. Run: bun run build:core");
|
|
585
|
-
}
|
|
586
|
-
|
|
587
|
-
const nativeOptions: NativeFinalizeReportOptions = {
|
|
588
|
-
homeDir: undefined,
|
|
589
|
-
localMessages: options.localMessages,
|
|
590
|
-
includeCursor: options.includeCursor,
|
|
591
|
-
since: options.since,
|
|
592
|
-
until: options.until,
|
|
593
|
-
year: options.year,
|
|
594
|
-
sinceTs: options.sinceTs,
|
|
595
|
-
untilTs: options.untilTs,
|
|
596
|
-
};
|
|
597
|
-
|
|
598
|
-
const result = await runInSubprocess<NativeGraphResult>("finalizeGraph", [nativeOptions]);
|
|
599
|
-
return fromNativeResult(result);
|
|
600
|
-
}
|
|
601
|
-
|
|
602
|
-
export interface ReportAndGraph {
|
|
603
|
-
report: ModelReport;
|
|
604
|
-
graph: TokenContributionData;
|
|
605
|
-
}
|
|
606
|
-
|
|
607
|
-
interface NativeReportAndGraph {
|
|
608
|
-
report: NativeModelReport;
|
|
609
|
-
graph: NativeGraphResult;
|
|
610
|
-
}
|
|
611
|
-
|
|
612
|
-
export async function finalizeReportAndGraphAsync(options: FinalizeOptions): Promise<ReportAndGraph> {
|
|
613
|
-
if (!isNativeAvailable()) {
|
|
614
|
-
throw new Error("Native module required. Run: bun run build:core");
|
|
615
|
-
}
|
|
616
|
-
|
|
617
|
-
const nativeOptions: NativeFinalizeReportOptions = {
|
|
618
|
-
homeDir: undefined,
|
|
619
|
-
localMessages: options.localMessages,
|
|
620
|
-
includeCursor: options.includeCursor,
|
|
621
|
-
since: options.since,
|
|
622
|
-
until: options.until,
|
|
623
|
-
year: options.year,
|
|
624
|
-
sinceTs: options.sinceTs,
|
|
625
|
-
untilTs: options.untilTs,
|
|
626
|
-
};
|
|
627
|
-
|
|
628
|
-
const result = await runInSubprocess<NativeReportAndGraph>("finalizeReportAndGraph", [nativeOptions]);
|
|
629
|
-
return {
|
|
630
|
-
report: result.report,
|
|
631
|
-
graph: fromNativeResult(result.graph),
|
|
632
|
-
};
|
|
633
|
-
}
|
package/src/sessions/types.ts
DELETED
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Unified message types for session parsers (matches Rust UnifiedMessage)
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
export interface TokenBreakdown {
|
|
6
|
-
input: number;
|
|
7
|
-
output: number;
|
|
8
|
-
cacheRead: number;
|
|
9
|
-
cacheWrite: number;
|
|
10
|
-
reasoning: number;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
export interface UnifiedMessage {
|
|
14
|
-
source: string;
|
|
15
|
-
modelId: string;
|
|
16
|
-
providerId: string;
|
|
17
|
-
sessionId: string;
|
|
18
|
-
timestamp: number;
|
|
19
|
-
date: string;
|
|
20
|
-
tokens: TokenBreakdown;
|
|
21
|
-
cost: number;
|
|
22
|
-
agent?: string;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
export type SourceType = "opencode" | "claude" | "codex" | "gemini" | "cursor" | "amp" | "droid" | "openclaw" | "pi" | "kimi";
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* Convert Unix milliseconds timestamp to YYYY-MM-DD date string
|
|
29
|
-
*/
|
|
30
|
-
export function timestampToDate(timestampMs: number): string {
|
|
31
|
-
const date = new Date(timestampMs);
|
|
32
|
-
const year = date.getUTCFullYear();
|
|
33
|
-
const month = String(date.getUTCMonth() + 1).padStart(2, "0");
|
|
34
|
-
const day = String(date.getUTCDate()).padStart(2, "0");
|
|
35
|
-
return `${year}-${month}-${day}`;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
export function createUnifiedMessage(
|
|
39
|
-
source: string,
|
|
40
|
-
modelId: string,
|
|
41
|
-
providerId: string,
|
|
42
|
-
sessionId: string,
|
|
43
|
-
timestamp: number,
|
|
44
|
-
tokens: TokenBreakdown,
|
|
45
|
-
cost: number = 0,
|
|
46
|
-
agent?: string
|
|
47
|
-
): UnifiedMessage {
|
|
48
|
-
return {
|
|
49
|
-
source,
|
|
50
|
-
modelId,
|
|
51
|
-
providerId,
|
|
52
|
-
sessionId,
|
|
53
|
-
timestamp,
|
|
54
|
-
date: timestampToDate(timestamp),
|
|
55
|
-
tokens,
|
|
56
|
-
cost,
|
|
57
|
-
agent,
|
|
58
|
-
};
|
|
59
|
-
}
|