tokentracker-cli 1.3.13 → 1.3.14
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/dashboard/dist/assets/{AchievementBadge-DkNsd5tj.js → AchievementBadge-DJK8AWBF.js} +1 -1
- package/dashboard/dist/assets/{AchievementsPage-Dr72Hcog.js → AchievementsPage-Cle78oKH.js} +2 -2
- package/dashboard/dist/assets/{AchievementsSection-CkOdGlnD.js → AchievementsSection-BPqXDoPP.js} +1 -1
- package/dashboard/dist/assets/{BadgeDetailModal-DADLfBsK.js → BadgeDetailModal-HsH_Pwsu.js} +1 -1
- package/dashboard/dist/assets/{BotAnimated-k6u1GRzw.js → BotAnimated-BWy2-z4Q.js} +1 -1
- package/dashboard/dist/assets/{Card-Dk6s3h-P.js → Card-DPGBuBDb.js} +1 -1
- package/dashboard/dist/assets/{CloudCheckoutPage-DL0pvok0.js → CloudCheckoutPage-ohIQnIhe.js} +1 -1
- package/dashboard/dist/assets/{CloudPage-BizN1MZL.js → CloudPage-OYiiZ4c4.js} +2 -2
- package/dashboard/dist/assets/{CommandPalette-B2crDNlV.js → CommandPalette-BmDZmpMi.js} +1 -1
- package/dashboard/dist/assets/{CommunityStatsModal-C6Rc5NME.js → CommunityStatsModal-L86uJgyp.js} +1 -1
- package/dashboard/dist/assets/{ConfirmModal-BrxBQn4n.js → ConfirmModal-COQfPXos.js} +1 -1
- package/dashboard/dist/assets/{Controls-C2mEPI72.js → Controls-BkKlT6Dz.js} +1 -1
- package/dashboard/dist/assets/{DashboardPage-BomPd7nt.js → DashboardPage-3dlQBOjz.js} +1 -1
- package/dashboard/dist/assets/{DateRangePopover-Gz-N_D7O.js → DateRangePopover-D0UeP8ig.js} +1 -1
- package/dashboard/dist/assets/{DevicePage-wmnNx9bd.js → DevicePage-K3CdWKaf.js} +1 -1
- package/dashboard/dist/assets/{DialogClose-D1dzj_on.js → DialogClose-DKQ2ZVA0.js} +1 -1
- package/dashboard/dist/assets/DialogDescription-MbuaPFlj.js +1 -0
- package/dashboard/dist/assets/{DialogTitle-BBxNf3O8.js → DialogTitle-ufFnN-8D.js} +1 -1
- package/dashboard/dist/assets/{ElectricLogo-DCopeDc8.js → ElectricLogo-Bb79UnTo.js} +1 -1
- package/dashboard/dist/assets/{FadeIn-DSndojVd.js → FadeIn-DlAKIU4I.js} +1 -1
- package/dashboard/dist/assets/{HeaderGithubStar-BBAGbevf.js → HeaderGithubStar-CzwSyhEY.js} +1 -1
- package/dashboard/dist/assets/{HoverTooltip-COD3xE9E.js → HoverTooltip-BEpwekkd.js} +1 -1
- package/dashboard/dist/assets/{IpCheckPage-BtMWefop.js → IpCheckPage-C7kpZ9JX.js} +1 -1
- package/dashboard/dist/assets/{LandingPage-DN2IVBw7.js → LandingPage-CfYk0Jzy.js} +2 -2
- package/dashboard/dist/assets/{LeaderboardPage-DkJowsRI.js → LeaderboardPage-XgjAHwpy.js} +2 -2
- package/dashboard/dist/assets/{LeaderboardProBadge-CRRphJNs.js → LeaderboardProBadge-wSlqVjBb.js} +1 -1
- package/dashboard/dist/assets/{LeaderboardProfileModal-WmZAsZx5.js → LeaderboardProfileModal-DaQrNYnu.js} +3 -3
- package/dashboard/dist/assets/{LeaderboardProfilePage-DWHu-eOp.js → LeaderboardProfilePage-3SWjG8FQ.js} +1 -1
- package/dashboard/dist/assets/{LimitsPage-BRFAWm-1.js → LimitsPage-DvM57ri3.js} +1 -1
- package/dashboard/dist/assets/{LocalOnlyNotice-BjJ8N4Zc.js → LocalOnlyNotice-CY6eDJEk.js} +1 -1
- package/dashboard/dist/assets/{LoginCard-CYmjHoYK.js → LoginCard-4bdpPQeD.js} +1 -1
- package/dashboard/dist/assets/{LoginModal-DX1D9F8b.js → LoginModal-Bmw7-b3f.js} +1 -1
- package/dashboard/dist/assets/{LoginPage-D7Ok7HiZ.js → LoginPage-CEI4nnlT.js} +1 -1
- package/dashboard/dist/assets/{PetPage-BYISPev2.js → PetPage-7Udtc9GY.js} +2 -2
- package/dashboard/dist/assets/{PopoverPopup-BlzqlKqF.js → PopoverPopup-r2BvRKLO.js} +1 -1
- package/dashboard/dist/assets/{ProviderIcon-BuLwtYjj.js → ProviderIcon-Cy_pKLdw.js} +1 -1
- package/dashboard/dist/assets/{ResetPasswordPage-BJRKclq9.js → ResetPasswordPage-QKUaLtO3.js} +1 -1
- package/dashboard/dist/assets/{Select-0YyBw95W.js → Select-BsUrn8Ui.js} +1 -1
- package/dashboard/dist/assets/{SelectItemText-CZKyxUjE.js → SelectItemText-Nis0uGZT.js} +1 -1
- package/dashboard/dist/assets/{SelfHostPage-C_Afofs-.js → SelfHostPage-DF8EzBEV.js} +1 -1
- package/dashboard/dist/assets/{ServiceStatusPage-0KpLdpon.js → ServiceStatusPage-BYmKzI_v.js} +1 -1
- package/dashboard/dist/assets/{SessionsPage-YtSyWMd0.js → SessionsPage-BsCVe75l.js} +1 -1
- package/dashboard/dist/assets/{SettingsPage-Bm641_AH.js → SettingsPage-CIZ6WmNR.js} +3 -3
- package/dashboard/dist/assets/{SkillsPage-DNg-I2g_.js → SkillsPage-cwHyK0Hp.js} +1 -1
- package/dashboard/dist/assets/{TokenGalaxy-BMN7WiRH.js → TokenGalaxy-2S-ud67v.js} +1 -1
- package/dashboard/dist/assets/{TooltipPopup-BF56BHfc.js → TooltipPopup-GG7xjDOP.js} +1 -1
- package/dashboard/dist/assets/{TrendMonitor-D0ea5xMA.js → TrendMonitor-CrbXrVMe.js} +1 -1
- package/dashboard/dist/assets/{WidgetsPage-CIAoHmJG.js → WidgetsPage-HrhnI3C-.js} +1 -1
- package/dashboard/dist/assets/{WrappedPage-CC_57Zr2.js → WrappedPage-sm7UVFon.js} +1 -1
- package/dashboard/dist/assets/{__vite-browser-external-CPskAZuH.js → __vite-browser-external-C7JgMYNl.js} +2 -2
- package/dashboard/dist/assets/{agent-logos-CcJUaB75.js → agent-logos-DGrrmPth.js} +1 -1
- package/dashboard/dist/assets/{arrow-left-CUiT31ZF.js → arrow-left-DOzsdmqR.js} +1 -1
- package/dashboard/dist/assets/{arrow-right-Tds6Mert.js → arrow-right-CHb0kJou.js} +1 -1
- package/dashboard/dist/assets/{arrow-up-right-CGSxdyzM.js → arrow-up-right-CH8vEEN1.js} +1 -1
- package/dashboard/dist/assets/{calendar-days-Cc8AtMa3.js → calendar-days-_D5qnyH_.js} +1 -1
- package/dashboard/dist/assets/{check-CzJylQ9j.js → check-DZLesnNy.js} +1 -1
- package/dashboard/dist/assets/{chevron-down-DyG9JVDO.js → chevron-down-QL4xkUtL.js} +1 -1
- package/dashboard/dist/assets/{cloud-checkout-DP5zddOq.js → cloud-checkout-DiCcWJVl.js} +1 -1
- package/dashboard/dist/assets/{composite-I_1t6PMI.js → composite-DObGcQmb.js} +1 -1
- package/dashboard/dist/assets/{download-B_LvkErh.js → download-BKp8pusR.js} +1 -1
- package/dashboard/dist/assets/{external-link-DDA3ObBn.js → external-link-B3p_TVGc.js} +1 -1
- package/dashboard/dist/assets/{flame-BqpVWH_1.js → flame-Df9OTUym.js} +1 -1
- package/dashboard/dist/assets/{format-tokens-D6QEOnGq.js → format-tokens-DXrEDEYs.js} +1 -1
- package/dashboard/dist/assets/{gift-BxbKo3W6.js → gift-DtWubiuR.js} +1 -1
- package/dashboard/dist/assets/{host-mode-o3qQY7tz.js → host-mode-C069A_hB.js} +1 -1
- package/dashboard/dist/assets/{icons-oGPZPj2n.js → icons-lB1kfROy.js} +1 -1
- package/dashboard/dist/assets/{index-BxtvQ1J7.js → index-D356L-jw.js} +1 -1
- package/dashboard/dist/assets/{index-DX--5z1g.js → index-DsXIWrJx.js} +1 -1
- package/dashboard/dist/assets/{index-Byukv2Nu.js → index-M5BiC0jx.js} +1 -1
- package/dashboard/dist/assets/{info-BoTz1AGZ.js → info-CSG8OkG4.js} +1 -1
- package/dashboard/dist/assets/{link-2-C09a122s.js → link-2-BkBGu7FX.js} +1 -1
- package/dashboard/dist/assets/{loader-circle--9U0axVe.js → loader-circle-BERDkbsP.js} +1 -1
- package/dashboard/dist/assets/{modifiers.esm-Cra0I6RP.js → modifiers.esm-Ce5IvVw2.js} +1 -1
- package/dashboard/dist/assets/{monitor-smartphone-C1ENjmOu.js → monitor-smartphone-zKuoJldz.js} +1 -1
- package/dashboard/dist/assets/{play-NqPqbW59.js → play-C0x-pxft.js} +1 -1
- package/dashboard/dist/assets/{plus-DZP82JeP.js → plus-DJvks-CX.js} +1 -1
- package/dashboard/dist/assets/{provider-display-BLo4k0bi.js → provider-display-C0e4tAFu.js} +1 -1
- package/dashboard/dist/assets/{react-CTLavVze.js → react-Bg0_YfGs.js} +1 -1
- package/dashboard/dist/assets/{safePolygon-Yw5w5Nw8.js → safePolygon-CptquMWZ.js} +1 -1
- package/dashboard/dist/assets/{search-DgV6mpMO.js → search-CLESf2Tg.js} +1 -1
- package/dashboard/dist/assets/{server-BybwAQjW.js → server-Cdwhp-2m.js} +1 -1
- package/dashboard/dist/assets/{shield-check-BiTYwWdT.js → shield-check-8U4XqmW3.js} +1 -1
- package/dashboard/dist/assets/{skills-api-Dx_Z8_SO.js → skills-api-ioDaxLLo.js} +1 -1
- package/dashboard/dist/assets/{sortable.esm-CmJnBLcr.js → sortable.esm-CEohF5EK.js} +1 -1
- package/dashboard/dist/assets/{store-DzNIKGzf.js → store-CyOeiGFE.js} +1 -1
- package/dashboard/dist/assets/{terminal-DPly-UPW.js → terminal-BjgwEAH-.js} +1 -1
- package/dashboard/dist/assets/{trash-DsL2ZAN5.js → trash-Skj6z7D1.js} +1 -1
- package/dashboard/dist/assets/{use-community-stats-CSTkXFed.js → use-community-stats-Cworqjzy.js} +1 -1
- package/dashboard/dist/assets/{use-latest-request-guard-CbAXXNlU.js → use-latest-request-guard-DMVWXXHE.js} +1 -1
- package/dashboard/dist/assets/{use-limits-display-prefs-mDl6Yv_-.js → use-limits-display-prefs-DKJZcYfE.js} +1 -1
- package/dashboard/dist/assets/{use-native-settings-Bu2C3b20.js → use-native-settings-CQF4BLQl.js} +1 -1
- package/dashboard/dist/assets/{use-ordered-list-DkGSfMTv.js → use-ordered-list-B9yoUGUU.js} +1 -1
- package/dashboard/dist/assets/use-reduced-motion-DPUViCfp.js +1 -0
- package/dashboard/dist/assets/{use-session-efficiency-pref-B2GDf83h.js → use-session-efficiency-pref-K00bK2sQ.js} +1 -1
- package/dashboard/dist/assets/{use-transform-BVVduBPJ.js → use-transform-Cfw11yOU.js} +1 -1
- package/dashboard/dist/assets/{use-usage-limits-fuzpbbVh.js → use-usage-limits-BE2dJXFd.js} +1 -1
- package/dashboard/dist/assets/{useCurrency-CdDQzroJ.js → useCurrency-BW7y9Tdv.js} +1 -1
- package/dashboard/dist/assets/{usePositioner-b6XXJtxE.js → usePositioner-DhtQcPOC.js} +1 -1
- package/dashboard/dist/assets/{useTokenFormat-90RoMQgI.js → useTokenFormat-BnvzUc-t.js} +1 -1
- package/dashboard/dist/assets/{zap-xEHzTW-T.js → zap-BQ3BR9On.js} +1 -1
- package/dashboard/dist/index.html +1 -1
- package/dashboard/dist/ip-check.html +1 -1
- package/dashboard/dist/leaderboard.html +1 -1
- package/dashboard/dist/share.html +1 -1
- package/package.json +1 -1
- package/src/commands/status.js +5 -1
- package/src/commands/sync.js +28 -1
- package/src/lib/jsonl-lines.js +34 -4
- package/src/lib/pricing/seed-snapshot.json +1 -1
- package/src/lib/rollout.js +148 -52
- package/src/lib/session-analytics.js +11 -10
- package/src/lib/upload-queue.js +1 -1
- package/dashboard/dist/assets/DialogDescription-ChbOGLc_.js +0 -1
- package/dashboard/dist/assets/use-reduced-motion-6nBw3cR5.js +0 -1
package/src/lib/rollout.js
CHANGED
|
@@ -2846,6 +2846,8 @@ async function parseClaudeFile({
|
|
|
2846
2846
|
continue;
|
|
2847
2847
|
}
|
|
2848
2848
|
|
|
2849
|
+
if (isOmOClaudeSdkMirror(obj)) continue;
|
|
2850
|
+
|
|
2849
2851
|
const usage = obj?.message?.usage || obj?.usage;
|
|
2850
2852
|
if (!usage || typeof usage !== "object") continue;
|
|
2851
2853
|
|
|
@@ -4901,6 +4903,14 @@ function isCodexTotalOnlyResetSentinel(lastUsage, totalUsage) {
|
|
|
4901
4903
|
// backward compatibility for the (msgId, reqId) format already persisted in
|
|
4902
4904
|
// cursors.claudeHashes (msgId strings don't contain `:`, so the two formats
|
|
4903
4905
|
// share the same Set without collision).
|
|
4906
|
+
// OmO Native routes Anthropic-subscription turns through the Claude Agent SDK,
|
|
4907
|
+
// which mirrors the same usage into ~/.claude/projects with entrypoint "sdk-ts"
|
|
4908
|
+
// and userType "external". OmO's passive reader already counts those turns
|
|
4909
|
+
// under source=omo — skip the mirrored Claude transcript copy (#726).
|
|
4910
|
+
function isOmOClaudeSdkMirror(obj) {
|
|
4911
|
+
return obj?.entrypoint === "sdk-ts" && obj?.userType === "external";
|
|
4912
|
+
}
|
|
4913
|
+
|
|
4904
4914
|
function claudeMessageDedupKey(obj) {
|
|
4905
4915
|
const msgId = typeof obj?.message?.id === "string" && obj.message.id ? obj.message.id : null;
|
|
4906
4916
|
if (!msgId) return null;
|
|
@@ -5542,6 +5552,79 @@ function hasZcodeNativeUsageSchema(dbPath, sqliteOptions = {}) {
|
|
|
5542
5552
|
}
|
|
5543
5553
|
}
|
|
5544
5554
|
|
|
5555
|
+
// true: readable with content; false: confirmed empty; null: unavailable or
|
|
5556
|
+
// unreadable. Only a confirmed empty database is safe to replace during discovery.
|
|
5557
|
+
function zcodeDbHasContent(dbPath, sqliteOptions = {}) {
|
|
5558
|
+
if (!dbPath || !fssync.existsSync(dbPath)) return null;
|
|
5559
|
+
let snapshot = null;
|
|
5560
|
+
let effectiveDbPath = dbPath;
|
|
5561
|
+
if (isUncPath(dbPath)) {
|
|
5562
|
+
try {
|
|
5563
|
+
snapshot = snapshotSqliteDb(dbPath);
|
|
5564
|
+
effectiveDbPath = snapshot.path;
|
|
5565
|
+
} catch (_error) {
|
|
5566
|
+
// Preserve the existing direct-read fallback for transient snapshot
|
|
5567
|
+
// failures and UNC implementations that support SQLite locking.
|
|
5568
|
+
}
|
|
5569
|
+
}
|
|
5570
|
+
try {
|
|
5571
|
+
const rows = readSqliteJsonRows(
|
|
5572
|
+
effectiveDbPath,
|
|
5573
|
+
"SELECT (SELECT COUNT(*) FROM session) AS sessions, (SELECT COUNT(*) FROM model_usage) AS requests",
|
|
5574
|
+
{
|
|
5575
|
+
label: "ZCode",
|
|
5576
|
+
timeout: 10_000,
|
|
5577
|
+
maxBuffer: 1024 * 1024,
|
|
5578
|
+
...sqliteOptions,
|
|
5579
|
+
throwOnReadFailure: true,
|
|
5580
|
+
},
|
|
5581
|
+
);
|
|
5582
|
+
const row = Array.isArray(rows) ? rows[0] : null;
|
|
5583
|
+
if (!row) return null;
|
|
5584
|
+
return (Number(row.sessions) || 0) > 0 || (Number(row.requests) || 0) > 0;
|
|
5585
|
+
} catch (_error) {
|
|
5586
|
+
return null;
|
|
5587
|
+
} finally {
|
|
5588
|
+
if (snapshot) snapshot.cleanup();
|
|
5589
|
+
}
|
|
5590
|
+
}
|
|
5591
|
+
|
|
5592
|
+
function hasZcodeCursorState(cursors) {
|
|
5593
|
+
return [cursors?.zcode, cursors?.zcode?.native, cursors?.zcode?.wsl]
|
|
5594
|
+
.some((state) => Object.keys(state?.messages || {}).length > 0) ||
|
|
5595
|
+
Object.keys(cursors?.hourly?.buckets || {}).some((key) => key.startsWith("zcode|")) ||
|
|
5596
|
+
Object.keys(cursors?.hourly?.groupQueued || {}).some((key) => key.startsWith("zcode|")) ||
|
|
5597
|
+
Object.keys(cursors?.projectHourly?.buckets || {}).some((key) => key.includes("|zcode|"));
|
|
5598
|
+
}
|
|
5599
|
+
|
|
5600
|
+
// Sync, session discovery and status must select the same installs. Once sync
|
|
5601
|
+
// records a priority-mode choice, retain it: switching databases underneath a
|
|
5602
|
+
// flat cursor would accumulate both installs in the same usage ledger.
|
|
5603
|
+
function resolveZcodeInstallPaths({ nativeValue, wslValue } = {}, env = process.env, deps = {}) {
|
|
5604
|
+
const mode = wsl.getWslMode(env);
|
|
5605
|
+
const priorityMode = (deps.platform || process.platform) === "win32" && ["native-first", "wsl-first"].includes(mode);
|
|
5606
|
+
const selection = deps.selection || deps.cursors?.zcodeInstallSelection;
|
|
5607
|
+
if (priorityMode && selection?.mode === mode &&
|
|
5608
|
+
selection.zcodeHome === (env.ZCODE_HOME?.trim() || null) &&
|
|
5609
|
+
typeof selection.dbPath === "string" && selection.dbPath) {
|
|
5610
|
+
// A newly discovered or temporarily unavailable install must not change
|
|
5611
|
+
// the cursor's owner. Only an explicit mode/home override releases it.
|
|
5612
|
+
return { native: selection.dbPath, wsl: null };
|
|
5613
|
+
}
|
|
5614
|
+
const paths = resolveInstallPaths({ nativeValue, wslValue }, env, deps);
|
|
5615
|
+
if (!priorityMode || (!selection && hasZcodeCursorState(deps.cursors))) {
|
|
5616
|
+
// Legacy cursors followed the original install resolver. Keep that choice
|
|
5617
|
+
// rather than feeding another database into an already-owned flat ledger.
|
|
5618
|
+
return paths;
|
|
5619
|
+
}
|
|
5620
|
+
const picked = paths.native || paths.wsl;
|
|
5621
|
+
const alternate = picked === nativeValue ? wslValue : nativeValue;
|
|
5622
|
+
if (picked && alternate && zcodeDbHasContent(picked) === false && zcodeDbHasContent(alternate) === true) {
|
|
5623
|
+
return { native: alternate, wsl: null };
|
|
5624
|
+
}
|
|
5625
|
+
return paths;
|
|
5626
|
+
}
|
|
5627
|
+
|
|
5545
5628
|
function buildZcodeNativeUsageSql({ hasSessionDirectory }) {
|
|
5546
5629
|
const directorySelect = hasSessionDirectory ? ", s.directory AS directory" : "";
|
|
5547
5630
|
const directoryJoin = hasSessionDirectory
|
|
@@ -15626,6 +15709,44 @@ function ompEntryTimestampMs(msg, entry) {
|
|
|
15626
15709
|
return null;
|
|
15627
15710
|
}
|
|
15628
15711
|
|
|
15712
|
+
// Tool results can be hundreds of MB, exceeding V8's ~2^29-character string
|
|
15713
|
+
// limit without carrying usage. Skip them without decoding; assistant usage
|
|
15714
|
+
// records are orders of magnitude smaller.
|
|
15715
|
+
const OMP_LIKE_MAX_RECORD_BYTES = 64 * 1024 * 1024;
|
|
15716
|
+
|
|
15717
|
+
async function scanOmpLikeTranscript(filePath, startOffset, maxRecordBytes, onEntry) {
|
|
15718
|
+
let stream;
|
|
15719
|
+
try {
|
|
15720
|
+
stream = fssync.createReadStream(filePath, { start: startOffset });
|
|
15721
|
+
} catch {
|
|
15722
|
+
return startOffset;
|
|
15723
|
+
}
|
|
15724
|
+
let scannedEndOffset = startOffset;
|
|
15725
|
+
let committedEndOffset = startOffset;
|
|
15726
|
+
for await (const record of physicalJsonlRecords(stream, {
|
|
15727
|
+
invalidUtf8: "record",
|
|
15728
|
+
maxRecordBytes,
|
|
15729
|
+
})) {
|
|
15730
|
+
scannedEndOffset += record.physicalBytes;
|
|
15731
|
+
if (record.terminated) {
|
|
15732
|
+
committedEndOffset = scannedEndOffset;
|
|
15733
|
+
if (record.oversized || !record.utf8Valid || !record.line || !record.line.trim()) continue;
|
|
15734
|
+
let entry;
|
|
15735
|
+
try { entry = JSON.parse(record.line); } catch { continue; }
|
|
15736
|
+
onEntry(entry);
|
|
15737
|
+
continue;
|
|
15738
|
+
}
|
|
15739
|
+
// A final incomplete record may still be in the process of being written.
|
|
15740
|
+
if (record.oversized || !record.utf8Valid || !record.line || !record.line.trim()) break;
|
|
15741
|
+
let entry;
|
|
15742
|
+
try { entry = JSON.parse(record.line); } catch { break; }
|
|
15743
|
+
onEntry(entry);
|
|
15744
|
+
committedEndOffset = scannedEndOffset;
|
|
15745
|
+
break;
|
|
15746
|
+
}
|
|
15747
|
+
return committedEndOffset;
|
|
15748
|
+
}
|
|
15749
|
+
|
|
15629
15750
|
// Shared implementation for the oh-my-pi session format. omp and omo both
|
|
15630
15751
|
// persist it verbatim, so they differ only in where the sessions live, which
|
|
15631
15752
|
// cursor namespace they own, and how reasoning tokens are spelled.
|
|
@@ -15647,6 +15768,7 @@ async function parseOmpLikeIncremental({
|
|
|
15647
15768
|
resolveFileCwd,
|
|
15648
15769
|
reasoningFields,
|
|
15649
15770
|
reasoningIncludedInOutput = false,
|
|
15771
|
+
maxRecordBytes = OMP_LIKE_MAX_RECORD_BYTES,
|
|
15650
15772
|
} = {}) {
|
|
15651
15773
|
await ensureDir(path.dirname(queuePath));
|
|
15652
15774
|
const projectEnabled = typeof projectQueuePath === "string" && projectQueuePath.length > 0;
|
|
@@ -15724,35 +15846,22 @@ async function parseOmpLikeIncremental({
|
|
|
15724
15846
|
const startOffset = stat.size < prevSize || inodeChanged ? 0 : prevSize;
|
|
15725
15847
|
if (stat.size <= startOffset) continue;
|
|
15726
15848
|
|
|
15727
|
-
|
|
15728
|
-
try {
|
|
15729
|
-
stream = fssync.createReadStream(filePath, {
|
|
15730
|
-
encoding: "utf8",
|
|
15731
|
-
start: startOffset,
|
|
15732
|
-
});
|
|
15733
|
-
} catch { continue; }
|
|
15734
|
-
const rl = readline.createInterface({ input: stream, crlfDelay: Infinity });
|
|
15735
|
-
|
|
15736
|
-
for await (const line of rl) {
|
|
15737
|
-
if (!line || !line.trim()) continue;
|
|
15738
|
-
let entry;
|
|
15739
|
-
try { entry = JSON.parse(line); } catch { continue; }
|
|
15740
|
-
|
|
15849
|
+
const committedEndOffset = await scanOmpLikeTranscript(filePath, startOffset, maxRecordBytes, (entry) => {
|
|
15741
15850
|
// First line of each file is type:"session" (header) — skip all
|
|
15742
15851
|
// non-message records.
|
|
15743
|
-
if (!entry || entry.type !== "message")
|
|
15852
|
+
if (!entry || entry.type !== "message") return;
|
|
15744
15853
|
|
|
15745
15854
|
// Only assistant messages carry token usage.
|
|
15746
15855
|
const msg = entry.message;
|
|
15747
|
-
if (!msg || msg.role !== "assistant")
|
|
15856
|
+
if (!msg || msg.role !== "assistant") return;
|
|
15748
15857
|
|
|
15749
15858
|
const usage = msg.usage;
|
|
15750
|
-
if (!usage || typeof usage !== "object")
|
|
15859
|
+
if (!usage || typeof usage !== "object") return;
|
|
15751
15860
|
|
|
15752
15861
|
// Dedup by top-level entry id (8-char string assigned by oh-my-pi).
|
|
15753
15862
|
const entryId = typeof entry.id === "string" && entry.id ? entry.id : null;
|
|
15754
|
-
if (!entryId)
|
|
15755
|
-
if (seenIds.has(entryId))
|
|
15863
|
+
if (!entryId) return;
|
|
15864
|
+
if (seenIds.has(entryId)) return;
|
|
15756
15865
|
|
|
15757
15866
|
recordsProcessed++;
|
|
15758
15867
|
|
|
@@ -15770,7 +15879,7 @@ async function parseOmpLikeIncremental({
|
|
|
15770
15879
|
reasoningTokens === 0
|
|
15771
15880
|
) {
|
|
15772
15881
|
seenIds.add(entryId);
|
|
15773
|
-
|
|
15882
|
+
return;
|
|
15774
15883
|
}
|
|
15775
15884
|
|
|
15776
15885
|
// Entries with no resolvable timestamp are skipped — they cannot be
|
|
@@ -15778,12 +15887,12 @@ async function parseOmpLikeIncremental({
|
|
|
15778
15887
|
const tsMs = ompEntryTimestampMs(msg, entry);
|
|
15779
15888
|
if (tsMs == null) {
|
|
15780
15889
|
seenIds.add(entryId);
|
|
15781
|
-
|
|
15890
|
+
return;
|
|
15782
15891
|
}
|
|
15783
15892
|
|
|
15784
15893
|
const tsIso = new Date(tsMs).toISOString();
|
|
15785
15894
|
const bucketStart = toUtcHalfHourStart(tsIso);
|
|
15786
|
-
if (!bucketStart)
|
|
15895
|
+
if (!bucketStart) return;
|
|
15787
15896
|
|
|
15788
15897
|
// Use provided totalTokens when available; otherwise sum all components.
|
|
15789
15898
|
// OmO folds reasoning into output, so the fallback must not add it again.
|
|
@@ -15820,14 +15929,12 @@ async function parseOmpLikeIncremental({
|
|
|
15820
15929
|
bucketsQueued: touchedBuckets.size,
|
|
15821
15930
|
});
|
|
15822
15931
|
}
|
|
15823
|
-
}
|
|
15932
|
+
});
|
|
15824
15933
|
|
|
15825
|
-
let postStat = stat;
|
|
15826
|
-
try { postStat = fssync.statSync(filePath); } catch {}
|
|
15827
15934
|
fileOffsets[filePath] = {
|
|
15828
|
-
size:
|
|
15829
|
-
mtimeMs:
|
|
15830
|
-
ino:
|
|
15935
|
+
size: committedEndOffset,
|
|
15936
|
+
mtimeMs: stat.mtimeMs,
|
|
15937
|
+
ino: stat.ino,
|
|
15831
15938
|
};
|
|
15832
15939
|
}
|
|
15833
15940
|
|
|
@@ -15860,28 +15967,16 @@ async function parseOmpLikeIncremental({
|
|
|
15860
15967
|
: null;
|
|
15861
15968
|
const projectRef = projectContext?.projectRef || null;
|
|
15862
15969
|
const projectKey = projectContext?.projectKey || null;
|
|
15970
|
+
let committedEndOffset = stat.size;
|
|
15863
15971
|
|
|
15864
15972
|
if (projectKey && projectRef) {
|
|
15865
|
-
|
|
15866
|
-
try {
|
|
15867
|
-
stream = fssync.createReadStream(filePath, {
|
|
15868
|
-
encoding: "utf8",
|
|
15869
|
-
start: startOffset,
|
|
15870
|
-
});
|
|
15871
|
-
} catch {
|
|
15872
|
-
continue;
|
|
15873
|
-
}
|
|
15874
|
-
const rl = readline.createInterface({ input: stream, crlfDelay: Infinity });
|
|
15875
|
-
for await (const line of rl) {
|
|
15876
|
-
if (!line || !line.trim()) continue;
|
|
15877
|
-
let entry;
|
|
15878
|
-
try { entry = JSON.parse(line); } catch { continue; }
|
|
15973
|
+
committedEndOffset = await scanOmpLikeTranscript(filePath, startOffset, maxRecordBytes, (entry) => {
|
|
15879
15974
|
const msg = entry?.type === "message" ? entry.message : null;
|
|
15880
15975
|
const usage = msg?.role === "assistant" ? msg.usage : null;
|
|
15881
|
-
if (!usage || typeof usage !== "object")
|
|
15976
|
+
if (!usage || typeof usage !== "object") return;
|
|
15882
15977
|
|
|
15883
15978
|
const entryId = typeof entry.id === "string" && entry.id ? entry.id : null;
|
|
15884
|
-
if (!entryId || projectSeenIds.has(entryId))
|
|
15979
|
+
if (!entryId || projectSeenIds.has(entryId)) return;
|
|
15885
15980
|
|
|
15886
15981
|
const input = toNonNegativeInt(usage.input);
|
|
15887
15982
|
const output = toNonNegativeInt(usage.output);
|
|
@@ -15896,7 +15991,7 @@ async function parseOmpLikeIncremental({
|
|
|
15896
15991
|
reasoningTokens === 0
|
|
15897
15992
|
) {
|
|
15898
15993
|
projectSeenIds.add(entryId);
|
|
15899
|
-
|
|
15994
|
+
return;
|
|
15900
15995
|
}
|
|
15901
15996
|
|
|
15902
15997
|
const tsMs = ompEntryTimestampMs(msg, entry);
|
|
@@ -15905,7 +16000,7 @@ async function parseOmpLikeIncremental({
|
|
|
15905
16000
|
: toUtcHalfHourStart(new Date(tsMs).toISOString());
|
|
15906
16001
|
if (!bucketStart) {
|
|
15907
16002
|
projectSeenIds.add(entryId);
|
|
15908
|
-
|
|
16003
|
+
return;
|
|
15909
16004
|
}
|
|
15910
16005
|
|
|
15911
16006
|
const totalTokens =
|
|
@@ -15932,15 +16027,13 @@ async function parseOmpLikeIncremental({
|
|
|
15932
16027
|
addTotals(projectBucket.totals, delta);
|
|
15933
16028
|
projectTouchedBuckets.add(projectBucketKey(projectKey, source, bucketStart));
|
|
15934
16029
|
projectSeenIds.add(entryId);
|
|
15935
|
-
}
|
|
16030
|
+
});
|
|
15936
16031
|
}
|
|
15937
16032
|
|
|
15938
|
-
let postStat = stat;
|
|
15939
|
-
try { postStat = fssync.statSync(filePath); } catch {}
|
|
15940
16033
|
projectFileOffsets[filePath] = {
|
|
15941
|
-
size:
|
|
15942
|
-
mtimeMs:
|
|
15943
|
-
ino:
|
|
16034
|
+
size: committedEndOffset,
|
|
16035
|
+
mtimeMs: stat.mtimeMs,
|
|
16036
|
+
ino: stat.ino,
|
|
15944
16037
|
};
|
|
15945
16038
|
}
|
|
15946
16039
|
}
|
|
@@ -24595,6 +24688,9 @@ module.exports = {
|
|
|
24595
24688
|
coerceEpochMs,
|
|
24596
24689
|
normalizeOpencodeModelFields,
|
|
24597
24690
|
hasZcodeNativeUsageSchema,
|
|
24691
|
+
zcodeDbHasContent,
|
|
24692
|
+
hasZcodeCursorState,
|
|
24693
|
+
resolveZcodeInstallPaths,
|
|
24598
24694
|
resolveQoderDbPath,
|
|
24599
24695
|
resolveQoderDbPaths,
|
|
24600
24696
|
resolveQoderCnDbPaths,
|
|
@@ -28,12 +28,13 @@ const fsp = require("node:fs/promises");
|
|
|
28
28
|
const os = require("node:os");
|
|
29
29
|
const path = require("node:path");
|
|
30
30
|
const readline = require("node:readline");
|
|
31
|
-
const { listClaudeProjectFiles, listRolloutFilesDeep, claudeMessageDedupKey, normalizeClaudeUsage, readZcodeDbMessages, coerceEpochMs, normalizeOpencodeModelFields, normalizeOpencodeTokens, deriveOpencodeMessageFingerprint } = require("./rollout");
|
|
31
|
+
const { listClaudeProjectFiles, listRolloutFilesDeep, claudeMessageDedupKey, normalizeClaudeUsage, readZcodeDbMessages, coerceEpochMs, resolveZcodeInstallPaths, normalizeOpencodeModelFields, normalizeOpencodeTokens, deriveOpencodeMessageFingerprint } = require("./rollout");
|
|
32
32
|
const { parseCodexRolloutFile } = require("./codex-rollout-parser");
|
|
33
33
|
const { computeRowCost, getModelPricingInfo } = require("./pricing");
|
|
34
34
|
const { normalizePerformance, mergePerformance, createClaudePerformanceCollector, createCodexPerformanceCollector, createZcodePerformanceCollector } = require("./session-performance");
|
|
35
35
|
const { readSqliteJsonRows, readSqliteJsonRowsAsync } = require("./sqlite-reader");
|
|
36
36
|
const { resolveZcodeNativeDbPath, resolveInstallPaths } = require("./install-resolver");
|
|
37
|
+
const { readCursorStateSummary } = require("./cursor-store");
|
|
37
38
|
const { USD_TICKS_PER_USD, normalizeGrokUsage } = require("./grok-usage");
|
|
38
39
|
const wsl = require("./wsl-probe");
|
|
39
40
|
const {
|
|
@@ -1975,7 +1976,7 @@ async function discoverSessionFiles(home, env = process.env, deps = {}) {
|
|
|
1975
1976
|
// it like the usage sync does (src/commands/sync.js): native candidate first
|
|
1976
1977
|
// (ZCODE_HOME, home, win32 APPDATA fallback), then the WSL install when the
|
|
1977
1978
|
// WSL mode probes it, picked with the same mode priority (default wsl-first)
|
|
1978
|
-
// so the browser reads the same
|
|
1979
|
+
// so the browser reads the same install the usage card counts. "both"
|
|
1979
1980
|
// preserves both paths; the scanner merges shared session/event identities.
|
|
1980
1981
|
const zcodePlatform = deps.platform || process.platform;
|
|
1981
1982
|
const zcodeNativeDbPath = (deps.resolveZcodeNativeDbPath || resolveZcodeNativeDbPath)({ home, env, platform: zcodePlatform });
|
|
@@ -1991,14 +1992,14 @@ async function discoverSessionFiles(home, env = process.env, deps = {}) {
|
|
|
1991
1992
|
: null;
|
|
1992
1993
|
const zcodeExisting = (dbPath) => (dbPath && fs.existsSync(dbPath) ? dbPath : null);
|
|
1993
1994
|
const zcodeWslDbPath = zcodeWslHome ? path.join(zcodeWslHome, "cli", "db", "db.sqlite") : null;
|
|
1994
|
-
const
|
|
1995
|
-
|
|
1996
|
-
|
|
1997
|
-
|
|
1998
|
-
|
|
1999
|
-
|
|
2000
|
-
|
|
2001
|
-
|
|
1995
|
+
const zcodeNativeExisting = zcodeExisting(zcodeNativeDbPath);
|
|
1996
|
+
const { cursors } = zcodePlatform === "win32"
|
|
1997
|
+
? await readCursorStateSummary({ trackerDir: path.join(home, ".tokentracker", "tracker") })
|
|
1998
|
+
: {};
|
|
1999
|
+
const zcodePaths = resolveZcodeInstallPaths({
|
|
2000
|
+
nativeValue: zcodePlatform === "win32" ? zcodeNativeDbPath : zcodeNativeExisting,
|
|
2001
|
+
wslValue: zcodeWslDbPath,
|
|
2002
|
+
}, env, { platform: zcodePlatform, cursors });
|
|
2002
2003
|
const zcode = [...new Set(Object.values(zcodePaths).filter(Boolean))];
|
|
2003
2004
|
const opencodeNativeDir = env.OPENCODE_HOME || path.join(env.XDG_DATA_HOME || path.join(home, ".local", "share"), "opencode");
|
|
2004
2005
|
const opencodeWslDir = zcodePlatform === "win32" && zcodeProbeWsl && wsl.shouldProbeWsl(env)
|
package/src/lib/upload-queue.js
CHANGED
|
@@ -122,7 +122,7 @@ async function compactPendingQueue({ queuePath, offset = 0, minPendingBytes = BA
|
|
|
122
122
|
temporary = null;
|
|
123
123
|
return { compacted: true, removedRecords, pendingBytesBefore, pendingBytesAfter };
|
|
124
124
|
} catch (error) {
|
|
125
|
-
if (error.code === "ENOENT" && !input) return { compacted: false, removedRecords: 0, pendingBytesBefore: 0, pendingBytesAfter: 0 };
|
|
125
|
+
if (error.code === "ENOENT" && !input && !temporary) return { compacted: false, removedRecords: 0, pendingBytesBefore: 0, pendingBytesAfter: 0 };
|
|
126
126
|
throw error;
|
|
127
127
|
} finally {
|
|
128
128
|
await input?.close();
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{r as n,K as a}from"./__vite-browser-external-CPskAZuH.js";import{u as p}from"./DialogTitle-BBxNf3O8.js";import{u as c}from"./composite-I_1t6PMI.js";const x=n.forwardRef(function(e,r){const{render:l,className:u,style:m,id:s,...t}=e,i=p(),o=c(s);return i.useSyncedValueWithCleanup("descriptionElementId",o),a("p",e,{ref:r,props:[{id:o},t]})});export{x as D};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{r as o}from"./__vite-browser-external-CPskAZuH.js";import{h as r,i as t,p as s}from"./react-CTLavVze.js";function i(){!r.current&&t();const[e]=o.useState(s.current);return e}export{i as u};
|