Load and display the last 10 cache entries as raw JSON output. DO NOT create extra files or pretty-print the data - output raw JSON only. Use when you need to understand cached session statistics, debug cache behavior, or work with actual cached data.
IMPORTANT: Always output raw JSON only. Do not create extra files for displaying data.
This skill helps you access and inspect the GitHub Copilot Token Tracker's local session file cache. The cache stores pre-computed statistics for session files to avoid re-processing unchanged files.
The extension maintains a local cache of session file statistics in VS Code's globalState. This cache contains:
Use this skill when you need to:
CRITICAL: When using this skill:
--json flag to output raw JSON--json and display the raw JSON outputThe cache is stored in VS Code's global state under the key 'sessionFileCache'. Each cache entry is keyed by the absolute file path and contains:
interface SessionFileCache {
tokens: number; // Total token count
interactions: number; // Number of interactions
modelUsage: ModelUsage; // Per-model token breakdown
mtime: number; // File modification timestamp
usageAnalysis?: SessionUsageAnalysis; // Detailed usage statistics
}
interface ModelUsage {
[model: string]: {
inputTokens: number;
outputTokens: number;
};
}
interface SessionUsageAnalysis {
toolCalls: ToolCallUsage; // Tool usage statistics
modeUsage: ModeUsage; // Mode distribution
contextReferences: ContextReferenceUsage; // Context reference counts
mcpTools: McpToolUsage; // MCP tool usage
}
Cache Storage: VS Code globalState → 'sessionFileCache'
context.globalState.get<Record<string, SessionFileCache>>('sessionFileCache')state.vscdb)Implementation: src/extension.ts (lines 74-80, 194, 336-360)
The cache can be accessed through the extension's context at runtime:
// Load cache from global state
const cacheData = context.globalState.get<Record<string, SessionFileCache>>('sessionFileCache');
const cacheEntries = Object.entries(cacheData || {});
// Get last 10 entries (sorted by modification time)
const last10 = cacheEntries
.sort((a, b) => (b[1].mtime || 0) - (a[1].mtime || 0))
.slice(0, 10);
// Display cache entries
for (const [filePath, cacheEntry] of last10) {
console.log({
file: filePath,
tokens: cacheEntry.tokens,
interactions: cacheEntry.interactions,
modelUsage: cacheEntry.modelUsage,
lastModified: new Date(cacheEntry.mtime).toISOString()
});
}
This skill includes an executable script that loads and displays actual cache data from disk:
Location: .github/skills/load-cache-data/load-cache-data.js
Usage:
# RECOMMENDED: Always use --json for raw JSON output
node .github/skills/load-cache-data/load-cache-data.js --json
# Show last N entries as JSON (default is 10)
node .github/skills/load-cache-data/load-cache-data.js --last 5 --json
# Show help
node .github/skills/load-cache-data/load-cache-data.js --help
Note: The script supports human-readable output without --json, but for LLM skills, always use --json to get structured data.
What it does:
Cache File Locations:
The script searches for cache export files in these locations:
%APPDATA%\Code\User\globalStorage\rajbos.copilot-token-tracker\cache.json (Windows)
%TEMP%\copilot-token-tracker-cache.json./cache-export.jsonCreating Cache Export Files:
Since the extension stores cache in VS Code's globalState (internal SQLite database), the cache data must be explicitly exported to one of the above locations for this script to access it. This can be done:
Exit Codes:
0: Cache file found and displayed successfully1: No cache file foundNote: If no cache file is found, the script will display the searched locations and instructions for exporting cache data.
Method: loadCacheFromStorage()
Location: src/extension.ts (lines 336-350)
Loads the cache from VS Code's global state on extension activation:
const cacheData = this.context.globalState.get<Record<string, SessionFileCache>>('sessionFileCache');
if (cacheData) {
this.sessionFileCache = new Map(Object.entries(cacheData));
}
Method: saveCacheToStorage()
Location: src/extension.ts (lines 352-360)
Saves the cache to VS Code's global state:
const cacheData = Object.fromEntries(this.sessionFileCache);
await this.context.globalState.update('sessionFileCache', cacheData);
Method: isCacheValid()
Location: src/extension.ts (lines 285-290)
Validates cache entries by comparing modification times:
private isCacheValid(filePath: string, currentMtime: number): boolean {
const cached = this.sessionFileCache.get(filePath);
return cached !== undefined && cached.mtime === currentMtime;
}
Method: clearExpiredCache()
Location: src/extension.ts (lines 308-333)
Removes cache entries for files that no longer exist:
const sessionFiles = await this.getCopilotSessionFiles();
const validPaths = new Set(sessionFiles);
for (const [filePath, _] of this.sessionFileCache) {
if (!validPaths.has(filePath)) {
this.sessionFileCache.delete(filePath);
}
}
getCopilotSessionFiles()isCacheValid()setCachedSessionData()saveCacheToStorage()clearExpiredCache()// Get cache data
const cache = context.globalState.get('sessionFileCache');
const entries = Object.entries(cache || {});
// Sort by most recent
entries.sort((a, b) => (b[1].mtime || 0) - (a[1].mtime || 0));
// Show top 10
console.log('Most recent sessions:');
entries.slice(0, 10).forEach(([path, data], i) => {
console.log(`${i + 1}. ${path.split('/').pop()}`);
console.log(` Tokens: ${data.tokens}, Interactions: ${data.interactions}`);
console.log(` Modified: ${new Date(data.mtime).toLocaleString()}`);
});
const cache = context.globalState.get('sessionFileCache');
const modelTotals = {};
for (const [path, data] of Object.entries(cache || {})) {
for (const [model, usage] of Object.entries(data.modelUsage)) {
if (!modelTotals[model]) {
modelTotals[model] = { input: 0, output: 0 };
}
modelTotals[model].input += usage.inputTokens;
modelTotals[model].output += usage.outputTokens;
}
}
console.log('Cached model usage:');
for (const [model, totals] of Object.entries(modelTotals)) {
console.log(` ${model}: ${totals.input + totals.output} tokens`);
}
const cache = context.globalState.get('sessionFileCache');
const entries = Object.entries(cache || {});
const stats = {
totalEntries: entries.length,
totalTokens: 0,
totalInteractions: 0,
oldestEntry: null,
newestEntry: null
};
entries.forEach(([path, data]) => {
stats.totalTokens += data.tokens;
stats.totalInteractions += data.interactions;
if (!stats.oldestEntry || data.mtime < stats.oldestEntry.mtime) {
stats.oldestEntry = { path, mtime: data.mtime };
}
if (!stats.newestEntry || data.mtime > stats.newestEntry.mtime) {
stats.newestEntry = { path, mtime: data.mtime };
}
});
console.log('Cache Statistics:', stats);
The cache is tightly integrated with the extension's token tracking:
Session File Processing: getSessionFileDataCached() (lines 1414-1450)
Statistics Calculation: calculateDetailedStats() (lines 379-693)
Performance Optimization:
Symptoms: Extension shows no cached data or logs "No cached session files found" Solutions:
getCopilotSessionFiles()Symptoms: Token counts don't match session file contents Solutions:
Symptoms: Extension slow to start or save Solutions:
clearExpiredCache()Cache implementation: src/extension.ts
Session file discovery: src/extension.ts
Session parsing: src/sessionParser.ts
Skill script: .github/skills/load-cache-data/load-cache-data.js
state.vscdb)