feat: Claude Code 原生 Windows 通知(C# / .NET 10 + Avalonia 12)
为 Claude Code 提供原生 Windows toast 通知:点击跳回原窗口、切回 Windows Terminal 标签、跨虚拟桌面、调用方图标、非阻塞投递;NativeAOT 单文件分发。
This commit is contained in:
@@ -0,0 +1,67 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text.Json;
|
||||
using Notify.Models;
|
||||
using Notify.Serialization;
|
||||
|
||||
namespace Notify.Services;
|
||||
|
||||
/// <summary>
|
||||
/// 每会话状态文件的读写,位于 %TEMP%\claude-notify-{session_id}.json
|
||||
/// </summary>
|
||||
public static class StateStore
|
||||
{
|
||||
private static string FilePath(string sessionId) =>
|
||||
Path.Combine(Path.GetTempPath(), $"claude-notify-{Sanitize(sessionId)}.json");
|
||||
|
||||
public static void Save(string sessionId, StateData data)
|
||||
{
|
||||
try
|
||||
{
|
||||
File.WriteAllText(FilePath(sessionId), JsonSerializer.Serialize(data, AppJsonContext.Default.StateData));
|
||||
}
|
||||
catch
|
||||
{
|
||||
// 落盘失败不致命
|
||||
}
|
||||
}
|
||||
|
||||
public static StateData? Load(string sessionId)
|
||||
{
|
||||
try
|
||||
{
|
||||
var path = FilePath(sessionId);
|
||||
if (File.Exists(path))
|
||||
{
|
||||
return JsonSerializer.Deserialize(File.ReadAllText(path), AppJsonContext.Default.StateData);
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
// 损坏或不可读则当作无状态
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void Delete(string sessionId)
|
||||
{
|
||||
try
|
||||
{
|
||||
var path = FilePath(sessionId);
|
||||
if (File.Exists(path))
|
||||
{
|
||||
File.Delete(path);
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
// 忽略
|
||||
}
|
||||
}
|
||||
|
||||
// 只保留文件名安全字符,避免 session_id 含特殊字符破坏路径
|
||||
private static string Sanitize(string s) =>
|
||||
new(s.Where(c => char.IsLetterOrDigit(c) || c is '-' or '_').ToArray());
|
||||
}
|
||||
Reference in New Issue
Block a user