AX Commander 비교본 런처 기능 대량 이식
변경 목적: Agent Compare 아래 비교본의 개발 문서와 런처 소스를 기준으로 현재 AX Commander에 빠져 있던 신규 런처 기능을 동일한 흐름으로 옮겨, 비교본 수준의 기능 폭을 현재 제품에 반영했습니다. 핵심 수정사항: 비교본의 신규 런처 핸들러 다수를 src/AxCopilot/Handlers로 이식하고 App.xaml.cs 등록 흐름에 연결했습니다. 빠른 링크, 파일 태그, 알림 센터, 포모도로, 파일 브라우저, 핫키 관리, OCR, 세션/스케줄/매크로, Git/정규식/네트워크/압축/해시/UUID/JWT/QR 등 AX Commander 기능을 추가했습니다. 핵심 수정사항: 신규 기능이 실제 동작하도록 AppSettings 확장, SchedulerService/FileTagService/NotificationCenterService/IconCacheService/UrlTemplateEngine/PomodoroService 추가, 배치 이름변경/세션/스케줄/매크로 편집 창 추가, NotificationService와 Symbols 보강, QR/OCR용 csproj 의존성과 Windows 타겟 프레임워크를 반영했습니다. 문서 반영: README.md와 docs/DEVELOPMENT.md에 비교본 기반 런처 기능 이식 이력과 검증 결과를 업데이트했습니다. 검증 결과: dotnet build src/AxCopilot/AxCopilot.csproj -c Release -v minimal -p:OutputPath=bin\\verify\\ -p:IntermediateOutputPath=obj\\verify\\ 실행 기준 경고 0개, 오류 0개를 확인했습니다.
This commit is contained in:
86
src/AxCopilot/Services/NotificationCenterService.cs
Normal file
86
src/AxCopilot/Services/NotificationCenterService.cs
Normal file
@@ -0,0 +1,86 @@
|
||||
using System.Collections.Concurrent;
|
||||
|
||||
namespace AxCopilot.Services;
|
||||
|
||||
/// <summary>알림 타입.</summary>
|
||||
public enum NotificationType { Info, Success, Warning, Error }
|
||||
|
||||
/// <summary>알림 항목.</summary>
|
||||
public record NotificationEntry(
|
||||
string Title,
|
||||
string Message,
|
||||
NotificationType Type,
|
||||
DateTime Timestamp);
|
||||
|
||||
/// <summary>
|
||||
/// Phase L3-7: 알림 센터 — 앱 전체에서 알림을 발행하고 이력을 관리합니다.
|
||||
/// 트레이 BalloonTip + 인앱 알림 큐를 결합합니다.
|
||||
/// </summary>
|
||||
public static class NotificationCenterService
|
||||
{
|
||||
private const int MaxHistory = 50;
|
||||
|
||||
private static readonly ConcurrentQueue<NotificationEntry> _history = new();
|
||||
|
||||
/// <summary>새 알림 발행 이벤트. UI 계층에서 구독하여 인앱 알림 표시에 활용합니다.</summary>
|
||||
public static event EventHandler<NotificationEntry>? NotificationRaised;
|
||||
|
||||
/// <summary>최근 알림 이력 (최대 50건, 최신 순).</summary>
|
||||
public static IReadOnlyList<NotificationEntry> History
|
||||
{
|
||||
get
|
||||
{
|
||||
var list = _history.ToArray();
|
||||
Array.Reverse(list);
|
||||
return list;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>알림을 발행합니다. 트레이 BalloonTip + 이벤트를 동시에 발화합니다.</summary>
|
||||
public static void Show(string title, string message, NotificationType type = NotificationType.Info)
|
||||
{
|
||||
var entry = Record(title, message, type);
|
||||
NotificationService.NotifyBalloonOnly(title, message);
|
||||
TryRaise(entry);
|
||||
}
|
||||
|
||||
/// <summary>성공 알림.</summary>
|
||||
public static void ShowSuccess(string title, string message)
|
||||
=> Show(title, message, NotificationType.Success);
|
||||
|
||||
/// <summary>경고 알림.</summary>
|
||||
public static void ShowWarning(string title, string message)
|
||||
=> Show(title, message, NotificationType.Warning);
|
||||
|
||||
/// <summary>오류 알림.</summary>
|
||||
public static void ShowError(string title, string message)
|
||||
=> Show(title, message, NotificationType.Error);
|
||||
|
||||
/// <summary>에이전트 작업 완료 알림 (BackgroundAgentService 전용 편의 메서드).</summary>
|
||||
public static void NotifyAgentCompleted(string agentType, string? result)
|
||||
{
|
||||
var preview = result?.Length > 80 ? result[..77] + "…" : result ?? "완료";
|
||||
Show($"{agentType} 에이전트 완료", preview, NotificationType.Success);
|
||||
}
|
||||
|
||||
/// <summary>이력을 초기화합니다.</summary>
|
||||
public static void ClearHistory()
|
||||
{
|
||||
while (_history.TryDequeue(out _)) { }
|
||||
}
|
||||
|
||||
internal static NotificationEntry Record(string title, string message, NotificationType type)
|
||||
{
|
||||
var entry = new NotificationEntry(title, message, type, DateTime.Now);
|
||||
_history.Enqueue(entry);
|
||||
while (_history.Count > MaxHistory && _history.TryDequeue(out _)) { }
|
||||
TryRaise(entry);
|
||||
return entry;
|
||||
}
|
||||
|
||||
private static void TryRaise(NotificationEntry entry)
|
||||
{
|
||||
try { NotificationRaised?.Invoke(null, entry); }
|
||||
catch (Exception) { }
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user