[Phase46] 대형 파일 분할 리팩터링 2차 — 19개 신규 파셜 파일 생성

## 분할 대상 및 결과

### AgentLoopService.cs (1,334줄 → 846줄)
- AgentLoopService.HtmlReport.cs (151줄): AutoSaveAsHtml, ConvertTextToHtml, EscapeHtml
- AgentLoopService.Verification.cs (349줄): 도구 분류 판별 + RunPostToolVerificationAsync + EmitEvent + CheckDecisionRequired + FormatToolCallSummary

### ChatWindow 분할 (8개 신규 파셜 파일)
- ChatWindow.PlanViewer.cs (474줄): 계획 뷰어 — AddPlanningCard, AddDecisionButtons, CollapseDecisionButtons, ShowPlanButton 등 8개 메서드
- ChatWindow.EventBanner.cs (411줄): AddAgentEventBanner, BuildFileQuickActions
- ChatWindow.TaskDecomposition.cs (1,170줄 → 307줄): RenderSuggestActionChips, BuildFeedbackContext, UpdateProgressBar, BuildDiffView 잔류
- ChatWindow.BottomBar.cs (345줄): BuildBottomBar, BuildCodeBottomBar, ShowLogLevelMenu, ShowLanguageMenu 등
- ChatWindow.MoodMenu.cs (456줄): ShowFormatMenu, ShowMoodMenu, ShowCustomMoodDialog 등
- ChatWindow.CustomPresets.cs (978줄 → 203줄): ShowCustomPresetDialog, SelectTopic 잔류
- ChatWindow.ConversationMenu.cs (255줄): ShowConversationMenu (카테고리/삭제/즐겨찾기 팝업)
- ChatWindow.ConversationTitleEdit.cs (108줄): EnterTitleEditMode

### SettingsViewModel 분할
- SettingsViewModel.LlmProperties.cs (417줄): LLM·에이전트 관련 바인딩 프로퍼티
- SettingsViewModel.Properties.cs (837줄 → 427줄): 기능 토글·테마·스니펫 등 앱 수준 프로퍼티

### TemplateService 분할
- TemplateService.Css.cs (559줄): 11종 CSS 테마 문자열 상수
- TemplateService.cs (734줄 → 179줄): 메서드 로직만 잔류

### PlanViewerWindow 분할
- PlanViewerWindow.StepRenderer.cs (616줄): RenderSteps + SwapSteps + EditStep + 버튼 빌더 9개
- PlanViewerWindow.cs (931줄 → 324줄): Win32/생성자/공개 API 잔류

### App.xaml.cs 분할 (776줄 → 452줄)
- App.Settings.cs (252줄): SetupTrayIcon, OpenSettings, ToggleDockBar, RefreshDockBar, OpenAiChat
- App.Helpers.cs (92줄): LoadAppIcon, IsAutoStartEnabled, SetAutoStart, OnExit

### LlmService.ToolUse.cs 분할 (719줄 → 115줄)
- LlmService.ClaudeTools.cs (180줄): SendClaudeWithToolsAsync, BuildClaudeToolBody
- LlmService.GeminiTools.cs (175줄): SendGeminiWithToolsAsync, BuildGeminiToolBody
- LlmService.OpenAiTools.cs (215줄): SendOpenAiWithToolsAsync, BuildOpenAiToolBody

### SettingsWindow.UI.cs 분할 (802줄 → 310줄)
- SettingsWindow.Storage.cs (167줄): RefreshStorageInfo, BtnStorageCleanup_Click 등
- SettingsWindow.HotkeyUI.cs (127줄): RefreshHotkeyBadges, EnsureHotkeyInCombo, GetKeyName 등
- SettingsWindow.DevMode.cs (90줄): DevModeCheckBox_Checked, UpdateDevModeContentVisibility

## 빌드 결과: 경고 0, 오류 0

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-03 20:51:26 +09:00
parent f5a1ba999c
commit aa907d7b79
29 changed files with 5540 additions and 5365 deletions

View File

