tokentracker-cli 0.63.1 → 0.64.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.
Files changed (42) hide show
  1. package/dashboard/dist/assets/{ActivityHeatmap-3rWViAnK.js → ActivityHeatmap-DjMtMPit.js} +1 -1
  2. package/dashboard/dist/assets/{Card-CjtoUN-V.js → Card-CD9YpCAv.js} +1 -1
  3. package/dashboard/dist/assets/{DashboardPage-C8Zm5caR.js → DashboardPage-Djhg-yJL.js} +1 -1
  4. package/dashboard/dist/assets/{DevicePage-DWgc0ITo.js → DevicePage-DA74Sryo.js} +1 -1
  5. package/dashboard/dist/assets/{DialogTitle-BOWoDnVq.js → DialogTitle-DDp9MHUJ.js} +1 -1
  6. package/dashboard/dist/assets/{FadeIn-CK1EopuS.js → FadeIn-CBspmJ4G.js} +1 -1
  7. package/dashboard/dist/assets/{HeaderGithubStar-C1CldHWg.js → HeaderGithubStar-BDgq5Gx4.js} +1 -1
  8. package/dashboard/dist/assets/{IpCheckPage-DKiEo4LO.js → IpCheckPage-L1GKKx8L.js} +1 -1
  9. package/dashboard/dist/assets/{LandingPage-BCzXJP9I.js → LandingPage-BxI6zHR6.js} +1 -1
  10. package/dashboard/dist/assets/{LeaderboardAvatar-Dw-KfosP.js → LeaderboardAvatar-DHKVlkOF.js} +1 -1
  11. package/dashboard/dist/assets/{LeaderboardPage-XQBrmlgA.js → LeaderboardPage-C8JB9MuB.js} +3 -3
  12. package/dashboard/dist/assets/{LeaderboardProfileModal-8xPG0MRj.js → LeaderboardProfileModal-CpciUHf2.js} +1 -1
  13. package/dashboard/dist/assets/{LeaderboardProfilePage-DHa73U-g.js → LeaderboardProfilePage-c2Pg5hum.js} +1 -1
  14. package/dashboard/dist/assets/{LimitsPage-BTF8cZ-P.js → LimitsPage-DkqHHv2V.js} +1 -1
  15. package/dashboard/dist/assets/{LocalOnlyNotice-BqLH4XMA.js → LocalOnlyNotice-CVAJM9pw.js} +1 -1
  16. package/dashboard/dist/assets/{LoginPage-OZf1-OnV.js → LoginPage-L9n2F1t8.js} +1 -1
  17. package/dashboard/dist/assets/{PopoverPopup-BQ03eBHT.js → PopoverPopup-B883Co46.js} +1 -1
  18. package/dashboard/dist/assets/{ResetPasswordPage-CqSU4VnK.js → ResetPasswordPage-dcb-XQ_8.js} +1 -1
  19. package/dashboard/dist/assets/{Select-C2miulxl.js → Select-Dn_eH-Cb.js} +1 -1
  20. package/dashboard/dist/assets/{SelectItemText-CvU6qFNt.js → SelectItemText-BBymhOah.js} +1 -1
  21. package/dashboard/dist/assets/{SettingsPage-DYiO30s5.js → SettingsPage-DpP5jrlC.js} +1 -1
  22. package/dashboard/dist/assets/{SkillsPage-DKHdur0w.js → SkillsPage-BKBEMpDa.js} +1 -1
  23. package/dashboard/dist/assets/{WidgetsPage-Dh_FKo1H.js → WidgetsPage-ByTWGppP.js} +1 -1
  24. package/dashboard/dist/assets/{WrappedPage-BIdXJTOA.js → WrappedPage-BzBYot91.js} +1 -1
  25. package/dashboard/dist/assets/{agent-logos-CWBw3t4a.js → agent-logos-7x6sZdXn.js} +1 -1
  26. package/dashboard/dist/assets/{arrow-up-right-D1Qv9-hJ.js → arrow-up-right-NtrFTgFM.js} +1 -1
  27. package/dashboard/dist/assets/{download-9hc1LZwP.js → download-DBI1zmF1.js} +1 -1
  28. package/dashboard/dist/assets/{info-Bw9sw3vW.js → info-WyXjj_mj.js} +1 -1
  29. package/dashboard/dist/assets/{main-BN1NzjX3.js → main-sjN9-3PX.js} +2 -2
  30. package/dashboard/dist/assets/{pencil-C8mN_ljR.js → pencil-zlgm1deI.js} +1 -1
  31. package/dashboard/dist/assets/{use-limits-display-prefs-CpHg_a82.js → use-limits-display-prefs-D_3UqeaO.js} +1 -1
  32. package/dashboard/dist/assets/{use-native-settings-BCMRmnLD.js → use-native-settings-BIZTMAe_.js} +1 -1
  33. package/dashboard/dist/assets/{use-usage-limits-CVu3Jff0.js → use-usage-limits-DyrBGYy1.js} +1 -1
  34. package/dashboard/dist/assets/{useCurrency-3hjYtt-n.js → useCurrency-BJEllMZE.js} +1 -1
  35. package/dashboard/dist/assets/{useScrollLock-BNfQujzc.js → useScrollLock-Bim1sAXp.js} +1 -1
  36. package/dashboard/dist/index.html +1 -1
  37. package/dashboard/dist/share.html +1 -1
  38. package/package.json +4 -2
  39. package/src/lib/opencode-go-limits.js +253 -20
  40. package/src/lib/pricing/seed-snapshot.json +1 -1
  41. package/src/lib/sqlite-reader.js +59 -0
  42. package/src/lib/usage-limits.js +4 -4
