tokentracker-cli 0.86.0 → 0.87.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/README.de.md +2 -0
- package/README.ja.md +2 -0
- package/README.ko.md +2 -0
- package/README.md +2 -0
- package/README.zh-CN.md +2 -0
- package/dashboard/dist/assets/{AchievementBadge-BgbH_mX4.js → AchievementBadge-CU9m5POo.js} +1 -1
- package/dashboard/dist/assets/{AchievementsPage-CQqkh1JS.js → AchievementsPage-ESzayVR5.js} +2 -2
- package/dashboard/dist/assets/{AchievementsSection-Dmkxpn0s.js → AchievementsSection-DUVRqw19.js} +1 -1
- package/dashboard/dist/assets/{BadgeDetailModal-7OQf37lk.js → BadgeDetailModal-CxNQcN6_.js} +1 -1
- package/dashboard/dist/assets/{Card-1PmWZRTK.js → Card-DXIoSOtO.js} +1 -1
- package/dashboard/dist/assets/{ClawdAnimated-CMJFagpX.js → ClawdAnimated-BsuxMkNd.js} +1 -1
- package/dashboard/dist/assets/{CommandPalette-D4OrwF1w.js → CommandPalette-C-amBp21.js} +1 -1
- package/dashboard/dist/assets/{CommunityStatsModal-BDC9EcwZ.js → CommunityStatsModal-ByFOQube.js} +1 -1
- package/dashboard/dist/assets/{ConfirmModal-22DL5C_9.js → ConfirmModal-BnUyidbn.js} +1 -1
- package/dashboard/dist/assets/{DashboardPage-CEXWzDtt.js → DashboardPage-GyXkKYW0.js} +1 -1
- package/dashboard/dist/assets/{DevicePage-8uhHB7kX.js → DevicePage-B_o-jhku.js} +1 -1
- package/dashboard/dist/assets/{DialogClose-BcJx6VK-.js → DialogClose-BSd7Jiag.js} +1 -1
- package/dashboard/dist/assets/DialogDescription-BFBVGbUT.js +1 -0
- package/dashboard/dist/assets/{DialogTitle-gRzunAqv.js → DialogTitle-XBpneDtQ.js} +1 -1
- package/dashboard/dist/assets/{FadeIn-4rlPdBVe.js → FadeIn-Dg0v4V9p.js} +1 -1
- package/dashboard/dist/assets/{HeaderGithubStar-CR003aO3.js → HeaderGithubStar-BIsQD1OK.js} +1 -1
- package/dashboard/dist/assets/{HoverTooltip-Dgz-dM8Q.js → HoverTooltip-CtmRa8ne.js} +1 -1
- package/dashboard/dist/assets/{IpCheckPage-B4PJRJP_.js → IpCheckPage-BUoLz5sL.js} +1 -1
- package/dashboard/dist/assets/LandingPage-BheA-lw8.js +2 -0
- package/dashboard/dist/assets/{LeaderboardAvatar-CL9LxiEf.js → LeaderboardAvatar-DAy9SOdL.js} +1 -1
- package/dashboard/dist/assets/{LeaderboardPage-DhIzM2Z2.js → LeaderboardPage-CwLqtEUN.js} +2 -2
- package/dashboard/dist/assets/{LeaderboardProfileModal-bbf5uJR5.js → LeaderboardProfileModal-BZ9yGyjB.js} +3 -3
- package/dashboard/dist/assets/{LeaderboardProfilePage-CzuPxscw.js → LeaderboardProfilePage-Cs-LTfvS.js} +1 -1
- package/dashboard/dist/assets/{LimitsPage-B59rb2gg.js → LimitsPage-BQle8e8N.js} +1 -1
- package/dashboard/dist/assets/{LocalOnlyNotice-BkK-6n1R.js → LocalOnlyNotice-Bp4CqObQ.js} +1 -1
- package/dashboard/dist/assets/{LoginCard-BFGCzEjE.js → LoginCard-BIXfWkR2.js} +1 -1
- package/dashboard/dist/assets/{LoginModal-yhkyscFn.js → LoginModal-B-ubPXdr.js} +1 -1
- package/dashboard/dist/assets/{LoginPage-DwU5s0F7.js → LoginPage-9arjWT-s.js} +1 -1
- package/dashboard/dist/assets/{PetPage-BPscYR6z.js → PetPage-BzAVsvh6.js} +1 -1
- package/dashboard/dist/assets/{PopoverPopup-E7PyGTTB.js → PopoverPopup-DMg7XE1h.js} +1 -1
- package/dashboard/dist/assets/{ProviderIcon-CvmnzwKU.js → ProviderIcon-BG3oqeST.js} +1 -1
- package/dashboard/dist/assets/{ResetPasswordPage-DD6qX616.js → ResetPasswordPage-LQ9rfcRE.js} +1 -1
- package/dashboard/dist/assets/{SegmentedControl-DjGBL_l1.js → SegmentedControl-GY2tRk1u.js} +1 -1
- package/dashboard/dist/assets/{Select-B2MGmsi2.js → Select-CCngFwmz.js} +1 -1
- package/dashboard/dist/assets/{SelectItemText-BaTwA_ZF.js → SelectItemText-B9Zm8WTR.js} +1 -1
- package/dashboard/dist/assets/{ServiceStatusPage-0K0y8A6m.js → ServiceStatusPage-BxPvk1-W.js} +1 -1
- package/dashboard/dist/assets/{SessionsPage-CxrtRm3B.js → SessionsPage-DGo6yAwP.js} +1 -1
- package/dashboard/dist/assets/SettingsPage-ConPEiwO.js +1 -0
- package/dashboard/dist/assets/{SkillsPage-BVOU8t3t.js → SkillsPage-D0PB3WR5.js} +1 -1
- package/dashboard/dist/assets/{TokenGalaxy-w7bwGloC.js → TokenGalaxy-Chh_fPIv.js} +1 -1
- package/dashboard/dist/assets/{ToolbarRootContext-BAzpDZej.js → ToolbarRootContext-BXacVvrF.js} +1 -1
- package/dashboard/dist/assets/{TrendMonitor-DyT7Q4xp.js → TrendMonitor-CjiCwNmO.js} +1 -1
- package/dashboard/dist/assets/{WidgetsPage-eDDtopQT.js → WidgetsPage-CBw9uBCO.js} +1 -1
- package/dashboard/dist/assets/{WrappedPage-CKkbdWHF.js → WrappedPage-CEpBAMZR.js} +1 -1
- package/dashboard/dist/assets/{__vite-browser-external-SU8sCTLB.js → __vite-browser-external-Dyag-P6u.js} +20 -13
- package/dashboard/dist/assets/{agent-logos-bkh9XZJd.js → agent-logos-CLQGE0AM.js} +1 -1
- package/dashboard/dist/assets/{arrow-up-right-D16zCIw8.js → arrow-up-right-CU2HDjoG.js} +1 -1
- package/dashboard/dist/assets/{check-BFL17JWQ.js → check-CucGM5lh.js} +1 -1
- package/dashboard/dist/assets/{chevron-right-CUJgrtkp.js → chevron-right-DYzUvcID.js} +1 -1
- package/dashboard/dist/assets/{copy-CRQiCjgs.js → copy-BFeQ31Tr.js} +1 -1
- package/dashboard/dist/assets/{download-Cd12nDrQ.js → download-Coq_llCX.js} +1 -1
- package/dashboard/dist/assets/{external-link-CvAfnsG-.js → external-link-BJiDBW3d.js} +1 -1
- package/dashboard/dist/assets/{flame-CCi681Yl.js → flame-5stsnhc0.js} +1 -1
- package/dashboard/dist/assets/{format-tokens-BAVt8uTZ.js → format-tokens-CpTJbo-2.js} +1 -1
- package/dashboard/dist/assets/{icons-CbKC96gR.js → icons-jsuvmnnO.js} +1 -1
- package/dashboard/dist/assets/{index-B9LWn-mo.js → index-BU6GsTbx.js} +1 -1
- package/dashboard/dist/assets/{index-B5b6PCh5.js → index-Bs97feNM.js} +1 -1
- package/dashboard/dist/assets/{index--TDvaL1y.js → index-DSD3RLQ4.js} +1 -1
- package/dashboard/dist/assets/{info-BPFpD--M.js → info-DNNUzeV_.js} +1 -1
- package/dashboard/dist/assets/{limits-providers-Cyedt-WJ.js → limits-providers-DKTqNO55.js} +1 -1
- package/dashboard/dist/assets/{link-2-BkEPPdfC.js → link-2-DC1hnQcE.js} +1 -1
- package/dashboard/dist/assets/{loader-circle-CzASiylJ.js → loader-circle-DtInM4Io.js} +1 -1
- package/dashboard/dist/assets/{maximize-2-CkwnHUJn.js → maximize-2-DxpsaYXp.js} +1 -1
- package/dashboard/dist/assets/{provider-display-BXBBedC-.js → provider-display-hkyvfEJF.js} +1 -1
- package/dashboard/dist/assets/{react-BXSctDQj.js → react-TbJoDSP4.js} +1 -1
- package/dashboard/dist/assets/{search-_qGma9tM.js → search-C7bnqB9b.js} +1 -1
- package/dashboard/dist/assets/{skills-api-DdmJjnJ9.js → skills-api-D7glOWg7.js} +1 -1
- package/dashboard/dist/assets/{store-owYCN530.js → store-CCVlzuqv.js} +1 -1
- package/dashboard/dist/assets/{terminal-Clzw-KEF.js → terminal-uQlsmzGi.js} +1 -1
- package/dashboard/dist/assets/{trash-2-C5Giwp_E.js → trash-2-B1yuX-oD.js} +1 -1
- package/dashboard/dist/assets/{use-community-stats-Dk8UjLEr.js → use-community-stats-0Fs5nY1G.js} +1 -1
- package/dashboard/dist/assets/{use-limits-display-prefs-CArM595Q.js → use-limits-display-prefs-CrftAn62.js} +1 -1
- package/dashboard/dist/assets/{use-native-settings-Cpd69kiF.js → use-native-settings-CVqB9eoO.js} +1 -1
- package/dashboard/dist/assets/{use-ordered-list--CzwhBTx.js → use-ordered-list-DAdPjLb5.js} +1 -1
- package/dashboard/dist/assets/use-reduced-motion-DVGYs3-k.js +1 -0
- package/dashboard/dist/assets/{use-session-efficiency-pref-DUXO8cCg.js → use-session-efficiency-pref-Cc52HiK0.js} +1 -1
- package/dashboard/dist/assets/{use-transform-Cg3kuMj_.js → use-transform-D76wHhX0.js} +1 -1
- package/dashboard/dist/assets/{use-usage-limits-DY9_mV28.js → use-usage-limits-B7Prb8rk.js} +1 -1
- package/dashboard/dist/assets/{useCurrency-BIe86hMn.js → useCurrency-DWoM_A3s.js} +1 -1
- package/dashboard/dist/assets/{useScrollLock-7-hejkNC.js → useScrollLock-Bp6ddiQo.js} +1 -1
- package/dashboard/dist/assets/{useTokenFormat-DEtLbRgQ.js → useTokenFormat-DZOYz5HT.js} +1 -1
- package/dashboard/dist/assets/{zap-DUxY1d-O.js → zap-DyeAeO8l.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/sync.js +11 -11
- package/src/lib/codex-rollout-parser.js +8 -52
- package/src/lib/jsonl-lines.js +104 -0
- package/src/lib/pricing/seed-snapshot.json +1 -1
- package/src/lib/rollout.js +89 -18
- package/src/lib/wsl-probe.js +36 -0
- package/dashboard/dist/assets/DialogDescription-D6zxtOM5.js +0 -1
- package/dashboard/dist/assets/LandingPage-3JQe-jOZ.js +0 -2
- package/dashboard/dist/assets/SettingsPage-CyvSWvDP.js +0 -1
- package/dashboard/dist/assets/use-reduced-motion-CcILnpU1.js +0 -1
package/src/lib/rollout.js
CHANGED
|
@@ -6,6 +6,7 @@ const readline = require("node:readline");
|
|
|
6
6
|
|
|
7
7
|
const crypto = require("node:crypto");
|
|
8
8
|
const { ensureDir, writeJson, chmod600IfPossible } = require("./fs");
|
|
9
|
+
const { physicalJsonlRecords } = require("./jsonl-lines");
|
|
9
10
|
const { readSqliteJsonRows, readSqliteJsonRowsAsync } = require("./sqlite-reader");
|
|
10
11
|
const wsl = require("./wsl-probe");
|
|
11
12
|
const { resolveInstallPaths } = require("./install-resolver");
|
|
@@ -180,7 +181,11 @@ async function parseRolloutIncremental({
|
|
|
180
181
|
source,
|
|
181
182
|
publicRepoResolver,
|
|
182
183
|
diagnostics,
|
|
184
|
+
invalidRecordPolicy = "skip",
|
|
183
185
|
}) {
|
|
186
|
+
if (invalidRecordPolicy !== "skip" && invalidRecordPolicy !== "throw") {
|
|
187
|
+
throw new TypeError(`unsupported invalidRecordPolicy: ${invalidRecordPolicy}`);
|
|
188
|
+
}
|
|
184
189
|
await ensureDir(path.dirname(queuePath));
|
|
185
190
|
let filesProcessed = 0;
|
|
186
191
|
let eventsAggregated = 0;
|
|
@@ -446,6 +451,7 @@ async function parseRolloutIncremental({
|
|
|
446
451
|
publicRepoCache,
|
|
447
452
|
publicRepoResolver,
|
|
448
453
|
projectContext,
|
|
454
|
+
invalidRecordPolicy,
|
|
449
455
|
})
|
|
450
456
|
: await parseRolloutFile({
|
|
451
457
|
filePath,
|
|
@@ -467,6 +473,7 @@ async function parseRolloutIncremental({
|
|
|
467
473
|
projectContext,
|
|
468
474
|
seenCodexEvents: codexEventTracker,
|
|
469
475
|
sessionId: codexSessionIdFromPath(filePath),
|
|
476
|
+
invalidRecordPolicy,
|
|
470
477
|
});
|
|
471
478
|
|
|
472
479
|
const nextCursor = {
|
|
@@ -760,6 +767,11 @@ async function parseClaudeIncremental({
|
|
|
760
767
|
const projectTouchedBuckets = projectEnabled ? new Set() : null;
|
|
761
768
|
const projectMetaCache = projectEnabled ? new Map() : null;
|
|
762
769
|
const publicRepoCache = projectEnabled ? new Map() : null;
|
|
770
|
+
// Sessions cluster into few repos, so the per-file freshness checks below
|
|
771
|
+
// keep stat-ing the same handful of .git/config paths. Share one stat per
|
|
772
|
+
// config per run, as the Codex path does — it matters most for WSL installs,
|
|
773
|
+
// where every stat crosses the \\wsl$ bridge (#374).
|
|
774
|
+
const projectFreshnessCache = projectEnabled ? new Map() : null;
|
|
763
775
|
const touchedBuckets = new Set();
|
|
764
776
|
// Persist seenMessageHashes across syncs to prevent cross-file duplicates
|
|
765
777
|
// (e.g. subagent file created after main session was already parsed).
|
|
@@ -878,7 +890,9 @@ async function parseClaudeIncremental({
|
|
|
878
890
|
const cachedContextAbsent = cachedProjectFileContext?.absent === true;
|
|
879
891
|
const projectContextFresh =
|
|
880
892
|
projectEnabled && cachedProjectFileContext && !cachedContextAbsent
|
|
881
|
-
? await isProjectFileContextFresh(cachedProjectFileContext
|
|
893
|
+
? await isProjectFileContextFresh(cachedProjectFileContext, {
|
|
894
|
+
freshnessCache: projectFreshnessCache,
|
|
895
|
+
})
|
|
882
896
|
: false;
|
|
883
897
|
const projectKnownAbsent = cachedCwd === null || cachedContextAbsent;
|
|
884
898
|
const projectSettled =
|
|
@@ -909,7 +923,7 @@ async function parseClaudeIncremental({
|
|
|
909
923
|
}
|
|
910
924
|
if (nextCwd) {
|
|
911
925
|
const projectContext = await resolveProjectContextForPath({
|
|
912
|
-
startDir: nextCwd,
|
|
926
|
+
startDir: wsl.mapWslCwdToUnc(nextCwd, filePath),
|
|
913
927
|
projectMetaCache,
|
|
914
928
|
publicRepoCache,
|
|
915
929
|
publicRepoResolver,
|
|
@@ -1945,6 +1959,7 @@ async function parseRolloutFile({
|
|
|
1945
1959
|
projectContext,
|
|
1946
1960
|
seenCodexEvents,
|
|
1947
1961
|
sessionId,
|
|
1962
|
+
invalidRecordPolicy,
|
|
1948
1963
|
}) {
|
|
1949
1964
|
const st = fileStat || (await fs.stat(filePath));
|
|
1950
1965
|
const endOffset = st.size;
|
|
@@ -1961,8 +1976,10 @@ async function parseRolloutFile({
|
|
|
1961
1976
|
};
|
|
1962
1977
|
}
|
|
1963
1978
|
|
|
1964
|
-
const stream = fssync.createReadStream(filePath, {
|
|
1965
|
-
|
|
1979
|
+
const stream = fssync.createReadStream(filePath, {
|
|
1980
|
+
start: startOffset,
|
|
1981
|
+
end: endOffset - 1,
|
|
1982
|
+
});
|
|
1966
1983
|
|
|
1967
1984
|
let model = typeof lastModel === "string" ? lastModel : null;
|
|
1968
1985
|
const usageDeltaState = createUsageDeltaState({
|
|
@@ -1987,8 +2004,19 @@ async function parseRolloutFile({
|
|
|
1987
2004
|
let currentProjectRef = projectRef || null;
|
|
1988
2005
|
let currentProjectKey = projectKey || null;
|
|
1989
2006
|
let eventsAggregated = 0;
|
|
2007
|
+
let scannedEndOffset = startOffset;
|
|
2008
|
+
let committedEndOffset = startOffset;
|
|
2009
|
+
|
|
2010
|
+
const invalidUtf8 = invalidRecordPolicy === "throw" ? "throw" : "record";
|
|
2011
|
+
for await (const record of physicalJsonlRecords(stream, { invalidUtf8 })) {
|
|
2012
|
+
scannedEndOffset += record.physicalBytes;
|
|
2013
|
+
if (record.terminated) committedEndOffset = scannedEndOffset;
|
|
2014
|
+
if (!record.utf8Valid) {
|
|
2015
|
+
if (!record.terminated) break;
|
|
2016
|
+
continue;
|
|
2017
|
+
}
|
|
1990
2018
|
|
|
1991
|
-
|
|
2019
|
+
const { line } = record;
|
|
1992
2020
|
if (!line) continue;
|
|
1993
2021
|
const maybeTokenCount = line.includes('"token_count"');
|
|
1994
2022
|
const maybeTurnContext =
|
|
@@ -1998,14 +2026,28 @@ async function parseRolloutFile({
|
|
|
1998
2026
|
line.includes('"cwd"') ||
|
|
1999
2027
|
line.includes('"current_date"') ||
|
|
2000
2028
|
line.includes('"forked_from_id"'));
|
|
2001
|
-
if (!maybeTokenCount && !maybeTurnContext)
|
|
2029
|
+
if (!maybeTokenCount && !maybeTurnContext) {
|
|
2030
|
+
if (invalidRecordPolicy === "throw" || !record.terminated) {
|
|
2031
|
+
try {
|
|
2032
|
+
JSON.parse(line);
|
|
2033
|
+
committedEndOffset = scannedEndOffset;
|
|
2034
|
+
} catch (error) {
|
|
2035
|
+
if (invalidRecordPolicy === "throw") throw error;
|
|
2036
|
+
break;
|
|
2037
|
+
}
|
|
2038
|
+
}
|
|
2039
|
+
continue;
|
|
2040
|
+
}
|
|
2002
2041
|
|
|
2003
2042
|
let obj;
|
|
2004
2043
|
try {
|
|
2005
2044
|
obj = JSON.parse(line);
|
|
2006
|
-
} catch (
|
|
2045
|
+
} catch (error) {
|
|
2046
|
+
if (invalidRecordPolicy === "throw") throw error;
|
|
2047
|
+
if (!record.terminated) break;
|
|
2007
2048
|
continue;
|
|
2008
2049
|
}
|
|
2050
|
+
if (!record.terminated) committedEndOffset = scannedEndOffset;
|
|
2009
2051
|
|
|
2010
2052
|
if (
|
|
2011
2053
|
(obj?.type === "turn_context" || obj?.type === "session_meta") &&
|
|
@@ -2025,7 +2067,7 @@ async function parseRolloutFile({
|
|
|
2025
2067
|
const nextCwd = obj.payload.cwd.trim();
|
|
2026
2068
|
if (nextCwd && nextCwd !== currentCwd) {
|
|
2027
2069
|
const context = await resolveProjectContextForPath({
|
|
2028
|
-
startDir: nextCwd,
|
|
2070
|
+
startDir: wsl.mapWslCwdToUnc(nextCwd, filePath),
|
|
2029
2071
|
projectMetaCache,
|
|
2030
2072
|
publicRepoCache,
|
|
2031
2073
|
publicRepoResolver,
|
|
@@ -2149,7 +2191,7 @@ async function parseRolloutFile({
|
|
|
2149
2191
|
}
|
|
2150
2192
|
|
|
2151
2193
|
return {
|
|
2152
|
-
endOffset,
|
|
2194
|
+
endOffset: committedEndOffset,
|
|
2153
2195
|
lastTotal: latestTotal,
|
|
2154
2196
|
tokenUsageBaselines: snapshotUsageBaselines(usageDeltaState),
|
|
2155
2197
|
lastModel: model,
|
|
@@ -2169,6 +2211,7 @@ async function scanRolloutProjectFileContexts({
|
|
|
2169
2211
|
publicRepoCache,
|
|
2170
2212
|
publicRepoResolver,
|
|
2171
2213
|
projectContext,
|
|
2214
|
+
invalidRecordPolicy,
|
|
2172
2215
|
}) {
|
|
2173
2216
|
const st = fileStat || (await fs.stat(filePath));
|
|
2174
2217
|
const endOffset = st.size;
|
|
@@ -2185,11 +2228,21 @@ async function scanRolloutProjectFileContexts({
|
|
|
2185
2228
|
};
|
|
2186
2229
|
}
|
|
2187
2230
|
|
|
2188
|
-
const stream = fssync.createReadStream(filePath, {
|
|
2189
|
-
const rl = readline.createInterface({ input: stream, crlfDelay: Infinity });
|
|
2231
|
+
const stream = fssync.createReadStream(filePath, { start: 0, end: endOffset - 1 });
|
|
2190
2232
|
let currentCwd = null;
|
|
2233
|
+
let scannedEndOffset = 0;
|
|
2234
|
+
let committedEndOffset = 0;
|
|
2235
|
+
|
|
2236
|
+
const invalidUtf8 = invalidRecordPolicy === "throw" ? "throw" : "record";
|
|
2237
|
+
for await (const record of physicalJsonlRecords(stream, { invalidUtf8 })) {
|
|
2238
|
+
scannedEndOffset += record.physicalBytes;
|
|
2239
|
+
if (record.terminated) committedEndOffset = scannedEndOffset;
|
|
2240
|
+
if (!record.utf8Valid) {
|
|
2241
|
+
if (!record.terminated) break;
|
|
2242
|
+
continue;
|
|
2243
|
+
}
|
|
2191
2244
|
|
|
2192
|
-
|
|
2245
|
+
const { line } = record;
|
|
2193
2246
|
if (
|
|
2194
2247
|
!line ||
|
|
2195
2248
|
!(
|
|
@@ -2198,15 +2251,27 @@ async function scanRolloutProjectFileContexts({
|
|
|
2198
2251
|
) ||
|
|
2199
2252
|
!line.includes('"cwd"')
|
|
2200
2253
|
) {
|
|
2254
|
+
if (line && (invalidRecordPolicy === "throw" || !record.terminated)) {
|
|
2255
|
+
try {
|
|
2256
|
+
JSON.parse(line);
|
|
2257
|
+
committedEndOffset = scannedEndOffset;
|
|
2258
|
+
} catch (error) {
|
|
2259
|
+
if (invalidRecordPolicy === "throw") throw error;
|
|
2260
|
+
break;
|
|
2261
|
+
}
|
|
2262
|
+
}
|
|
2201
2263
|
continue;
|
|
2202
2264
|
}
|
|
2203
2265
|
|
|
2204
2266
|
let obj;
|
|
2205
2267
|
try {
|
|
2206
2268
|
obj = JSON.parse(line);
|
|
2207
|
-
} catch (
|
|
2269
|
+
} catch (error) {
|
|
2270
|
+
if (invalidRecordPolicy === "throw") throw error;
|
|
2271
|
+
if (!record.terminated) break;
|
|
2208
2272
|
continue;
|
|
2209
2273
|
}
|
|
2274
|
+
if (!record.terminated) committedEndOffset = scannedEndOffset;
|
|
2210
2275
|
if (
|
|
2211
2276
|
(obj?.type !== "turn_context" && obj?.type !== "session_meta") ||
|
|
2212
2277
|
!obj?.payload ||
|
|
@@ -2219,7 +2284,7 @@ async function scanRolloutProjectFileContexts({
|
|
|
2219
2284
|
const nextCwd = obj.payload.cwd.trim();
|
|
2220
2285
|
if (!nextCwd || nextCwd === currentCwd) continue;
|
|
2221
2286
|
const context = await resolveProjectContextForPath({
|
|
2222
|
-
startDir: nextCwd,
|
|
2287
|
+
startDir: wsl.mapWslCwdToUnc(nextCwd, filePath),
|
|
2223
2288
|
projectMetaCache,
|
|
2224
2289
|
publicRepoCache,
|
|
2225
2290
|
publicRepoResolver,
|
|
@@ -2230,7 +2295,7 @@ async function scanRolloutProjectFileContexts({
|
|
|
2230
2295
|
}
|
|
2231
2296
|
|
|
2232
2297
|
return {
|
|
2233
|
-
endOffset,
|
|
2298
|
+
endOffset: committedEndOffset,
|
|
2234
2299
|
lastTotal,
|
|
2235
2300
|
tokenUsageBaselines,
|
|
2236
2301
|
lastModel,
|
|
@@ -4129,6 +4194,7 @@ function readZcodeDbMessages(dbPath, sqliteOptions = {}) {
|
|
|
4129
4194
|
|
|
4130
4195
|
async function parseOpencodeDbIncremental({
|
|
4131
4196
|
dbMessages,
|
|
4197
|
+
dbPath,
|
|
4132
4198
|
cursors,
|
|
4133
4199
|
queuePath,
|
|
4134
4200
|
projectQueuePath,
|
|
@@ -4225,6 +4291,7 @@ async function parseOpencodeDbIncremental({
|
|
|
4225
4291
|
if (projectEnabled) {
|
|
4226
4292
|
const projectContext = await resolveProjectContextForDb({
|
|
4227
4293
|
msg,
|
|
4294
|
+
dbPath,
|
|
4228
4295
|
projectMetaCache,
|
|
4229
4296
|
publicRepoCache,
|
|
4230
4297
|
publicRepoResolver,
|
|
@@ -4444,6 +4511,7 @@ function qoderProjectPath(row) {
|
|
|
4444
4511
|
|
|
4445
4512
|
async function parseQoderDbIncremental({
|
|
4446
4513
|
dbMessages,
|
|
4514
|
+
dbPath,
|
|
4447
4515
|
cursors,
|
|
4448
4516
|
queuePath,
|
|
4449
4517
|
projectQueuePath,
|
|
@@ -4515,7 +4583,7 @@ async function parseQoderDbIncremental({
|
|
|
4515
4583
|
const projectPath = qoderProjectPath(row);
|
|
4516
4584
|
if (projectPath) {
|
|
4517
4585
|
const context = await resolveProjectContextForPath({
|
|
4518
|
-
startDir: projectPath,
|
|
4586
|
+
startDir: wsl.mapWslCwdToUnc(projectPath, dbPath),
|
|
4519
4587
|
projectMetaCache,
|
|
4520
4588
|
publicRepoCache,
|
|
4521
4589
|
publicRepoResolver,
|
|
@@ -4975,6 +5043,7 @@ async function parseClaudeScienceIncremental({
|
|
|
4975
5043
|
// Resolve project context from DB message (no file path available)
|
|
4976
5044
|
async function resolveProjectContextForDb({
|
|
4977
5045
|
msg,
|
|
5046
|
+
dbPath,
|
|
4978
5047
|
projectMetaCache,
|
|
4979
5048
|
publicRepoCache,
|
|
4980
5049
|
publicRepoResolver,
|
|
@@ -4983,7 +5052,9 @@ async function resolveProjectContextForDb({
|
|
|
4983
5052
|
const cwd = msg?.path?.cwd;
|
|
4984
5053
|
if (!cwd || typeof cwd !== "string") return null;
|
|
4985
5054
|
return resolveProjectContextForPath({
|
|
4986
|
-
|
|
5055
|
+
// The DB itself is read over the distro's UNC bridge on Windows, so its
|
|
5056
|
+
// path carries the prefix the recorded POSIX cwd needs (#374).
|
|
5057
|
+
startDir: wsl.mapWslCwdToUnc(cwd, dbPath),
|
|
4987
5058
|
projectMetaCache,
|
|
4988
5059
|
publicRepoCache,
|
|
4989
5060
|
publicRepoResolver,
|
|
@@ -11141,7 +11212,7 @@ async function parseOmpIncremental({
|
|
|
11141
11212
|
const cwd = await resolveOmpFileCwd(filePath);
|
|
11142
11213
|
const projectContext = cwd
|
|
11143
11214
|
? await resolveProjectContextForPath({
|
|
11144
|
-
startDir: cwd,
|
|
11215
|
+
startDir: wsl.mapWslCwdToUnc(cwd, filePath),
|
|
11145
11216
|
projectMetaCache,
|
|
11146
11217
|
publicRepoCache,
|
|
11147
11218
|
publicRepoResolver,
|
package/src/lib/wsl-probe.js
CHANGED
|
@@ -164,6 +164,40 @@ function isUncPath(p) {
|
|
|
164
164
|
return typeof p === "string" && (p.startsWith("\\\\") || p.startsWith("//"));
|
|
165
165
|
}
|
|
166
166
|
|
|
167
|
+
const WSL_UNC_ROOT_RE = /^[\\/]{2}(wsl\$|wsl\.localhost)[\\/]([^\\/]+)[\\/]/i;
|
|
168
|
+
const WINDOWS_DRIVE_PREFIX_RE = /^\/[A-Za-z]:[\\/]/;
|
|
169
|
+
|
|
170
|
+
// `\\wsl$\Ubuntu-24.04\home\u\...` -> `\\wsl$\Ubuntu-24.04\`. Returns null for
|
|
171
|
+
// native and non-WSL UNC paths.
|
|
172
|
+
function wslUncRoot(p) {
|
|
173
|
+
if (typeof p !== "string") return null;
|
|
174
|
+
const match = WSL_UNC_ROOT_RE.exec(p);
|
|
175
|
+
return match ? `\\\\${match[1]}\\${match[2]}\\` : null;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
// A WSL session records its cwd as a POSIX path (`/home/u/dev/app`) while the
|
|
179
|
+
// transcript itself is read over the distro's UNC bridge. Probing that raw
|
|
180
|
+
// POSIX path from Windows resolves it against the current drive
|
|
181
|
+
// (`C:\home\u\dev\app`), which never exists — so project attribution finds no
|
|
182
|
+
// `.git`, and every WSL session ends up with a null projectKey (#374).
|
|
183
|
+
// Re-anchor the cwd onto the UNC prefix the transcript came from.
|
|
184
|
+
//
|
|
185
|
+
// The prefix is taken from the transcript path rather than re-probed, which
|
|
186
|
+
// also picks whichever of `\\wsl$` / `\\wsl.localhost` actually resolves on
|
|
187
|
+
// this machine — they are not interchangeable everywhere. Anything that isn't
|
|
188
|
+
// a POSIX cwd from a WSL-hosted file is returned untouched.
|
|
189
|
+
function mapWslCwdToUnc(cwd, transcriptPath) {
|
|
190
|
+
if (typeof cwd !== "string" || !cwd.startsWith("/")) return cwd;
|
|
191
|
+
// `new URL("file:///C:/dev/app").pathname` is "/C:/dev/app" — a leading
|
|
192
|
+
// slash, but a Windows path rather than a POSIX one. Qoder feeds exactly
|
|
193
|
+
// that shape in via `project_uri`; re-anchoring it would invent
|
|
194
|
+
// `\\wsl$\Distro\C:\dev\app`.
|
|
195
|
+
if (WINDOWS_DRIVE_PREFIX_RE.test(cwd)) return cwd;
|
|
196
|
+
const root = wslUncRoot(transcriptPath);
|
|
197
|
+
if (!root) return cwd;
|
|
198
|
+
return root + cwd.slice(1).replaceAll("/", "\\");
|
|
199
|
+
}
|
|
200
|
+
|
|
167
201
|
function snapshotSqliteDb(dbPath) {
|
|
168
202
|
const tmpRoot = fssync.mkdtempSync(
|
|
169
203
|
path.join(require("node:os").tmpdir(), "tokentracker-wsl-snap-"),
|
|
@@ -191,6 +225,8 @@ module.exports = {
|
|
|
191
225
|
resetWslProbeCache,
|
|
192
226
|
discoverWslHome,
|
|
193
227
|
isUncPath,
|
|
228
|
+
wslUncRoot,
|
|
229
|
+
mapWslCwdToUnc,
|
|
194
230
|
snapshotSqliteDb,
|
|
195
231
|
getWslMode,
|
|
196
232
|
isInvalidWslMode,
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{r as n,A as a}from"./__vite-browser-external-SU8sCTLB.js";import{u as p}from"./DialogTitle-gRzunAqv.js";import{u as c}from"./useScrollLock-7-hejkNC.js";const x=n.forwardRef(function(e,r){const{render:l,className:u,style:m,id:s,...t}=e,{store:i}=p(),o=c(s);return i.useSyncedValueWithCleanup("descriptionElementId",o),a("p",e,{ref:r,props:[{id:o},t]})});export{x as D};
|