@@ -0,0 +1,417 @@
using System.Collections.ObjectModel;
using AxCopilot.Models;
namespace AxCopilot.ViewModels;
public partial class SettingsViewModel
{
/// <summary>CodeSettings 바인딩용 프로퍼티. XAML에서 {Binding Code.EnableLsp} 등으로 접근.</summary>
public Models.CodeSettings Code => _service.Settings.Llm.Code;
// ─── 등록 모델 목록 ───────────────────────────────────────────────────
public ObservableCollection<RegisteredModelRow> RegisteredModels { get; } = new();
public string LlmService
{
get => _llmService;
set { _llmService = value; OnPropertyChanged(); OnPropertyChanged(nameof(IsInternalService)); OnPropertyChanged(nameof(IsExternalService)); OnPropertyChanged(nameof(NeedsEndpoint)); OnPropertyChanged(nameof(NeedsApiKey)); OnPropertyChanged(nameof(IsGeminiSelected)); OnPropertyChanged(nameof(IsClaudeSelected)); }
}
public bool IsInternalService => _llmService is "ollama" or "vllm";
public bool IsExternalService => _llmService is "gemini" or "claude";
public bool NeedsEndpoint => _llmService is "ollama" or "vllm";
public bool NeedsApiKey => _llmService is not "ollama";
public bool IsGeminiSelected => _llmService == "gemini";
public bool IsClaudeSelected => _llmService == "claude";
// ── Ollama 설정 ──
public string OllamaEndpoint { get => _ollamaEndpoint; set { _ollamaEndpoint = value; OnPropertyChanged(); } }
public string OllamaApiKey { get => _ollamaApiKey; set { _ollamaApiKey = value; OnPropertyChanged(); } }
public string OllamaModel { get => _ollamaModel; set { _ollamaModel = value; OnPropertyChanged(); } }
// ── vLLM 설정 ──
public string VllmEndpoint { get => _vllmEndpoint; set { _vllmEndpoint = value; OnPropertyChanged(); } }
public string VllmApiKey { get => _vllmApiKey; set { _vllmApiKey = value; OnPropertyChanged(); } }
public string VllmModel { get => _vllmModel; set { _vllmModel = value; OnPropertyChanged(); } }
// ── Gemini 설정 ──
public string GeminiApiKey { get => _geminiApiKey; set { _geminiApiKey = value; OnPropertyChanged(); } }
public string GeminiModel { get => _geminiModel; set { _geminiModel = value; OnPropertyChanged(); } }
// ── Claude 설정 ──
public string ClaudeApiKey { get => _claudeApiKey; set { _claudeApiKey = value; OnPropertyChanged(); } }
public string ClaudeModel { get => _claudeModel; set { _claudeModel = value; OnPropertyChanged(); } }
// ── 공통 응답 설정 ──
public bool LlmStreaming
{
get => _llmStreaming;
set { _llmStreaming = value; OnPropertyChanged(); }
}
public int LlmMaxContextTokens
{
get => _llmMaxContextTokens;
set { _llmMaxContextTokens = value; OnPropertyChanged(); }
}
public int LlmRetentionDays
{
get => _llmRetentionDays;
set { _llmRetentionDays = value; OnPropertyChanged(); }
}
public double LlmTemperature
{
get => _llmTemperature;
set { _llmTemperature = Math.Round(Math.Clamp(value, 0.0, 2.0), 1); OnPropertyChanged(); }
}
// 에이전트 기본 파일 접근 권한
private string _defaultAgentPermission;
public string DefaultAgentPermission
{
get => _defaultAgentPermission;
set { _defaultAgentPermission = value; OnPropertyChanged(); }
}
// ── 코워크/에이전트 고급 설정 ──
private string _defaultOutputFormat;
public string DefaultOutputFormat
{
get => _defaultOutputFormat;
set { _defaultOutputFormat = value; OnPropertyChanged(); }
}
private string _autoPreview;
public string AutoPreview
{
get => _autoPreview;
set { _autoPreview = value; OnPropertyChanged(); }
}
private int _maxAgentIterations;
public int MaxAgentIterations
{
get => _maxAgentIterations;
set { _maxAgentIterations = Math.Clamp(value, 1, 100); OnPropertyChanged(); }
}
private int _maxRetryOnError;
public int MaxRetryOnError
{
get => _maxRetryOnError;
set { _maxRetryOnError = Math.Clamp(value, 0, 10); OnPropertyChanged(); }
}
private string _agentLogLevel;
public string AgentLogLevel
{
get => _agentLogLevel;
set { _agentLogLevel = value; OnPropertyChanged(); }
}
private string _agentDecisionLevel = "detailed";
public string AgentDecisionLevel
{
get => _agentDecisionLevel;
set { _agentDecisionLevel = value; OnPropertyChanged(); }
}
private string _planMode = "off";
public string PlanMode
{
get => _planMode;
set { _planMode = value; OnPropertyChanged(); }
}
private bool _enableMultiPassDocument;
public bool EnableMultiPassDocument
{
get => _enableMultiPassDocument;
set { _enableMultiPassDocument = value; OnPropertyChanged(); }
}
private bool _enableCoworkVerification;
public bool EnableCoworkVerification
{
get => _enableCoworkVerification;
set { _enableCoworkVerification = value; OnPropertyChanged(); }
}
private bool _enableFilePathHighlight = true;
public bool EnableFilePathHighlight
{
get => _enableFilePathHighlight;
set { _enableFilePathHighlight = value; OnPropertyChanged(); }
}
private string _folderDataUsage;
public string FolderDataUsage
{
get => _folderDataUsage;
set { _folderDataUsage = value; OnPropertyChanged(); }
}
// ── 모델 폴백 + 보안 + MCP ──
private bool _enableAuditLog;
public bool EnableAuditLog
{
get => _enableAuditLog;
set { _enableAuditLog = value; OnPropertyChanged(); }
}
private bool _enableAgentMemory;
public bool EnableAgentMemory
{
get => _enableAgentMemory;
set { _enableAgentMemory = value; OnPropertyChanged(); }
}
private bool _enableProjectRules = true;
public bool EnableProjectRules
{
get => _enableProjectRules;
set { _enableProjectRules = value; OnPropertyChanged(); }
}
private int _maxMemoryEntries;
public int MaxMemoryEntries
{
get => _maxMemoryEntries;
set { _maxMemoryEntries = value; OnPropertyChanged(); }
}
// ── 이미지 입력 (멀티모달) ──
private bool _enableImageInput = true;
public bool EnableImageInput
{
get => _enableImageInput;
set { _enableImageInput = value; OnPropertyChanged(); }
}
private int _maxImageSizeKb = 5120;
public int MaxImageSizeKb
{
get => _maxImageSizeKb;
set { _maxImageSizeKb = value; OnPropertyChanged(); }
}
// ── 자동 모델 라우팅 ──
private bool _enableAutoRouter;
public bool EnableAutoRouter
{
get => _enableAutoRouter;
set { _enableAutoRouter = value; OnPropertyChanged(); }
}
private double _autoRouterConfidence = 0.7;
public double AutoRouterConfidence
{
get => _autoRouterConfidence;
set { _autoRouterConfidence = value; OnPropertyChanged(); }
}
// ── 에이전트 훅 시스템 ──
private bool _enableToolHooks = true;
public bool EnableToolHooks
{
get => _enableToolHooks;
set { _enableToolHooks = value; OnPropertyChanged(); }
}
private int _toolHookTimeoutMs = 10000;
public int ToolHookTimeoutMs
{
get => _toolHookTimeoutMs;
set { _toolHookTimeoutMs = value; OnPropertyChanged(); }
}
// ── 스킬 시스템 ──
private bool _enableSkillSystem = true;
public bool EnableSkillSystem
{
get => _enableSkillSystem;
set { _enableSkillSystem = value; OnPropertyChanged(); }
}
private string _skillsFolderPath = "";
public string SkillsFolderPath
{
get => _skillsFolderPath;
set { _skillsFolderPath = value; OnPropertyChanged(); }
}
private int _slashPopupPageSize = 6;
public int SlashPopupPageSize
{
get => _slashPopupPageSize;
set { _slashPopupPageSize = Math.Clamp(value, 3, 10); OnPropertyChanged(); }
}
// ── 드래그&드롭 AI ──
private bool _enableDragDropAiActions = true;
public bool EnableDragDropAiActions
{
get => _enableDragDropAiActions;
set { _enableDragDropAiActions = value; OnPropertyChanged(); }
}
private bool _dragDropAutoSend;
public bool DragDropAutoSend
{
get => _dragDropAutoSend;
set { _dragDropAutoSend = value; OnPropertyChanged(); }
}
// ── 코드 리뷰 ──
private bool _enableCodeReview = true;
public bool EnableCodeReview
{
get => _enableCodeReview;
set { _enableCodeReview = value; OnPropertyChanged(); }
}
// ── 시각 효과 + 알림 + 개발자 모드 (공통) ──
private bool _enableChatRainbowGlow;
public bool EnableChatRainbowGlow
{
get => _enableChatRainbowGlow;
set { _enableChatRainbowGlow = value; OnPropertyChanged(); }
}
private bool _notifyOnComplete;
public bool NotifyOnComplete
{
get => _notifyOnComplete;
set { _notifyOnComplete = value; OnPropertyChanged(); }
}
private bool _showTips;
public bool ShowTips
{
get => _showTips;
set { _showTips = value; OnPropertyChanged(); }
}
private bool _devMode;
public bool DevMode
{
get => _devMode;
set { _devMode = value; OnPropertyChanged(); }
}
private bool _devModeStepApproval;
public bool DevModeStepApproval
{
get => _devModeStepApproval;
set { _devModeStepApproval = value; OnPropertyChanged(); }
}
private bool _workflowVisualizer;
public bool WorkflowVisualizer
{
get => _workflowVisualizer;
set { _workflowVisualizer = value; OnPropertyChanged(); }
}
private bool _freeTierMode;
public bool FreeTierMode
{
get => _freeTierMode;
set { _freeTierMode = value; OnPropertyChanged(); }
}
private int _freeTierDelaySeconds = 4;
public int FreeTierDelaySeconds
{
get => _freeTierDelaySeconds;
set { _freeTierDelaySeconds = value; OnPropertyChanged(); }
}
private bool _showTotalCallStats;
public bool ShowTotalCallStats
{
get => _showTotalCallStats;
set { _showTotalCallStats = value; OnPropertyChanged(); }
}
private string _defaultMood = "modern";
public string DefaultMood
{
get => _defaultMood;
set { _defaultMood = value; OnPropertyChanged(); }
}
// 차단 경로/확장자 (읽기 전용 UI)
public ObservableCollection<string> BlockedPaths { get; } = new();
public ObservableCollection<string> BlockedExtensions { get; } = new();
public string Hotkey
{
get => _hotkey;
set { _hotkey = value; OnPropertyChanged(); }
}
public int MaxResults
{
get => _maxResults;
set { _maxResults = value; OnPropertyChanged(); }
}
public double Opacity
{
get => _opacity;
set { _opacity = value; OnPropertyChanged(); OnPropertyChanged(nameof(OpacityPercent)); }
}
public int OpacityPercent => (int)Math.Round(_opacity * 100);
public string SelectedThemeKey
{
get => _selectedThemeKey;
set
{
_selectedThemeKey = value;
OnPropertyChanged();
OnPropertyChanged(nameof(IsCustomTheme));
foreach (var card in ThemeCards)
card.IsSelected = card.Key == value;
}
}
public bool IsCustomTheme => _selectedThemeKey == "custom";
public string LauncherPosition
{
get => _launcherPosition;
set { _launcherPosition = value; OnPropertyChanged(); }
}
public string WebSearchEngine
{
get => _webSearchEngine;
set { _webSearchEngine = value; OnPropertyChanged(); }
}
public bool SnippetAutoExpand
{
get => _snippetAutoExpand;
set { _snippetAutoExpand = value; OnPropertyChanged(); }
}
public string Language
{
get => _language;
set { _language = value; OnPropertyChanged(); }
}
public string IndexSpeed
{
get => _indexSpeed;
set { _indexSpeed = value; OnPropertyChanged(); OnPropertyChanged(nameof(IndexSpeedHint)); }
}
public string IndexSpeedHint => _indexSpeed switch
{
"fast" => "CPU 사용률이 높아질 수 있습니다. 고성능 PC에 권장합니다.",
"slow" => "인덱싱이 오래 걸리지만 PC 성능에 영향을 주지 않습니다.",
_ => "일반적인 PC에 적합한 균형 설정입니다.",
};
}