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:
2026-04-05 00:59:45 +09:00
parent 0929778ca7
commit 0336904258
115 changed files with 30749 additions and 1 deletions

View File

@@ -22,6 +22,9 @@ public class AppSettings
[JsonPropertyName("operationMode")]
public string OperationMode { get; set; } = "internal";
[JsonIgnore]
public bool InternalModeEnabled => string.Equals(OperationMode, "internal", StringComparison.OrdinalIgnoreCase);
[JsonPropertyName("hotkey")]
public string Hotkey { get; set; } = "Alt+Space";
@@ -88,6 +91,9 @@ public class AppSettings
[JsonPropertyName("snippets")]
public List<SnippetEntry> Snippets { get; set; } = new();
[JsonPropertyName("quickLinks")]
public List<QuickLinkEntry> QuickLinks { get; set; } = new();
[JsonPropertyName("clipboardHistory")]
public ClipboardHistorySettings ClipboardHistory { get; set; } = new();
@@ -100,6 +106,21 @@ public class AppSettings
[JsonPropertyName("reminder")]
public ReminderSettings Reminder { get; set; } = new();
[JsonPropertyName("customHotkeys")]
public List<HotkeyAssignment> CustomHotkeys { get; set; } = new();
[JsonPropertyName("appSessions")]
public List<AppSession> AppSessions { get; set; } = new();
[JsonPropertyName("schedules")]
public List<ScheduleEntry> Schedules { get; set; } = new();
[JsonPropertyName("macros")]
public List<MacroEntry> Macros { get; set; } = new();
[JsonPropertyName("ssh_hosts")]
public List<SshHostEntry> SshHosts { get; set; } = new();
[JsonPropertyName("llm")]
public LlmSettings Llm { get; set; } = new();
}
@@ -245,6 +266,18 @@ public class LauncherSettings
/// <summary>모니터별 독 바 위치. key=디바이스명, value=[left, top]</summary>
[JsonPropertyName("monitorDockPositions")]
public Dictionary<string, List<double>> MonitorDockPositions { get; set; } = new(StringComparer.OrdinalIgnoreCase);
/// <summary>런처 마지막 위치 기억 여부. 기본 false.</summary>
[JsonPropertyName("rememberPosition")]
public bool RememberPosition { get; set; } = false;
/// <summary>런처 마지막 Left 좌표. -1이면 기본 위치.</summary>
[JsonPropertyName("lastLeft")]
public double LastLeft { get; set; } = -1;
/// <summary>런처 마지막 Top 좌표. -1이면 기본 위치.</summary>
[JsonPropertyName("lastTop")]
public double LastTop { get; set; } = -1;
}
/// <summary>
@@ -432,6 +465,168 @@ public class SnippetEntry
public string Content { get; set; } = ""; // 확장될 전체 텍스트
}
public class QuickLinkEntry
{
[JsonPropertyName("keyword")]
public string Keyword { get; set; } = "";
[JsonPropertyName("name")]
public string Name { get; set; } = "";
[JsonPropertyName("urlTemplate")]
public string UrlTemplate { get; set; } = "";
[JsonPropertyName("description")]
public string Description { get; set; } = "";
}
public class HotkeyAssignment
{
[JsonPropertyName("hotkey")]
public string Hotkey { get; set; } = "";
[JsonPropertyName("target")]
public string Target { get; set; } = "";
[JsonPropertyName("label")]
public string Label { get; set; } = "";
[JsonPropertyName("type")]
public string Type { get; set; } = "app";
}
public class AppSession
{
[JsonPropertyName("name")]
public string Name { get; set; } = "";
[JsonPropertyName("description")]
public string Description { get; set; } = "";
[JsonPropertyName("apps")]
public List<SessionApp> Apps { get; set; } = new();
[JsonPropertyName("createdAt")]
public DateTime CreatedAt { get; set; } = DateTime.Now;
}
public class SessionApp
{
[JsonPropertyName("path")]
public string Path { get; set; } = "";
[JsonPropertyName("args")]
public string Arguments { get; set; } = "";
[JsonPropertyName("label")]
public string Label { get; set; } = "";
[JsonPropertyName("snap")]
public string SnapPosition { get; set; } = "full";
[JsonPropertyName("delayMs")]
public int DelayMs { get; set; } = 0;
}
public class ScheduleEntry
{
[JsonPropertyName("id")]
public string Id { get; set; } = Guid.NewGuid().ToString("N")[..8];
[JsonPropertyName("name")]
public string Name { get; set; } = "";
[JsonPropertyName("enabled")]
public bool Enabled { get; set; } = true;
[JsonPropertyName("triggerType")]
public string TriggerType { get; set; } = "daily";
[JsonPropertyName("triggerTime")]
public string TriggerTime { get; set; } = "09:00";
[JsonPropertyName("weekDays")]
public List<int> WeekDays { get; set; } = new();
[JsonPropertyName("triggerDate")]
public string? TriggerDate { get; set; }
[JsonPropertyName("actionType")]
public string ActionType { get; set; } = "app";
[JsonPropertyName("actionTarget")]
public string ActionTarget { get; set; } = "";
[JsonPropertyName("actionArgs")]
public string ActionArgs { get; set; } = "";
[JsonPropertyName("lastRun")]
public DateTime? LastRun { get; set; }
[JsonPropertyName("conditionProcess")]
public string ConditionProcess { get; set; } = "";
[JsonPropertyName("conditionProcessMustRun")]
public bool ConditionProcessMustRun { get; set; } = true;
}
public class MacroEntry
{
[JsonPropertyName("id")]
public string Id { get; set; } = Guid.NewGuid().ToString("N")[..8];
[JsonPropertyName("name")]
public string Name { get; set; } = "";
[JsonPropertyName("description")]
public string Description { get; set; } = "";
[JsonPropertyName("steps")]
public List<MacroStep> Steps { get; set; } = new();
[JsonPropertyName("createdAt")]
public DateTime CreatedAt { get; set; } = DateTime.Now;
}
public class MacroStep
{
[JsonPropertyName("type")]
public string Type { get; set; } = "app";
[JsonPropertyName("target")]
public string Target { get; set; } = "";
[JsonPropertyName("args")]
public string Args { get; set; } = "";
[JsonPropertyName("label")]
public string Label { get; set; } = "";
[JsonPropertyName("delayMs")]
public int DelayMs { get; set; } = 500;
}
public class SshHostEntry
{
[JsonPropertyName("id")]
public string Id { get; set; } = Guid.NewGuid().ToString();
[JsonPropertyName("name")]
public string Name { get; set; } = "";
[JsonPropertyName("host")]
public string Host { get; set; } = "";
[JsonPropertyName("port")]
public int Port { get; set; } = 22;
[JsonPropertyName("user")]
public string User { get; set; } = "";
[JsonPropertyName("note")]
public string Note { get; set; } = "";
}
// ─── 클립보드 히스토리 ────────────────────────────────────────────────────────
public class ClipboardHistorySettings