37fc06e274
- 子命令 save/notify/input/cleanup:纯互操作 IPC,不加载 Avalonia
- 命名管道:瘦客户端投递请求,Host 未运行时自动拉起并重试
- 每会话状态文件 %TEMP%\claude-notify-{id}.json,保存前台窗口与 prompt
- Host 单例互斥量 + 管道监听,收到请求切回 UI 线程弹窗
- stdin 改为 UTF-8 原始字节读取,修复中文乱码与读不到的问题
- 符合 Claude Code 插件规范的 .claude-plugin 与 hooks 结构
68 lines
1.6 KiB
C#
68 lines
1.6 KiB
C#
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());
|
|
}
|