@@ -1,5 +1,6 @@
1
1
  const cp = require("node:child_process");
2
2
  const fssync = require("node:fs");
3
+ const { promisify } = require("node:util");
3
4
 
4
5
  const warnedSqliteReadFailures = new Set();
5
6
 
@@ -116,6 +117,63 @@ function readSqliteJsonRows(dbPath, sql, options = {}) {
116
117
  return [];
117
118
  }
118
119
 
120
+ async function readSqliteRowsWithCliAsync(dbPath, sql, { execFile, timeout, maxBuffer }) {
121
+ const { stdout } = await execFile("sqlite3", ["-json", dbPath, sql], {
122
+ encoding: "utf8",
123
+ maxBuffer,
124
+ timeout,
125
+ });
126
+ if (!stdout || !stdout.trim()) return [];
127
+ const rows = JSON.parse(stdout);
128
+ return Array.isArray(rows) ? rows : [];
129
+ }
130
+
131
+ // Async twin of readSqliteJsonRows for hot paths that must not block the event
132
+ // loop (e.g. the usage-limits poll — see the "limits 路径 spawnSync 冻结全端点"
133
+ // lesson). The CLI path runs via async execFile; the node:sqlite fallback is
134
+ // synchronous (no async API exists), but it only runs when the sqlite3 CLI is
135
+ // absent — uncommon on macOS/Linux, where the async path keeps the loop free.
136
+ async function readSqliteJsonRowsAsync(dbPath, sql, options = {}) {
137
+ if (!dbPath || !sql) return [];
138
+ try {
139
+ if (!fssync.existsSync(dbPath)) return [];
140
+ } catch (_e) {
141
+ return [];
142
+ }
143
+ const execFile = options.execFile || promisify(cp.execFile);
144
+ const requireFn = options.requireFn || require;
145
+ const env = options.env || process.env;
146
+ const timeout = Number.isFinite(options.timeout) ? options.timeout : 30_000;
147
+ const maxBuffer = Number.isFinite(options.maxBuffer) ? options.maxBuffer : 50 * 1024 * 1024;
148
+ const label = options.label || "local";
149
+
150
+ let cliError = null;
151
+ try {
152
+ return await readSqliteRowsWithCliAsync(dbPath, sql, { execFile, timeout, maxBuffer });
153
+ } catch (err) {
154
+ cliError = err;
155
+ }
156
+
157
+ let nodeSqliteError = null;
158
+ try {
159
+ return readSqliteRowsWithNode(dbPath, sql, { requireFn });
160
+ } catch (err) {
161
+ nodeSqliteError = err;
162
+ }
163
+
164
+ if (isSqliteCliUnavailable(cliError) && isNodeSqliteUnavailable(nodeSqliteError)) {
165
+ warnSqliteUnavailable({
166
+ dbPath,
167
+ label,
168
+ cliError,
169
+ nodeSqliteError,
170
+ env,
171
+ stderr: options.stderr,
172
+ });
173
+ }
174
+ return [];
175
+ }
176
+
119
177
  function readSqliteFirstValue(dbPath, sql, column, options = {}) {
120
178
  const rows = readSqliteJsonRows(dbPath, sql, options);
121
179
  const row = rows[0];
@@ -131,6 +189,7 @@ function resetSqliteReaderWarningsForTests() {
131
189
 
132
190
  module.exports = {
133
191
  readSqliteJsonRows,
192
+ readSqliteJsonRowsAsync,
134
193
  readSqliteFirstValue,
135
194
  resetSqliteReaderWarningsForTests,
136
195
  };
@@ -2477,10 +2477,10 @@ async function fetchUsageLimitsUncached({
2477
2477
  .catch((reason) => ({ configured: true, error: reason?.message || "Unknown error" })),
2478
2478
  withProviderTimeout(fetchZcodeLimits({ home, env, fetchImpl: providerFetch }), "ZCode", providerTimeoutMs)
2479
2479
  .catch((reason) => ({ configured: true, error: reason?.message || "Unknown error" })),
2480
- // OpenCode Go scrapes the workspace dashboard (no public REST API yet,
2481
- // tracked at anomalyco/opencode#16017). Auth is via two env vars, see
2482
- // src/lib/opencode-go-limits.js for the exact endpoint + cookie shape.
2483
- withProviderTimeout(fetchOpencodeGoLimits({ env, fetchImpl: providerFetch }), "OpenCode Go", providerTimeoutMs)
2480
+ // OpenCode Go: local opencode.db cost-vs-dollar-cap estimate by default
2481
+ // (auth-free, zero-config), upgraded to the exact server-side scrape when an
2482
+ // OPENCODE_GO_AUTH_COOKIE is set. See src/lib/opencode-go-limits.js.
2483
+ withProviderTimeout(fetchOpencodeGoLimits({ home, env, fetchImpl: providerFetch }), "OpenCode Go", providerTimeoutMs)
2484
2484
  .catch((reason) => ({ configured: true, error: reason?.message || "Unknown error" })),
2485
2485
  ]);
2486
2486