using AxCopilot.Core; using AxCopilot.SDK; using AxCopilot.Services; using AxCopilot.Themes; namespace AxCopilot.Handlers; /// /// ~ prefix 핸들러: 워크스페이스 프로필 저장/복원/관리 /// 예: ~dev, ~save dev, ~delete dev, ~rename dev work /// public class WorkspaceHandler : IActionHandler { private readonly ContextManager _context; private readonly SettingsService _settings; public string? Prefix => "~"; public PluginMetadata Metadata => new("workspace", "워크스페이스", "1.0", "AX"); public WorkspaceHandler(ContextManager context, SettingsService settings) { _context = context; _settings = settings; } public Task> GetItemsAsync(string query, CancellationToken ct) { var parts = query.Trim().Split(' ', StringSplitOptions.RemoveEmptyEntries); // 서브 커맨드 분기 if (parts.Length == 0 || string.IsNullOrEmpty(query)) { // 프로필 목록 표시 var items = _settings.Settings.Profiles .Select(p => new LauncherItem( $"~{p.Name}", $"{p.Windows.Count}개 창 | {p.CreatedAt:MM/dd HH:mm}", null, p, Symbol: Symbols.Workspace)) .ToList(); if (items.Count == 0) items.Add(new LauncherItem("저장된 프로필 없음", "~save <이름> 으로 현재 배치를 저장하세요", null, null, Symbol: Symbols.Info)); return Task.FromResult>(items); } var cmd = parts[0].ToLowerInvariant(); if (cmd == "save") { var name = parts.Length > 1 ? parts[1] : "default"; return Task.FromResult>(new[] { new LauncherItem($"현재 창 배치를 '{name}'으로 저장", "Enter로 확인", null, new WorkspaceAction(WorkspaceActionType.Save, name), Symbol: Symbols.Save) }); } if (cmd == "delete" && parts.Length > 1) { return Task.FromResult>(new[] { new LauncherItem($"프로필 '{parts[1]}' 삭제", "Enter로 확인 (되돌릴 수 없습니다)", null, new WorkspaceAction(WorkspaceActionType.Delete, parts[1]), Symbol: Symbols.Delete) }); } if (cmd == "rename" && parts.Length > 2) { return Task.FromResult>(new[] { new LauncherItem($"프로필 '{parts[1]}' → '{parts[2]}'로 이름 변경", "Enter로 확인", null, new WorkspaceAction(WorkspaceActionType.Rename, parts[1], parts[2]), Symbol: Symbols.Rename) }); } // 이름으로 프로필 검색 var matched = _settings.Settings.Profiles .Where(p => p.Name.Contains(query, StringComparison.OrdinalIgnoreCase)) .Select(p => new LauncherItem( $"~{p.Name} 복원", $"{p.Windows.Count}개 창 | {p.CreatedAt:MM/dd HH:mm}", null, new WorkspaceAction(WorkspaceActionType.Restore, p.Name), Symbol: Symbols.Restore)); return Task.FromResult>(matched); } public async Task ExecuteAsync(LauncherItem item, CancellationToken ct) { if (item.Data is not WorkspaceAction action) return; switch (action.Type) { case WorkspaceActionType.Restore: var result = await _context.RestoreProfileAsync(action.Name, ct); LogService.Info($"복원 결과: {result.Message}"); break; case WorkspaceActionType.Save: _context.CaptureProfile(action.Name); break; case WorkspaceActionType.Delete: _context.DeleteProfile(action.Name); break; case WorkspaceActionType.Rename when action.NewName != null: _context.RenameProfile(action.Name, action.NewName); break; } } } public record WorkspaceAction(WorkspaceActionType Type, string Name, string? NewName = null); public enum WorkspaceActionType { Restore, Save, Delete, Rename }