1
0
Files
AnchorCli/SessionManager.cs
Tomi Eckert 1e943e6566 refactor: apply Single Responsibility Principle to Program.cs and ReplLoop.cs
extracted responsibilities from Program.cs (208→46 lines) and ReplLoop.cs (274→174 lines) into focused service classes: HeaderRenderer, SessionManager, ApplicationStartup, ResponseStreamer, SpinnerService, UsageDisplayer, and ContextCompactionService. Each class now has a single, well-defined responsibility, improving testability and maintainability.
2026-03-11 16:59:06 +01:00

84 lines
2.3 KiB
C#

using Spectre.Console;
namespace AnchorCli;
/// <summary>
/// Manages session persistence, including auto-load on startup and auto-save on exit.
/// </summary>
internal sealed class SessionManager
{
private readonly ChatSession _session;
private readonly string _sessionPath;
public SessionManager(ChatSession session, string sessionPath = ".anchor/session.json")
{
_session = session;
_sessionPath = sessionPath;
}
/// <summary>
/// Attempts to load a session from disk. Returns true if successful.
/// </summary>
public async Task<bool> TryLoadAsync(CancellationToken cancellationToken = default)
{
if (!File.Exists(_sessionPath))
{
return false;
}
try
{
await _session.LoadAsync(_sessionPath, cancellationToken);
AnsiConsole.MarkupLine($"[dim grey]Auto-loaded previous session.[/]");
// Print the last message if there is one
if (_session.History.Count > 1)
{
var lastMessage = _session.History[^1];
var preview = lastMessage.Text.Length > 280
? lastMessage.Text[..277] + "..."
: lastMessage.Text;
AnsiConsole.MarkupLine($"[dim grey] Last message: {Markup.Escape(preview)}[/]");
}
return true;
}
catch
{
// Ignore load errors
return false;
}
}
/// <summary>
/// Attempts to save the session to disk. Returns true if successful.
/// </summary>
public async Task<bool> TrySaveAsync(CancellationToken cancellationToken = default)
{
try
{
var directory = Path.GetDirectoryName(_sessionPath);
if (!string.IsNullOrEmpty(directory) && !Directory.Exists(directory))
{
Directory.CreateDirectory(directory);
}
await _session.SaveAsync(_sessionPath, cancellationToken);
return true;
}
catch
{
// Ignore save errors
return false;
}
}
/// <summary>
/// Saves the session after an LLM turn completes.
/// </summary>
public async Task SaveAfterTurnAsync(CancellationToken cancellationToken = default)
{
await TrySaveAsync(cancellationToken);
}
}