tokentrace 0.14.2 → 0.15.0
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/CHANGELOG.md +20 -0
- package/README.md +22 -2
- package/dist/runtime/scan.mjs +5 -2
- package/package.json +14 -13
- package/scripts/package-inspect.mjs +2 -2
- package/server.json +2 -2
- package/src/ingestion/adapters/sqlite-history.ts +6 -2
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,26 @@ All notable changes to TokenTrace are documented here.
|
|
|
4
4
|
|
|
5
5
|
## Unreleased
|
|
6
6
|
|
|
7
|
+
## [0.15.0] - 2026-05-22
|
|
8
|
+
|
|
9
|
+
### Changed
|
|
10
|
+
|
|
11
|
+
- Bumped minimum Node.js to 20.0.0 (Node 18 LTS reached end of life on 2025-04-30). This is a breaking change for users still on Node 18.
|
|
12
|
+
- Upgraded `better-sqlite3` from 11 to 12 (latest major).
|
|
13
|
+
- Upgraded `lucide-react` from 0.468 to 1.16 (first stable major release).
|
|
14
|
+
- Upgraded `open` from 10 to 11 (now requires Node 20+, aligns with engines bump).
|
|
15
|
+
- Bumped minor/patch versions for `tsx`, `postcss`, `autoprefixer`, `@types/react`, `@types/node`.
|
|
16
|
+
|
|
17
|
+
### Fixed
|
|
18
|
+
|
|
19
|
+
- `sqlite-history` adapter now uses SQLite identifier quoting (`""`) instead of `JSON.stringify()` when interpolating user table names into raw queries. Previously, a table name containing a quote could have caused a SQL parse error during read-only ingestion.
|
|
20
|
+
- Made `eslint-plugin-react-hooks` an explicit devDependency so lint setup no longer relies on accidental dependency hoisting from `eslint-config-next`.
|
|
21
|
+
- Raised global Vitest `testTimeout`/`hookTimeout` to 30s and bumped per-test/spawn timeouts in CLI subprocess tests (`mcp-server`, `serve-command`, `statusline-cli`) so they are no longer flaky under macOS process-spawn latency.
|
|
22
|
+
|
|
23
|
+
### Documentation
|
|
24
|
+
|
|
25
|
+
- Added a Troubleshooting section to the README covering the `prebuild-install` deprecation warning from `better-sqlite3`, native build errors, and `EBADENGINE` warnings.
|
|
26
|
+
|
|
7
27
|
## [0.14.2] - 2026-05-21
|
|
8
28
|
|
|
9
29
|
### Added
|
package/README.md
CHANGED
|
@@ -244,8 +244,6 @@ The CLI sets `TOKENTRACE_DB` and `DATABASE_URL` automatically. You can override
|
|
|
244
244
|
TOKENTRACE_HOME=/custom/path tokentrace
|
|
245
245
|
```
|
|
246
246
|
|
|
247
|
-
If `npm install -g tokentrace` prints a `prebuild-install` deprecation warning, it is from the native SQLite dependency chain used by `better-sqlite3`. The install should continue normally, and TokenTrace still runs locally.
|
|
248
|
-
|
|
249
247
|
## Where TokenTrace Looks
|
|
250
248
|
|
|
251
249
|
Default discovery checks these locations when present:
|
|
@@ -478,6 +476,28 @@ The ingestion system is intentionally pluggable:
|
|
|
478
476
|
|
|
479
477
|
Contributions are welcome. See [CONTRIBUTING.md](CONTRIBUTING.md) for local setup, parser guidelines, pricing update notes, and the release policy.
|
|
480
478
|
|
|
479
|
+
## Troubleshooting
|
|
480
|
+
|
|
481
|
+
### `prebuild-install` deprecation warning during install
|
|
482
|
+
|
|
483
|
+
```
|
|
484
|
+
npm warn deprecated prebuild-install@7.1.3: No longer maintained...
|
|
485
|
+
```
|
|
486
|
+
|
|
487
|
+
This is a transitive dependency of `better-sqlite3` (the native SQLite driver TokenTrace uses to store local data). The warning is harmless — the install completes normally and TokenTrace runs as expected. It will go away once `better-sqlite3` upstream migrates to a different prebuilt binary loader; there is nothing to fix on the TokenTrace side.
|
|
488
|
+
|
|
489
|
+
### Native build errors on `better-sqlite3`
|
|
490
|
+
|
|
491
|
+
If the prebuilt binary cannot be downloaded (offline machine, restrictive proxy, unsupported Node ABI), `better-sqlite3` will try to compile from source and may fail. Workarounds:
|
|
492
|
+
|
|
493
|
+
- Ensure Node.js is a supported LTS (TokenTrace requires `>= 20.0.0`; Node 20 or 22 LTS is recommended).
|
|
494
|
+
- Install build tools: Xcode Command Line Tools on macOS, `build-essential` and `python3` on Linux, or the "Desktop development with C++" workload on Windows.
|
|
495
|
+
- Retry the install with network access to `github.com` so the prebuilt binary can be fetched.
|
|
496
|
+
|
|
497
|
+
### `EBADENGINE` warnings
|
|
498
|
+
|
|
499
|
+
These appear when your local Node version is older than the `engines` field of a transitive dependency. They are warnings, not errors. Upgrading to the latest Node LTS resolves them.
|
|
500
|
+
|
|
481
501
|
## Known Limitations
|
|
482
502
|
|
|
483
503
|
- Claude Code and Codex CLI log formats are inferred defensively and may need refinement with real sample logs.
|
package/dist/runtime/scan.mjs
CHANGED
|
@@ -2909,12 +2909,15 @@ import Database2 from "better-sqlite3";
|
|
|
2909
2909
|
function openReadonly(filePath) {
|
|
2910
2910
|
return new Database2(filePath, { readonly: true, fileMustExist: true });
|
|
2911
2911
|
}
|
|
2912
|
+
function quoteIdent(name) {
|
|
2913
|
+
return `"${name.replace(/"/g, '""')}"`;
|
|
2914
|
+
}
|
|
2912
2915
|
function candidateTables(db2) {
|
|
2913
2916
|
const tables = db2.prepare("SELECT name FROM sqlite_master WHERE type = 'table' AND name NOT LIKE 'sqlite_%'").all();
|
|
2914
2917
|
return tables.map((table) => table.name).filter((name) => usageTableNames.includes(name) || /usage|token|message|session/i.test(name));
|
|
2915
2918
|
}
|
|
2916
2919
|
function columnsFor(db2, tableName) {
|
|
2917
|
-
const columns = db2.prepare(`PRAGMA table_info(${
|
|
2920
|
+
const columns = db2.prepare(`PRAGMA table_info(${quoteIdent(tableName)})`).all();
|
|
2918
2921
|
return new Set(columns.map((column) => column.name.toLowerCase()));
|
|
2919
2922
|
}
|
|
2920
2923
|
function hasUsageShape(columns) {
|
|
@@ -2923,7 +2926,7 @@ function hasUsageShape(columns) {
|
|
|
2923
2926
|
return hasModel && hasUsage2;
|
|
2924
2927
|
}
|
|
2925
2928
|
function tableRows(db2, tableName) {
|
|
2926
|
-
return db2.prepare(`SELECT * FROM ${
|
|
2929
|
+
return db2.prepare(`SELECT * FROM ${quoteIdent(tableName)} LIMIT 50000`).all();
|
|
2927
2930
|
}
|
|
2928
2931
|
function providerId(value) {
|
|
2929
2932
|
if (!value) return "local";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tokentrace",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.15.0",
|
|
4
4
|
"mcpName": "io.github.abhiyoheswaran1/tokentrace",
|
|
5
5
|
"description": "Local-first dashboard for AI CLI token, cost, and session analytics.",
|
|
6
6
|
"author": {
|
|
@@ -74,10 +74,10 @@
|
|
|
74
74
|
"prepack": "npm run build:runtime"
|
|
75
75
|
},
|
|
76
76
|
"overrides": {
|
|
77
|
-
"postcss": "^8.5.
|
|
77
|
+
"postcss": "^8.5.15"
|
|
78
78
|
},
|
|
79
79
|
"engines": {
|
|
80
|
-
"node": ">=
|
|
80
|
+
"node": ">=20.0.0"
|
|
81
81
|
},
|
|
82
82
|
"keywords": [
|
|
83
83
|
"tokens",
|
|
@@ -94,24 +94,24 @@
|
|
|
94
94
|
],
|
|
95
95
|
"license": "MIT",
|
|
96
96
|
"dependencies": {
|
|
97
|
-
"@types/node": "^22.10.5",
|
|
98
|
-
"@types/react": "^19.0.4",
|
|
99
97
|
"@radix-ui/react-slot": "^1.1.1",
|
|
100
|
-
"
|
|
98
|
+
"@types/node": "^22.19.19",
|
|
99
|
+
"@types/react": "^19.2.15",
|
|
100
|
+
"autoprefixer": "^10.5.0",
|
|
101
|
+
"better-sqlite3": "^12.10.0",
|
|
101
102
|
"class-variance-authority": "^0.7.1",
|
|
102
103
|
"clsx": "^2.1.1",
|
|
103
104
|
"drizzle-orm": "^0.45.2",
|
|
104
105
|
"get-port": "^7.2.0",
|
|
105
|
-
"lucide-react": "^
|
|
106
|
+
"lucide-react": "^1.16.0",
|
|
106
107
|
"next": "^15.5.18",
|
|
107
|
-
"open": "^
|
|
108
|
-
"
|
|
109
|
-
"postcss": "^8.5.14",
|
|
108
|
+
"open": "^11.0.0",
|
|
109
|
+
"postcss": "^8.5.15",
|
|
110
110
|
"react": "^19.0.0",
|
|
111
111
|
"react-dom": "^19.0.0",
|
|
112
112
|
"recharts": "^2.15.0",
|
|
113
|
-
"tailwindcss": "^3.4.17",
|
|
114
113
|
"tailwind-merge": "^2.6.0",
|
|
114
|
+
"tailwindcss": "^3.4.17",
|
|
115
115
|
"typescript": "^5.7.2"
|
|
116
116
|
},
|
|
117
117
|
"devDependencies": {
|
|
@@ -119,9 +119,10 @@
|
|
|
119
119
|
"@types/better-sqlite3": "^7.6.12",
|
|
120
120
|
"@types/react-dom": "^19.0.2",
|
|
121
121
|
"esbuild": "^0.28.0",
|
|
122
|
-
"eslint": "^9.
|
|
122
|
+
"eslint": "^9.39.4",
|
|
123
123
|
"eslint-config-next": "^15.1.4",
|
|
124
|
-
"
|
|
124
|
+
"eslint-plugin-react-hooks": "^5.2.0",
|
|
125
|
+
"tsx": "^4.22.3",
|
|
125
126
|
"vitest": "^3.2.4"
|
|
126
127
|
}
|
|
127
128
|
}
|
|
@@ -48,8 +48,8 @@ if (packageJson.dependencies?.["drizzle-orm"] !== "^0.45.2") {
|
|
|
48
48
|
fail("Keep the published drizzle-orm dependency floor at ^0.45.2 or newer.");
|
|
49
49
|
}
|
|
50
50
|
|
|
51
|
-
if (packageJson.overrides?.postcss !== "^8.5.
|
|
52
|
-
fail("Keep the PostCSS override at ^8.5.
|
|
51
|
+
if (packageJson.overrides?.postcss !== "^8.5.15") {
|
|
52
|
+
fail("Keep the PostCSS override at ^8.5.15 or newer.");
|
|
53
53
|
}
|
|
54
54
|
|
|
55
55
|
const blockedPackageEntries = [
|
package/server.json
CHANGED
|
@@ -8,12 +8,12 @@
|
|
|
8
8
|
"url": "https://github.com/abhiyoheswaran1/tokentrace",
|
|
9
9
|
"source": "github"
|
|
10
10
|
},
|
|
11
|
-
"version": "0.
|
|
11
|
+
"version": "0.15.0",
|
|
12
12
|
"packages": [
|
|
13
13
|
{
|
|
14
14
|
"registryType": "npm",
|
|
15
15
|
"identifier": "tokentrace",
|
|
16
|
-
"version": "0.
|
|
16
|
+
"version": "0.15.0",
|
|
17
17
|
"runtimeHint": "npx",
|
|
18
18
|
"packageArguments": [
|
|
19
19
|
{
|
|
@@ -24,6 +24,10 @@ function openReadonly(filePath: string) {
|
|
|
24
24
|
return new Database(filePath, { readonly: true, fileMustExist: true });
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
+
function quoteIdent(name: string) {
|
|
28
|
+
return `"${name.replace(/"/g, '""')}"`;
|
|
29
|
+
}
|
|
30
|
+
|
|
27
31
|
function candidateTables(db: Database.Database) {
|
|
28
32
|
const tables = db
|
|
29
33
|
.prepare("SELECT name FROM sqlite_master WHERE type = 'table' AND name NOT LIKE 'sqlite_%'")
|
|
@@ -34,7 +38,7 @@ function candidateTables(db: Database.Database) {
|
|
|
34
38
|
}
|
|
35
39
|
|
|
36
40
|
function columnsFor(db: Database.Database, tableName: string) {
|
|
37
|
-
const columns = db.prepare(`PRAGMA table_info(${
|
|
41
|
+
const columns = db.prepare(`PRAGMA table_info(${quoteIdent(tableName)})`).all() as Array<{ name: string }>;
|
|
38
42
|
return new Set(columns.map((column) => column.name.toLowerCase()));
|
|
39
43
|
}
|
|
40
44
|
|
|
@@ -52,7 +56,7 @@ function hasUsageShape(columns: Set<string>) {
|
|
|
52
56
|
}
|
|
53
57
|
|
|
54
58
|
function tableRows(db: Database.Database, tableName: string) {
|
|
55
|
-
return db.prepare(`SELECT * FROM ${
|
|
59
|
+
return db.prepare(`SELECT * FROM ${quoteIdent(tableName)} LIMIT 50000`).all() as UsageRow[];
|
|
56
60
|
}
|
|
57
61
|
|
|
58
62
|
function providerId(value: string | null) {
|