@tokscale/cli 1.0.12 → 1.0.13
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 +47 -5
- package/dist/cli.js.map +1 -1
- package/dist/tui/config/themes.d.ts.map +1 -1
- package/dist/tui/config/themes.js +1 -1
- package/dist/tui/config/themes.js.map +1 -1
- package/dist/wrapped.d.ts +35 -0
- package/dist/wrapped.d.ts.map +1 -0
- package/dist/wrapped.js +569 -0
- package/dist/wrapped.js.map +1 -0
- package/package.json +4 -2
- package/src/cli.ts +55 -5
- package/src/tui/config/themes.ts +1 -1
- package/src/wrapped.ts +673 -0
package/src/cli.ts
CHANGED
|
@@ -13,6 +13,7 @@ const pkg = require("../package.json") as { version: string };
|
|
|
13
13
|
import pc from "picocolors";
|
|
14
14
|
import { login, logout, whoami } from "./auth.js";
|
|
15
15
|
import { submit } from "./submit.js";
|
|
16
|
+
import { generateWrapped } from "./wrapped.js";
|
|
16
17
|
import { PricingFetcher } from "./pricing.js";
|
|
17
18
|
import {
|
|
18
19
|
loadCursorCredentials,
|
|
@@ -203,7 +204,7 @@ async function main() {
|
|
|
203
204
|
|
|
204
205
|
program
|
|
205
206
|
.name("tokscale")
|
|
206
|
-
.description("
|
|
207
|
+
.description("Tokscale - Track AI coding costs across OpenCode, Claude Code, Codex, Gemini, and Cursor")
|
|
207
208
|
.version(pkg.version);
|
|
208
209
|
|
|
209
210
|
program
|
|
@@ -292,9 +293,21 @@ async function main() {
|
|
|
292
293
|
await handleGraphCommand(options);
|
|
293
294
|
});
|
|
294
295
|
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
296
|
+
program
|
|
297
|
+
.command("wrapped")
|
|
298
|
+
.description("Generate 2025 Wrapped shareable image")
|
|
299
|
+
.option("--output <file>", "Output file path (default: tokscale-2025-wrapped.png)")
|
|
300
|
+
.option("--year <year>", "Year to generate wrapped for (default: current year)")
|
|
301
|
+
.option("--opencode", "Include only OpenCode data")
|
|
302
|
+
.option("--claude", "Include only Claude Code data")
|
|
303
|
+
.option("--codex", "Include only Codex CLI data")
|
|
304
|
+
.option("--gemini", "Include only Gemini CLI data")
|
|
305
|
+
.option("--cursor", "Include only Cursor IDE data")
|
|
306
|
+
.option("--no-spinner", "Disable loading spinner (for scripting)")
|
|
307
|
+
.option("--short", "Display total tokens in abbreviated format (e.g., 7.14B)")
|
|
308
|
+
.action(async (options) => {
|
|
309
|
+
await handleWrappedCommand(options);
|
|
310
|
+
});
|
|
298
311
|
|
|
299
312
|
program
|
|
300
313
|
.command("login")
|
|
@@ -410,7 +423,7 @@ async function main() {
|
|
|
410
423
|
// Global flags should go to main program
|
|
411
424
|
const isGlobalFlag = ['--help', '-h', '--version', '-V'].includes(firstArg);
|
|
412
425
|
const hasSubcommand = args.length > 0 && !firstArg.startsWith('-');
|
|
413
|
-
const knownCommands = ['monthly', 'models', 'graph', 'login', 'logout', 'whoami', 'submit', 'cursor', 'tui', 'help'];
|
|
426
|
+
const knownCommands = ['monthly', 'models', 'graph', 'wrapped', 'login', 'logout', 'whoami', 'submit', 'cursor', 'tui', 'help'];
|
|
414
427
|
const isKnownCommand = hasSubcommand && knownCommands.includes(firstArg);
|
|
415
428
|
|
|
416
429
|
if (isKnownCommand || isGlobalFlag) {
|
|
@@ -908,6 +921,43 @@ async function handleGraphCommand(options: GraphCommandOptions) {
|
|
|
908
921
|
}
|
|
909
922
|
}
|
|
910
923
|
|
|
924
|
+
interface WrappedCommandOptions extends FilterOptions {
|
|
925
|
+
output?: string;
|
|
926
|
+
year?: string;
|
|
927
|
+
spinner?: boolean; // --no-spinner sets this to false
|
|
928
|
+
short?: boolean;
|
|
929
|
+
}
|
|
930
|
+
|
|
931
|
+
async function handleWrappedCommand(options: WrappedCommandOptions) {
|
|
932
|
+
const useSpinner = options.spinner !== false;
|
|
933
|
+
const spinner = useSpinner ? createSpinner({ color: "cyan" }) : null;
|
|
934
|
+
spinner?.start(pc.gray("Generating your 2025 Wrapped..."));
|
|
935
|
+
|
|
936
|
+
try {
|
|
937
|
+
const enabledSources = getEnabledSources(options);
|
|
938
|
+
const outputPath = await generateWrapped({
|
|
939
|
+
output: options.output,
|
|
940
|
+
year: options.year || "2025",
|
|
941
|
+
sources: enabledSources,
|
|
942
|
+
short: options.short,
|
|
943
|
+
});
|
|
944
|
+
|
|
945
|
+
spinner?.stop();
|
|
946
|
+
console.log(pc.green(`\n ✓ Your Tokscale Wrapped image is ready!`));
|
|
947
|
+
console.log(pc.white(` ${outputPath}`));
|
|
948
|
+
console.log();
|
|
949
|
+
console.log(pc.gray(" Share it on Twitter/X with #TokscaleWrapped"));
|
|
950
|
+
console.log();
|
|
951
|
+
} catch (error) {
|
|
952
|
+
if (spinner) {
|
|
953
|
+
spinner.error(`Failed to generate wrapped: ${(error as Error).message}`);
|
|
954
|
+
} else {
|
|
955
|
+
console.error(pc.red(`Failed to generate wrapped: ${(error as Error).message}`));
|
|
956
|
+
}
|
|
957
|
+
process.exit(1);
|
|
958
|
+
}
|
|
959
|
+
}
|
|
960
|
+
|
|
911
961
|
function getSourceLabel(source: string): string {
|
|
912
962
|
switch (source) {
|
|
913
963
|
case "opencode":
|
package/src/tui/config/themes.ts
CHANGED
|
@@ -95,7 +95,7 @@ export const colorPalettes: Record<ColorPaletteName, GraphColorPalette> = {
|
|
|
95
95
|
},
|
|
96
96
|
};
|
|
97
97
|
|
|
98
|
-
export const DEFAULT_PALETTE: ColorPaletteName = "
|
|
98
|
+
export const DEFAULT_PALETTE: ColorPaletteName = "blue";
|
|
99
99
|
|
|
100
100
|
export const getPaletteNames = (): ColorPaletteName[] =>
|
|
101
101
|
Object.keys(colorPalettes) as ColorPaletteName[];
|