feat(usage): split throttle thresholds per bucket, add draggable gauge markers

This commit is contained in:
mika kuns
2026-08-07 11:01:45 +02:00
parent 231b063751
commit 7eeb8f5086
33 changed files with 2289 additions and 147 deletions
@@ -28,9 +28,15 @@ public sealed class TranscriptUsageReader : ITranscriptUsageReader
if (Directory.Exists(_projectsRoot))
{
foreach (var file in Directory.EnumerateFiles(_projectsRoot, "*.jsonl", SearchOption.AllDirectories))
// A transcript last written before the window began cannot hold a record inside it, so
// it is skipped unread — that is what keeps a 7-day range off the full history (hundreds
// of MB). One day of slack absorbs local-vs-UTC skew between mtime and record stamps.
var mtimeCutoff = start.ToDateTime(TimeOnly.MinValue).AddDays(-1);
foreach (var file in new DirectoryInfo(_projectsRoot).EnumerateFiles("*.jsonl", SearchOption.AllDirectories))
{
ct.ThrowIfCancellationRequested();
if (file.LastWriteTime < mtimeCutoff) continue;
foreach (var record in GetOrReadFile(file))
{
@@ -67,8 +73,8 @@ public sealed class TranscriptUsageReader : ITranscriptUsageReader
if (string.IsNullOrWhiteSpace(sessionId) || !Directory.Exists(_projectsRoot))
return Task.FromResult<SessionUsageTotals?>(null);
var file = Directory
.EnumerateFiles(_projectsRoot, $"{sessionId}.jsonl", SearchOption.AllDirectories)
var file = new DirectoryInfo(_projectsRoot)
.EnumerateFiles($"{sessionId}.jsonl", SearchOption.AllDirectories)
.FirstOrDefault();
if (file is null) return Task.FromResult<SessionUsageTotals?>(null);
@@ -89,17 +95,16 @@ public sealed class TranscriptUsageReader : ITranscriptUsageReader
new SessionUsageTotals(input, output, cacheRead, cacheCreation));
}
private List<UsageMessageRecord> GetOrReadFile(string file)
private List<UsageMessageRecord> GetOrReadFile(FileInfo info)
{
var info = new FileInfo(file);
if (_cache.TryGetValue(file, out var cached) &&
if (_cache.TryGetValue(info.FullName, out var cached) &&
cached.Length == info.Length && cached.LastWriteUtc == info.LastWriteTimeUtc)
{
return cached.Records;
}
var records = ReadFile(file);
_cache[file] = new FileCacheEntry(info.Length, info.LastWriteTimeUtc, records);
var records = ReadFile(info.FullName);
_cache[info.FullName] = new FileCacheEntry(info.Length, info.LastWriteTimeUtc, records);
return records;
}