@tokscale/cli 1.2.2 → 1.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.
- package/dist/cli.js +27 -8
- package/dist/cli.js.map +1 -1
- package/dist/graph-types.d.ts +1 -1
- package/dist/graph-types.d.ts.map +1 -1
- package/dist/native.d.ts +1 -0
- package/dist/native.d.ts.map +1 -1
- package/dist/native.js.map +1 -1
- package/dist/sessions/types.d.ts +1 -1
- package/dist/sessions/types.d.ts.map +1 -1
- package/dist/submit.d.ts +1 -0
- package/dist/submit.d.ts.map +1 -1
- package/dist/submit.js +3 -1
- package/dist/submit.js.map +1 -1
- package/dist/tui/App.d.ts.map +1 -1
- package/dist/tui/App.js +4 -0
- package/dist/tui/App.js.map +1 -1
- package/dist/tui/hooks/useData.d.ts.map +1 -1
- package/dist/tui/hooks/useData.js +2 -1
- package/dist/tui/hooks/useData.js.map +1 -1
- package/dist/tui/types/index.d.ts +1 -1
- package/dist/tui/types/index.d.ts.map +1 -1
- package/dist/tui/types/index.js +2 -1
- package/dist/tui/types/index.js.map +1 -1
- package/dist/tui/utils/colors.d.ts.map +1 -1
- package/dist/tui/utils/colors.js +3 -0
- package/dist/tui/utils/colors.js.map +1 -1
- package/dist/wrapped.d.ts.map +1 -1
- package/dist/wrapped.js +5 -2
- package/dist/wrapped.js.map +1 -1
- package/package.json +2 -2
- package/src/cli.ts +27 -8
- package/src/graph-types.ts +1 -1
- package/src/native.ts +4 -2
- package/src/sessions/types.ts +1 -1
- package/src/submit.ts +4 -2
- package/src/tui/App.tsx +1 -0
- package/src/tui/hooks/useData.ts +3 -2
- package/src/tui/types/index.ts +3 -2
- package/src/tui/utils/colors.ts +2 -0
- package/src/wrapped.ts +6 -3
package/src/cli.ts
CHANGED
|
@@ -121,6 +121,7 @@ interface FilterOptions {
|
|
|
121
121
|
amp?: boolean;
|
|
122
122
|
droid?: boolean;
|
|
123
123
|
openclaw?: boolean;
|
|
124
|
+
pi?: boolean;
|
|
124
125
|
}
|
|
125
126
|
|
|
126
127
|
interface DateFilterOptions {
|
|
@@ -446,6 +447,7 @@ async function main() {
|
|
|
446
447
|
.option("--amp", "Show only Amp usage")
|
|
447
448
|
.option("--droid", "Show only Factory Droid usage")
|
|
448
449
|
.option("--openclaw", "Show only OpenClaw usage")
|
|
450
|
+
.option("--pi", "Show only Pi usage")
|
|
449
451
|
.option("--today", "Show only today's usage")
|
|
450
452
|
.option("--week", "Show last 7 days")
|
|
451
453
|
.option("--month", "Show current month")
|
|
@@ -483,6 +485,7 @@ async function main() {
|
|
|
483
485
|
.option("--amp", "Show only Amp usage")
|
|
484
486
|
.option("--droid", "Show only Factory Droid usage")
|
|
485
487
|
.option("--openclaw", "Show only OpenClaw usage")
|
|
488
|
+
.option("--pi", "Show only Pi usage")
|
|
486
489
|
.option("--today", "Show only today's usage")
|
|
487
490
|
.option("--week", "Show last 7 days")
|
|
488
491
|
.option("--month", "Show current month")
|
|
@@ -529,12 +532,13 @@ async function main() {
|
|
|
529
532
|
path.join(homeDir, ".moltbot", "agents"),
|
|
530
533
|
path.join(homeDir, ".moldbot", "agents"),
|
|
531
534
|
];
|
|
535
|
+
const piSessions = path.join(homeDir, ".pi", "agent", "sessions");
|
|
532
536
|
|
|
533
537
|
let localMessages: ParsedMessages | null = null;
|
|
534
538
|
try {
|
|
535
539
|
localMessages = await parseLocalSourcesAsync({
|
|
536
540
|
homeDir,
|
|
537
|
-
sources: ["opencode", "claude", "codex", "gemini", "amp", "droid", "openclaw"],
|
|
541
|
+
sources: ["opencode", "claude", "codex", "gemini", "amp", "droid", "openclaw", "pi"],
|
|
538
542
|
});
|
|
539
543
|
} catch (e) {
|
|
540
544
|
console.error(`Error: ${(e as Error).message}`);
|
|
@@ -634,6 +638,15 @@ async function main() {
|
|
|
634
638
|
headlessPaths: [],
|
|
635
639
|
headlessMessageCount: 0,
|
|
636
640
|
},
|
|
641
|
+
{
|
|
642
|
+
source: "pi",
|
|
643
|
+
label: "Pi",
|
|
644
|
+
sessionsPath: piSessions,
|
|
645
|
+
messageCount: localMessages.piCount,
|
|
646
|
+
headlessSupported: false,
|
|
647
|
+
headlessPaths: [],
|
|
648
|
+
headlessMessageCount: 0,
|
|
649
|
+
},
|
|
637
650
|
];
|
|
638
651
|
|
|
639
652
|
if (options.json) {
|
|
@@ -723,6 +736,7 @@ async function main() {
|
|
|
723
736
|
.option("--amp", "Include only Amp data")
|
|
724
737
|
.option("--droid", "Include only Factory Droid data")
|
|
725
738
|
.option("--openclaw", "Include only OpenClaw data")
|
|
739
|
+
.option("--pi", "Include only Pi data")
|
|
726
740
|
.option("--today", "Show only today's usage")
|
|
727
741
|
.option("--week", "Show last 7 days")
|
|
728
742
|
.option("--month", "Show current month")
|
|
@@ -748,6 +762,7 @@ async function main() {
|
|
|
748
762
|
.option("--amp", "Include only Amp data")
|
|
749
763
|
.option("--droid", "Include only Factory Droid data")
|
|
750
764
|
.option("--openclaw", "Include only OpenClaw data")
|
|
765
|
+
.option("--pi", "Include only Pi data")
|
|
751
766
|
.option("--no-spinner", "Disable loading spinner (for scripting)")
|
|
752
767
|
.option("--short", "Display total tokens in abbreviated format (e.g., 7.14B)")
|
|
753
768
|
.addOption(new Option("--agents", "Show Top OpenCode Agents (default)").conflicts("clients"))
|
|
@@ -793,6 +808,7 @@ async function main() {
|
|
|
793
808
|
.option("--amp", "Include only Amp data")
|
|
794
809
|
.option("--droid", "Include only Factory Droid data")
|
|
795
810
|
.option("--openclaw", "Include only OpenClaw data")
|
|
811
|
+
.option("--pi", "Include only Pi data")
|
|
796
812
|
.option("--since <date>", "Start date (YYYY-MM-DD)")
|
|
797
813
|
.option("--until <date>", "End date (YYYY-MM-DD)")
|
|
798
814
|
.option("--year <year>", "Filter to specific year")
|
|
@@ -807,6 +823,7 @@ async function main() {
|
|
|
807
823
|
amp: options.amp,
|
|
808
824
|
droid: options.droid,
|
|
809
825
|
openclaw: options.openclaw,
|
|
826
|
+
pi: options.pi,
|
|
810
827
|
since: options.since,
|
|
811
828
|
until: options.until,
|
|
812
829
|
year: options.year,
|
|
@@ -829,6 +846,7 @@ async function main() {
|
|
|
829
846
|
.option("--amp", "Show only Amp usage")
|
|
830
847
|
.option("--droid", "Show only Factory Droid usage")
|
|
831
848
|
.option("--openclaw", "Show only OpenClaw usage")
|
|
849
|
+
.option("--pi", "Show only Pi usage")
|
|
832
850
|
.option("--today", "Show only today's usage")
|
|
833
851
|
.option("--week", "Show last 7 days")
|
|
834
852
|
.option("--month", "Show current month")
|
|
@@ -985,7 +1003,7 @@ async function main() {
|
|
|
985
1003
|
}
|
|
986
1004
|
|
|
987
1005
|
function getEnabledSources(options: FilterOptions): SourceType[] | undefined {
|
|
988
|
-
const hasFilter = options.opencode || options.claude || options.codex || options.gemini || options.cursor || options.amp || options.droid || options.openclaw;
|
|
1006
|
+
const hasFilter = options.opencode || options.claude || options.codex || options.gemini || options.cursor || options.amp || options.droid || options.openclaw || options.pi;
|
|
989
1007
|
if (!hasFilter) return undefined; // All sources
|
|
990
1008
|
|
|
991
1009
|
const sources: SourceType[] = [];
|
|
@@ -997,6 +1015,7 @@ function getEnabledSources(options: FilterOptions): SourceType[] | undefined {
|
|
|
997
1015
|
if (options.amp) sources.push("amp");
|
|
998
1016
|
if (options.droid) sources.push("droid");
|
|
999
1017
|
if (options.openclaw) sources.push("openclaw");
|
|
1018
|
+
if (options.pi) sources.push("pi");
|
|
1000
1019
|
return sources;
|
|
1001
1020
|
}
|
|
1002
1021
|
|
|
@@ -1086,7 +1105,7 @@ async function showModelReport(options: FilterOptions & DateFilterOptions & { be
|
|
|
1086
1105
|
const useSpinner = extraOptions?.spinner !== false;
|
|
1087
1106
|
const spinner = useSpinner ? createSpinner({ color: "cyan" }) : null;
|
|
1088
1107
|
|
|
1089
|
-
const localSources: SourceType[] = (enabledSources || ['opencode', 'claude', 'codex', 'gemini', 'cursor', 'amp', 'droid', 'openclaw'])
|
|
1108
|
+
const localSources: SourceType[] = (enabledSources || ['opencode', 'claude', 'codex', 'gemini', 'cursor', 'amp', 'droid', 'openclaw', 'pi'])
|
|
1090
1109
|
.filter(s => s !== 'cursor');
|
|
1091
1110
|
|
|
1092
1111
|
spinner?.start(pc.gray("Scanning session data..."));
|
|
@@ -1116,7 +1135,7 @@ async function showModelReport(options: FilterOptions & DateFilterOptions & { be
|
|
|
1116
1135
|
|
|
1117
1136
|
let report: ModelReport;
|
|
1118
1137
|
try {
|
|
1119
|
-
const emptyMessages: ParsedMessages = { messages: [], opencodeCount: 0, claudeCount: 0, codexCount: 0, geminiCount: 0, ampCount: 0, droidCount: 0, openclawCount: 0, processingTimeMs: 0 };
|
|
1138
|
+
const emptyMessages: ParsedMessages = { messages: [], opencodeCount: 0, claudeCount: 0, codexCount: 0, geminiCount: 0, ampCount: 0, droidCount: 0, openclawCount: 0, piCount: 0, processingTimeMs: 0 };
|
|
1120
1139
|
report = await finalizeReportAsync({
|
|
1121
1140
|
localMessages: localMessages || emptyMessages,
|
|
1122
1141
|
includeCursor: includeCursor && (cursorSync.synced || hasCursorUsageCache()),
|
|
@@ -1223,7 +1242,7 @@ async function showMonthlyReport(options: FilterOptions & DateFilterOptions & {
|
|
|
1223
1242
|
|
|
1224
1243
|
const dateFilters = getDateFilters(options);
|
|
1225
1244
|
const enabledSources = getEnabledSources(options);
|
|
1226
|
-
const localSources: SourceType[] = (enabledSources || ['opencode', 'claude', 'codex', 'gemini', 'cursor', 'amp', 'droid', 'openclaw'])
|
|
1245
|
+
const localSources: SourceType[] = (enabledSources || ['opencode', 'claude', 'codex', 'gemini', 'cursor', 'amp', 'droid', 'openclaw', 'pi'])
|
|
1227
1246
|
.filter(s => s !== 'cursor');
|
|
1228
1247
|
const includeCursor = !enabledSources || enabledSources.includes('cursor');
|
|
1229
1248
|
|
|
@@ -1332,7 +1351,7 @@ async function outputJsonReport(
|
|
|
1332
1351
|
const enabledSources = getEnabledSources(options);
|
|
1333
1352
|
const onlyCursor = enabledSources?.length === 1 && enabledSources[0] === 'cursor';
|
|
1334
1353
|
const includeCursor = !enabledSources || enabledSources.includes('cursor');
|
|
1335
|
-
const localSources: SourceType[] = (enabledSources || ['opencode', 'claude', 'codex', 'gemini', 'cursor', 'amp', 'droid', 'openclaw'])
|
|
1354
|
+
const localSources: SourceType[] = (enabledSources || ['opencode', 'claude', 'codex', 'gemini', 'cursor', 'amp', 'droid', 'openclaw', 'pi'])
|
|
1336
1355
|
.filter(s => s !== 'cursor');
|
|
1337
1356
|
|
|
1338
1357
|
const { cursorSync, localMessages } = await loadDataSourcesParallel(
|
|
@@ -1345,7 +1364,7 @@ async function outputJsonReport(
|
|
|
1345
1364
|
process.exit(1);
|
|
1346
1365
|
}
|
|
1347
1366
|
|
|
1348
|
-
const emptyMessages: ParsedMessages = { messages: [], opencodeCount: 0, claudeCount: 0, codexCount: 0, geminiCount: 0, ampCount: 0, droidCount: 0, openclawCount: 0, processingTimeMs: 0 };
|
|
1367
|
+
const emptyMessages: ParsedMessages = { messages: [], opencodeCount: 0, claudeCount: 0, codexCount: 0, geminiCount: 0, ampCount: 0, droidCount: 0, openclawCount: 0, piCount: 0, processingTimeMs: 0 };
|
|
1349
1368
|
|
|
1350
1369
|
if (reportType === "models") {
|
|
1351
1370
|
const report = await finalizeReportAsync({
|
|
@@ -1380,7 +1399,7 @@ async function handleGraphCommand(options: GraphCommandOptions) {
|
|
|
1380
1399
|
|
|
1381
1400
|
const dateFilters = getDateFilters(options);
|
|
1382
1401
|
const enabledSources = getEnabledSources(options);
|
|
1383
|
-
const localSources: SourceType[] = (enabledSources || ['opencode', 'claude', 'codex', 'gemini', 'cursor', 'amp', 'droid', 'openclaw'])
|
|
1402
|
+
const localSources: SourceType[] = (enabledSources || ['opencode', 'claude', 'codex', 'gemini', 'cursor', 'amp', 'droid', 'openclaw', 'pi'])
|
|
1384
1403
|
.filter(s => s !== 'cursor');
|
|
1385
1404
|
const includeCursor = !enabledSources || enabledSources.includes('cursor');
|
|
1386
1405
|
|
package/src/graph-types.ts
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
/**
|
|
7
7
|
* Valid source identifiers
|
|
8
8
|
*/
|
|
9
|
-
export type SourceType = "opencode" | "claude" | "codex" | "gemini" | "cursor" | "amp" | "droid" | "openclaw";
|
|
9
|
+
export type SourceType = "opencode" | "claude" | "codex" | "gemini" | "cursor" | "amp" | "droid" | "openclaw" | "pi";
|
|
10
10
|
|
|
11
11
|
/**
|
|
12
12
|
* Token breakdown by category
|
package/src/native.ts
CHANGED
|
@@ -153,8 +153,9 @@ interface NativeParsedMessages {
|
|
|
153
153
|
codexCount: number;
|
|
154
154
|
geminiCount: number;
|
|
155
155
|
ampCount: number;
|
|
156
|
-
droidCount
|
|
157
|
-
openclawCount
|
|
156
|
+
droidCount: number;
|
|
157
|
+
openclawCount: number;
|
|
158
|
+
piCount: number;
|
|
158
159
|
processingTimeMs: number;
|
|
159
160
|
}
|
|
160
161
|
|
|
@@ -355,6 +356,7 @@ export interface ParsedMessages {
|
|
|
355
356
|
ampCount: number;
|
|
356
357
|
droidCount: number;
|
|
357
358
|
openclawCount: number;
|
|
359
|
+
piCount: number;
|
|
358
360
|
processingTimeMs: number;
|
|
359
361
|
}
|
|
360
362
|
|
package/src/sessions/types.ts
CHANGED
|
@@ -22,7 +22,7 @@ export interface UnifiedMessage {
|
|
|
22
22
|
agent?: string;
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
-
export type SourceType = "opencode" | "claude" | "codex" | "gemini" | "cursor" | "amp" | "droid" | "openclaw";
|
|
25
|
+
export type SourceType = "opencode" | "claude" | "codex" | "gemini" | "cursor" | "amp" | "droid" | "openclaw" | "pi";
|
|
26
26
|
|
|
27
27
|
/**
|
|
28
28
|
* Convert Unix milliseconds timestamp to YYYY-MM-DD date string
|
package/src/submit.ts
CHANGED
|
@@ -25,6 +25,7 @@ interface SubmitOptions {
|
|
|
25
25
|
amp?: boolean;
|
|
26
26
|
droid?: boolean;
|
|
27
27
|
openclaw?: boolean;
|
|
28
|
+
pi?: boolean;
|
|
28
29
|
since?: string;
|
|
29
30
|
until?: string;
|
|
30
31
|
year?: string;
|
|
@@ -50,7 +51,7 @@ interface SubmitResponse {
|
|
|
50
51
|
details?: string[];
|
|
51
52
|
}
|
|
52
53
|
|
|
53
|
-
type SourceType = "opencode" | "claude" | "codex" | "gemini" | "cursor" | "amp" | "droid" | "openclaw";
|
|
54
|
+
type SourceType = "opencode" | "claude" | "codex" | "gemini" | "cursor" | "amp" | "droid" | "openclaw" | "pi";
|
|
54
55
|
|
|
55
56
|
async function checkGhCliExists(): Promise<boolean> {
|
|
56
57
|
try {
|
|
@@ -193,7 +194,7 @@ export async function submit(options: SubmitOptions = {}): Promise<void> {
|
|
|
193
194
|
|
|
194
195
|
console.log(pc.gray(" Scanning local session data..."));
|
|
195
196
|
|
|
196
|
-
const hasFilter = options.opencode || options.claude || options.codex || options.gemini || options.cursor || options.amp || options.droid || options.openclaw;
|
|
197
|
+
const hasFilter = options.opencode || options.claude || options.codex || options.gemini || options.cursor || options.amp || options.droid || options.openclaw || options.pi;
|
|
197
198
|
let sources: SourceType[] | undefined;
|
|
198
199
|
let includeCursor = true;
|
|
199
200
|
if (hasFilter) {
|
|
@@ -206,6 +207,7 @@ export async function submit(options: SubmitOptions = {}): Promise<void> {
|
|
|
206
207
|
if (options.amp) sources.push("amp");
|
|
207
208
|
if (options.droid) sources.push("droid");
|
|
208
209
|
if (options.openclaw) sources.push("openclaw");
|
|
210
|
+
if (options.pi) sources.push("pi");
|
|
209
211
|
includeCursor = sources.includes("cursor");
|
|
210
212
|
}
|
|
211
213
|
|
package/src/tui/App.tsx
CHANGED
|
@@ -288,6 +288,7 @@ export function App(props: AppProps) {
|
|
|
288
288
|
if (key.name === "6") { handleSourceToggle("amp"); return; }
|
|
289
289
|
if (key.name === "7") { handleSourceToggle("droid"); return; }
|
|
290
290
|
if (key.name === "8") { handleSourceToggle("openclaw"); return; }
|
|
291
|
+
if (key.name === "9") { handleSourceToggle("pi"); return; }
|
|
291
292
|
|
|
292
293
|
if (key.name === "up") {
|
|
293
294
|
if (activeTab() === "overview") {
|
package/src/tui/hooks/useData.ts
CHANGED
|
@@ -158,8 +158,8 @@ async function loadData(
|
|
|
158
158
|
const phase1Results = await Promise.allSettled([
|
|
159
159
|
includeCursor && isCursorLoggedIn() ? syncCursorCache() : Promise.resolve({ synced: false, rows: 0, error: undefined }),
|
|
160
160
|
localSources.length > 0
|
|
161
|
-
? parseLocalSourcesAsync({ sources: localSources as ("opencode" | "claude" | "codex" | "gemini" | "amp" | "droid" | "openclaw")[], since, until, year })
|
|
162
|
-
: Promise.resolve({ messages: [], opencodeCount: 0, claudeCount: 0, codexCount: 0, geminiCount: 0, ampCount: 0, droidCount: 0, openclawCount: 0, processingTimeMs: 0 } as ParsedMessages),
|
|
161
|
+
? parseLocalSourcesAsync({ sources: localSources as ("opencode" | "claude" | "codex" | "gemini" | "amp" | "droid" | "openclaw" | "pi")[], since, until, year })
|
|
162
|
+
: Promise.resolve({ messages: [], opencodeCount: 0, claudeCount: 0, codexCount: 0, geminiCount: 0, ampCount: 0, droidCount: 0, openclawCount: 0, piCount: 0, processingTimeMs: 0 } as ParsedMessages),
|
|
163
163
|
]);
|
|
164
164
|
|
|
165
165
|
const cursorSync = phase1Results[0].status === "fulfilled"
|
|
@@ -184,6 +184,7 @@ async function loadData(
|
|
|
184
184
|
ampCount: 0,
|
|
185
185
|
droidCount: 0,
|
|
186
186
|
openclawCount: 0,
|
|
187
|
+
piCount: 0,
|
|
187
188
|
processingTimeMs: 0,
|
|
188
189
|
};
|
|
189
190
|
|
package/src/tui/types/index.ts
CHANGED
|
@@ -2,7 +2,7 @@ import type { ColorPaletteName } from "../config/themes.js";
|
|
|
2
2
|
|
|
3
3
|
export type TabType = "overview" | "model" | "daily" | "stats";
|
|
4
4
|
export type SortType = "cost" | "tokens" | "date";
|
|
5
|
-
export type SourceType = "opencode" | "claude" | "codex" | "cursor" | "gemini" | "amp" | "droid" | "openclaw";
|
|
5
|
+
export type SourceType = "opencode" | "claude" | "codex" | "cursor" | "gemini" | "amp" | "droid" | "openclaw" | "pi";
|
|
6
6
|
|
|
7
7
|
export type { ColorPaletteName };
|
|
8
8
|
|
|
@@ -163,7 +163,8 @@ export const SOURCE_LABELS: Record<SourceType, string> = {
|
|
|
163
163
|
amp: "AM",
|
|
164
164
|
droid: "DR",
|
|
165
165
|
openclaw: "CL",
|
|
166
|
+
pi: "PI",
|
|
166
167
|
} as const;
|
|
167
168
|
|
|
168
169
|
export const TABS: readonly TabType[] = ["overview", "model", "daily", "stats"] as const;
|
|
169
|
-
export const ALL_SOURCES: readonly SourceType[] = ["opencode", "claude", "codex", "cursor", "gemini", "amp", "droid", "openclaw"] as const;
|
|
170
|
+
export const ALL_SOURCES: readonly SourceType[] = ["opencode", "claude", "codex", "cursor", "gemini", "amp", "droid", "openclaw", "pi"] as const;
|
package/src/tui/utils/colors.ts
CHANGED
|
@@ -61,6 +61,7 @@ export const SOURCE_COLORS: Record<SourceType, string> = {
|
|
|
61
61
|
amp: "#EC4899",
|
|
62
62
|
droid: "#10b981",
|
|
63
63
|
openclaw: "#ef4444",
|
|
64
|
+
pi: "#f97316",
|
|
64
65
|
};
|
|
65
66
|
|
|
66
67
|
export function getSourceColor(source: SourceType | string): string {
|
|
@@ -70,5 +71,6 @@ export function getSourceColor(source: SourceType | string): string {
|
|
|
70
71
|
export function getSourceDisplayName(source: string): string {
|
|
71
72
|
if (source === "droid") return "Droid";
|
|
72
73
|
if (source === "openclaw") return "OpenClaw";
|
|
74
|
+
if (source === "pi") return "Pi";
|
|
73
75
|
return source.charAt(0).toUpperCase() + source.slice(1);
|
|
74
76
|
}
|
package/src/wrapped.ts
CHANGED
|
@@ -65,6 +65,7 @@ const SOURCE_DISPLAY_NAMES: Record<string, string> = {
|
|
|
65
65
|
amp: "Amp",
|
|
66
66
|
droid: "Droid",
|
|
67
67
|
openclaw: "OpenClaw",
|
|
68
|
+
pi: "Pi",
|
|
68
69
|
};
|
|
69
70
|
|
|
70
71
|
const ASSETS_BASE_URL = "https://tokscale.ai/assets/logos";
|
|
@@ -97,6 +98,7 @@ const CLIENT_LOGO_URLS: Record<string, string> = {
|
|
|
97
98
|
"Amp": `${ASSETS_BASE_URL}/amp.png`,
|
|
98
99
|
"Droid": `${ASSETS_BASE_URL}/droid.png`,
|
|
99
100
|
"OpenClaw": `${ASSETS_BASE_URL}/openclaw.png`,
|
|
101
|
+
"Pi": `${ASSETS_BASE_URL}/pi.png`,
|
|
100
102
|
};
|
|
101
103
|
|
|
102
104
|
const PROVIDER_LOGO_URLS: Record<string, string> = {
|
|
@@ -214,8 +216,8 @@ async function ensureFontsLoaded(): Promise<void> {
|
|
|
214
216
|
|
|
215
217
|
async function loadWrappedData(options: WrappedOptions): Promise<WrappedData> {
|
|
216
218
|
const year = options.year || new Date().getFullYear().toString();
|
|
217
|
-
const sources = options.sources || ["opencode", "claude", "codex", "gemini", "cursor", "amp", "droid", "openclaw"];
|
|
218
|
-
const localSources = sources.filter(s => s !== "cursor") as ("opencode" | "claude" | "codex" | "gemini" | "amp" | "droid" | "openclaw")[];
|
|
219
|
+
const sources = options.sources || ["opencode", "claude", "codex", "gemini", "cursor", "amp", "droid", "openclaw", "pi"];
|
|
220
|
+
const localSources = sources.filter(s => s !== "cursor") as ("opencode" | "claude" | "codex" | "gemini" | "amp" | "droid" | "openclaw" | "pi")[];
|
|
219
221
|
const includeCursor = sources.includes("cursor");
|
|
220
222
|
|
|
221
223
|
const since = `${year}-01-01`;
|
|
@@ -225,7 +227,7 @@ async function loadWrappedData(options: WrappedOptions): Promise<WrappedData> {
|
|
|
225
227
|
includeCursor && isCursorLoggedIn() ? syncCursorCache() : Promise.resolve({ synced: false, rows: 0, error: undefined }),
|
|
226
228
|
localSources.length > 0
|
|
227
229
|
? parseLocalSourcesAsync({ sources: localSources, since, until, year })
|
|
228
|
-
: Promise.resolve({ messages: [], opencodeCount: 0, claudeCount: 0, codexCount: 0, geminiCount: 0, ampCount: 0, droidCount: 0, openclawCount: 0, processingTimeMs: 0 } as ParsedMessages),
|
|
230
|
+
: Promise.resolve({ messages: [], opencodeCount: 0, claudeCount: 0, codexCount: 0, geminiCount: 0, ampCount: 0, droidCount: 0, openclawCount: 0, piCount: 0, processingTimeMs: 0 } as ParsedMessages),
|
|
229
231
|
]);
|
|
230
232
|
|
|
231
233
|
const cursorSync = phase1Results[0].status === "fulfilled"
|
|
@@ -249,6 +251,7 @@ async function loadWrappedData(options: WrappedOptions): Promise<WrappedData> {
|
|
|
249
251
|
ampCount: 0,
|
|
250
252
|
droidCount: 0,
|
|
251
253
|
openclawCount: 0,
|
|
254
|
+
piCount: 0,
|
|
252
255
|
processingTimeMs: 0,
|
|
253
256
|
};
|
|
254
257
|
|