119 lines
4.3 KiB
C#
119 lines
4.3 KiB
C#
using AxCopilot.Core;
|
|
using AxCopilot.SDK;
|
|
using AxCopilot.Services;
|
|
using AxCopilot.Themes;
|
|
|
|
namespace AxCopilot.Handlers;
|
|
|
|
/// <summary>
|
|
/// ~ prefix 핸들러: 워크스페이스 프로필 저장/복원/관리
|
|
/// 예: ~dev, ~save dev, ~delete dev, ~rename dev work
|
|
/// </summary>
|
|
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<IEnumerable<LauncherItem>> 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<IEnumerable<LauncherItem>>(items);
|
|
}
|
|
|
|
var cmd = parts[0].ToLowerInvariant();
|
|
|
|
if (cmd == "save")
|
|
{
|
|
var name = parts.Length > 1 ? parts[1] : "default";
|
|
return Task.FromResult<IEnumerable<LauncherItem>>(new[]
|
|
{
|
|
new LauncherItem($"현재 창 배치를 '{name}'으로 저장", "Enter로 확인", null,
|
|
new WorkspaceAction(WorkspaceActionType.Save, name), Symbol: Symbols.Save)
|
|
});
|
|
}
|
|
|
|
if (cmd == "delete" && parts.Length > 1)
|
|
{
|
|
return Task.FromResult<IEnumerable<LauncherItem>>(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<IEnumerable<LauncherItem>>(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<IEnumerable<LauncherItem>>(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 }
|