feat: Implement history tracking with new CLI commands for viewing past transcripts and usage statistics.
This commit is contained in:
92
Commands/HistoryCommand.cs
Normal file
92
Commands/HistoryCommand.cs
Normal file
@@ -0,0 +1,92 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using System.CommandLine;
|
||||
using Spectre.Console;
|
||||
using Toak.Core;
|
||||
|
||||
namespace Toak.Commands;
|
||||
|
||||
public static class HistoryCommand
|
||||
{
|
||||
public static async Task ExecuteAsync(int count, string grep, string export, bool shred, bool verbose)
|
||||
{
|
||||
Logger.Verbose = verbose;
|
||||
|
||||
if (shred)
|
||||
{
|
||||
HistoryManager.Shred();
|
||||
AnsiConsole.MarkupLine("[green]History successfully shredded.[/]");
|
||||
return;
|
||||
}
|
||||
|
||||
var entries = HistoryManager.LoadEntries();
|
||||
if (entries.Count == 0)
|
||||
{
|
||||
AnsiConsole.MarkupLine("[yellow]No history found.[/]");
|
||||
return;
|
||||
}
|
||||
|
||||
// Apply grep filter
|
||||
if (!string.IsNullOrWhiteSpace(grep))
|
||||
{
|
||||
entries = entries.Where(e =>
|
||||
e.RawTranscript.Contains(grep, StringComparison.OrdinalIgnoreCase) ||
|
||||
e.RefinedText.Contains(grep, StringComparison.OrdinalIgnoreCase))
|
||||
.ToList();
|
||||
|
||||
if (entries.Count == 0)
|
||||
{
|
||||
AnsiConsole.MarkupLine($"[yellow]No history entries match '{grep}'.[/]");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Get last N
|
||||
entries = entries.OrderBy(e => e.Timestamp).TakeLast(count).ToList();
|
||||
|
||||
// Export
|
||||
if (!string.IsNullOrWhiteSpace(export))
|
||||
{
|
||||
try
|
||||
{
|
||||
using var writer = new StreamWriter(export);
|
||||
writer.WriteLine($"# Toak Transcriptions - {DateTime.Now:yyyy-MM-dd}");
|
||||
writer.WriteLine();
|
||||
|
||||
foreach (var entry in entries)
|
||||
{
|
||||
writer.WriteLine($"## {entry.Timestamp.ToLocalTime():HH:mm:ss}");
|
||||
writer.WriteLine(entry.RefinedText);
|
||||
writer.WriteLine();
|
||||
}
|
||||
|
||||
AnsiConsole.MarkupLine($"[green]Successfully exported {entries.Count} entries to {export}[/]");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
AnsiConsole.MarkupLine($"[red]Error exporting history:[/] {ex.Message}");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Display
|
||||
var table = new Table().Border(TableBorder.Rounded);
|
||||
table.AddColumn("Time");
|
||||
table.AddColumn("Skill");
|
||||
table.AddColumn("Text");
|
||||
|
||||
foreach (var entry in entries)
|
||||
{
|
||||
table.AddRow(
|
||||
$"[dim]{entry.Timestamp.ToLocalTime():HH:mm:ss}[/]",
|
||||
entry.SkillName != null ? $"[blue]{entry.SkillName}[/]" : "-",
|
||||
entry.RefinedText.Replace("[", "[[").Replace("]", "]]") // Escape spectre markup
|
||||
);
|
||||
}
|
||||
|
||||
AnsiConsole.Write(table);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user