token-rats 0.0.2 → 0.0.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/README.md +0 -4
- package/dist/index.js +86 -8
- package/package.json +18 -5
package/README.md
CHANGED
|
@@ -86,7 +86,3 @@ Authentication uses a device-code flow:
|
|
|
86
86
|
Token Rats is open source. The CLI source is in [`packages/cli/`](.) and the parsers are in [`packages/parsers/`](../parsers/). You can inspect exactly what is read from your disk and what is sent to the server.
|
|
87
87
|
|
|
88
88
|
**Privacy posture:** Token Rats reads usage counts only — never prompts or completions. The parser source is in `packages/parsers/`. We literally can't read what you typed.
|
|
89
|
-
|
|
90
|
-
## License
|
|
91
|
-
|
|
92
|
-
MIT
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,37 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
+
// src/commands/install-cursor.ts
|
|
4
|
+
import { spawn } from "node:child_process";
|
|
5
|
+
async function installCursorCommand(opts = {}) {
|
|
6
|
+
const pm = opts.packageManager ?? "npm";
|
|
7
|
+
console.log("\x1B[1mtoken-rats install-cursor\x1B[0m");
|
|
8
|
+
console.log(
|
|
9
|
+
"Installs better-sqlite3 globally for faster Cursor extraction.\nYou don't need this for Cursor support to work \u2014 sql.js (already\nbundled) handles it. This is purely a speed upgrade for large DBs.\n"
|
|
10
|
+
);
|
|
11
|
+
const args = ["install", "-g", "better-sqlite3@^9.4.3"];
|
|
12
|
+
console.log(`\x1B[2m$ ${pm} ${args.join(" ")}\x1B[0m
|
|
13
|
+
`);
|
|
14
|
+
const exitCode = await new Promise((resolve) => {
|
|
15
|
+
const child = spawn(pm, args, { stdio: "inherit" });
|
|
16
|
+
child.on("close", (code) => resolve(code ?? 1));
|
|
17
|
+
child.on("error", (err) => {
|
|
18
|
+
console.error(`\x1B[31mFailed to launch ${pm}: ${err.message}\x1B[0m`);
|
|
19
|
+
resolve(1);
|
|
20
|
+
});
|
|
21
|
+
});
|
|
22
|
+
if (exitCode === 0) {
|
|
23
|
+
console.log(
|
|
24
|
+
"\n\x1B[32m\u2713\x1B[0m Done. Future `token-rats sync` runs will prefer better-sqlite3."
|
|
25
|
+
);
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
console.error(
|
|
29
|
+
`
|
|
30
|
+
\x1B[31mInstall failed (exit ${exitCode}). Cursor still works via sql.js \u2014 no action required.\x1B[0m`
|
|
31
|
+
);
|
|
32
|
+
process.exit(exitCode);
|
|
33
|
+
}
|
|
34
|
+
|
|
3
35
|
// ../../node_modules/.pnpm/zod@3.23.8/node_modules/zod/lib/index.mjs
|
|
4
36
|
var util;
|
|
5
37
|
(function(util2) {
|
|
@@ -4971,6 +5003,7 @@ function toNonNegInt3(v) {
|
|
|
4971
5003
|
}
|
|
4972
5004
|
|
|
4973
5005
|
// src/lib/cursor-extract.ts
|
|
5006
|
+
import { readFile } from "node:fs/promises";
|
|
4974
5007
|
async function tryNodeSqlite(dbPath) {
|
|
4975
5008
|
let DatabaseConstructor;
|
|
4976
5009
|
try {
|
|
@@ -4982,6 +5015,42 @@ async function tryNodeSqlite(dbPath) {
|
|
|
4982
5015
|
}
|
|
4983
5016
|
return readWithDb(() => new DatabaseConstructor(dbPath, { readOnly: true }));
|
|
4984
5017
|
}
|
|
5018
|
+
async function trySqlJs(dbPath) {
|
|
5019
|
+
let initSqlJs;
|
|
5020
|
+
try {
|
|
5021
|
+
const mod = await import("sql.js");
|
|
5022
|
+
initSqlJs = mod.default ?? mod;
|
|
5023
|
+
} catch {
|
|
5024
|
+
return null;
|
|
5025
|
+
}
|
|
5026
|
+
let SQL;
|
|
5027
|
+
let fileBytes;
|
|
5028
|
+
try {
|
|
5029
|
+
SQL = await initSqlJs();
|
|
5030
|
+
fileBytes = await readFile(dbPath);
|
|
5031
|
+
} catch {
|
|
5032
|
+
return null;
|
|
5033
|
+
}
|
|
5034
|
+
const sqlDb = new SQL.Database(new Uint8Array(fileBytes));
|
|
5035
|
+
const adapter = {
|
|
5036
|
+
prepare: (sql) => ({
|
|
5037
|
+
all: () => {
|
|
5038
|
+
const results = sqlDb.exec(sql);
|
|
5039
|
+
if (results.length === 0) return [];
|
|
5040
|
+
const { columns, values } = results[0];
|
|
5041
|
+
return values.map((row) => {
|
|
5042
|
+
const obj = {};
|
|
5043
|
+
for (let i = 0; i < columns.length; i++) {
|
|
5044
|
+
obj[columns[i]] = row[i];
|
|
5045
|
+
}
|
|
5046
|
+
return obj;
|
|
5047
|
+
});
|
|
5048
|
+
}
|
|
5049
|
+
}),
|
|
5050
|
+
close: () => sqlDb.close()
|
|
5051
|
+
};
|
|
5052
|
+
return readWithDb(() => adapter);
|
|
5053
|
+
}
|
|
4985
5054
|
async function tryBetterSqlite3(dbPath) {
|
|
4986
5055
|
let Database;
|
|
4987
5056
|
try {
|
|
@@ -5072,13 +5141,17 @@ async function readCursorDb(dbPath) {
|
|
|
5072
5141
|
if (fromNodeSqlite !== null) {
|
|
5073
5142
|
return { rows: fromNodeSqlite, skipped: null };
|
|
5074
5143
|
}
|
|
5144
|
+
const fromSqlJs = await trySqlJs(dbPath);
|
|
5145
|
+
if (fromSqlJs !== null) {
|
|
5146
|
+
return { rows: fromSqlJs, skipped: null };
|
|
5147
|
+
}
|
|
5075
5148
|
const fromBetter = await tryBetterSqlite3(dbPath);
|
|
5076
5149
|
if (fromBetter !== null) {
|
|
5077
5150
|
return { rows: fromBetter, skipped: null };
|
|
5078
5151
|
}
|
|
5079
5152
|
return {
|
|
5080
5153
|
rows: [],
|
|
5081
|
-
skipped: "Could not open Cursor DB (
|
|
5154
|
+
skipped: "Could not open Cursor DB (sqlite drivers unavailable). Run `npx token-rats install-cursor` for native speed, or upgrade to Node \u226522.5."
|
|
5082
5155
|
};
|
|
5083
5156
|
}
|
|
5084
5157
|
|
|
@@ -5550,7 +5623,7 @@ async function whoamiCommand(opts) {
|
|
|
5550
5623
|
|
|
5551
5624
|
// src/index.ts
|
|
5552
5625
|
function getVersion() {
|
|
5553
|
-
return "0.0.
|
|
5626
|
+
return "0.0.3";
|
|
5554
5627
|
}
|
|
5555
5628
|
function printHelp() {
|
|
5556
5629
|
console.log(`
|
|
@@ -5560,12 +5633,14 @@ function printHelp() {
|
|
|
5560
5633
|
token-rats <command> [flags]
|
|
5561
5634
|
|
|
5562
5635
|
\x1B[1mCommands:\x1B[0m
|
|
5563
|
-
login
|
|
5564
|
-
sync
|
|
5565
|
-
watch
|
|
5566
|
-
whoami
|
|
5567
|
-
logout
|
|
5568
|
-
|
|
5636
|
+
login Authenticate with Token Rats (opens browser)
|
|
5637
|
+
sync Read local Claude Code + Cursor logs and upload counts
|
|
5638
|
+
watch Watch logs in real-time; upload new sessions as they appear
|
|
5639
|
+
whoami Show the currently signed-in account
|
|
5640
|
+
logout Clear your stored credentials
|
|
5641
|
+
install-cursor Install better-sqlite3 globally for faster Cursor reads
|
|
5642
|
+
(sql.js works out of the box \u2014 this is opt-in speed-up)
|
|
5643
|
+
help Show this help message
|
|
5569
5644
|
|
|
5570
5645
|
\x1B[1mFlags (all commands):\x1B[0m
|
|
5571
5646
|
--api-url <url> Override API URL (default: https://api.tokenrats.com)
|
|
@@ -5649,6 +5724,9 @@ async function main() {
|
|
|
5649
5724
|
case "logout":
|
|
5650
5725
|
logoutCommand();
|
|
5651
5726
|
break;
|
|
5727
|
+
case "install-cursor":
|
|
5728
|
+
await installCursorCommand();
|
|
5729
|
+
break;
|
|
5652
5730
|
default:
|
|
5653
5731
|
console.error(`\x1B[31mUnknown command: ${command}\x1B[0m`);
|
|
5654
5732
|
console.error(`Run \x1B[1mtoken-rats help\x1B[0m for a list of commands.`);
|
package/package.json
CHANGED
|
@@ -1,20 +1,30 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "token-rats",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.3",
|
|
4
4
|
"description": "Sync your Claude Code + Cursor token usage to your Token Rats leaderboard.",
|
|
5
|
-
"license": "
|
|
5
|
+
"license": "UNLICENSED",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"bin": {
|
|
8
8
|
"token-rats": "./dist/index.js"
|
|
9
9
|
},
|
|
10
|
-
"files": [
|
|
10
|
+
"files": [
|
|
11
|
+
"dist",
|
|
12
|
+
"README.md"
|
|
13
|
+
],
|
|
11
14
|
"repository": {
|
|
12
15
|
"type": "git",
|
|
13
16
|
"url": "git+https://github.com/hsalberti/token-rats.git",
|
|
14
17
|
"directory": "packages/cli"
|
|
15
18
|
},
|
|
16
19
|
"homepage": "https://tokenrats.com",
|
|
17
|
-
"keywords": [
|
|
20
|
+
"keywords": [
|
|
21
|
+
"claude",
|
|
22
|
+
"claude-code",
|
|
23
|
+
"cursor",
|
|
24
|
+
"tokens",
|
|
25
|
+
"leaderboard",
|
|
26
|
+
"ai-usage"
|
|
27
|
+
],
|
|
18
28
|
"publishConfig": {
|
|
19
29
|
"access": "public"
|
|
20
30
|
},
|
|
@@ -26,7 +36,6 @@
|
|
|
26
36
|
"prepublishOnly": "node build.mjs"
|
|
27
37
|
},
|
|
28
38
|
"optionalDependencies": {
|
|
29
|
-
"better-sqlite3": "^9.4.3",
|
|
30
39
|
"chokidar": "^3.6.0",
|
|
31
40
|
"clipboardy": "^4.0.0",
|
|
32
41
|
"open": "^10.1.0"
|
|
@@ -37,9 +46,13 @@
|
|
|
37
46
|
"@token-rats/pricing": "workspace:*",
|
|
38
47
|
"@types/better-sqlite3": "^7.6.12",
|
|
39
48
|
"@types/node": "22.10.2",
|
|
49
|
+
"@types/sql.js": "^1.4.11",
|
|
40
50
|
"esbuild": "^0.24.2",
|
|
41
51
|
"tsx": "4.19.2",
|
|
42
52
|
"typescript": "5.7.2",
|
|
43
53
|
"vitest": "2.1.8"
|
|
54
|
+
},
|
|
55
|
+
"dependencies": {
|
|
56
|
+
"sql.js": "^1.14.1"
|
|
44
57
|
}
|
|
45
58
|
}
|