From bebe859052c7ccb89c2bea527860768641971739 Mon Sep 17 00:00:00 2001 From: Liuba Gonta Date: Fri, 30 Jan 2026 13:51:19 +0100 Subject: [PATCH 1/7] fix: fix dashboard data discrepancy --- src/extension.ts | 46 ++++++++++++++++++++++++++++++++++++---------- 1 file changed, 36 insertions(+), 10 deletions(-) diff --git a/src/extension.ts b/src/extension.ts index 6f1db3e..39950ff 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -611,9 +611,23 @@ class CopilotTokenTracker implements vscode.Disposable { } try { + // Get session file details to access lastInteraction timestamp + const details = await this.getSessionFileDetails(sessionFile); + + // Skip empty sessions (no interactions = just opened chat panel, no messages sent) + if (details.interactions === 0) { + skippedFiles++; + continue; + } + + // Use lastInteraction date (fallback to modified date) for consistency with Diagnostic view + const lastActivity = details.lastInteraction + ? new Date(details.lastInteraction) + : new Date(details.modified); + const fileStats = fs.statSync(sessionFile); - if (fileStats.mtime >= monthStart) { + if (lastActivity >= monthStart) { // Check if data is cached before making calls const wasCached = this.isCacheValid(sessionFile, fileStats.mtime.getTime()); @@ -649,7 +663,7 @@ class CopilotTokenTracker implements vscode.Disposable { monthStats.modelUsage[model].outputTokens += usage.outputTokens; } - if (fileStats.mtime >= todayStart) { + if (lastActivity >= todayStart) { todayStats.tokens += tokens; todayStats.sessions += 1; todayStats.interactions += interactions; @@ -672,7 +686,7 @@ class CopilotTokenTracker implements vscode.Disposable { } } else { - // File is too old, skip it + // Session is too old (no activity in current month), skip it skippedFiles++; } } catch (fileError) { @@ -682,7 +696,7 @@ class CopilotTokenTracker implements vscode.Disposable { this.log(`✅ Analysis complete: Today ${todayStats.sessions} sessions, Month ${monthStats.sessions} sessions`); if (skippedFiles > 0) { - this.log(`⏭️ Skipped ${skippedFiles} session file(s) (too old, not in current month)`); + this.log(`⏭️ Skipped ${skippedFiles} session file(s) (empty or no activity in current month)`); } const totalCacheAccesses = cacheHits + cacheMisses; this.log(`💾 Cache performance: ${cacheHits} hits, ${cacheMisses} misses (${totalCacheAccesses > 0 ? ((cacheHits / totalCacheAccesses) * 100).toFixed(1) : 0}% hit rate)`); @@ -3198,7 +3212,22 @@ class CopilotTokenTracker implements vscode.Disposable { fourteenDaysAgo.setDate(fourteenDaysAgo.getDate() - 14); const detailedSessionFiles: SessionFileDetails[] = []; - for (const file of sessionFiles.slice(0, 500)) { + // Sort files by modification time (most recent first) before taking first 500 + // This ensures we prioritize recent sessions regardless of their folder location + const sortedFiles = sessionFiles + .map(file => { + try { + const stat = fs.statSync(file); + return { file, mtime: stat.mtime.getTime() }; + } catch { + return { file, mtime: 0 }; + } + }) + .sort((a, b) => b.mtime - a.mtime) + .map(item => item.file); + + // Process up to 500 most recent session files + for (const file of sortedFiles.slice(0, 500)) { // Check if panel was disposed if (!panel.visible && panel.viewColumn === undefined) { this.log('Diagnostic panel closed, stopping background load'); @@ -3207,11 +3236,8 @@ class CopilotTokenTracker implements vscode.Disposable { try { const details = await this.getSessionFileDetails(file); - // Filter: skip empty sessions (no interactions = just opened chat panel, no messages sent) - if (details.interactions === 0) { - continue; - } - // Filter: only include sessions with activity in the last 14 days + // Include all sessions (even empty ones) to show complete session history in diagnostics + // Filter: only include sessions with activity in the last 14 days based on lastInteraction const lastActivity = details.lastInteraction ? new Date(details.lastInteraction) : new Date(details.modified); From a67d0aaa87c9be5bc67ed488fb9420fe18a130f7 Mon Sep 17 00:00:00 2001 From: Liuba Gonta <98797067+liubchigo@users.noreply.github.com> Date: Fri, 30 Jan 2026 13:58:24 +0100 Subject: [PATCH 2/7] Update src/extension.ts Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- src/extension.ts | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/extension.ts b/src/extension.ts index 39950ff..98dd420 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -3214,15 +3214,18 @@ class CopilotTokenTracker implements vscode.Disposable { // Sort files by modification time (most recent first) before taking first 500 // This ensures we prioritize recent sessions regardless of their folder location - const sortedFiles = sessionFiles - .map(file => { + const fileStats = await Promise.all( + sessionFiles.map(async (file) => { try { - const stat = fs.statSync(file); + const stat = await fs.promises.stat(file); return { file, mtime: stat.mtime.getTime() }; } catch { return { file, mtime: 0 }; } }) + ); + + const sortedFiles = fileStats .sort((a, b) => b.mtime - a.mtime) .map(item => item.file); From 98977f3e86d8b63291de7f9d8a366054fe9d3a12 Mon Sep 17 00:00:00 2001 From: Liuba Gonta <98797067+liubchigo@users.noreply.github.com> Date: Fri, 30 Jan 2026 13:58:53 +0100 Subject: [PATCH 3/7] Update src/extension.ts Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- src/extension.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/extension.ts b/src/extension.ts index 98dd420..1c108b5 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -3239,8 +3239,8 @@ class CopilotTokenTracker implements vscode.Disposable { try { const details = await this.getSessionFileDetails(file); - // Include all sessions (even empty ones) to show complete session history in diagnostics - // Filter: only include sessions with activity in the last 14 days based on lastInteraction + // Include sessions (including empty ones) in diagnostics, but only if they have activity + // (based on lastInteraction or modified time) within the last 14 days const lastActivity = details.lastInteraction ? new Date(details.lastInteraction) : new Date(details.modified); From d743c8b5888abe7cbf3631d4a3675ab8da80db68 Mon Sep 17 00:00:00 2001 From: Liuba Gonta Date: Fri, 30 Jan 2026 14:07:33 +0100 Subject: [PATCH 4/7] fix: optimize file check --- src/extension.ts | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/extension.ts b/src/extension.ts index 1c108b5..4e50f96 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -611,6 +611,15 @@ class CopilotTokenTracker implements vscode.Disposable { } try { + // Fast check: Get file stats first to avoid processing old files + const fileStats = fs.statSync(sessionFile); + + // Skip files modified before the current month (quick filter) + if (fileStats.mtime < monthStart) { + skippedFiles++; + continue; + } + // Get session file details to access lastInteraction timestamp const details = await this.getSessionFileDetails(sessionFile); @@ -624,8 +633,6 @@ class CopilotTokenTracker implements vscode.Disposable { const lastActivity = details.lastInteraction ? new Date(details.lastInteraction) : new Date(details.modified); - - const fileStats = fs.statSync(sessionFile); if (lastActivity >= monthStart) { // Check if data is cached before making calls From bb4d227938ce80925a47de46adf621094585d376 Mon Sep 17 00:00:00 2001 From: Liuba Gonta <98797067+liubchigo@users.noreply.github.com> Date: Fri, 30 Jan 2026 14:12:25 +0100 Subject: [PATCH 5/7] Update src/extension.ts Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- src/extension.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/extension.ts b/src/extension.ts index 4e50f96..0f6137a 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -3246,8 +3246,9 @@ class CopilotTokenTracker implements vscode.Disposable { try { const details = await this.getSessionFileDetails(file); - // Include sessions (including empty ones) in diagnostics, but only if they have activity - // (based on lastInteraction or modified time) within the last 14 days + // Consider all session files (including those without interactions) for diagnostics. + // Sessions are only included if their last activity is within the last 14 days, where + // "activity" is based on lastInteraction when present, or the file's modified time otherwise. const lastActivity = details.lastInteraction ? new Date(details.lastInteraction) : new Date(details.modified); From 192a5d5ae717eadea51038432d9bb4d853636d2b Mon Sep 17 00:00:00 2001 From: Liuba Gonta Date: Fri, 30 Jan 2026 14:13:57 +0100 Subject: [PATCH 6/7] perf: reduce file reads with early mtime and interaction filtering --- src/extension.ts | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/src/extension.ts b/src/extension.ts index 0f6137a..8ee9a08 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -615,33 +615,37 @@ class CopilotTokenTracker implements vscode.Disposable { const fileStats = fs.statSync(sessionFile); // Skip files modified before the current month (quick filter) + // This is the main performance optimization - filters out old sessions without reading file content if (fileStats.mtime < monthStart) { skippedFiles++; continue; } - // Get session file details to access lastInteraction timestamp - const details = await this.getSessionFileDetails(sessionFile); + // For files within current month, check if data is cached to avoid redundant reads + const mtime = fileStats.mtime.getTime(); + const wasCached = this.isCacheValid(sessionFile, mtime); + + // Get interactions count (uses cache if available) + const interactions = await this.countInteractionsInSessionCached(sessionFile, mtime); // Skip empty sessions (no interactions = just opened chat panel, no messages sent) - if (details.interactions === 0) { + if (interactions === 0) { skippedFiles++; continue; } - // Use lastInteraction date (fallback to modified date) for consistency with Diagnostic view + // Get remaining data (all use cache if available) + const tokens = await this.estimateTokensFromSessionCached(sessionFile, mtime); + const modelUsage = await this.getModelUsageFromSessionCached(sessionFile, mtime); + const editorType = this.getEditorTypeFromPath(sessionFile); + + // For date filtering, get lastInteraction from session details + const details = await this.getSessionFileDetails(sessionFile); const lastActivity = details.lastInteraction ? new Date(details.lastInteraction) : new Date(details.modified); if (lastActivity >= monthStart) { - // Check if data is cached before making calls - const wasCached = this.isCacheValid(sessionFile, fileStats.mtime.getTime()); - - const tokens = await this.estimateTokensFromSessionCached(sessionFile, fileStats.mtime.getTime()); - const interactions = await this.countInteractionsInSessionCached(sessionFile, fileStats.mtime.getTime()); - const modelUsage = await this.getModelUsageFromSessionCached(sessionFile, fileStats.mtime.getTime()); - const editorType = this.getEditorTypeFromPath(sessionFile); // Update cache statistics if (wasCached) { From a135640015a5bdc93e33c3a7ccbedd7b7b0efd07 Mon Sep 17 00:00:00 2001 From: Liuba Gonta Date: Fri, 30 Jan 2026 14:29:34 +0100 Subject: [PATCH 7/7] improve comment --- src/extension.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/extension.ts b/src/extension.ts index 8ee9a08..675bc39 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -3250,9 +3250,7 @@ class CopilotTokenTracker implements vscode.Disposable { try { const details = await this.getSessionFileDetails(file); - // Consider all session files (including those without interactions) for diagnostics. - // Sessions are only included if their last activity is within the last 14 days, where - // "activity" is based on lastInteraction when present, or the file's modified time otherwise. + // Only include sessions with activity (lastInteraction or file modified time) within the last 14 days const lastActivity = details.lastInteraction ? new Date(details.lastInteraction) : new Date(details.modified);