# AX Commander — 개발 문서 --- ## 📑 목차 1. [관련 문서](#관련-문서) 2. [사내 전용 프로그램 개발 원칙](#사내-전용-프로그램-개발-원칙) 3. [프로젝트 구조](#프로젝트-구조) 4. [아키텍처 개요](#아키텍처-개요) 5. [핵심 데이터 흐름](#핵심-데이터-흐름) 6. [각 핸들러 상세](#각-핸들러-상세) 7. [설정 UI (SettingsWindow)](#설정-ui-settingswindow) 8. [설정 스키마 (`settings.json`)](#설정-스키마-settingsjson) 9. [주요 기능 상세](#주요-기능-상세) 10. [데이터 저장 경로](#데이터-저장-경로) 11. [보안 고려사항](#보안-고려사항) 12. [테마 커스터마이징](#테마-커스터마이징) 13. [단위 테스트](#단위-테스트) 14. [코드 검토 이력](#코드-검토-이력) 15. [버그 수정 이력](#버그-수정-이력) 16. [알려진 제한사항 및 향후 개선](#알려진-제한사항-및-향후-개선) 17. [개발 환경](#개발-환경) 18. [경쟁 제품 기능 비교](#경쟁-제품-기능-비교) 19. [새로운 핸들러/키워드 추가 방법](#새로운-핸들러키워드-추가-방법-개발자-가이드) 20. [사내 LLM / AI Agent 연동 가이드](#사내-llm--ai-agent-연동-가이드-향후-확장) 21. [버전 이력](#버전-이력) 22. [개발 검토 — 워크플로우 병목 분석 그래프](#개발-검토--워크플로우-병목-분석-그래프) 23. [양식 기반 문서 생성 (Template Mode)](#양식-기반-문서-생성-template-mode) --- ## 관련 문서 | 문서 | 설명 | |------|------| | [AX Agent 로드맵](AGENT_ROADMAP.html) | AX Agent 대화 서비스 고도화 종합 계획 (Phase 2.5~11) | | [AX Commander 로드맵](LAUNCHER_ROADMAP.html) | AX Commander 런처 고도화 계획 | | [사용 가이드](../src/AxCopilot/Assets/AX%20Copilot%20사용가이드.htm) | 사용자용 단축키 & 예약어 가이드 | --- ## 사내 전용 프로그램 개발 원칙 > **AX Commander는 사내 전용 프로그램입니다.** > 아래 원칙을 반드시 준수하여 개발하세요. ### 외부 연결 금지 | 금지 항목 | 설명 | |-----------|------| | 외부 HTTP/HTTPS 호출 | `HttpClient`, `WebClient`, `HttpWebRequest` 등으로 외부 서버에 요청 금지 | | 외부 SDK 연동 | 서드파티 클라우드 SDK, AI API, SaaS 라이브러리 사용 금지 | | 원격 플러그인 다운로드 | 런타임에 외부에서 DLL/코드 다운로드 금지 | | 텔레메트리 / 오류 수집 | 사용 데이터를 외부 서버로 전송하는 일체의 코드 금지 | | NuGet 패키지 | 외부 네트워크 통신이 내장된 패키지 신규 도입 금지 | **허용**: 로컬 파일 시스템 접근, Windows API (P/Invoke), 사내 인트라넷 URL (명시적으로 허가된 경우만), 로컬 프로세스 실행. ### 외부 SDK 금지 기존에 등록된 `JsonSkillLoader`의 HTTP 스킬 기능(`type: "http"`)은 **사내 인트라넷 엔드포인트 전용**으로만 사용해야 합니다. 인터넷 접근이 필요한 기능은 구현하지 않습니다. ### 의존성 관리 신규 NuGet 패키지를 추가하기 전에 다음을 확인하세요: 1. 패키지가 외부 서버와 통신하는지 검토 2. 동일한 기능을 BCL(Base Class Library)이나 Windows API로 구현 가능한지 먼저 검토 3. 추가 시 `DEVELOPMENT.md`에 이유를 기록 ### UI 색상·레이아웃 규칙 > **모든 UI 개발 시 아래 규칙을 반드시 준수하세요.** (상세: `docs/AI_Service_Review.html` §12.8) 1. **시스템 기본 컨트롤 사용 금지** — `ContextMenu`, `MessageBox`, `ComboBox` 드롭다운을 채팅 창에 사용하지 않음. 반드시 커스텀 `Popup` 기반으로 구현 2. **색상 하드코딩 금지** — `Brushes.White`, `#A0A4BE` 등 하드코딩하면 라이트/다크 테마 전환 시 대비가 깨짐 - XAML: `{DynamicResource PrimaryText}`, `{DynamicResource SecondaryText}` 등 리소스 키 사용 - 코드비하인드: `TryFindResource("PrimaryText") as Brush ?? Brushes.White` 패턴 사용 3. **수평 스크롤바 금지** — 아이콘/칩 목록은 `ScrollViewer` 가로 스크롤 대신 `WrapPanel`로 창 폭에 맞게 자동 줄바꿈 4. **Popup 내부에 `Button` 사용 금지** — 포커스 캡처로 팝업이 즉시 닫힘. `Border` + `MouseLeftButtonUp` 패턴 사용 5. **폰트 크기** — 메뉴 항목 13px 이상, 설명 텍스트 12px 이상 (가독성 확보) 6. **호버/클릭 효과 필수** — `#18FFFFFF` 반투명 배경 + 핸드 커서, 팝업 `PopupAnimation="Fade"` 기본 적용 7. **사용자 의사결정 UI = 하단 드롭다운 메뉴 패턴** — AI가 사용자에게 선택을 요청할 때(포맷, 디자인, 권한 등) 아이콘을 주욱 나열하지 않고 **컴팩트 드롭다운 버튼** `[라벨: 현재값 ▾]` → 클릭 시 `Popup` 메뉴 표시. 마지막 항목에 텍스트 입력 옵션 포함 가능. - 설정(Settings)에서 해당 값의 기본값을 선택할 수 있어야 함 - 같은 패턴을 모든 탭(Chat, Cowork, Code)에 일관 적용 8. **프리뷰 패널 = 탭 기반** — 다중 파일 프리뷰를 탭으로 관리, 파일명 표시, 탭 축소, 외부 프로그램 실행 아이콘 포함 9. **켜기/끄기 UI = ToggleSwitch 스타일 사용** — 설정 창 등 모든 on/off 옵션에는 기본 `CheckBox`가 아닌 `Style="{StaticResource ToggleSwitch}"` 좌우 슬라이드 토글을 사용. 카테고리 선택 목록도 동일하게 적용 (Grid 좌: 라벨, 우: 토글) 10. **ContextMenu 사용 금지 → 커스텀 Popup 메뉴** — WPF 기본 `ContextMenu`/`MenuItem` 사용 금지. 모든 우클릭 메뉴·드롭다운을 커스텀 `Popup` (Border + MouseLeftButtonUp 패턴, 12px 라운드, 호버, 드롭섀도)으로 구현 9. **폴더 데이터 활용 시 관련성 검증 필수** — 적극 활용 모드에서도 대화 주제와 무관한 파일은 읽지 않음. 계획 단계에서 읽을 파일 목록과 이유를 먼저 제시 10. **인터랙티브 영역 최소 크기 36px** — 버튼·아이콘·메뉴 등 클릭 가능한 요소는 보내기 버튼(36×36)과 동일한 터치 크기 확보. FontSize 최소 12px, Padding 최소 6px. 폴더바·모델 선택 등 텍스트 영역도 MinHeight=34 이상 --- ## 프로젝트 구조 ``` AX Commander/ ├── src/ │ ├── AxCommander/ # 메인 WPF 애플리케이션 │ │ ├── App.xaml / App.xaml.cs # 앱 진입점, 서비스 초기화, 트레이 아이콘 │ │ ├── Assets/ │ │ │ ├── icon.ico # 다이아몬드 픽셀 보석 아이콘 (7크기: 16~256px) │ │ │ ├── diamond_pixel.svg # 아이콘 SVG 원본 (참고용) │ │ │ ├── mascot.png # About 창 마스코트 이미지 (선택) │ │ │ └── Quotes/ │ │ │ └── famous.json # 내장 명언 500개 (EmbeddedResource) │ │ ├── Core/ │ │ │ ├── CommandResolver.cs # 프리픽스 기반 라우팅 테이블 │ │ │ ├── ContextManager.cs # 윈도우 스냅샷 & 복원 (워크스페이스) │ │ │ ├── FuzzyEngine.cs # 퍼지 검색 + 한국어 초성 지원 │ │ │ ├── InputListener.cs # 전역 키보드 훅 (WH_KEYBOARD_LL) │ │ │ └── PluginHost.cs # DLL/JSON 플러그인 로더 │ │ ├── Handlers/ │ │ │ ├── AliasHandler.cs # @(URL) ~(폴더) >(배치) 핸들러 │ │ │ ├── CalculatorHandler.cs # = 계산기 + 단위변환 + 통화변환 │ │ │ ├── ClipboardHandler.cs # $ 클립보드 변환 (12종 내장) │ │ │ ├── ClipboardHistoryHandler.cs # # 클립보드 히스토리 │ │ │ ├── ColorHandler.cs # color HEX/RGB/HSL/HSV 변환기 │ │ │ ├── ColorPickHandler.cs # pick 스포이드 색상 추출 │ │ │ ├── DateCalcHandler.cs # date 날짜 계산/D-day/타임스탬프 │ │ │ ├── EncodeHandler.cs # encode base64/url/hex/md5/sha256 │ │ │ ├── EnvHandler.cs # env 환경변수 조회 │ │ │ ├── EmojiHandler.cs # emoji 이모지 피커 (300+ 이모지) │ │ │ ├── JsonHandler.cs # json JSON 검증/포맷/미니파이 │ │ │ ├── JsonSkillLoader.cs # .skill.json HTTP API 연동 │ │ │ ├── NoteHandler.cs # note 빠른 메모 저장/조회 │ │ │ ├── PortHandler.cs # port 포트/프로세스 점검 │ │ │ ├── RecentFilesHandler.cs # recent Windows 최근 파일 │ │ │ ├── RenameHandler.cs # rename 파일 일괄 이름변경 │ │ │ ├── ScreenCaptureHandler.cs # cap 화면/창/스크롤 캡처 │ │ │ ├── ScaffoldHandler.cs # scaffold 프로젝트 스캐폴딩 │ │ │ ├── ServiceHandler.cs # svc Windows 서비스 관리 │ │ │ ├── SnapHandler.cs # snap 창 배치 레이아웃 │ │ │ ├── SnippetHandler.cs # ; 텍스트 스니펫 │ │ │ ├── SystemCommandHandler.cs # / 시스템 명령 + 타이머/알람 │ │ │ ├── TextStatsHandler.cs # stats 텍스트 통계 분석 │ │ │ ├── UninstallHandler.cs # uninstall 앱 제거 (레지스트리) │ │ │ ├── FavoriteHandler.cs # fav 즐겨찾기 (파일·폴더) │ │ │ ├── MonitorHandler.cs # monitor 시스템 리소스 모니터 │ │ │ └── WorkspaceHandler.cs # ! 워크스페이스 관리 │ │ ├── Models/ │ │ │ ├── AppSettings.cs # 설정 POCO (JSON 직렬화) │ │ │ └── DailyUsageStats.cs # 일별 사용 통계 데이터 모델 │ │ ├── Services/ │ │ │ ├── ClipboardHistoryService.cs # WM_CLIPBOARDUPDATE 훅 │ │ │ ├── IndexService.cs # 파일 시스템 인덱서 │ │ │ ├── LogService.cs # 파일 로거 │ │ │ ├── NotificationService.cs # 트레이 풍선 알림 (타이머/알람) │ │ │ ├── QuoteService.cs # 명언 JSON 로더 (famous.json 내장 리소스) │ │ │ ├── SessionTrackingService.cs # PC 잠금/해제 시간 추적 │ │ │ ├── L10n.cs # 정적 다국어 서비스 (ko/en/ja/zh/vi) │ │ │ ├── SettingsService.cs # settings.json 로드/저장 │ │ │ ├── UsageRankingService.cs # 실행 빈도 추적 & 퍼지 결과 정렬 │ │ │ ├── UsageStatisticsService.cs # 일별 통계 집계 (런처 호출/명령/활성시간) │ │ │ ├── WindowTracker.cs # 이전 활성 창 핸들 보존 (snap/cap용) │ │ │ └── WorktimeReminderService.cs # 잠금 해제 시 사용시간 알림 팝업 서비스 │ │ ├── Themes/ │ │ │ ├── Converters.cs # WPF 값 변환기 │ │ │ ├── Symbols.cs # Segoe MDL2 Assets 상수 │ │ │ ├── Dark.xaml / Light.xaml / OLED.xaml │ │ │ ├── Nord.xaml / Monokai.xaml / Catppuccin.xaml / Sepia.xaml │ │ │ ├── Alfred.xaml / AlfredLight.xaml │ │ ├── ViewModels/ │ │ │ ├── LauncherViewModel.cs # 런처 MVVM ViewModel │ │ │ ├── SettingsViewModel.cs # 설정 창 ViewModel + 보조 모델 │ │ │ │ # (ThemeCardModel, ColorRowModel, │ │ │ │ # AppShortcutModel, SnippetRowModel) │ │ │ └── StatisticsViewModel.cs # 사용 통계 창 ViewModel (DayBarItem, CommandStatItem) │ │ └── Views/ │ │ ├── LauncherWindow.xaml/.cs # 메인 런처 UI │ │ ├── LargeTypeWindow.xaml/.cs # Large Type 전체 화면 오버레이 │ │ ├── SettingsWindow.xaml/.cs # 설정 창 UI (좌측 사이드바 10탭) │ │ ├── AboutWindow.xaml/.cs # 개발자 정보 창 │ │ ├── HelpDetailWindow.xaml/.cs # 도움말 전체 목록 카드 창 │ │ ├── EyeDropperWindow.xaml/.cs # 전체 화면 스포이드 오버레이 │ │ ├── ColorPickResultWindow.xaml/.cs # 색상 추출 결과 반투명 팝업 │ │ ├── ReminderPopupWindow.xaml/.cs # 잠금 해제 사용시간 알림 팝업 │ │ ├── StatisticsWindow.xaml/.cs # 사용 통계 차트 창 │ │ └── TrayContextMenu.cs # 트레이 컨텍스트 메뉴 팩토리 (모던 테마 인식) │ ├── AxCommander.SDK/ │ │ └── IActionHandler.cs # 플러그인 계약 (LauncherItem, PluginMetadata) │ ├── AxCommander.Tests/ │ │ ├── Core/FuzzyEngineTests.cs # 퍼지 엔진 단위 테스트 (19개) │ │ ├── Handlers/ClipboardTransformTests.cs # 클립보드 변환 테스트 (21개) │ │ └── Services/SettingsServiceTests.cs # 설정 서비스 테스트 (17개) │ ├── AxCommander.Installer.Offline/ # 오프라인 인스톨러 (.NET 8, self-contained ZIP 내장) │ │ ├── SetupForm.cs # 모던 WinForms UI (그라데이션 헤더, 설치/업그레이드/제거) │ │ └── Program.cs │ └── AxCommander.Installer.Online/ # 온라인 인스톨러 (.NET Framework 4.8, ~1MB) │ ├── OnlineSetupForm.cs # .NET 4.8 WinForms UI + .NET 8 런타임 자동 다운로드 │ └── Program.cs ├── tools/ │ └── IconGenerator/ # 다이아몬드 픽셀 아이콘 생성 도구 (.NET 8 콘솔) │ └── Program.cs # 보석 다이아몬드 컷 + RGBG 4색 → ICO 생성 ├── docs/ │ └── DEVELOPMENT.md # 이 파일 ├── build.bat # 3종 빌드 스크립트 (본체 + 오프라인 + 온라인) └── README.md ``` --- ## 아키텍처 개요 ``` ┌─────────────────────────────────────────────────────────┐ │ App.xaml.cs │ │ (서비스 초기화 · 핸들러 등록 · 트레이 아이콘 관리) │ └────────┬───────────────────────────────────────────┬────┘ │ │ ┌────────▼────────┐ ┌──────────▼───────┐ │ LauncherWindow │ ◄─── MVVM ─────────► │ SettingsWindow │ │ (WPF, OLED 스타일)│ │ (좌측 사이드바) │ └────────┬────────┘ └──────────────────┘ │ 입력 ┌────────▼────────┐ │ CommandResolver │ ← 프리픽스 라우터 └────────┬────────┘ │ 프리픽스 분기 ┌────────┴────────────────────────────────────────────────┐ │ = Calculator/Currency /System+Timer ; Snippet │ │ # History @ UrlAlias ~ Folder > Batch $ Clip │ │ ! Workspace ? WebSearch emoji color recent │ │ note uninstall kill media info [plugin/skill] │ └────────────────────────────────────────────────────────┘ │ 프리픽스 없음 ┌────────▼────────┐ │ FuzzyEngine │ ← 한국어 초성 + 퍼지 매칭 └─────────────────┘ ``` --- ## 핵심 데이터 흐름 ### 검색 흐름 1. 사용자가 런처에 텍스트 입력 2. `LauncherViewModel.InputText` setter 트리거 3. `CommandResolver.ResolveAsync(input)` 호출 4. 프리픽스 일치 → 해당 `IActionHandler.GetItemsAsync()` 호출 5. 프리픽스 없음 → `FuzzyEngine.Search()` 호출 6. 결과를 `ObservableCollection`에 바인딩 7. `LauncherWindow` ListView 자동 갱신 ### 실행 흐름 1. 사용자가 `Enter` 키 입력 2. `LauncherViewModel.ExecuteSelectedAsync()` 호출 3. `CommandResolver.ExecuteAsync(item, lastInput)` 호출 4. 프리픽스 있음 → `handler.ExecuteAsync(item)` 위임 5. 프리픽스 없음 → `IndexEntry.Path`를 `Process.Start`로 실행 6. 런처 창 자동 숨김 ### 테마 전환 흐름 1. 설정 창 테마 탭에서 카드 클릭 2. `SettingsViewModel.SelectTheme(key)` 호출 3. `ThemePreviewRequested` 이벤트 발생 4. `App.PreviewCallback` → `LauncherWindow.ApplyTheme(key)` 호출 5. `Application.Current.Resources.MergedDictionaries` 교체 (런타임 핫스왑) 6. 설정 저장 없이 닫으면 `RevertCallback`으로 원복 --- ## 각 핸들러 상세 ### CalculatorHandler (`=`) - **엔진**: `MathEvaluator` 재귀 하강 파서 (외부 의존성 없음) - **연산자**: `+`, `-`, `*`, `/`, `%`, `^` (거듭제곱) - **함수**: `sqrt`, `abs`, `ceil`, `floor`, `round`, `sin`, `cos`, `tan`, `asin`, `acos`, `atan`, `log`, `log2`, `ln`, `exp`, `pow`, `min`, `max` - **상수**: `pi`, `e`, `inf` - **리터럴**: 일반 정수/소수, 16진수(`0xFF`), 과학적 표기(`1.5e3`) - **단위 변환**: `100km in miles`, `32f in c`, `5lb to kg` 등 (길이/온도/무게/속도/데이터/넓이) - **통화 변환**: `100 USD to KRW`, `50 EUR in JPY` — `open.er-api.com` 무료 API, 1시간 캐시 - **실행**: 결과를 클립보드에 복사 ### SystemCommandHandler (`/`) | 명령 | 기능 | P/Invoke | |------|------|----------| | `/lock` | 화면 잠금 | `user32.LockWorkStation` | | `/sleep` | 절전 | `WinForms.SetSuspendState(Suspend)` | | `/hibernate` | 최대 절전 | `WinForms.SetSuspendState(Hibernate)` | | `/restart` | 재시작 | `shutdown /r /t 5` | | `/shutdown` | 종료 | `shutdown /s /t 5` | | `/logout` | 로그아웃 | `user32.ExitWindowsEx(EWX_LOGOFF)` | | `/recycle` | 휴지통 비우기 | `shell32.SHEmptyRecycleBin` | | `/timer 5m` | 타이머 | `Task.Delay` + `NotificationService.Notify` | | `/timer 1h30m 회의` | 라벨 포함 타이머 | 위와 동일 | | `/alarm 14:30` | 지정 시각 알람 | 목표 시각 미래 계산 + `Task.Delay` | 각 명령은 `SystemCommandSettings`에서 개별 활성화/비활성화 가능. 위험한 명령(재시작, 종료 등)은 실행 전 `MessageBox.Show` 확인 다이얼로그 표시. 타이머/알람 완료 시 트레이 풍선 알림(`NotificationService.Notify`). **명령 별칭** (v0.8 추가): `CommandAliases` 딕셔너리로 명령키별 별칭 목록 설정 가능. ```json "commandAliases": { "lock": ["잠금", "l"], "sleep": ["절전", "s"], "restart": ["재시작", "r"], "shutdown": ["종료"], "logout": ["로그아웃"] } ``` 예) `/잠금` 또는 `/l` 입력 시 화면 잠금 실행. 설정 UI의 시스템 탭에서 쉼표 구분으로 편집 가능. ### EmojiHandler (`emoji`) - 300+ 이모지 내장 (한국어+영어 키워드 태그) - **사용**: `emoji 하트`, `emoji wave`, `emoji` (기본 30개) - **실행**: 이모지 문자를 클립보드에 복사 - **카테고리**: 표정/감정, 손/몸, 하트/기호, 음식, 동물, 물건/도구, 이동수단, 장소, 기호 ### ColorHandler (`color`) - **입력 형식**: HEX(`#FF5500`), RGB(`255,85,0` / `rgb(255,85,0)`), RGBA, HSL(`hsl(24,100%,50%)`), 색상 이름(`red`, `빨강`) - **출력**: HEX / RGB / HSL / HSV 4가지 형식 동시 표시 - **색상 이름**: 30+ 한/영 색상 이름 지원 (red, 빨강, skyblue, 하늘색 등) - **실행**: 선택한 형식을 클립보드에 복사 ### RecentFilesHandler (`recent`) - `%APPDATA%\Microsoft\Windows\Recent` 폴더의 `.lnk` 파일 읽기 - 최근 수정 순 정렬, 최대 100개 스캔 → 20개 표시 - 10초 캐시 - **실행**: Windows 셸이 `.lnk` 링크를 따라 원본 파일 실행 ### NoteHandler (`note`) - **저장**: `note 내일 회의 9시` → `%APPDATA%\AxCommander\notes.txt` 에 타임스탬프와 함께 append - **조회**: `note` → 최근 10개 역순 표시 (Enter로 클립보드 복사) - **전체 삭제**: `note clear` 또는 목록 맨 아래 항목 선택 - **알림**: 저장 시 트레이 풍선 알림 표시 ### UninstallHandler (`uninstall`) - `HKLM\SOFTWARE\...\Uninstall` + `HKCU\SOFTWARE\...\Uninstall` 레지스트리 스캔 - `WOW6432Node` 경로도 포함 (32비트 앱) - 이름 / 게시자로 검색, 30초 캐시 - **실행**: `UninstallString` 파싱 후 `Process.Start` — `msiexec` 자동 처리 - 시스템 구성 요소(`SystemComponent=1`) 및 KB 패치 자동 필터링 ### SnippetHandler (`;`) - 설정 `snippets[]` 배열에서 키워드를 퍼지 검색 - **변수 치환**: `{date}`, `{time}`, `{datetime}`, `{year}`, `{month}`, `{day}` - **붙여넣기**: `Clipboard.SetText` 후 `SendInput(Ctrl+V)` 시뮬레이션 (100ms 지연) ### ClipboardHistoryService + ClipboardHistoryHandler (`#`) - `HwndSource(HWND_MESSAGE)` 기반 숨겨진 메시지 창 생성 - `AddClipboardFormatListener` + `WM_CLIPBOARDUPDATE` 훅 - 최대 `maxItems`개 저장 (기본 50), FIFO 방식 - **보안 제외 패턴**: `ExcludePatterns` Regex 목록으로 민감 데이터 자동 제외 - `SuppressNextCapture()`: 자체 붙여넣기 시 중복 기록 방지 ### ClipboardHandler (`$`) 12가지 내장 변환기: | 키 | 변환 | |----|------| | `$json` | JSON 포맷팅 | | `$upper` / `$lower` | 대/소문자 변환 | | `$ts` | Unix 타임스탬프 → 날짜 | | `$epoch` | 날짜 → Unix 타임스탬프 | | `$urle` / `$urld` | URL 인코딩/디코딩 | | `$b64e` / `$b64d` | Base64 인코딩/디코딩 | | `$md` | Markdown 제거 | | `$trim` | 공백 정리 | | `$lines` | 빈 줄 제거 | --- ## 설정 UI (SettingsWindow) ### 레이아웃 구조 설정 창(`SettingsWindow.xaml`)은 **좌측 사이드바 + 우측 컨텐츠** 방식으로 구성됩니다. WPF `TabControl`의 커스텀 `ControlTemplate`으로 구현되며, `TabStripPlacement="Left"`를 사용합니다. ``` ┌──────────────────────────────────────────────────────────┐ │ 820 × 610 │ │ ┌────────────┐ ┌────────────────────────────────────┐ │ │ │ AX │ │ │ │ │ │ Commander │ │ 선택된 탭의 컨텐츠 │ │ │ │────────────│ │ (ScrollViewer + StackPanel) │ │ │ │ ● 일반 │ │ │ │ │ │ 테마 │ │ │ │ │ │ 색상 편집 │ │ │ │ │ │ 스니펫 │ │ │ │ │ │ 클립보드 │ │ │ │ │ │ 시스템 │ │ │ │ │ │ 빠른 실행 │ │ │ │ │ │ 배치 명령 │ │ │ │ │ │ 캡처 │ │ │ │ │ │ 알림 │ │ │ │ │ └────────────┘ └────────────────────────────────────┘ │ │ ─────────────────────────────────────────────────────── │ │ AX Commander · v1.0 [취소] [💾 저장] │ └──────────────────────────────────────────────────────────┘ ``` ### 탭 구성 | 탭 | MDL2 아이콘 | 주요 설정 항목 | |----|------------|--------------| | 일반 | E713 | 글로벌 단축키, 최대 결과 수, **기본 검색 엔진**, 투명도, **런처 위치**, 인덱스 경로, **검색 확장자** (태그형 UI, 추가/삭제 가능) | | 테마 | E790 | 11개 테마 카드 (클릭 → 즉시 미리보기): Dark/Light/OLED/Nord/Monokai/Catppuccin/Sepia/Alfred/Alfred Light/System/Custom | | 색상 편집 | E771 | 커스텀 테마 14개 색상 (커스텀 선택 시만 활성) | | 스니펫 | E70B | **자동 확장 토글**, 스니펫 추가/삭제, 변수 치환 안내 | | 클립보드 | E77F | 활성화 토글, 최대 보관 개수, 보안 패턴 표시 | | 시스템 | E7E8 | 7개 시스템 명령 개별 활성화/비활성화, **명령별 별칭 편집**, **별칭 기본값 초기화** | | 빠른 실행 | E7C3 | 키워드→앱/URL/폴더 단축키 추가/삭제 | | 배치 명령 | E756 | **`>` 프리픽스 배치 명령 추가/삭제, ShowWindow 옵션** | | 캡처 | E722 | `cap` 프리픽스 문자열 변경, 파일 자동 저장 토글·저장 경로 설정 | | 알림 | EA8F | 잠금 해제 알림 활성화 토글, 표시 위치(4방향), 표시 간격, 자동 닫힘 시간 | ### 디자인 시스템 **컬러 아이콘 박스** — 각 설정 행 좌측에 `36×36 CornerRadius="9"` 박스로 기능을 시각적으로 구분합니다. | 기능 영역 | 배경색 | |----------|--------| | 단축키 / 빠른 실행 | `#4B5EFC` | | 검색 | `#00A8CC` | | 투명도 / 절전 | `#7B2FBE` | | 스니펫 | `#FF6B35` | | 클립보드 활성화 | `#20B2AA` | | 보관 개수 | `#FF8C42` | | 보안 / 화면 잠금 | `#C50F1F` | | 재시작 | `#107C10` | | 시스템 종료 | `#C50F1F` | | 로그아웃 | `#CA5010` | **토글 스위치** (`ToggleSwitch` 스타일) — iOS 스타일의 커스텀 `CheckBox` 스타일. 클립보드 활성화와 시스템 명령 7개에 적용. ``` OFF: [○──────] 배경: #D0D0E0 ON: [──────●] 배경: #4B5EFC ``` **SideNavItem 스타일** — 탭 선택 상태: - 선택됨: 좌측 3px `#4B5EFC` accent bar + `#EEF0FF` 배경 + SemiBold 텍스트 - 호버: `#F4F4FF` 배경 - 비선택: 투명 배경 ### SettingsViewModel 보조 모델 ```csharp // 테마 카드 (테마 탭) class ThemeCardModel { Key, Name, PreviewBackground/Text/Accent/..., IsSelected } // 커스텀 색상 행 (색상 편집 탭) class ColorRowModel { Label, Property, Hex, Preview(SolidColorBrush) } // 빠른 실행 단축키 (빠른 실행 탭) class AppShortcutModel { Key, Description, Target, Type, TypeSymbol, TypeLabel } // 스니펫 행 (스니펫 탭) class SnippetRowModel { Key, Name, Content, Preview } // 배치 명령 행 (배치 명령 탭) class BatchCommandModel { Key, Command, ShowWindow } ``` --- ## 설정 스키마 (`settings.json`) ```jsonc { "version": "1.0", "hotkey": "Alt+Space", "launcher": { "opacity": 0.96, "maxResults": 7, "theme": "dark", // system|dark|light|oled|nord|monokai|catppuccin|sepia|custom "width": 680, "position": "center-top", // center-top|center|bottom "webSearchEngine": "g", // g|n|d|y|w (Google|Naver|DuckDuckGo|YouTube|Wikipedia) "snippetAutoExpand": true, // 글로벌 스니펫 자동 확장 활성화 "customTheme": { /* 14개 색상 키 */ } }, "indexPaths": [ "%USERPROFILE%\\Desktop", "%APPDATA%\\Microsoft\\Windows\\Start Menu" ], "indexExtensions": [ ".exe", ".lnk", ".bat", ".ps1", ".url", ".cmd", ".msi", ".pdf", ".doc", ".docx", ".xls", ".xlsx", ".ppt", ".pptx", ".hwp", ".hwpx", ".txt", ".md", ".csv", ".json", ".xml", ".yaml", ".yml", ".log", ".ini", ".png", ".jpg", ".jpeg", ".gif", ".bmp", ".svg", ".webp", ".zip", ".7z", ".rar" ], "aliases": [ { "key": "vscode", "type": "app", "target": "C:\\...\\Code.exe", "description": "VS Code" }, { "key": "gh", "type": "url", "target": "https://github.com" }, { "key": "dl", "type": "folder", "target": "%USERPROFILE%\\Downloads" }, { "key": "build", "type": "batch", "target": "dotnet build", "description": "빌드", "showWindow": true }, { "key": "test", "type": "batch", "target": "dotnet test", "description": "테스트", "showWindow": false } ], "snippets": [ { "key": "addr", "name": "회사 주소", "content": "서울시 강남구 ..." } ], "clipboardHistory": { "enabled": true, "maxItems": 50, "excludePatterns": ["^\\d{4}[\\s\\-]?\\d{4}[\\s\\-]?\\d{4}[\\s\\-]?\\d{4}$"] }, "systemCommands": { "showLock": true, "showSleep": true, "showRestart": true, "showShutdown": true, "showHibernate": false, "showLogout": true, "showRecycleBin": true, "commandAliases": { "lock": ["잠금", "l"], "sleep": ["절전", "s"], "restart": ["재시작"], "shutdown": ["종료"], "hibernate": [], "logout": ["로그아웃"], "recycle": [] } }, "clipboardTransformers": [ { "key": "$mine", "type": "regex", "pattern": "foo", "replace": "bar", "timeout": 2000 } ], "screenCapture": { "prefix": "cap", // cap 프리픽스 문자열 (변경 가능) "saveToFile": false, // true면 캡처 결과를 파일로도 저장 "savePath": "" // 빈 문자열이면 %USERPROFILE%\Pictures\Screenshots\ }, "reminder": { "enabled": false, // 잠금 해제 사용시간 알림 활성화 "position": "BottomRight", // TopLeft|TopRight|BottomLeft|BottomRight "intervalMinutes": 60, // 알림 최소 간격 (분): 30|60|120|240 "autoDismissSeconds": 10 // 자동 닫힘 초: 5|10|15|20|30 }, "monitorMismatch": "warn", // fit|skip|warn "profiles": [], // !save로 자동 관리 "plugins": [ { "path": "C:\\Plugins\\MyPlugin.dll", "enabled": true } ] } ``` --- ## 주요 기능 상세 ### 파일 액션 서브메뉴 (`→` 키) 검색 결과에서 파일이나 앱(IndexEntry)이 선택된 상태에서 `→` 키(커서가 입력 끝에 있을 때)를 누르면 파일 액션 서브메뉴로 진입합니다. **진입 조건**: `InputBox.CaretIndex == Text.Length && Text.Length > 0 && SelectedItem.Data is IndexEntry` **제공 액션**: | 액션 | 설명 | 구현 | |------|------|------| | 경로 복사 | 파일 전체 경로를 클립보드에 복사 | `Clipboard.SetText(path)` | | 파일 탐색기에서 열기 | 탐색기에서 해당 파일을 선택 상태로 표시 | `explorer.exe /select,"path"` | | 관리자 권한으로 실행 | UAC 권한 상승 후 실행 (파일만, 폴더 제외) | `ProcessStartInfo { Verb = "runas" }` | | 터미널에서 열기 | Windows Terminal 또는 cmd.exe로 해당 경로 열기 | `wt.exe -d "dir"` → 실패 시 `cmd.exe /k cd /d "dir"` | **상태 흐름**: ``` 일반 모드 → [→ 키] → 액션 모드 (breadcrumb 바 표시) → [Enter] → 액션 실행 + 닫기 → [Esc] → 일반 모드 복귀 (이전 쿼리 복원) ``` **관련 코드**: - `LauncherViewModel.EnterActionMode()` — 액션 항목 빌드 및 `_savedQuery` 저장 - `LauncherViewModel.ExitActionMode()` — 이전 쿼리 복원 및 재검색 - `LauncherViewModel.ExecuteFileAction()` — 정적 메서드로 액션 실행 - `LauncherWindow.xaml` — `Grid.Row="1"` breadcrumb 바 (ShowActionModeBar 바인딩) --- ### Large Type (`Shift+Enter`) 선택된 항목의 텍스트를 전체 화면 오버레이로 크게 표시합니다. **표시 텍스트 우선순위**: 1. 계산기 결과 (`SelectedItem.Data is string`) → 계산 결과값 2. 클립보드 히스토리 텍스트 (`ClipboardEntry.IsText`) → 전체 텍스트 3. 기본 → `SelectedItem.Title` **글꼴 크기 자동 결정** (`LargeTypeWindow`): | 텍스트 길이 | FontSize | |------------|---------| | ≤ 10자 | 120 | | ≤ 30자 | 96 | | ≤ 60자 | 72 | | ≤ 120자 | 52 | | 그 외 | 38 | `Viewbox Stretch=Uniform`으로 최종 크기를 화면에 맞게 스케일링합니다. **닫기**: `Esc` 키 / 화면 클릭 / 우상단 버튼 **관련 코드**: - `Views/LargeTypeWindow.xaml/.cs` — 전체 화면 오버레이 창 - `LauncherViewModel.GetLargeTypeText()` — 텍스트 추출 로직 - `LauncherWindow.xaml.cs` → `ShowLargeType()` → `new LargeTypeWindow(text).Show()` > **주의**: 클립보드 병합 대기 항목이 있는 상태에서 `Shift+Enter`를 누르면 Large Type 대신 **클립보드 병합**이 실행됩니다. --- ### 클립보드 병합 (`Shift+↑↓`, `Shift+Enter`) `#` 프리픽스(클립보드 히스토리) 모드에서 여러 항목을 선택하여 하나로 합쳐 클립보드에 복사합니다. **조작법**: | 키 | 동작 | |----|------| | `Shift+↓` | 현재 항목 선택/해제 후 다음 항목으로 이동 | | `Shift+↑` | 현재 항목 선택/해제 후 이전 항목으로 이동 | | `Shift+Enter` | 선택된 항목들을 `\n`으로 합쳐 클립보드에 복사 | | `Esc` | 선택 취소 및 모드 종료 | **힌트 바**: 선택 항목이 있으면 `Grid.Row="3"` 힌트 바 표시 ``` ✓ 2개 선택됨 · Shift+Enter로 합치기 · Esc로 취소 ``` **병합 순서**: `Results` 컬렉션의 표시 순서 기준 (HashSet 순서 아님) **관련 코드**: - `LauncherViewModel._mergeQueue` — `HashSet` 병합 대기 큐 - `LauncherViewModel.ToggleMergeItem()` — 항목 추가/제거 토글 - `LauncherViewModel.ExecuteMerge()` — Results 순서 기준으로 `\n` 결합 후 클립보드 복사 - `LauncherViewModel.ClearMerge()` — 큐 초기화 --- ### 런처 키 바인딩 전체 표 | 키 | 동작 | |----|------| | `↑` / `↓` | 결과 목록 탐색 | | `Enter` | 선택 항목 실행 | | `Shift+Enter` | Large Type 표시 (병합 항목 있으면 클립보드 병합) | | `→` (커서 끝) | 파일 액션 서브메뉴 진입 | | `Shift+↓` | 현재 항목 병합 선택 + 다음으로 이동 | | `Shift+↑` | 현재 항목 병합 선택 + 이전으로 이동 | | `Tab` | 선택 항목 제목을 입력창에 자동완성 | | `Esc` | 액션 모드면 이전 화면 복귀 / 아니면 런처 닫기 | | `Ctrl+,` | 설정 창 열기 | --- ## 데이터 저장 경로 모든 사용자 데이터는 `%APPDATA%\AxCommander\`에 저장됩니다. EXE 실행 파일 옆에는 어떤 파일도 생성하지 않으므로, 어느 경로에서 실행해도 실행 파일 폴더는 깨끗하게 유지됩니다. ``` %APPDATA%\AxCommander\ ├── settings.json # 전체 설정 (JSON 평문) ├── clipboard_history.dat # 클립보드 히스토리 (DPAPI 암호화 바이너리) ├── usage.json # 실행 빈도 랭킹 데이터 ├── notes.txt # 빠른 메모 저장 ├── favorites.json # 즐겨찾기 목록 ├── routines.json # 루틴 자동화 정의 (사용자 편집 가능) ├── logs/ │ └── app-YYYY-MM-DD.log # 일별 로그 (14일 자동 삭제) ├── stats/ │ └── YYYY-MM-DD.json # 일별 사용 통계 (30일 자동 삭제) ├── templates/ │ └── *.json # 프로젝트 스캐폴딩 사용자 템플릿 └── plugins/ └── *.dll # 외부 플러그인 (선택) ``` **자동 삭제 정책**: | 파일 | 보존 기간 | 방식 | |------|----------|------| | 로그 (`logs/app-*.log`) | 14일 | 앱 시작 시 1회 `PurgeOldLogs()` | | 통계 (`stats/*.json`) | 30일 | 통계 기록 시 `PurgeOldFiles()` | | 클립보드 히스토리 | 무기한 (최대 항목 수 제한) | `maxItems` 설정값 기준 FIFO | | 기타 (settings, notes 등) | 무기한 | 수동 관리 | --- ## 보안 고려사항 | 항목 | 구현 | |------|------| | URL 스킴 검증 | `http`, `https`, `ftp`, `ftps`, `ms-settings`, `mailto`, `file` 허용. `javascript:` 등 차단 | | PowerShell 인젝션 방지 | `>` 명령어 입력의 `"` 이스케이프 처리 | | ReDoS 방지 | 사용자 정의 Regex에 `TimeSpan` 타임아웃 적용 | | 자격증명 저장 | Windows Credential Manager (`advapi32.dll`, DPAPI 암호화) | | 클립보드 민감 데이터 | Regex 기반 제외 패턴 (`excludePatterns`) — 신용카드·IP 등 기본 차단 | | API 타임아웃 | JSON 스킬 HTTP 요청 3초 제한 | | 시스템 명령 확인 | 재시작·종료·로그아웃 실행 전 `MessageBox.Show` 2단계 확인 | | **디컴파일 방지** | `Security/AntiTamper.cs` — 디버거 감지 (관리형+네이티브+원격), 디컴파일러 프로세스 감지 (dnSpy, ILSpy, dotPeek, x64dbg 등 15종), Release 빌드만 활성 | | **PDB 제거** | Release 빌드 시 `DebugType=none`, `DebugSymbols=false`. build.bat에서 `.pdb`/`.xml` 전수 삭제 | | **소스 링크 비활성** | `EnableSourceLink=false`, `EmbedAllSources=false` — 소스 코드 경로 노출 차단 | | **난독화 호환** | `[assembly: Obfuscation]` 속성 적용. Obfuscar/ConfuserEx/Dotfuscator 연동 시 자동 난독화 | --- ## 테마 커스터마이징 테마 XAML 파일(`Themes/*.xaml`)은 색상 14개 + 모양 2개 = **총 16개 ResourceKey**를 정의합니다: | 키 | 타입 | 용도 | |----|------|------| | `LauncherBackground` | SolidColorBrush | 전체 배경 | | `ItemBackground` | SolidColorBrush | 항목 기본 배경 | | `ItemSelectedBackground` | SolidColorBrush | 선택된 항목 배경 | | `ItemHoverBackground` | SolidColorBrush | 호버 배경 | | `PrimaryText` | SolidColorBrush | 주 텍스트 색상 | | `SecondaryText` | SolidColorBrush | 보조 텍스트 색상 | | `PlaceholderText` | SolidColorBrush | 플레이스홀더 텍스트 | | `AccentColor` | SolidColorBrush | 강조색 (선택 바, 배지 등) | | `SeparatorColor` | SolidColorBrush | 구분선 색상 | | `HintBackground` | SolidColorBrush | 힌트 배경 | | `HintText` | SolidColorBrush | 힌트 텍스트 | | `BorderColor` | SolidColorBrush | 창 테두리 | | `ScrollbarThumb` | SolidColorBrush | 스크롤바 색상 | | `ShadowColor` | Color | 드롭 섀도우 색상 | | `WindowCornerRadius` | CornerRadius | 창 전체 모서리 라운딩 | | `ItemCornerRadius` | CornerRadius | 결과 항목 모서리 라운딩 | **테마별 모서리 라운딩 값**: | 테마 | WindowCornerRadius | ItemCornerRadius | 특징 | |------|-------------------|-----------------|------| | Dark / Light | 20 | 10 | 기본 부드러운 라운딩 | | OLED | 26 | 13 | 가장 둥근 형태 | | Catppuccin | 22 | 12 | 약간 더 둥근 파스텔 느낌 | | Nord | 16 | 8 | 약간 각진 북유럽 스타일 | | Monokai | 14 | 6 | 에디터 스타일 — 적당히 각진 | | Sepia | 12 | 6 | 클래식하고 차분한 느낌 | | Alfred / AlfredLight | 14 | 6 | Alfred 앱과 유사한 비율 | **트레이 컨텍스트 메뉴**: `TrayContextMenu.cs`의 `ModernTrayRenderer`는 런타임에 `Application.Current.Resources`에서 WPF 테마 색상(`LauncherBackground`, `AccentColor` 등)을 읽어 트레이 메뉴 배경·텍스트·호버 색상에 그대로 적용합니다. 테마를 전환하면 다음 메뉴 오픈 시 새 테마가 반영됩니다. **새 테마 추가 순서**: 1. `Themes/MyTheme.xaml` 작성 (위 16개 키 모두 정의, `WindowCornerRadius`·`ItemCornerRadius` 포함) 2. `.csproj`에 `` 추가 3. `LauncherWindow.xaml.cs`의 `GetEffectiveThemeName()` switch에 케이스 추가 4. `SettingsViewModel.ThemeCards` 목록에 `ThemeCardModel` 항목 추가 --- ## 단위 테스트 ```bash dotnet test src/AxCommander.Tests ``` | 파일 | 테스트 수 | 대상 | |------|----------|------| | `FuzzyEngineTests.cs` | 19 | CalculateScore, FuzzyMatch, 초성 검색 | | `ClipboardTransformTests.cs` | 21 | 12개 내장 변환기 | | `SettingsServiceTests.cs` | 17 | 기본값, JSON 직렬화 라운드트립 | 테스트 프로젝트는 `InternalsVisibleTo`로 `internal` 메서드에 접근합니다. --- ## 코드 검토 이력 ### v0.3 최종 검토 결과 (2026-03-24) 전체 소스 코드 정적 분석 결과 **컴파일 오류 없음** 확인. v0.3 신규 코드 포함. | 검토 항목 | 결과 | |----------|------| | 타입 참조 (`Symbols.Lock`, `Symbols.MediaPlay`, `Symbols.Computer`) | ✅ 모두 `Themes/Symbols.cs`에 정의됨 | | XAML 컨버터 (`BoolToVisibility`, `CountToVisibility`, `SymbolToBackground` 등) | ✅ `App.xaml`에 모두 등록됨 | | ViewModel 바인딩 (`ShowActionModeBar`, `ActionModeBreadcrumb`, `ShowMergeHint`, `MergeHintText`) | ✅ `LauncherViewModel`에 모두 정의됨 | | `LauncherItem` 생성자 호출부 (`Symbol:` named parameter) | ✅ SDK 레코드 시그니처 일치 | | `ClipboardEntry` `IsText` / `Text` 프로퍼티 | ✅ `ClipboardHistoryService.cs`에 정의됨 | | `HashSet` 동등성 | ✅ record 구조적 동등성 + 동일 객체 참조로 정상 작동 | | `IndexEntry.Path` 프로퍼티 | ✅ `IndexService.cs`에 정의됨 | | `FileAction` enum / `FileActionData` record 접근성 | ✅ 동일 파일(ViewModels) 내 정의, 접근 가능 | | `LargeTypeWindow` 네임스페이스 | ✅ `AxCommander.Views` — LauncherWindow와 동일 네임스페이스, import 불필요 | | `LauncherWindow.xaml` Grid.Row 번호 | ✅ Row 0~4 순서 정확 (0:입력, 1:액션바, 2:구분선, 3:병합힌트, 4:리스트) | --- ## 버그 수정 이력 ### v0.1 → v0.2 | 파일 | 문제 | 수정 내용 | |------|------|----------| | `InputListener.cs` | `LogService.Services.LogService.XXX()` — 존재하지 않는 네임스페이스 경로로 컴파일 오류 발생 | `using AxCommander.Services;` 추가 후 `LogService.XXX()` 직접 호출로 수정. 파일 하단의 빈 `namespace LogService { }` 선언 제거 | ### v0.2 → v0.3 | 파일 | 변경 내용 | |------|----------| | `Core/HotkeyParser.cs` (신규) | 핫키 문자열 파싱/포맷 — `"Alt+Space"` ↔ `HotkeyDefinition` 변환 | | `Core/InputListener.cs` | 하드코딩 Alt+Space 제거 → `HotkeyDefinition` 기반 동적 핫키 + `SuspendHotkey` 지원 | | `Views/SettingsWindow.xaml/.cs` | Alfred 스타일 핫키 레코더 UI (클릭 → 배지 표시 → 키 입력 캡처) | | `Views/LargeTypeWindow.xaml/.cs` (신규) | 전체 화면 Large Type 오버레이 | | `ViewModels/LauncherViewModel.cs` | 파일 액션 모드 + 클립보드 병합 + Large Type 텍스트 추출 추가 | | `Views/LauncherWindow.xaml` | 액션 모드 breadcrumb 바 (Row 1) + 병합 힌트 바 (Row 3) 추가 | | `Views/LauncherWindow.xaml.cs` | `→`, `Shift+Enter`, `Shift+↑↓` 키 핸들러 추가 / Esc 액션모드 분기 | | `App.xaml.cs` | 설정 저장 후 핫키 갱신 + SuspendHotkey 콜백 주입 | ### v0.3 → v0.4 (Alfred 비교 기반 설정 UI 개선) | 파일 | 변경 내용 | |------|----------| | `Models/AppSettings.cs` | `LauncherSettings`에 `WebSearchEngine`, `SnippetAutoExpand`, `Position` 필드 추가 | | `Handlers/WebSearchHandler.cs` | 기본 검색 엔진을 하드코딩에서 `settings.Launcher.WebSearchEngine` 런타임 읽기로 전환 / 불필요한 `using AxCommander.Models` 제거 | | `App.xaml.cs` | `WebSearchHandler` 생성자에 `settings` 주입 | | `Core/SnippetExpander.cs` | `HandleKey()` 진입부에 `SnippetAutoExpand` 비활성화 시 즉시 반환 추가 | | `ViewModels/LauncherViewModel.cs` | `WindowPosition` 프로퍼티 추가 (설정 연동) | | `Views/LauncherWindow.xaml.cs` | `CenterOnScreen()` — `position` 설정 연동 + `ActualHeight/Width = 0` 방어 처리 | | `ViewModels/SettingsViewModel.cs` | `LauncherPosition`, `WebSearchEngine`, `SnippetAutoExpand` 바인딩 프로퍼티 추가 / `BatchCommandModel` 및 배치 명령 CRUD 추가 | | `Views/SettingsWindow.xaml` | 일반 탭: 기본 검색 엔진·런처 위치 ComboBox 추가 / 스니펫 탭: 자동 확장 토글 추가 / 8번째 탭 배치 명령 탭 추가 | | `Views/SettingsWindow.xaml.cs` | `AddBatchCommand_Click`, `DeleteBatchCommand_Click` 핸들러 추가 | **버그 수정**: | 파일 | 버그 | 수정 | |------|------|------| | `Views/LauncherWindow.xaml.cs` | `CenterOnScreen()` — 첫 `Show()` 호출 시 레이아웃 패스 이전 `ActualHeight`가 0이 되는 타이밍 이슈 | `var h = ActualHeight > 0 ? ActualHeight : 80` 방어 처리 추가 | | `Handlers/WebSearchHandler.cs` | `using AxCommander.Models` — 파일 내 Models 타입 미사용 불필요한 임포트 | 해당 `using` 제거 | ### v0.4 → v0.5 (배포 준비 + About 창 + 트레이 기능 강화) | 파일 | 변경 내용 | |------|----------| | `App.xaml.cs` | 자동 시작 토글 — `HKCU\...\Run` 레지스트리 읽기/쓰기, 트레이 메뉴 체크박스 항목 추가 | | `App.xaml.cs` | "정보" 트레이 메뉴 항목 추가 → `AboutWindow` 오픈 | | `Views/AboutWindow.xaml/.cs` (신규) | 개발자 정보 창 — 그라데이션 헤더, 마스코트 이미지, 개발 목적, 블로그 링크, 버전 정보 | | `AxCommander.csproj` | `Assets/mascot.png/.jpg/.webp` 조건부 CopyToOutputDirectory 추가 | | `Views/SettingsWindow.xaml` | 단축키 아이콘 E704(InkingTool) → E765(Keyboard) 수정 | | `Views/LargeTypeWindow.xaml` | `LineHeight="1.2"` 제거 — WPF LineHeight는 픽셀 단위, 1.2px는 런타임 오류 유발 | | `AxCommander.csproj` | `` 추가 — WPF+WinForms 동시 사용 시 `KeyEventArgs` 모호성 해소 | **설정 파일 경로 확인**: `%APPDATA%\AxCommander\settings.json` — 이미 올바른 경로 사용 중, 별도 변경 없음. **배포 방식**: `dotnet publish` → 단일 `.exe` 파일 (SelfContained, PublishSingleFile). 인스톨러 없이 EXE 복사 후 즉시 실행 가능. ### v0.5 → v0.6 (Alfred 비교 기반 7개 기능 추가) | 파일 | 변경 내용 | |------|----------| | `Handlers/EmojiHandler.cs` (신규) | `emoji` 프리픽스, 300+ 이모지 내장 데이터베이스, 한/영 태그 검색, 클립보드 복사 | | `Handlers/ColorHandler.cs` (신규) | `color` 프리픽스, HEX/RGB/RGBA/HSL/색상이름 → HEX+RGB+HSL+HSV 4종 변환 | | `Handlers/SystemCommandHandler.cs` | `/timer`, `/alarm` 추가 — 시간 문자열 파싱(5m/1h30m/30s), Task.Delay 기반 백그라운드 타이머 | | `Handlers/RecentFilesHandler.cs` (신규) | `recent` 프리픽스, Windows Recent .lnk 파싱, 최근순 정렬, 10초 캐시 | | `Handlers/CalculatorHandler.cs` | `= 100 USD to KRW` 통화 변환 추가 — `CurrencyConverter` 내부 클래스, `open.er-api.com` 무료 API, 1시간 캐시, `async` 전환 | | `Handlers/UninstallHandler.cs` (신규) | `uninstall` 프리픽스, 레지스트리 HKLM/HKCU/WOW6432Node 스캔, msiexec/exe 제거 실행 | | `Handlers/NoteHandler.cs` (신규) | `note` 프리픽스, notes.txt append 저장, 역순 조회, clear 명령, ValueTuple 명시적 패턴 매칭 | | `Services/NotificationService.cs` (신규) | static delegate 패턴 — App.xaml.cs에서 트레이 아이콘과 연결, 타이머/알람 알림에 사용 | | `Themes/Symbols.cs` | Emoji/ColorPicker/Timer/RecentFiles/Currency/Uninstall/Note 심볼 추가 | | `App.xaml.cs` | 5개 핸들러 등록 (Emoji/Color/Recent/Note/Uninstall) + `NotificationService.Initialize()` 연결 | **버그 수정**: | 파일 | 버그 | 수정 | |------|------|------| | `Handlers/NoteHandler.cs` | `case ("__SAVE__", string content):` — `object?` 타입에 대한 positional 패턴 컴파일 불안정 | `case ValueTuple t when t.Item1 == "__SAVE__":` 명시적 타입 패턴으로 변경 | | `Themes/Symbols.cs` | `Warning` 상수 중복 정의 (신규 추가 시 실수) | 하단 중복 제거 | ### v0.6 → v0.7 (개발자 도구 + 화면 캡처 + 랭킹 시스템) | 파일 | 변경 내용 | |------|----------| | `Handlers/PortHandler.cs` (신규) | `port` 프리픽스, TCP 활성 연결 조회, 포트번호/프로세스명 검색, netstat -ano PID 매핑 | | `Services/UsageRankingService.cs` (신규) | 실행 빈도 JSON 저장(`usage.json`), `SortByUsage()` 제공 | | `Core/CommandResolver.cs` | 퍼지 검색 결과를 `UsageRankingService.SortByUsage()`로 재정렬, IndexEntry 실행 시 `RecordExecution()` 호출 | | `Handlers/EnvHandler.cs` (신규) | `env` 프리픽스, 우선순위 환경변수 20개 표시, 키/값 모두 검색, Enter로 복사 | | `Handlers/JsonHandler.cs` (신규) | `json` 프리픽스, 클립보드 또는 인라인 JSON 파싱, `format`/`minify` 서브커맨드, `System.Text.Json` 내장 | | `Handlers/EncodeHandler.cs` (신규) | `encode ` 프리픽스(뒤 공백), base64/url/hex/md5/sha1/sha256/sha512/html 인코딩 + decode 접두사로 역변환 | | `Services/WindowTracker.cs` (신규) | `GetForegroundWindow()` P/Invoke, `Capture()` 호출 시 PreviousWindow 저장 | | `Handlers/SnapHandler.cs` (신규) | `snap` 프리픽스, left/right/top/bottom/full/tl/tr/bl/br/center/restore, `SetWindowPos` + `GetMonitorInfo` | | `Handlers/ScreenCaptureHandler.cs` (신규) | `cap` 프리픽스, screen(전체)/window(창)/scroll(스크롤 캡처), `PrintWindow`+`BitBlt`, 오버랩 검출 스티칭, `%USERPROFILE%\Pictures\Screenshots\` 저장 | | `Themes/Symbols.cs` | PortIcon/EnvVar/JsonValid/JsonFormat/JsonMinify/EncodeIcon/SnapLayout/CaptureIcon/ScrollCapture 심볼 추가 | | `App.xaml.cs` | 6개 핸들러 등록 (Port/Env/Json/Encode/Snap/ScreenCapture) + `OnHotkeyTriggered()`에 `WindowTracker.Capture()` 추가 | **v0.7 코드 검토 후 즉시 수정 (버그 픽스):** | 파일 | 수정 내용 | |------|----------| | `Handlers/PortHandler.cs` | `GetPidForPort()`가 루프마다 `netstat -ano` 실행하던 N+1 문제 → `RefreshProcessCache()` 내부에서 netstat 1회 실행 후 `_pidMap(포트→PID)` 캐시 구축. `GetPidForPort()`는 캐시 조회만 수행 | | `Handlers/ScreenCaptureHandler.cs` | `AreSimilar()`/`FindOverlap()`의 `GetPixel()` 픽셀 비교 → `LockBits + unsafe 포인터` 연산으로 교체 (~50× 속도 향상) | | `ViewModels/LauncherViewModel.cs` | `PrefixMap`에 v0.6 핸들러(emoji/color/recent/note/uninstall) + v0.7 핸들러(port/env/json/encode/snap/cap) + `/`(SystemCommand) 누락 항목 일괄 추가. `kill`/`media`/`info` 키를 공백 포함 버전으로 수정 | | `AxCommander.csproj` | `true` 추가 | **스크롤 캡처 동작 방식**: 1. `WindowTracker.PreviousWindow`에 저장된 이전 활성 창을 포그라운드로 활성화 2. `PrintWindow(PW_RENDERFULLCONTENT=2)` 또는 `CopyFromScreen` 폴백으로 첫 프레임 캡처 3. `WM_VSCROLL SB_PAGEDOWN` (스크롤 가능 자식 창이 있는 경우) 또는 `WM_KEYDOWN VK_NEXT` 전송 4. 120ms 대기 후 재캡처, 이전 프레임 하단 20%와 비교하여 97% 이상 유사하면 스크롤 종료 감지 → 중단 5. 각 프레임 사이 오버랩 픽셀 수를 픽셀 샘플링으로 계산하여 비겹치는 부분만 수직 스티칭 6. 결과를 `%USERPROFILE%\Pictures\Screenshots\scroll_yyyyMMdd_HHmmss.png`로 저장 + 클립보드 복사 **실행 빈도 랭킹 동작 방식**: - 퍼지 검색(파일/앱/폴더) 실행 시 `IndexEntry.Path`를 키로 카운트 증가 - `usage.json`에 비동기 저장 (앱 종료 시에도 누적됨) - 다음 검색부터 `SortByUsage`로 상위 항목이 결과 목록 최상단에 표시 ### About 창 (`AboutWindow`) ``` ┌─────────────────────────────┐ │ [블루-퍼플 그라데이션 헤더] │ │ (마스코트 이미지 원형) │ │ AX Commander │ │ v1.0 │ ├─────────────────────────────┤ │ ┌─── 개발 목적 배너 ─────────┐ │ │ │ 업무 편의성 증가 및 LLM ... │ │ │ └─────────────────────────┘ │ │ │ │ 🏢 AX연구소 AI팀 │ │ 백승재 · SW Architect │ │ 🔗 www.swarchitect.net │ │ │ │ AX Commander · .NET 8 │ └─────────────────────────────┘ ``` - 앱 아이콘: `Assets/icon.ico` — 다이아몬드 픽셀 보석 컷 디자인 (Blue/Green/Red/Green 4색, 흰색 facet 선) - 7개 크기 (16, 24, 32, 48, 64, 128, 256px) 포함 - `tools/IconGenerator/` 콘솔 앱으로 재생성 가능: `dotnet run -- <출력경로>` - SVG 원본: `Assets/diamond_pixel.svg` - 마스코트 이미지: `Assets/mascot.png` (또는 .jpg/.webp) 존재 시 자동 로드, 없으면 앱 아이콘 표시 - 정보 창: 초기 표시 시 앱 아이콘, 개발자 이름 클릭 시 마스코트 오버레이 - 창 드래그 이동 가능 (`MouseDown` → `DragMove`) - 블로그 링크 클릭 시 기본 브라우저로 열기 --- ## v0.7 3차 전체 점검 수정 (버그·보안·스레딩) > 빌드 오류 3건, 컴파일 경고 1건, 런타임 버그 6건, 보안 이슈 2건을 수정하였습니다. ### 컴파일 오류 수정 | 파일 | 수정 내용 | 오류 코드 | |------|----------|----------| | `Services/UsageRankingService.cs` | `using System.IO;` 누락 추가 (`Path`, `File`, `Directory` 인식 불가) | CS0103 | | `Views/SettingsWindow.xaml.cs` | `Key.Enter`와 `Key.Return` 중복 switch 케이스 → `Key.Enter or Key.Return` 단일 arm으로 통합 | CS8510 | | `Core/ContextManager.cs` | `EnumDisplayMonitors` 콜백 람다 파라미터 혼합 타입 (`ref RECT` + 암시적 `_`) → 전체 명시적 타입으로 수정 (×2) | CS0748 | | `Assets/icon.ico` | 아이콘 파일 누락 → 다이아몬드 픽셀 보석 아이콘으로 교체 (`tools/IconGenerator`로 생성, 7크기 ICO) | CS7064 | | `Views/SettingsWindow.xaml.cs` | `NewIndexPathBox` nullable 역참조 → null 조건 추가 | CS8602 | ### 런타임 버그 수정 | 파일 | 수정 내용 | 심각도 | |------|----------|-------| | `Handlers/JsonSkillLoader.cs` | `NavigatePath`: `field[0` 같이 `]` 없는 경로 파싱 시 `IndexOf` 반환 −1로 인한 예외 → `closingIdx < 0` 조기 반환 추가 | HIGH | | `Services/ClipboardHistoryService.cs` | `_ignoreNext` 플래그를 `volatile bool`로 선언하여 스레드 간 가시성 보장 | MEDIUM | | `Services/ClipboardHistoryService.cs` | `Initialize()` 호출 시 이미 초기화된 경우(`_msgSource != null`) 또는 `Dispose()` 후 재호출 방지 가드 추가 | MEDIUM | | `Services/ClipboardHistoryService.cs` | `Dispose()` 중복 호출 방지를 위한 `_disposed` 플래그 추가 | MEDIUM | | `Services/IndexService.cs` | `ScheduleRebuild`: `_debounceTimer` 교체 시 비원자적 Dispose + 재할당을 `_timerLock` 으로 보호 | MEDIUM | | `Services/SettingsService.cs` | settings.json 백업 실패 시 빈 `catch {}` → `LogService.Warn`으로 원인 기록 | MEDIUM | ### 보안 수정 | 파일 | 수정 내용 | 심각도 | |------|----------|-------| | `Handlers/JsonSkillLoader.cs` | `ExecuteAsync`: `item.ActionUrl` 실행 전 `http`/`https` 스킴 검증 추가 — API 응답이 조작된 `file://` 등 비표준 URL 실행 방지 | MEDIUM | ### 데드 코드 제거 | 파일 | 수정 내용 | |------|----------| | `Handlers/SystemCommandHandler.cs` | `allCommands` 목록에서 `timer`·`alarm` no-op 항목 제거 — 두 명령은 `q.StartsWith` early-return으로 완전히 처리되며, `Action = () => Task.CompletedTask` 항목은 클릭 시 아무것도 하지 않아 사용자 혼란 유발 | --- ## v0.7 2차 코드 검토 수정 (컴파일러 경고 제거) | 파일 | 수정 내용 | 경고 코드 | |------|----------|----------| | `Services/UsageRankingService.cs` | `using AxCommander.Services;` 자기 자신 namespace import 제거 | CS0105 | | `Handlers/PortHandler.cs` | `UdpStatistics? udpStats = null;` 미사용 변수 제거 | CS0219 | | `Handlers/PortHandler.cs` | `using System.Net;` 미사용 using 제거 (모든 네트워크 타입은 `System.Net.NetworkInformation`에서 확보) | IDE0005 | | `Handlers/ScreenCaptureHandler.cs` | 미사용 P/Invoke `keybd_event` 선언 제거 (실제 키 전송은 `SendMessage`로 구현) | CS0649 | | `Handlers/ScreenCaptureHandler.cs` | 미사용 상수 `KEYEVENTF_KEYUP`, `SB_BOTTOM` 제거 | CS0219 | | `Handlers/SnapHandler.cs` | 주석 `"snap " 프리픽스` → `"snap" 프리픽스` (실제 Prefix 필드와 일치) | 문서 오류 | ### v0.7 → v0.8 (UI 개선 + 명령 별칭 + 사용 통계) | 파일 | 변경 내용 | |------|----------| | `Views/SettingsWindow.xaml` | 스니펫 탭 "추가" 버튼 `Width="60"` → `MinWidth="72"` (텍스트 잘림 수정) | | `Models/AppSettings.cs` | `SystemCommandSettings`에 `CommandAliases` 딕셔너리 추가 | | `Handlers/SystemCommandHandler.cs` | `GetItemsAsync` 필터링에 별칭 매칭 추가 — `/잠금`, `/l` 등 사용자 정의 별칭으로도 명령 접근 가능 | | `ViewModels/SettingsViewModel.cs` | `AliasLock`·`AliasSleep`·`AliasRestart`·`AliasShutdown`·`AliasHibernate`·`AliasLogout`·`AliasRecycle` 7개 별칭 프로퍼티 추가 / `ResetSystemCommandAliases()` 추가 | | `Views/SettingsWindow.xaml` | 시스템 탭 행을 4열 레이아웃으로 재설계 — [아이콘][이름/프리픽스][별칭 TextBox][토글], "별칭 기본값 초기화" 버튼 추가 | | `Views/SettingsWindow.xaml.cs` | `ResetCommandAliases_Click` 핸들러 추가 | | `Models/DailyUsageStats.cs` (신규) | 일별 사용 통계 데이터 모델 — `LauncherOpens`, `CommandUsage`, `ActiveSeconds` | | `Services/UsageStatisticsService.cs` (신규) | static 통계 서비스 — `%APPDATA%\AxCommander\stats\YYYY-MM-DD.json` 저장, 30일 롤링 삭제, `RecordLauncherOpen()` / `RecordCommandUsage()` / `AddActiveSeconds()` / `GetStats()` | | `Services/SessionTrackingService.cs` (신규) | `SystemEvents.SessionSwitch` 기반 PC 활성 시간 추적 — 잠금 시 누적 초 기록, 해제 시 타이머 재개, `Dispose()` 시 플러시 | | `ViewModels/StatisticsViewModel.cs` (신규) | `DayBarItem` / `CommandStatItem` 레코드, `LauncherOpenBars` / `ActiveTimeBars` / `TopCommands` 컬렉션, 요약 카드 문자열 | | `Views/StatisticsWindow.xaml` (신규) | 다크 그라데이션 헤더, 4개 요약 카드, 런처 호출 막대 차트 (최근 14일), PC 활성 시간 막대 차트 (최근 14일), 상위 명령 순위 목록 | | `Views/StatisticsWindow.xaml.cs` (신규) | 드래그 이동, 새로고침/닫기 버튼 핸들러 | | `Views/TrayContextMenu.cs` | `GlyphStats = "\uE9D9"` (Chart) 상수 추가 | | `App.xaml.cs` | `_sessionTracking` 필드 추가, `OnHotkeyTriggered()`에 `UsageStatisticsService.RecordLauncherOpen()` 추가, 트레이 메뉴 "사용 통계" 항목 추가, `OnExit()`에 `_sessionTracking?.Dispose()` 추가 | | `Core/CommandResolver.cs` | `ExecuteAsync()`에 명령 사용 통계 기록 추가 — 프리픽스 + 첫 단어를 키로 `UsageStatisticsService.RecordCommandUsage()` 호출 | **사용 통계 데이터 저장 경로**: `%APPDATA%\AxCommander\stats\` **일별 JSON 형식**: ```json { "date": "2026-03-26", "launcherOpens": 42, "commandUsage": { "/lock": 3, "=": 8, ";addr": 5 }, "activeSeconds": 18432 } ``` **차트 구성**: - 런처 호출 횟수: 최근 14일 막대 차트 (오늘 강조) - PC 활성 시간: 최근 14일 막대 차트 (초 → 시간 환산) - 상위 명령: 30일 합산 Top 10, 순위 + 명령키 + 사용횟수 + 비율 바 **빌드 검증**: `dotnet build --output "C:/Temp/axtest"` — **0 errors, 0 warnings** 확인 ### v0.8 → v0.9 (UX 버그 수정 + 클립보드 영속성 + 다국어 + 단일 인스턴스) | 파일 | 변경 내용 | |------|----------| | `Views/LauncherWindow.xaml` | `Window` 요소에 `PreviewKeyDown="Window_PreviewKeyDown"` 추가. TextBox에서 키 핸들러 제거 (ScrollViewer 키 소비 문제 해결) | | `Views/LauncherWindow.xaml.cs` | `Window_PreviewKeyDown` 으로 Escape·Enter·Down·Up·Right·Tab 일괄 처리. Tab 커서 위치를 `Dispatcher.BeginInvoke(DispatcherPriority.Input)`으로 뒤로 이동 수정. `Window_KeyDown`은 Ctrl+, 전담 | | `Services/ClipboardHistoryService.cs` | JSON 영속성 추가 — `%APPDATA%\AxCommander\clipboard_history.json`. `Initialize()` 시 로드, 항목 변경·삭제 시 비동기 저장, `Dispose()` 시 동기 저장 | | `Handlers/ClipboardHistoryHandler.cs` | 클립보드 항목 선택 후 이전 창 포커스 복원 + Ctrl+V 자동 붙여넣기. `SetForegroundWindow` P/Invoke 추가, 150ms 딜레이 후 `WindowTracker.PreviousWindow`로 포커스 이동 | | `App.xaml.cs` | 단일 인스턴스 Mutex (`Global\\AXCommander_SingleInstance`) 추가. 중복 실행 시 안내 메시지 후 `Shutdown()`. 트레이 `DoubleClick` → `MouseClick` (좌클릭 한 번으로 런처 토글). `L10n.SetLanguage(settings.Settings.Launcher.Language)` 호출 추가. `OnExit()`에 Mutex 해제 추가 | | `Services/SettingsService.cs` | `CreateDefaults()` 에서 `D:\Non_Document` 존재 시 인덱스 경로에 자동 추가 | | `Services/L10n.cs` (신규) | 정적 다국어 서비스 — `L10n.SetLanguage(lang)` / `L10n.Get(key)`. 지원 언어: ko·en·ja·zh·vi. 키: placeholder·loading·no_results·clipboard_empty·merge_hint 등 | | `Models/AppSettings.cs` | `LauncherSettings`에 `Language` 프로퍼티 추가 (`"ko"` 기본값) | | `ViewModels/SettingsViewModel.cs` | `Language` 프로퍼티 추가, `Save()` 시 `L10n.SetLanguage()` 호출 | | `ViewModels/LauncherViewModel.cs` | `PlaceholderText` → `L10n.Get("placeholder")` 반환 | | `Views/SettingsWindow.xaml` | 일반 탭 상단에 언어 선택 ComboBox 추가 (한국어/English/日本語/中文/Tiếng Việt) | | `Handlers/HelpHandler.cs` | 헤더 항목 `Data = "__HELP_OVERVIEW__"` 설정. `ExecuteAsync` 에서 `HelpDetailWindow` 열기 | | `Views/HelpDetailWindow.xaml` (신규) | 프레임리스 다크 창 (720×640). 모든 도움말 항목을 카드 형태로 표시. ESC 닫기, 드래그 이동 | | `Views/HelpDetailWindow.xaml.cs` (신규) | `HelpItemModel` 클래스 (Category·Command·Title·Description·Example·Symbol·ColorBrush) | | `Views/` | `AboutWindow`에 `mascot.png` 이미지 표시 — `Assets/mascot.png` 파일이 있을 때만 표시 (없으면 공간 숨김) | **방향키 내비게이션 버그 원인 및 수정**: TextBox 내부의 `PART_ContentHost`(ScrollViewer)가 터널링 단계(PreviewKeyDown)에서 Up/Down 키를 소비하므로 TextBox 레벨 이벤트 핸들러로는 차단 불가. 수정: Window 레벨 `PreviewKeyDown`으로 이동 — Window는 터널링 최상위이므로 모든 자식 요소보다 먼저 키 이벤트를 수신. **Tab 커서 위치 버그 원인 및 수정**: `_vm.InputText = title` 바인딩 업데이트는 렌더링 사이클 이후에 TextBox에 반영되므로 직후 `CaretIndex`를 설정해도 바인딩이 덮어씀. 수정: `Dispatcher.BeginInvoke(() => InputBox.CaretIndex = ..., DispatcherPriority.Input)` 으로 다음 입력 처리 사이클에 커서 위치 설정. **클립보드 히스토리 JSON 형식** (`clipboard_history.json`): ```json [ { "text": "복사한 텍스트", "ts": "2026-03-26T10:30:00" }, { "text": "이전 복사", "ts": "2026-03-26T10:25:00" } ] ``` 이미지 타입은 직렬화하지 않음 (텍스트 전용 저장). **빌드 검증**: `dotnet build --output "C:/Temp/axtest3"` — **0 errors, 0 warnings** 확인 ### v0.9 2차 (잠금 해제 알림 + 화면 캡처 설정 + 테마 모양 + 트레이 메뉴 개선) | 파일 | 변경 내용 | |------|----------| | `Assets/Quotes/famous.json` (신규) | 내장 명언 500개 JSON (EmbeddedResource) — 동서양 철학자·사상가·과학자·경영자·작가·한국 위인 등 다양한 인물 | | `Services/QuoteService.cs` (신규) | `GetRandomQuote()` — `famous.json` EmbeddedResource 로드, 앱 생애 동안 한 번만 파싱, 랜덤 반환 | | `Services/WorktimeReminderService.cs` (신규) | `SessionTrackingService`로부터 잠금 해제 이벤트를 구독하여 누적 사용시간 계산. 설정한 간격(30~240분) 이상 경과 시 `ReminderPopupWindow` 표시. `enabled` 설정이 꺼져 있으면 즉시 비활성 | | `Views/ReminderPopupWindow.xaml/.cs` (신규) | 잠금 해제 팝업 — 사용 시간·격려 문구·명언 표시. 설정한 화면 모서리(4방향)에 위치. `SetNoActivate()` P/Invoke로 포커스 비활성 상태 유지. 설정한 초 후 자동 닫힘 | | `Models/AppSettings.cs` | `ScreenCaptureSettings` 중첩 클래스 추가 (`Prefix`, `SaveToFile`, `SavePath`). `ReminderSettings` 중첩 클래스 추가 (`Enabled`, `Position`, `IntervalMinutes`, `AutoDismissSeconds`) | | `Views/SettingsWindow.xaml/.cs` | 캡처 탭 추가 — `cap` 프리픽스 TextBox, 파일 저장 토글, 저장 경로 TextBox+폴더 선택 버튼. 알림 탭 추가 — 활성화 토글, 위치 ComboBox(4방향), 간격 ComboBox(30/60/120/240분), 자동 닫힘 ComboBox(5/10/15/20/30초) | | `ViewModels/SettingsViewModel.cs` | `CapPrefix`, `SaveToFile`, `SavePath`, `ReminderEnabled`, `ReminderPosition`, `ReminderIntervalMinutes`, `ReminderAutoDismissSeconds` 프로퍼티 추가 | | `Handlers/ScreenCaptureHandler.cs` | `Prefix` 프로퍼티를 `settings.ScreenCapture.Prefix` 런타임 값으로 교체. 캡처 성공 시 `settings.ScreenCapture.SaveToFile`이 true면 `SavePath`(빈 값이면 기본 경로)에 PNG 파일 저장 | | `App.xaml.cs` | `WorktimeReminderService` 초기화 + `SessionTrackingService`와 연결. `OnExit()`에 `_worktimeReminder?.Dispose()` 추가 | | `Themes/*.xaml` (9개 파일) | 각 테마에 `WindowCornerRadius`·`ItemCornerRadius` `CornerRadius` 리소스 추가 (테마별 고유 값 적용) | | `Views/LauncherWindow.xaml` | 창 최상위 `Border.CornerRadius` → `{DynamicResource WindowCornerRadius}`. 항목 `ControlTemplate Border.CornerRadius` → `{DynamicResource ItemCornerRadius}` | | `Views/LauncherWindow.xaml.cs` | `BuildCustomDictionary()`에 `WindowCornerRadius`·`ItemCornerRadius` 기본값(20, 10) 추가 | | `Views/TrayContextMenu.cs` | `DarkTrayRenderer`/`DarkColorTable` → `ModernTrayRenderer`/`ModernColorTable` 전면 재작성. WPF `Application.Current.Resources`에서 `LauncherBackground`·`AccentColor`·`PrimaryText` 등을 읽어 테마 색상 반영. `SetWindowRgn` P/Invoke로 메뉴 창 모서리 라운딩. 시작 시 자동실행 항목 글리프 → 전구(`\uE82F`), 활성 시 앰버 색상(`#FFB300`) + 후광 효과. `OnRenderItemCheck` 빈 override로 기본 체크마크 억제 | | `Themes/Symbols.cs` | `ReminderBell = "\uEA8F"` (벨 아이콘) + `Lightbulb = "\uE82F"` (전구 아이콘) 추가 | | `Handlers/HelpHandler.cs` | `cap` 항목: 프리픽스 변경 가능·파일 저장 경로 설명 추가. `info` 항목: 커맨드 표시 `"info · *"`, `*` 단축키 설명 추가. 신규 `알림` 카테고리 항목 추가 (잠금 해제 사용시간 알림) | **WorktimeReminderService 동작 흐름**: ``` SessionTrackingService.Unlocked 이벤트 → WorktimeReminderService.OnUnlocked() → 설정 disabled? → 무시 → 마지막 알림 이후 경과 시간 < IntervalMinutes? → 무시 → ReminderPopupWindow(사용시간, 명언) 표시 (Dispatcher.Invoke) → _lastReminderTime 갱신 ``` **트레이 메뉴 `ThemeColor()` 헬퍼**: ```csharp private static Color ThemeColor(string key, Color fallback) { try { if (Application.Current?.Resources[key] is System.Windows.Media.SolidColorBrush b) return Color.FromArgb(b.Color.A, b.Color.R, b.Color.G, b.Color.B); } catch { } return fallback; } ``` WPF ResourceDictionary를 WinForms GDI 렌더러에서 안전하게 읽기 위해 try/catch로 감쌉니다. **빌드 검증**: `dotnet build` — **0 errors, 0 warnings** 확인 ### v0.9 3차 (보안 강화 + 글로벌 캡처 단축키 + 영역 미세조정) | 파일 | 변경 내용 | |------|----------| | `Services/ClipboardHistoryService.cs` | 클립보드 히스토리 저장을 **DPAPI 암호화**로 전환. `clipboard_history.json`(평문) → `clipboard_history.dat`(DPAPI). 구버전 평문 파일 자동 마이그레이션 + 원본 삭제. `DataProtectionScope.CurrentUser` — 현재 Windows 사용자 계정에서만 복호화 가능 | | `AxCommander.csproj` | `System.Security.Cryptography.ProtectedData 8.0.0` NuGet 패키지 추가 (로컬 전용, 네트워크 통신 없음) | | `Models/AppSettings.cs` | `ScreenCaptureSettings`에서 `SaveToFile`, `SavePath` 완전 제거 (보안 정책). `GlobalHotkeyEnabled`, `GlobalHotkey`, `GlobalHotkeyMode`, `ScrollDelayMs` 추가. `CustomThemeColors`에 `WindowCornerRadius`, `ItemCornerRadius` 추가 | | `Handlers/ScreenCaptureHandler.cs` | 파일 저장 로직(`ShouldSave`, `GetSaveDir`, `bmp.Save()`) 전면 제거 — 캡처 결과는 **클립보드에만 복사**. `CaptureDirectAsync(mode)` public 메서드 추가 (글로벌 단축키용). 스크롤 딜레이 하드코딩 120ms → `ScrollDelayMs` 설정값 사용 | | `Core/InputListener.cs` | `_captureHotkey` + `CaptureHotkeyTriggered` 이벤트 추가. `UpdateCaptureHotkey(string, bool)` 메서드로 캡처 단축키 동적 등록/해제 | | `Core/HotkeyParser.cs` | `PrintScreen`(0x2C), `Pause`(0x13), `ScrollLock`(0x91) 키 추가 | | `App.xaml.cs` | `OnCaptureHotkeyTriggered` 핸들러 추가 — 런처 없이 `CaptureDirectAsync` 직접 호출. 설정 저장 시 캡처 단축키 갱신 | | `ViewModels/SettingsViewModel.cs` | `CapGlobalHotkeyEnabled`, `CapGlobalHotkey`, `CapGlobalMode`, `CapScrollDelayMs/Str`, `CustomWindowCornerRadius`, `CustomItemCornerRadius` 프로퍼티 + Load/Save | | `Views/SettingsWindow.xaml` | 캡처 탭: 파일 저장 UI 전면 제거, 글로벌 단축키 섹션 추가 (활성 토글·키 레코더·모드 선택·기본값 복원), 스크롤 딜레이 ComboBox. 색상 편집 탭: "모양 (모서리 라운딩)" 섹션 + 슬라이더 2개 (창/항목) | | `Views/SettingsWindow.xaml.cs` | `CapHotkeyRecorder_PreviewKeyDown` 키 녹화 핸들러, `ResetCapGlobalHotkey_Click` 추가 | | `Views/LauncherWindow.xaml.cs` | `BuildCustomDictionary()`가 커스텀 `WindowCornerRadius`/`ItemCornerRadius` 설정값 적용 (기존 하드코딩 20/10 → 사용자 값) | | `Views/LauncherWindow.xaml` | 액션 breadcrumb 바 하드코딩 `#4B5EFC` → `{DynamicResource AccentColor}` 교체 | | `Views/RegionSelectWindow.xaml.cs` | `_endPoint` 필드 추가, 드래그 종료 후 화살표 키(1px/Shift 10px) 미세조정 + Enter 확정 지원 | | `Views/TrayContextMenu.cs` | `SetWindowRgn` 실패 시 `DeleteObject(rgn)` 호출 → GDI 핸들 누수 수정 | | `Handlers/HelpHandler.cs` | `_entries.Length - 6` 하드코딩 → `_entries.Count(e => e.Category != "키보드")` 동적 계산. `cap` 항목 설명에 글로벌 단축키 언급 추가 | | `Views/ReminderPopupWindow.xaml.cs` | `GetWindowLong`/`SetWindowLong` → `GetWindowLongPtr`/`SetWindowLongPtr` 64비트 안전 교체. 타이머 Tick 핸들러 해제. Esc 키 닫기 지원 | | `Services/WorktimeReminderService.cs` | `lock(_lock)` 스레드 동기화 추가 (SessionSwitch 백그라운드 스레드 ↔ UI 스레드 레이스 컨디션 해소). `IntervalMinutes` 최소값 보호 (`Math.Max(1, ...)`) | **보안 정책 변경**: - 캡처: 파일 저장 기능 코드에서 완전 제거. 설정 UI에도 없음. 클립보드에만 복사. - 클립보드 히스토리: DPAPI `DataProtectionScope.CurrentUser`로 암호화 저장. 파일 확장자 `.json` → `.dat`. 다른 사용자/PC에서 열 수 없음. - 통계(`stats/*.json`): 민감 데이터 아님, 암호화 미적용. **빌드 검증**: `dotnet build` — **0 errors, 0 warnings** 확인 ### v0.9 → v1.0 (정식 릴리스 — 유틸리티 8종 + 스포이드 + 서비스 관리) | 파일 | 변경 내용 | |------|----------| | `Handlers/ColorPickHandler.cs` (신규) | `pick` 프리픽스. 전체 화면 스포이드 모드(`EyeDropperWindow`) → 클릭 지점 색상 HEX 코드 추출 → 반투명 결과 창(`ColorPickResultWindow`) 5초 표시 → 클립보드 복사 | | `Views/EyeDropperWindow.xaml/.cs` (신규) | 전체 화면 투명 오버레이. 마우스 따라다니는 돋보기 원 + 실시간 HEX 코드 레이블. `GetPixel` P/Invoke로 화면 픽셀 색상 읽기. 좌클릭 확정, 우클릭/Esc 취소 | | `Views/ColorPickResultWindow.xaml/.cs` (신규) | 반투명 다크 팝업. 색상 미리보기 원 + HEX/RGB 텍스트 + 자동 닫힘 5초 타이머 | | `Handlers/DateCalcHandler.cs` (신규) | `date` 프리픽스. `+30d`/`-100d` 가감, D-day 계산, Unix timestamp ↔ 날짜 변환, 요일·ISO 주차, `date unix` 현재 타임스탬프 | | `Handlers/ServiceHandler.cs` (신규) | `svc` 프리픽스. `ServiceController` API로 Windows 서비스 검색·상태 조회. `svc start/stop/restart [이름]`으로 제어(관리자 권한 UAC). `svc restart clipboard` → AX 클립보드 히스토리 서비스 강제 재시작 | | `Services/ClipboardHistoryService.cs` | `Reinitialize()` 메서드 추가 — Dispose 후 내부 상태 초기화 + 클립보드 모니터링 재개 | | `AxCommander.csproj` | `System.ServiceProcess.ServiceController 8.0.1` NuGet 패키지 추가 (로컬 전용) | | `Handlers/TextStatsHandler.cs` (신규) | `stats` 프리픽스. 클립보드 텍스트 글자·단어·줄 수, UTF-8 바이트, 키워드 빈도(Top 5), 읽기 시간 추정, 특정 키워드 검색 | | `Handlers/FavoriteHandler.cs` (신규) | `fav` 프리픽스. 자주 쓰는 파일·폴더 경로를 `favorites.json`에 저장, `fav add/del` 서브커맨드 | | `Handlers/RenameHandler.cs` (신규) | `rename` 프리픽스. 폴더\패턴 파일 목록, 템플릿 변수 `{n}`순번 `{date}`날짜 `{orig}`원본명, 미리보기 후 실행 | | `Handlers/MonitorHandler.cs` (신규) | `monitor` 프리픽스. CPU·메모리(`GlobalMemoryStatusEx`)·디스크·가동시간·Top 5 프로세스 | | `Handlers/ScaffoldHandler.cs` (신규) | `scaffold` 프리픽스. 내장 5개 + 사용자 JSON 템플릿 | | `Themes/Symbols.cs` | EyeDropper·DateIcon·ServiceIcon + TextStats·Favorite·RenameIcon·MonitorIcon·ScaffoldIcon 8개 심볼 추가 | | `Handlers/ClipboardPipeHandler.cs` (신규) | `pipe` 프리픽스. 19종 필터를 `>` 체이닝 — upper/lower/trim/sort/unique/reverse/number/quote/b64e/b64d/urle/urld/md/lines/count/csv/tab/trimall 등 | | `Handlers/JournalHandler.cs` (신규) | `journal` 프리픽스. `UsageStatisticsService` 데이터 기반 업무 일지 마크다운 자동 생성 (활성 시간, 런처 호출, 명령어 사용 순위) | | `Handlers/RoutineHandler.cs` (신규) | `routine` 프리픽스. `routines.json` + 내장 2개(morning/endofday). 앱·폴더·URL·명령을 순서대로 일괄 실행 | | `Handlers/BatchTextHandler.cs` (신규) | `batch` 프리픽스. 클립보드 각 줄에 동시 변환 — prefix/suffix/wrap/number/sort/unique/trim/replace/csv/split/indent 등 14종 | | `Handlers/DiffHandler.cs` (신규) | `diff` 프리픽스. 클립보드 최근 2개 비교 + 파일 2개 경로 비교 + **파일 선택 다이얼로그(OpenFileDialog)** 지원 | | `Handlers/WindowSwitchHandler.cs` (신규) | `win` 프리픽스. `EnumWindows` P/Invoke로 열린 창 목록 조회·검색, `SetForegroundWindow`로 즉시 전환. 최소화 창 자동 복원 | | `Handlers/HelpHandler.cs` | 14개 신규 핸들러 도움말 항목 추가 | | `Views/HelpDetailWindow.xaml/.cs` | **카테고리별 페이지네이션 재설계** — 상단 카테고리 탭 바 + ← → 키 페이지 전환 + 이전/다음 버튼 + 페이지 인디케이터 | | `App.xaml.cs` | 14개 핸들러 등록 + `DispatcherUnhandledException` 전역 예외 핸들러 + `LoadAppIcon` 내장 리소스 폴백 | | `Services/ClipboardHistoryService.cs` | `Reinitialize()` 메서드 추가 (ServiceHandler의 클립보드 강제 재시작용) | | `AxCommander.csproj` | `IncludeNativeLibrariesForSelfExtract=true` (단일 EXE 배포), `System.ServiceProcess.ServiceController 8.0.1` 추가, mascot/icon 내장 리소스 | **배포** (`build.bat` 더블클릭으로 3종 자동 빌드): | 파일 | 크기 | 용도 | |------|------|------| | `dist\AxCommander\` | 163MB (폴더) | 본체 EXE + DLL — 폴더째 복사해도 실행 가능 | | `dist\AxCommander_Setup.exe` | ~136MB | 오프라인 인스톨러 (본체+런타임 모두 ZIP 내장, 인터넷 불필요) | | `dist\AxCommander_Setup_Online.exe` | **~1MB** | 온라인 인스톨러 (.NET Framework 4.8 기반, 본체(~2MB) ZIP 내장 + .NET 8 Runtime 인터넷 자동 설치) | 인스톨러 기능: 설치 경로 선택 · 바탕화면 바로가기 · 시작 메뉴 · 자동 실행 · 프로그램 추가/제거 · 기존 설치 감지 → 업그레이드 · 제거 **v1.0 최종 수정 (디자인/오류 검수)**: | 파일 | 수정 | |------|------| | `Views/SettingsWindow.xaml` | `{StaticResource ModernComboBox}` 참조 2곳 제거 — 해당 스타일 미정의로 설정 창 XamlParseException 크래시 수정 | | `Views/TrayContextMenu.cs` | `MakeItem()`에 1×1 투명 더미 `Image` 설정 — `OnRenderItemImage` 콜백이 호출되지 않아 글리프 아이콘 미표시 문제 수정. `OnRenderItemCheck`에서도 `DrawGlyph()` 호출. 전구 꺼짐 색상 `#A0A08C` → `#78788C` 진한 회색으로 변경 | | `App.xaml.cs` | 자동실행 `autoStartItem`에 `Image = new Bitmap(1,1)` 추가 | | `Views/HelpDetailWindow.xaml.cs` | `NavigateToPage()` 빈 카테고리 방어 코드 | | `Handlers/WindowSwitchHandler.cs` | 자기 프로세스 제외를 하드코딩 타이틀 대신 `Process.GetCurrentProcess().ProcessName` 비교로 변경 | **v1.0 UI/UX 최종 수정**: | 파일 | 수정 | |------|------| | `Views/SettingsWindow.xaml` | 사이드바 `TabPanel`을 `ScrollViewer`로 감싸 탭 10개+ 스크롤 지원. `ModernComboBox` 미정의 참조 제거 (XamlParseException 수정) | | `Views/TrayContextMenu.cs` | `MakeItem()`에 1×1 더미 Image 설정 → 글리프 아이콘 표시. `DrawLightbulbGlow`를 `PathGradientBrush` 원형 그라데이션으로 교체 (빛 대칭). `OnRenderItemCheck`에서도 `DrawGlyph` 호출 | | `Views/HelpDetailWindow.xaml` | 카테고리 탭 바 `ScrollViewer` → `WrapPanel` (스크롤 제거, 모두 표시). 창 크기 880×680 | | `Views/HelpDetailWindow.xaml.cs` | 프로그램 개요 3개 항목(설명/사용법/저장경로) 자동 삽입. `NavigateToPage()` 빈 카테고리 방어 코드 | | `Handlers/HelpHandler.cs` | `static _entries` → `_baseEntries` + `GetEntries()` 동적 메서드. 설정에서 변경한 캡처 프리픽스·글로벌 핫키 실시간 반영 | | `Views/AboutWindow.xaml/.cs` | 상단 원형 → 앱 아이콘(icon.ico) 표시. 마스코트는 숨김 상태로 로드 → 사용자 클릭 시 오버레이만. 조직명 행에서 이름/직급 제거 (하단에만 표시). `TryLoadAppIcon()` + `TryLoadMascot()` 분리 | | `Services/LogService.cs` | `PurgeOldLogs()` 추가 — 14일 초과 로그 자동 삭제 (앱 세션 당 1회) | | `App.xaml.cs` | `DispatcherUnhandledException` 전역 예외 핸들러. `LoadAppIcon` pack:// 내장 리소스 폴백. `HelpHandler(settings)` 주입 | **v1.0 추가 기능**: | 파일 | 변경 | |------|------| | `Services/FaviconService.cs` (신규) | URL 별칭 항목에 사이트 favicon 표시. Google Favicon API → 디스크 캐시(`%APPDATA%\AxCommander\favicons\`) → `IconPath`에 경로 전달 | | `Handlers/AliasHandler.cs` | `UrlAliasHandler.GetFaviconPath()` — favicon 캐시 경로 조회 + 백그라운드 다운로드 | | `Views/LauncherWindow.xaml` | 아이템 아이콘 영역에 `IconPath` 이미지 표시 지원 (`NullToCollapsedConverter`로 심볼/이미지 자동 전환) | | `Themes/Converters.cs` | `NullToCollapsedConverter` 추가 | | `App.xaml` | `NullToCollapsedConverter` 글로벌 등록 | | `Handlers/WebSearchHandler.cs` | `?ni`(네이버 이미지), `?gi`(구글 이미지) 엔진 추가 (총 10개) | | `Handlers/HelpHandler.cs` | 웹 검색 항목에 10개 엔진 전체 목록 표시 | | `ViewModels/SettingsViewModel.cs` | `ValidateBeforeSave()` — 예약어/프리픽스 충돌 감지. 충돌 시 `MessageBox` 알림 + 저장 거부 | | `Views/SettingsWindow.xaml/.cs` | 하단 바에 **내보내기/불러오기** 버튼 추가 (`.axsettings` 파일) | **v1.0 아이콘 교체 + 최종 디자인 검수**: | 파일 | 수정 | |------|------| | `Assets/icon.ico` | 다이아몬드 픽셀 보석 컷 아이콘으로 교체 (Blue/Green/Red/Green 4색, 흰색 facet 선, 7크기 16~256px) | | `Assets/diamond_pixel.svg` | 아이콘 SVG 원본 (참고용) | | `tools/IconGenerator/` | 아이콘 생성 콘솔 앱 (.NET 8 WinForms, `System.Drawing`으로 보석 다이아몬드 렌더링 → ICO 출력) | | `Views/AboutWindow.xaml` | 버전 텍스트 폴백 `"v1.0"` → `"v1.0.1"` (csproj `Version=1.0.1`과 일치) | | `Views/SettingsWindow.xaml` | 사이드바 `ScrollViewer`에서 `DockPanel.Dock="Top"` 제거 → 마지막 자식으로 남은 공간 채워 스크롤 정상 동작 | **최종 검수 결과**: - 전체 빌드 (3개 프로젝트): **0 errors, 0 warnings** - 버전 일치: csproj `1.0.1` = AboutWindow `v1.0.1` ✓ - CornerRadius DynamicResource 바인딩: 정상 ✓ - 사이드바 ScrollViewer: 수정 완료 (DockPanel.Dock 제거) ✓ - 전구 글로우: PathGradientBrush 중심 대칭 확인 ✓ - HelpHandler 항목: 전체 정확성 확인 ✓ - 아이콘 로딩: pack:// 리소스 + 파일시스템 폴백 정상 ✓ --- ## 🚧 개발 예정 — `!` 예약어 LLM 대화 기능 > **상태**: 구현 완료 (핵심 기능) > **버전**: v1.0.5 > **마지막 업데이트**: 2026-03-28 ### 개요 `!` 예약어를 입력하면 LLM(대규모 언어 모델) 서비스에 질의를 보내고 응답을 받아 표시하는 **AI 대화 기능**. 런처 입력창에서 `!질문내용` 또는 `! 질문내용`으로 시작하면 전용 대화 창이 열리며, Claude Code / Gemini 스타일의 대화 인터페이스를 제공한다. ### 입력 방식 | 입력 | 동작 | |------|------| | `!안녕하세요` | `!` 제거 후 "안녕하세요"를 LLM에 전송 | | `! 안녕하세요` | `!`와 텍스트 사이 공백 제거 후 "안녕하세요"를 LLM에 전송 | | `!` (단독) | 대화 창만 열기 (빈 상태) | ### 대화 창 (ChatWindow) 설계 **레이아웃: 2패널 구조** ``` ┌──────────────────────────────────────────────────┐ │ [≡] AX Commander — AI 대화 [_][□][✕] │ ├──────────┬───────────────────────────────────────┤ │ [+ 새 대화] │ │ │ [🔍 검색] │ 대화 메시지 영역 │ │ │ (마크다운 렌더링) │ │ ── 고정 ── │ │ │ 📌 서버설정 │ │ │ 📌 코드리뷰 │ │ │ │ │ │ ── 오늘 ── │ │ │ API 오류.. │ │ │ 배포 방법.. │ │ │ │ │ │ ── 어제 ── │ ┌────────────────────────────────┐ │ │ 회의록 정리 │ │ 메시지를 입력하세요... [▶] │ │ │ │ └────────────────────────────────┘ │ ├──────────┴───────────────────────────────────────┤ │ Ollama ▾ │ llama3:8b ▾ │ ● 연결됨 │ 토큰: 1.2k │ └──────────────────────────────────────────────────┘ ``` **좌측 패널 — 대화 목록**: - **새 대화** 버튼 (Ctrl+N) - **검색** — 대화 제목·내용 필터 - **고정 대화** — 핀 고정 항목이 최상단에 위치 (우클릭 > 고정/해제) - **날짜별 그룹** — 오늘 / 어제 / 이번 주 / 이전 순서 - **대화 삭제** — 우클릭 > 삭제 (확인 다이얼로그) **우측 패널 — 대화 영역**: - 메시지 버블 (사용자: 우측 / AI: 좌측) - **마크다운 렌더링** — 코드 블록, 목록, 볼드 등 기본 지원 - **코드 블록 복사** 버튼 - **스트리밍 응답** — SSE/스트림 지원 시 한 글자씩 표시 - **재생성** 버튼 — 마지막 응답을 다시 요청 - **복사** 버튼 — 개별 메시지 클립보드 복사 **창 기능**: - 창 크기 자유 조절 (가로·세로) - 전체 화면 / 최소화 / 최대화 지원 - 테마 연동 (DynamicResource 사용, 런처와 동일한 8종 테마) - 독립 창 (런처와 별도로 열림, 항상 위 선택 가능) ### 대화 저장 — 로컬 전용 **핵심**: LLM API(Ollama, vLLM, Gemini)는 모두 **무상태(stateless)**. 서버 측에서 이전 대화를 기억하지 않음. 따라서 **모든 대화는 로컬에 저장**하고, API 호출 시 이전 대화 맥락을 함께 전송해야 함. ``` %APPDATA%/AxCommander/ conversations/ {uuid}.json ← 개별 대화 파일 conversation-index.json ← 제목·날짜·고정 여부 인덱스 ``` **대화 파일 구조 (예시)**: ```json { "id": "a1b2c3d4-...", "title": "서버 설정 방법", "createdAt": "2026-03-27T10:00:00", "updatedAt": "2026-03-27T10:05:00", "pinned": true, "provider": "ollama", "model": "llama3:8b", "messages": [ { "role": "user", "content": "nginx 설정 방법 알려줘", "timestamp": "..." }, { "role": "assistant", "content": "nginx 설정은...", "timestamp": "..." } ] } ``` **보관 정책**: - 기본 보관 기간: **30일** (설정에서 변경 가능: 7일 / 30일 / 90일 / 무제한) - 고정(📌)된 대화는 보관 기간과 무관하게 **영구 보관** - 만료된 대화는 앱 시작 시 자동 정리 **대화 관리 동작**: - **보관함으로 이동**: 우클릭 > "보관함으로 이동" — 보관 기간이 지나도 자동 삭제되지 않음 (수동 삭제만 가능) - **삭제**: 우클릭 > "삭제" — 확인 대화상자("이 대화를 정말 삭제하시겠습니까? 이 작업은 되돌릴 수 없습니다.") 표시 후 진행 - **보관함 탭**: 좌측 패널 하단에 "보관함" 탭 별도 표시, 보관된 대화 목록 열람 가능 - 보관함 내 대화도 삭제 가능 (동일한 확인 절차) **API 호출 시 컨텍스트 전송**: - 전체 대화 이력을 `messages` 배열로 전송 (OpenAI 호환 형식) - 토큰 한도 초과 시 오래된 메시지부터 자동 잘라냄 (sliding window) - 시스템 프롬프트는 설정에서 커스터마이징 가능 ### 지원 LLM 서비스 (4종) 설정 창에서 서비스별 모델 등록 후, 대화 창 입력 바에서 모델 선택 Popup으로 전환 가능. | 서비스 | 연결 방식 | 설정값 | |--------|----------|--------| | **Ollama** | 로컬 HTTP (`http://localhost:11434`) | 엔드포인트 URL, 모델명 | | **vLLM** | HTTP API (OpenAI 호환) | 엔드포인트 URL, 모델명, API 키 | | **Gemini API** | Google REST API | API 키, 모델명 (gemini-2.0-flash 등) | | **Claude API** | Anthropic REST API | API 키, 모델명 (claude-sonnet-4-20250514 등) | ### API 키 암호화 체계 **암호화 모드 전환**: `settings.json` → `llm.encryptionEnabled` 설정으로 제어 | 모드 | `encryptionEnabled` | 설명 | 용도 | |------|---------------------|------|------| | **비암호화 (기본)** | `false` | API 키·모델명을 평문으로 저장/표시 | 내부 개발 배포, 테스트 | | **암호화** | `true` | AES-256-CBC(앱 공용 키)로 암호화 저장 | 운영 배포 | **비암호화 모드** (현재 기본값): - API 키, 모델명이 settings.json에 **평문**으로 저장됨 - 설정 창에서 입력한 값이 그대로 보이고 저장됨 - 내부 개발자 배포 시 빠른 설정에 적합 **암호화 모드** (`encryptionEnabled: true`로 전환 시): - 앱 내장 고정 키 + AES-256-CBC로 암호화 - PBKDF2(SHA-256, 100,000회 반복)로 256-bit 키 파생 - 관리자 PC에서 암호화한 값이 모든 PC에서 동일하게 복호화됨 - AxKeyEncryptor 도구로 사전 암호화 가능 - 설정 창에서 이미 저장된 키는 "(저장됨)"으로 표시 **운영 배포 시 암호화 전환 방법**: 1. `settings.json`에서 `"encryptionEnabled": true` 설정 2. 기존 평문 키/모델명은 앱 재시작 시 설정 저장하면 자동으로 암호화됨 3. 또는 AxKeyEncryptor 도구로 미리 암호화한 값 배포 **하위 호환**: 암호화 모드에서 복호화 실패 시 평문으로 간주하여 동작 (마이그레이션 안전) > **대화 내역 암호화**는 `encryptionEnabled`와 별개로 항상 **PC별 AES-256-GCM + DPAPI**로 암호화됩니다. 이는 대화 프라이버시 보호를 위한 별도 계층입니다. ### 설정 UI (SettingsWindow — 새 탭 "AI 대화") | 설정 항목 | 타입 | 기본값 | |-----------|------|--------| | LLM 서비스 선택 | ComboBox (Ollama/vLLM/Gemini) | Ollama | | 엔드포인트 URL | TextBox | `http://localhost:11434` | | 모델명 | TextBox / ComboBox | `llama3:8b` | | API 키 (암호화) | PasswordBox | (없음) | | 시스템 프롬프트 | TextBox (여러 줄) | "당신은 유능한 AI 비서입니다." | | 대화 보관 기간 | ComboBox | 30일 | | 최대 컨텍스트 토큰 | Slider / TextBox | 4096 | | 스트리밍 응답 | ToggleSwitch | ON | | 연결 테스트 | Button | "연결 테스트" | ### 구현 파일 구조 (예상) ``` src/AxCommander/ Models/ ChatMessage.cs ← 메시지 모델 (role, content, timestamp) Conversation.cs ← 대화 모델 (id, title, messages, pinned, ...) LlmSettings.cs ← LLM 설정 모델 Services/ LlmService.cs ← LLM API 추상화 (Ollama/vLLM/Gemini 통합) OllamaClient.cs ← Ollama HTTP 클라이언트 VllmClient.cs ← vLLM (OpenAI 호환) 클라이언트 GeminiClient.cs ← Gemini REST 클라이언트 ConversationStore.cs ← 대화 로컬 저장/로드/삭제/만료 처리 KeyEncryptionService.cs ← API 키 암호화/복호화 ViewModels/ ChatViewModel.cs ← 대화 창 ViewModel Views/ ChatWindow.xaml / .cs ← 전용 대화 창 (2패널) Handlers/ LlmChatHandler.cs ← ! 예약어 핸들러 (런처에서 ChatWindow 열기) src/AxKeyEncryptor/ ← 별도 프로젝트 (암호화 도구) Program.cs ← 콘솔 또는 간단한 WinForms GUI ``` ### 단계별 구현 현황 | 단계 | 내용 | 상태 | |------|------|------| | **1단계** | Ollama 연결 + 기본 대화 창 (단일 대화) | ✅ 완료 | | **2단계** | 대화 목록 + 저장/로드 + 고정/삭제/분류/이름변경 | ✅ 완료 | | **3단계** | vLLM / Gemini / Claude 연결 추가 + 설정 탭 | ✅ 완료 | | **4단계** | 스트리밍 응답 + 마크다운/코드 구문 강조 렌더링 | ✅ 완료 | | **5단계** | 프롬프트 카드 + 사용자 프롬프트 템플릿 | ✅ 완료 | | **6단계** | 토큰 사용량(k/m 단위) + 응답 소요시간 표시 | ✅ 완료 | | **7단계** | 타이핑 효과 + 피드백(좋아요/싫어요) 영속성 | ✅ 완료 | | **8단계** | 커스텀 Popup 메뉴 통일 (ContextMenu 제거) | ✅ 완료 | | **9단계** | 지연 캡처 (Shift+Enter 3/5/10초 타이머) | ✅ 완료 | | **향후** | 멀티 에이전트, 내보내기, Cowork 탭 | 계획 중 | --- ## 알려진 제한사항 및 향후 개선 | 항목 | 현황 | 개선 방향 | |------|------|----------| | 클립보드 히스토리 이미지 | 텍스트만 지원 | `IDataObject` 이미지 타입 추가 | | 클립보드 병합 항목 시각 표시 | 힌트 바로만 개수 표시 | 리스트 항목에 체크마크 아이콘 추가 | | 스니펫 글로벌 확장 | 런처에서만 동작 | `WH_KEYBOARD_LL` 백그라운드 확장 | | 인덱스 경로 | Desktop + Start Menu | Program Files 등 추가 옵션 | | 보안 제외 패턴 편집 | 읽기 전용 표시 | 설정 UI에서 패턴 추가/삭제 지원 | ### 향후 개선 — ONNX 임베딩 코드 검색 (사양 확보 시) 현재 코드 검색은 **TF-IDF + SQLite 영속 인덱스** 방식을 사용합니다 (v1.5.x). 사내 PC 사양이 확보되면 ONNX 로컬 임베딩으로 업그레이드하여 시맨틱 검색 품질을 크게 개선할 수 있습니다. #### 현재 구현 (TF-IDF + SQLite) - **방식**: 키워드 기반 TF-IDF 코사인 유사도 + 바이그램 + 스톱워드 제거 - **저장**: `%APPDATA%\AxCopilot\index\{folderHash}.db` (SQLite) - **장점**: 외부 의존 없음, 배포 +3MB, 저사양 PC에서도 동작 - **한계**: 동의어/의미 유사성 미지원 ("사용자 인증" ↔ "로그인 검증" 매칭 불가) #### ONNX 임베딩 업그레이드 계획 | 항목 | 내용 | |------|------| | **NuGet** | `Microsoft.ML.OnnxRuntime` 1.17+ (CPU 전용) | | **모델** | `all-MiniLM-L6-v2` (90MB, 384차원) 또는 `bge-small-en` (130MB) | | **벡터 DB** | 기존 SQLite에 BLOB 컬럼 추가 (384×float32 = 1.5KB/청크) | | **배포 크기** | 현재 ~20MB → ~160MB (+140MB) | | **최소 사양** | RAM 4GB 이상, CPU AVX2 지원 권장 | #### 업그레이드 절차 (개발자 가이드) 1. **NuGet 추가**: ```bash dotnet add src/AxCopilot/AxCopilot.csproj package Microsoft.ML.OnnxRuntime --version 1.17.0 ``` 2. **모델 배치**: `Assets/models/all-MiniLM-L6-v2.onnx` (빌드 시 복사) 3. **CodeIndexService 수정**: ```csharp // 인덱싱 시 청크별 임베딩 벡터 생성 var embedding = _onnxSession.Run(new[] { tokenizedInput }); // SQLite chunks 테이블에 embedding BLOB 컬럼 추가 // 검색 시 코사인 유사도를 벡터 간 계산 ``` 4. **SQLite 스키마 확장**: ```sql ALTER TABLE chunks ADD COLUMN embedding BLOB; -- 검색 시: SELECT ... ORDER BY cosine_similarity(query_vec, embedding) DESC ``` 5. **설정 추가**: `AppSettings.Llm.Code.UseEmbeddingSearch` (bool, default false) - false: 기존 TF-IDF 사용 (저사양 호환) - true: ONNX 임베딩 사용 (고품질) 6. **폴백**: ONNX 로드 실패 시 자동으로 TF-IDF 모드로 전환 > **참고**: 사내 PC 사양(CPU, RAM)이 낮아 ONNX 런타임 로드 시간(3~5초)과 > 인덱싱 시간이 길어질 수 있음. 반드시 사양 확인 후 도입 결정. ### 미지원 — 개발 계획 없음 아래 기능은 Alfred 비교에서 언급된 바 있으나 **AX Commander에 불필요한 기능으로 확정**되어 구현하지 않습니다. 향후 Alfred 비교 시에도 이 항목들은 비교 대상에서 제외합니다. | 기능 | 이유 | |------|------| | 워크플로우 자동화 체인 | 사내 업무 흐름상 불필요. 배치 명령(`>`)으로 충분히 대체 가능 | | 연락처 검색 | MAPI/vCard 연동 복잡도 대비 사용 빈도 낮음 | | 사전 (Dictionary) | OS 내장 사전 및 브라우저 검색으로 충분히 대체 가능 | | QR코드 생성 | 업무 활용도 낮음, 외부 의존성 없는 구현 비용 대비 효용 낮음 | --- ## 개발 환경 - **IDE**: Visual Studio 2022 / JetBrains Rider / VS Code (C# Dev Kit) - **SDK**: .NET 8 SDK - **타겟**: `net8.0-windows`, `win-x64` - **UI 프레임워크**: WPF (`UseWPF=true`) + WinForms (`UseWindowsForms=true`, ColorDialog 사용) - **테스트**: xUnit 2.9.0, FluentAssertions 6.12.0 --- ## 경쟁 제품 기능 비교 AX Commander v1.0 기준으로 macOS Alfred 5, macOS Spotlight, Windows PowerToys Run과 비교합니다. | 기능 | AX Commander | Alfred 5 | Spotlight | PowerToys Run | |------|:---:|:---:|:---:|:---:| | 앱/파일 퍼지 검색 | O | O | O | O | | 한국어 초성 검색 | **O** | X | X | X | | 실행 빈도 학습 | O | O | O | O | | 계산기 + 수학 함수 | O | O | △ (기본) | O | | 단위 변환 | O | O | O | O | | 통화 변환 (실시간) | O | O | X | X | | 웹 검색 (다중 엔진) | O | O | O | O | | 클립보드 히스토리 | O | O (Powerpack) | X | X | | 클립보드 파이프라인 체이닝 | **O** | X | X | X | | 텍스트 일괄 처리 (batch) | **O** | X | X | X | | 텍스트 스니펫 + 자동 확장 | O | O (Powerpack) | X | X | | 파일 액션 서브메뉴 | O | O | X | X | | JSON 포맷/검증 | O | X | X | X | | 인코딩/해싱 (Base64, SHA) | O | X | X | X | | 색상 변환 (HEX/RGB/HSL) | O | X | X | X | | 스포이드 색상 추출 | **O** | X | X | X | | 포트/프로세스 조회 | O | X | X | X | | 환경변수 조회 | O | X | X | X | | 화면 캡처 (4모드) | O | X | △ (스크린샷) | X | | 글로벌 캡처 단축키 | O | X | O | X | | 스크롤 캡처 (자동 스티칭) | **O** | X | X | X | | 영역 캡처 키보드 미세조정 | **O** | X | X | X | | 창 스냅 레이아웃 | O | X | X | O | | 워크스페이스 저장/복원 | O | X | X | X | | 윈도우 스위처 (검색+전환) | **O** | X | X | O | | 시스템 명령 (잠금/절전/종료) | O | O | X | O | | 미디어 제어 | O | O | O | X | | 타이머/알람 | O | X | X | X | | 프로세스 종료 (kill) | O | X | X | O | | 서비스 관리 (svc) | **O** | X | X | X | | 날짜 계산/D-day/타임스탬프 | **O** | X | X | X | | 파일 비교 (diff) | **O** | X | X | X | | 파일 일괄 이름변경 | **O** | X | X | O | | 프로젝트 스캐폴딩 | **O** | X | X | X | | 즐겨찾기 관리 | O | X | X | X | | 업무 일지 자동 생성 | **O** | X | X | X | | 루틴 자동화 | **O** | △ (워크플로우) | X | X | | 시스템 리소스 모니터 | O | X | X | O | | 이모지 피커 | O | X | X | O | | 최근 파일 | O | O | O | X | | 빠른 메모 | O | X | X | X | | 앱 제거 | O | X | X | X | | 잠금 해제 사용시간 알림 | **O** | X | X | X | | 테마 (9종 + 커스텀 + 모양) | O | O | X | △ (제한) | | 다국어 (5개 언어) | O | O | O | O | | 플러그인 DLL 확장 | O | O | X | O | | DPAPI 클립보드 암호화 | **O** | X | X | X | | 단일 EXE 배포 | **O** | X | N/A | X | | 완전 오프라인 (외부 통신 없음) | **O** | △ | O | O | **O** = 지원, **△** = 부분 지원, **X** = 미지원, **굵은 O** = AX Commander 고유 기능 --- ## 새로운 핸들러/키워드 추가 방법 (개발자 가이드) ### 1단계: IActionHandler 구현 ```csharp // Handlers/MyNewHandler.cs using AxCommander.SDK; using AxCommander.Themes; namespace AxCommander.Handlers; public class MyNewHandler : IActionHandler { // 이 핸들러를 트리거하는 프리픽스 (null이면 퍼지 검색에 통합) public string? Prefix => "myprefix"; public PluginMetadata Metadata => new( "MyNew", "내 새로운 기능 — myprefix", "1.0", "AX"); public Task> GetItemsAsync(string query, CancellationToken ct) { // query: 프리픽스 이후의 입력 텍스트 // LauncherItem의 Data 필드에 실행 시 필요한 데이터를 담아 반환 return Task.FromResult>( [ new LauncherItem( "제목", "설명 · Enter로 실행", null, "실행 시 전달될 데이터", Symbol: Symbols.Info) ]); } public Task ExecuteAsync(LauncherItem item, CancellationToken ct) { // item.Data에서 데이터를 꺼내 실행 if (item.Data is string data) { // 작업 수행 } return Task.CompletedTask; } } ``` ### 2단계: 핸들러 등록 (App.xaml.cs) ```csharp // App.xaml.cs OnStartup() 내부, HelpHandler 위에 추가 commandResolver.RegisterHandler(new MyNewHandler()); ``` ### 3단계: 심볼 추가 (Symbols.cs) ```csharp // Themes/Symbols.cs public const string MyNewIcon = "\uE946"; // Segoe MDL2 Assets 유니코드 ``` 참고: [Segoe MDL2 Assets 아이콘 목록](https://learn.microsoft.com/en-us/windows/apps/design/style/segoe-ui-symbol-font) ### 4단계: 도움말 항목 추가 (HelpHandler.cs) `_entries` 배열에 항목 추가 (키보드 섹션 위에): ```csharp new("카테고리", "myprefix", "기능 제목", "기능 설명", "사용 예시", Symbols.MyNewIcon, "#HEX색상"), ``` ### 5단계: 설정이 필요한 경우 1. `Models/AppSettings.cs`에 설정 클래스 추가 2. `ViewModels/SettingsViewModel.cs`에 프로퍼티 추가 3. `Views/SettingsWindow.xaml`에 탭 또는 섹션 추가 ### 6단계: 외부 DLL 플러그인 외부 개발자는 `AxCommander.SDK` 프로젝트의 `IActionHandler`를 구현하는 DLL을 만들어 `settings.json`의 `plugins` 배열에 등록합니다: ```json "plugins": [ { "path": "C:\\Plugins\\MyPlugin.dll", "enabled": true } ] ``` 런타임에 `PluginHost`가 Assembly.LoadFrom()으로 로드하고 `IActionHandler` 구현체를 자동 검색하여 등록합니다. --- ## 사내 LLM / AI Agent 연동 가이드 (향후 확장) AX Commander는 사내 LLM 또는 AI Agent를 연동하여 **자연어 질의-응답** 기능을 추가할 수 있도록 설계되어 있습니다. ### 연동 시나리오 1. **사내 인트라넷 LLM API**: 별도 프리픽스(`ai` 또는 `?? `) 입력 → 사내 AI 서버에 질의 → 응답을 런처 결과로 표시 2. **키워드 없는 자동 감지**: 프리픽스가 없고 퍼지 검색 결과가 없을 때 → 자동으로 AI에 질의 폴백 3. **클립보드 AI 분석**: 클립보드 텍스트를 AI에 전달하여 요약/번역/교정 결과 반환 ### 구현 방법 #### 방법 A: 전용 핸들러 (권장) ```csharp // Handlers/AiQueryHandler.cs public class AiQueryHandler : IActionHandler { public string? Prefix => "ai"; // 또는 "??" 등 private readonly HttpClient _client; // 사내 인트라넷 전용 public AiQueryHandler(string intranetEndpoint) { _client = new HttpClient { BaseAddress = new Uri(intranetEndpoint) }; _client.Timeout = TimeSpan.FromSeconds(10); } public async Task> GetItemsAsync(string query, CancellationToken ct) { if (string.IsNullOrWhiteSpace(query)) return [new LauncherItem("AI에게 질문하세요", "사내 LLM에 질의합니다", null, null)]; try { // 사내 인트라넷 API 호출 (DEVELOPMENT.md 개발 원칙에 의거, // 사내 명시 허가된 엔드포인트만 호출 가능) var response = await _client.PostAsJsonAsync("/api/chat", new { prompt = query }, ct); var result = await response.Content.ReadAsStringAsync(ct); return [new LauncherItem( "AI 응답", result.Length > 200 ? result[..197] + "…" : result, null, result, Symbol: Symbols.Lightbulb)]; } catch (Exception ex) { return [new LauncherItem("AI 응답 실패", ex.Message, null, null, Symbol: Symbols.Error)]; } } public Task ExecuteAsync(LauncherItem item, CancellationToken ct) { if (item.Data is string text) Application.Current?.Dispatcher.Invoke(() => Clipboard.SetText(text)); return Task.CompletedTask; } } ``` #### 방법 B: CommandResolver 폴백 통합 `Core/CommandResolver.cs`의 `ResolveAsync` 메서드에서 퍼지 검색 결과가 0건일 때 AI 핸들러로 폴백: ```csharp // Core/CommandResolver.cs if (fuzzyResults.Count == 0 && _aiHandler != null) { return await _aiHandler.GetItemsAsync(input, ct); } ``` #### 방법 C: JSON 스킬 플러그인 (기존 인프라 활용) 기존 `JsonSkillLoader`가 이미 HTTP API 호출을 지원하므로, `.skill.json` 파일로 LLM API를 등록: ```json { "prefix": "ai", "name": "사내 AI 질의", "type": "http", "url": "https://intranet.company.com/api/llm", "method": "POST", "bodyTemplate": "{\"prompt\": \"{{query}}\"}", "responsePath": "data.answer" } ``` ### 보안 고려사항 | 항목 | 원칙 | |------|------| | 엔드포인트 | **사내 인트라넷 URL만 허용** — settings.json에 명시적 등록 필요 | | 타임아웃 | 최대 10초 (런처 UX 유지) | | 데이터 | 클립보드 내용을 AI에 전달할 때 보안 패턴 검사 선행 (기존 `excludePatterns` 활용) | | 인증 | Windows 인증(SSPI) 또는 사내 토큰 — `CredentialManager` (advapi32.dll, DPAPI) 사용 | | 로깅 | AI 질의 내용은 로그에 기록하지 않음 (민감 데이터 포함 가능) | ### 설정 UI 확장 설정 창에 **AI 탭**을 추가하여 다음을 관리: | 설정 항목 | 설명 | |----------|------| | AI 연동 활성화 | 기능 전체 토글 | | 사내 API 엔드포인트 | 인트라넷 URL 입력 | | 프리픽스 | `ai`, `??`, 또는 빈 값 (자동 폴백) | | 타임아웃 (초) | 1~30초 | | 자동 폴백 | 검색 결과 0건 시 자동으로 AI 질의 | ### 로드맵 | 단계 | 내용 | |------|------| | Phase 1 | `ai` 프리픽스 핸들러 + 사내 REST API 연동 (텍스트 질의/응답) | | Phase 2 | 자동 폴백 (퍼지 검색 결과 없을 때) | | Phase 3 | 클립보드 AI 분석 (`ai summarize`, `ai translate`, `ai proofread`) | | Phase 4 | Agent 모드 — 멀티턴 대화 + 도구 호출 (파일 읽기, 계산 등을 AI가 결정) | --- ## 슬래시 명령어 (/ Commands) AX Agent 대화 입력창에서 `/`를 입력하면 자동완성 팝업이 표시됩니다. 현재 탭에 맞는 명령어만 필터링됩니다. ### 공통 명령어 (모든 탭) | 명령어 | 기능 | 설명 | |--------|------|------| | `/summary` | Summary | 텍스트/문서를 핵심 포인트 중심으로 요약 | | `/translate` | Translate | 텍스트를 영어로 번역 (원문 톤 유지) | | `/explain` | Explain | 내용을 쉽고 자세하게 설명 (예시 포함) | | `/fix` | Fix | 맞춤법, 문법, 자연스러운 표현 교정 | | `/help` | Help | 슬래시 명령어 도움말 창 표시 | ### 개발 명령어 (Cowork/Code 탭 전용) | 명령어 | 기능 | 사용 도구 | |--------|------|-----------| | `/review` | Code Review | `code_review` (diff_review) | | `/pr` | PR Summary | `code_review` (pr_summary) | | `/test` | Test | `test_loop` | | `/structure` | Structure | `folder_map` | | `/build` | Build | `build_run` | | `/search` | Search | `search_codebase` | ### 스킬 명령어 `%APPDATA%\AxCopilot\skills\` 폴더에 `*.skill.md` 파일을 추가하면 슬래시 명령어로 자동 등록됩니다. **스킬 파일 형식** (2종류 지원): 1) **기존 형식** (`*.skill.md` 단일 파일): ```markdown --- name: skill-name label: 표시 이름 description: 설명 icon: \uE768 --- 시스템 프롬프트 내용... ``` 2) **SKILL.md 표준** (agentskills.io 호환, Claude Code/Cursor/Windsurf 공통): ``` skill-name/ ├── SKILL.md ├── scripts/ (선택) └── references/ (선택) ``` ```markdown --- name: skill-name description: 설명. 사용 시점 키워드 포함 권장. license: Apache-2.0 compatibility: Requires Python 3.14+ metadata: label: 표시 이름 icon: \uE768 author: team-name version: "1.0" allowed-tools: process file_read grep_tool --- 지시사항 마크다운... ``` **기본 제공 스킬** (자동 생성): - `/daily-standup` — 데일리 스탠드업 보고서 - `/bug-hunt` — 잠재적 버그 패턴 검색 - `/code-explain` — 코드 상세 설명 ### 에이전트 도구 목록 (v1.5.0) | 도구명 | 기능 | 탭 | |--------|------|----| | `file_read` | 파일 읽기 | Cowork/Code | | `file_write` | 파일 쓰기 | Cowork/Code | | `file_edit` | 파일 편집 (줄 기반) | Cowork/Code | | `glob` | 파일 패턴 검색 | Cowork/Code | | `grep_tool` | 텍스트 검색 | Cowork/Code | | `process` | 프로세스 실행 | Cowork/Code | | `folder_map` | 폴더 구조 조회 | Cowork/Code | | `document_read` | 문서 읽기 (PDF/DOCX) | Cowork/Code | | `search_codebase` | 코드 시맨틱 검색 (TF-IDF) | Cowork/Code | | `code_review` | AI 코드 리뷰 | Cowork/Code | | `project_rules` | AX.md 개발 지침 관리 | Cowork/Code | | `git_tool` | Git 작업 | Code | | `build_run` | 빌드/테스트 실행 | Code | | `dev_env_detect` | 개발 환경 감지 | Code | | `lsp` | LSP 코드 인텔리전스 | Code | | `test_loop` | 테스트 자동 루프 | Code | | `spawn_agent` | 서브에이전트 생성 | Code | | `wait_agents` | 서브에이전트 결과 대기 | Code | | `skill_manager` | 스킬 관리 (list/info/reload) | Cowork/Code | | `memory` | 에이전트 메모리 관리 | Cowork/Code | | `excel_create` | Excel 생성 | Cowork/Code | | `docx_create` | Word 생성 | Cowork/Code | | `csv_create` | CSV 생성 | Cowork/Code | | `markdown_create` | 마크다운 생성 | Cowork/Code | | `html_create` | HTML 생성 | Cowork/Code | | `chart_create` | 차트 생성 | Cowork/Code | | `batch_create` | 배치 스크립트 생성 | Cowork/Code | | `document_review` | 문서 품질 검증 | Cowork/Code | | `format_convert` | 포맷 변환 | Cowork/Code | --- ## 버전 이력 > **⚠ 버전 변경 시 반드시 아래 모든 항목을 동시에 수정하세요. 하나라도 빠지면 버전 불일치가 발생합니다.** > > | # | 수정 대상 | 파일 경로 | 수정 내용 | > |---|----------|----------|----------| > | 1 | **프로젝트 버전** | `src/AxCopilot/AxCopilot.csproj` → `` | 버전 번호 변경 (설정 창·Windows 속성에 자동 반영) | > | 2 | **인스톨러 프로젝트 버전** | `src/AxCopilot.Installer/AxCopilot.Installer.csproj` → `` | 인스톨러 어셈블리 버전 일치 | > | 3 | **인스톨러 표시 버전** | `src/AxCopilot.Installer/SetupForm.cs` → `AppVer` 상수 | 설치 UI 헤더·레지스트리에 표시되는 버전 문자열 | > | 4 | **개발 문서 버전 이력** | `docs/DEVELOPMENT.md` → 버전 이력 섹션 | 새 버전 항목 추가 (이 파일) | > | 5 | **사용자 가이드 문서** | `src/AxCopilot/Assets/AX Copilot 사용가이드.htm` | 헤더 `version-tag` + 버전 이력 섹션에 새 항목 추가 | > | 6 | **헬프 창 내용** | `src/AxCopilot/Views/HelpDetailWindow.xaml.cs` | `_overviewItems`의 신기능 항목·프리뷰 항목 갱신 | > | 7 | **MCP 클라이언트 버전** | `src/AxCopilot/Services/McpClientService.cs` → `clientInfo.version` | MCP 프로토콜 클라이언트 버전 문자열 | > | 8 | **로드맵 문서** | `docs/AGENT_ROADMAP.md`, `docs/AGENT_ROADMAP.html`, `docs/LAUNCHER_ROADMAP.md`, `docs/LAUNCHER_ROADMAP.html` | 푸터/헤더 버전 번호 갱신 | > > **인스톨러 주의**: `SetupForm.cs`의 `AppVer` 상수는 설치 UI 헤더 표시 + `RegAdd()`에서 > 레지스트리 `DisplayVersion`에 기록됩니다. 이 값이 앱 본체와 다르면 업그레이드 감지가 오작동합니다. > **반드시 앱 본체 csproj ``과 동일하게 유지하세요.** > > 설정 창(`SettingsWindow.xaml.cs → SetVersionText()`)과 정보 창(`AboutWindow.xaml.cs`)은 > 앱 본체 csproj ``을 리플렉션으로 읽으므로 별도 수정 불필요합니다. > **⚠ 사용자 노출 문서 작성 원칙 (사용자 가이드 · 헬프 창)** > > 사용자 가이드(`AX Copilot 사용가이드.htm`)와 헬프 창(`HelpDetailWindow.xaml.cs`)은 > **사용자가 직접 보는 문서**입니다. 외부에 내부 기술 스택이 노출되지 않도록 아래 원칙을 반드시 준수하세요. > > | 구분 | 사용 금지 (내부 기술) | 대신 사용 (사용자 관점) | > |------|---------------------|----------------------| > | 프로토콜/라이브러리 | MCP, JSON-RPC, stdio, P/Invoke, DPAPI, LCS, REST API | "외부 도구 연결", "암호화 저장" | > | 클래스/서비스명 | McpClientService, TokenEstimator, AuditLogService, DiffService | 기능 설명으로 대체 | > | 내부 구조 | ParentId/BranchLabel, FallbackModels, SettingsViewModel | "대화 분기", "자동 전환", "설정" | > | 코드 패턴 | CJK 가중치, 동적 반복 한도, SWE-bench, 다단계 반성 | "더 정확한 분석", "AI 성능 개선" | > | 파일명/경로 | english.json, movies.json, SetupForm.cs, endpoint/apiKey | 언급하지 않음 | > > **원칙**: 사용자에게는 "무엇을 할 수 있는지"만 전달합니다. > "어떻게 구현했는지"는 이 개발 문서(`DEVELOPMENT.md`)에만 기록합니다. > > **적용 대상**: 버전 이력, 신기능 설명, 개요 항목, 모든 사용자 노출 텍스트 ### v2.0.0 (2026-04-04) > **개발 범위**: Phase 17/18 완료 릴리즈 — 멀티에이전트 팀·Reflexion·훅 고도화·스킬 고도화 전면 완료. ## v2.0.0 (2026-04-04) ### Phase 17 — 에이전트 인프라 고도화 완료 - **Phase 17-A (Reflexion)**: ReflexionService + JsonlReflexionRepository + TaskTypeClassifier 구현. 세션 완료 후 LLM 자기평가 .jsonl 저장. 다음 세션 시스템 프롬프트에 교훈 자동 주입. - **Phase 17-B (TaskState/EventLog)**: TaskStateService (현재태스크/완료태스크/차단이슈 영속화). AgentEventLog (.jsonl 이벤트 기록, 17개 이벤트 타입). - **Phase 17-C (훅 확장)**: ExtendedHooksConfig 11개 이벤트 종류. ExtendedHookRunner 4타입(Command/Http/Prompt/Agent). watchPaths → FileWatcherService 연동. - **Phase 17-D (스킬 고도화)**: context:fork 격리 실행. paths: glob 패턴 기반 자동 활성화. user-invocable:false AI 전용 스킬. - **Phase 17-E/F/G**: @include 메모리 계층화, acceptEdits/패턴 권한 시스템, 멀티파일 Diff 추적기 (이전 릴리즈 완료). ### Phase 18 — 멀티에이전트 팀 + 에코시스템 완료 - **Phase 18-A1 (CoordinatorAgentService)**: LLM 계획 수립 → 의존성 토폴로지 정렬 → 병렬 서브에이전트 실행 → 결과 합성. - **Phase 18-A2~A4**: WorktreeManager + DelegateAgentTool + BackgroundAgentService 완전 연동. - **Phase 18-B1 (리플레이)**: WorkflowAnalyzerWindow 리플레이 탭 — AgentReplayService + ReplayTimelineViewModel. - **Phase 18-C1 (플러그인 갤러리)**: PluginGalleryViewModel + PluginInstallService + SettingsWindow 플러그인 탭. - **Phase 18-C2/C3**: AiSnippetHandler + QuickLinkHandler 구현 완료. - **SlashCommandRegistry**: IAgentChatContext ChatWindow 통합. /compact, /memory, /plan 등 레지스트리 명령 실행. ### 신규 파일 (주요) - Services/Agent/CoordinatorAgentService.cs, AgentLoopService.Coordinator.cs - Services/Agent/ReflexionService.cs, AgentLoopService.Reflexion.cs - Services/Agent/TaskStateService.cs, AgentLoopService.TaskState.cs - Views/ChatWindow.SlashContext.cs, Views/SettingsWindow.Plugins.cs - Views/Controls/AgentSettingsPanel.xaml + .cs - Views/Controls/AgentSessionHeaderBar.xaml + .cs - Views/Controls/AgentSidebarView.xaml + .cs --- ### v1.8.0 > **개발 범위**: 에이전트 인프라 전면 고도화 — Phase 17-UI, 17-A~G, 18-A~C, L3 완료. 사내/사외 네트워크 모드 추가. | 구분 | 내용 | |------|------| | **에이전트 채팅 화면 개편 (Phase 17-UI)** | 채팅 창 서브 바에 Plan 모드 3상태 토글 (Off / Auto / Always) 추가. 클릭 시 순환 전환, 활성 상태 색상 강조. `LlmSettings.PlanMode` 설정 연동 | | **Reflexion 강화 (Phase 17-A)** | `ReflexionService` + `ReflexionRepository`: 성공·실패 시 자기평가 기록. 동일 유형 작업 시 과거 교훈 시스템 메시지 자동 주입. `AgentLoopService.Reflexion.cs` 파셜 추가 | | **TaskState Working Memory + 이벤트 로그 (Phase 17-B)** | `TaskStateService`: 세션 요약·참조 파일 목록 JSON 영속화. 압축 후에도 Working Memory 복원. `AgentEventLog` JSONL 기록 (SessionStart/UserMessage/ToolRequest/ToolResult/AssistantMessage/HookFired/CompactionTriggered 등). `AgentLoopService.TaskState.cs` 파셜 추가 | | **훅 시스템 고도화 (Phase 17-C)** | `ExtendedHookRunner` — Command/Http/Prompt 3종 타입. `HookEventKind` 열거형 18종 이벤트 (SessionStart/SessionEnd/UserPromptSubmit/PreToolUse/PostToolUse/PostToolUseFailure/PreCompact/PostCompact/AgentStop 등). Prompt 모드: `{{tool_name}}` `{{tool_input}}` 변수 치환 → LLM 보안 검사 → Block 신호 탐지. `AgentLoopService.ExtendedHooks.cs` 파셜 추가 | | **스킬 시스템 고도화 (Phase 17-D)** | `PathBasedSkillActivator`: `paths:` 프론트매터 glob 매칭으로 파일 작업 시 스킬 자동 컨텍스트 주입. `context:fork` 스킬: `SkillManagerTool.SetForkRunner()` DI 콜백 주입 → 격리된 LLM 호출. `AgentLoopService.Skills.cs` 파셜 추가 | | **계층 메모리/컨텍스트 고도화 (Phase 17-E)** | `HierarchicalMemoryService`: Managed→User→Project→Local 4-layer AX.md 수집. `AxMdIncludeResolver`: `@파일경로` 재귀 해석 최대 5단계 (순환 참조 감지). `PathScopedRuleInjector`: `.ax/rules/*.md` paths: 프론트매터 기반 경로 범위 규칙 주입. `AgentLoopService.Memory.cs` 파셜 추가. 설정: `EnableMemorySystem` | | **권한 시스템 고도화 (Phase 17-F)** | `PermissionDecisionService` Chain of Responsibility: DenyRuleHandler→AllowRuleHandler→AcceptEditsHandler→PlanModeHandler→BypassHandler. `AgentLoopService.Permissions.cs` 파셜 추가. `EvaluateToolPermission()`: Deny=즉시차단/Allow=확인 스킵/Ask=기존 흐름. `PermissionsConfig.AllowRules/DenyRules` 설정 기반 패턴 규칙 | | **멀티파일 Diff 추적 + 도구 위험도 (Phase 17-G)** | `AgentLoopService.DiffTracker.cs` 파셜: `CaptureOriginalFileContent()` 쓰기 전 원본 캡처, `TrackFileModificationForDiff()` 성공 후 `MultiFileDiffViewModel` 기록. `ToolRiskMapper` 연계 ToolCall 이벤트에 `[⚠ 높음]`/`[• 보통]` 위험도 태그 추가. 설정: `EnableDiffTracker` | | **멀티에이전트 팀 (Phase 18-A)** | `DelegateAgentTool` + `AgentLoopService.RunSubAgentAsync()` 위임 연결. ToolRegistry에 자동 등록. 서브에이전트 독립 루프 실행 지원 | | **에이전트 리플레이 (Phase 18-B)** | `AgentReplayService`: JSONL 이벤트 로그 파일 열거 + 단계별 재생. `ReplayTimelineViewModel`: 재생 UI 바인딩 ViewModel | | **플러그인 설치 서비스 (Phase 18-C)** | `PluginInstallService`: 로컬 zip 파일 기반 설치 (URL 다운로드 없음). `PluginManifest` / `InstalledPlugin` / `PluginInstallResult` 레코드. 레지스트리 JSONL 영속화 | | **사내/사외 네트워크 모드** | `AppSettings.InternalModeEnabled` (기본: 사내 모드). 사외 전환 시 비밀번호 `axgo123!` 인증 필요. `WebSearchHandler` + `HttpTool` 에서 모드 체크 적용 | | **알림 센터 (L3-7)** | `NotificationCenterService`: 알림 타입(Info/Success/Warning/Error) + 히스토리 큐(최대 50건). `NotificationRaised` 이벤트로 UI 구독 지원 | | **플러그인 갤러리 ViewModel (L3-1)** | `PluginGalleryViewModel`: 설치된 플러그인 목록 + 설치/제거/활성화 커맨드 바인딩. `PluginItemViewModel` 래퍼 | | **파라미터 퀵링크 (L3-4)** | `QuickLinkHandler` (`ql` 프리픽스) + `UrlTemplateEngine`. `{0}`, `{query}` 플레이스홀더 치환. 설정에서 `QuickLinkEntry` 목록 관리 | | **AI 스니펫 (L3-3)** | `AiSnippetHandler` (`ai` 프리픽스) + `SnippetTemplateService`. 업무 이메일/요약/번역/코드리뷰/커밋 기본 템플릿 5종 내장. LLM 호출 후 클립보드 복사. AI 비활성화 시 항목 미표시 | | **웹 검색 AI 요약 (L3-2)** | `WebSearchSummaryHandler` (`?!` 프리픽스) + `ContentExtractor`. URL 또는 검색어 입력 시 AI가 요약 생성 후 클립보드 복사. 사외 모드 + AI 활성화 상태에서만 동작 | ### v1.7.2 > **개발 범위**: 안정화 릴리즈 — 런처 속도, 에이전트 컨텍스트 압축, 대화 복원, 버그 수정 11건 | 구분 | 내용 | |------|------| | **컨텍스트 압축 (Context Condenser)** | 2단계 자동 압축 구현. 1단계: 오래된 도구 결과를 LLM 호출 없이 1500자로 축약. 2단계: 이전 대화를 LLM으로 요약하여 교체. 모델별 토큰 한도 자동 인식 (Claude 180K, Gemini 900K, GPT-4 120K, Ollama 16K). 65% 임계값에서 압축 시작 | | **대화 이력 복원** | 앱 재시작 시 탭별 마지막 대화를 자동 복원. `LastConversationIds` 설정에 탭↔대화 ID 매핑 저장. 종료·탭 전환 시 자동 영속화 | | **런처 속도 개선** | 핫키 응답 ~230ms 절감. `Thread.Sleep` 단축 (200→110ms), 애니메이션 최적화 (fade 160→100ms, slide 200→120ms). 텍스트 미사용 시 즉시 런처 표시 | | **검증 리팩터링** | 도구 실행 후 검증을 읽기 전용(`file_read`, `directory_list`)으로 제한. 검증 결과를 보고만 하고 직접 수정하지 않도록 변경 — 문서 품질 저하 방지 | | **설정 비밀번호 수정** | 개발자 모드·스텝바이스텝 토글이 설정 창 열 때마다 비밀번호 재입력을 요구하던 문제 수정. `IsLoaded` 가드 추가 | | **계획 버튼 동기화** | PlanViewerWindow에서 승인 후 대화창 인라인 승인/취소 버튼이 자동 축소되지 않던 문제 수정. `TCS.ContinueWith` 콜백 추가 | | **야간 시간 수정** | PC 미종료 상태에서 자정 넘길 때 근무 시간이 전날부터 누적되던 문제 수정. `_sessionStart`를 자정(DateTime.Today)으로 리셋 | | **클립보드 붙여넣기 수정** | 이전 활성 창에 `SetForegroundWindow` 호출 후 `Ctrl+V` 전송하도록 변경 — 런처가 포커스를 뺏는 문제 해결 | | **활성 창 캡처 수정** | 런처가 완전히 숨겨질 때까지 대기 + 대상 창에 `SetForegroundWindow` 호출 — 런처 자체가 캡처되던 문제 해결 | | **스크롤 캡처 수정** | `FindOverlap` 다중 행 비교로 오버랩 감지 정확도 향상. `StitchFrames`를 증분 스티칭으로 변경 — 전체 프레임 중복 붙여넣기 문제 해결 | | **런처 잔여 결과 제거** | `OnShown()`에서 `Results.Clear()` 호출 추가 — 런처 재표시 시 이전 검색 결과가 순간적으로 보이던 문제 해결 | | **AI 모델 호환성 가이드** | 개발자 가이드에 도구 사용(Function Calling) 지원 모델 표 추가. 클라우드(Claude/Gemini) + Ollama 로컬 모델 15종 호환성 명시. 사내 환경 추천 조합 포함 | ### v1.7.1 > **개발 범위**: 에이전트 루프 검증 강제 + UI 개선 + 도구 스키마 수정 | 구분 | 내용 | |------|------| | **도구 실행 후 검증 강제 (Post-Tool Verification)** | 문서 생성 도구(`file_write`, `docx_create`, `html_create`, `excel_create` 등) 실행 후 LLM에 검증 전용 호출을 자동 삽입. 생성된 파일을 `file_read`로 읽고 내용 완전성·구조·맞춤법을 확인하도록 강제. 문제 발견 시 즉시 수정 도구 호출. OpenHands 등 오픈소스에는 없는 차별화 기능. `EnablePostToolVerification` 설정 토글 (기본 OFF) | | **Gemini 배열 스키마 수정** | `MultiReadTool.paths`와 `UserAskTool.options`에 `Items` 필드 추가. Gemini API가 array 타입 파라미터에 items 필드를 필수로 요구하는 문제 해결 | | **워크플로우 분석기 UI 개선** | 타이틀바 전체 영역 드래그 가능 (`Background="Transparent"` 추가), 활성 탭 텍스트 White 강조, 상태 텍스트 `TextTrimming` + `MaxWidth` 적용 | | **플랜 뷰어 버튼 가시성** | 아웃라인 버튼 배경 `0x18` 틴트 + 테두리 `0x80` 불투명도 + `1.2px` 두께로 가시성 개선 | | **워터마크 슬래시 칩 충돌 수정** | 슬래시 칩 활성 시 `InputWatermark` 즉시 숨김 처리 | | **피드백 학습 컨텍스트** | `BuildFeedbackContext()`를 Cowork/Code 시스템 프롬프트에 주입. 최근 20건 대화의 좋아요/싫어요 패턴 분석 | | **수정 후 재시도 버튼** | 두 번째 액션바에 재시도 버튼 추가 (사용자 피드백 입력 후 재생성) | | **설정 추가** | `EnablePostToolVerification`(bool, 기본 false) — 문서 생성 후 검증 LLM 호출 강제 | ### v1.7.0 > **개발 범위**: Phase 16 — 에이전트 지능 강화 + 개발자 경험 | 구분 | 내용 | |------|------| | **플랜 모드 (Plan Mode)** | 에이전트 도구 실행 전 구조화된 계획 생성→사용자 검토/승인→실행 흐름. `PlanMode` 3모드(off/always/auto). always=LLM 텍스트 전용 계획 생성(최대 3회 수정 요청), auto=계획 감지 시 승인 요청 | | **도구/커넥터 관리 UI** | 설정 › AX Agent › 도구 탭 신설. 52개 에이전트 도구를 6개 카테고리(파일/검색, 문서 생성, 문서 품질, 코드/개발, 데이터/유틸, 시스템)별 카드 표시. 개별 활성/비활성 토글 + MCP 서버 연결 상태 실시간 표시. `DisabledTools` 설정으로 영속 | | **프로젝트 규칙 시스템** | `.ax/rules/*.md` YAML 프론트매터(name, description, applies-to, when) 파싱. glob 패턴 매칭, when 조건 필터링. 시스템 프롬프트에 "프로젝트 규칙" 섹션 자동 주입. ProjectRuleTool에 list_rules/read_rule 액션 추가. `EnableProjectRules` 토글 | | **반복 테스트-수정 루프** | TestLoopTool `auto_fix` 액션 — 테스트 실행→구조화된 실패 파싱(.NET Failed/pytest FAILED, 파일 경로·라인 번호 추출)→`[AUTO_FIX:]` 마커 출력. AgentLoopService에서 test_loop+AUTO_FIX 감지 시 반복 예산 자동 확장. `MaxTestFixIterations` 설정 | | **병렬 도구 실행** | 읽기 전용 도구(file_read, grep_tool, glob 등 12종 ReadOnlyTools 셋) 자동 분류 → `Task.WhenAll()` 병렬 실행, 쓰기 도구는 순차 유지. ParallelState 클래스로 async ref 제약 해결. `EnableParallelTools` 토글 | | **SKILL.md 표준 호환** | 외부↔내부 도구 이름 매핑 테이블 20개(Bash→process, Read→file_read, Grep→grep_tool, execute_command→process 등). ParseSkillFile에서 스킬 본문 로드 시 자동 치환 | | **사내 보안 예외** | AntiTamper 보안 감지에 사내 IP 대역(11.99/11.90/12.25/12.23/12.24) 예외 처리. IsTrustedNetwork()로 IPv4 프리픽스 매칭 | | **설정 추가** | `PlanMode`(off/always/auto), `EnableProjectRules`(bool), `MaxTestFixIterations`(int), `EnableParallelTools`(bool), `DisabledTools`(List\) | ### v1.6.1 > **개발 범위**: 설정 UI 개선 + 헬프 IP 보호 + 모델 선택 버그 수정 + 차세대 고도화 계획 수립 | 구분 | 내용 | |------|------| | **고품질 문서 생성 설정** | 설정 › 에이전트 › 코워크에 "고품질 문서 생성" ToggleSwitch 추가. 멀티패스 문서 엔진 기본값 OFF (무료 API 환경 호환성). 비활성 시 `document_plan`/`document_assemble` 도구 차단 | | **헬프 화면 IP 보호** | 버전별 신기능 항목 삭제, 영역별 핵심 기능 중심 재구성. 내부 기술 용어(SSE, AES-256-GCM, DPAPI, OpenXML 등) 노출 제거. CLAUDE.md에 헬프 IP 보호 규칙 추가 | | **모델 선택 팝업 버그 수정** | 서비스만 변경 후 모델 미선택 시 팝업 닫으면 이전 서비스/모델로 롤백. 모델 확정(`Save`) 시에만 변경 반영 | | **ESC 키 닫기 확장** | AboutWindow(개발 정보) ESC 키 닫기 추가 | | **가이드 버전 표기 제거** | 사용자/개발자 가이드 헤더 version-tag 및 푸터 버전 번호 제거. CLAUDE.md에 가이드 버전 미표기 규칙 추가 | | **차세대 고도화 계획 수립** | Phase 16(v1.7.0)~18(v2.0) 계획: 플랜 모드, 도구 관리 UI, 프로젝트 규칙, 자기 성찰, 멀티파일 Diff, 에이전트 팀 등 18개 기능 | ### v1.6.0 > **개발 범위**: Phase 15 — 멀티패스 문서 엔진 + 내장 스킬 29종 확장 + 에이전트 도구 42개 + PPT 네이티브 생성 | 구분 | 내용 | |------|------| | **멀티패스 문서 생성 엔진** | `document_plan` (개요 구조화) + `document_assemble` (섹션별 조립) 도구 신규 추가. 3페이지 이상 문서 작성 시 개요→섹션별 상세→조립 방식으로 품질 대폭 향상. 코워크 보고서/문서 프리셋에 멀티패스 지시문 자동 포함 | | **PPT 네이티브 생성** | `pptx_create` 도구 — OpenXML SDK 기반 C# 네이티브 구현. Python/Node 없이 슬라이드 생성 (title/content/two_column/table/blank 레이아웃, 4종 테마) | | **데이터 분석 도구** | `data_pivot` — CSV/JSON 그룹화·피벗·집계 (sum/avg/count/min/max), 필터·정렬·Top N 지원. LINQ 기반 순수 C# 구현 | | **템플릿 렌더링** | `template_render` — Mustache 스타일 변수 치환 + 반복({{#list}}) + 조건부({{^cond}}) 렌더링. 정기 보고서 템플릿 자동화 | | **이미지 분석** | `image_analyze` — LLM 멀티모달 활용 이미지 설명/텍스트 추출/차트 데이터 해석/비교 분석 | | **파일 변경 감지** | `file_watch` — 폴더 내 최근 변경·생성 파일 탐지 (상대 시간 지원: 1h/24h/7d), 유형별 통계 | | **텍스트 요약** | `text_summarize` — 긴 텍스트/문서 청크 분할 → 핵심 문장 추출 요약 (bullet/paragraph/executive/technical 스타일) | | **내장 스킬 16종 추가** | email-draft, translate, compare, weekly-report, log-analyze, sql-report, data-convert, refactor, gen-test, impact + 외부 검증 스킬 6종: security-audit (보안 코드 감사/OWASP), prd-generator (요구사항 정의서/유저스토리), adr-writer (아키텍처 결정 기록), changelog (변경이력/릴리즈노트), dependency-audit (의존성 분석/라이선스), perf-audit (성능 감사/안티패턴) — **총 29종** | | **설정 추가** | `EnableMultiPassDocument` (멀티패스 문서 ON/OFF), `MultiPassThresholdPages` (자동 멀티패스 기준 페이지 수, 기본 3) | | **가이드 뷰어 버튼 수정** | 닫기/최소화/최대화 버튼 MouseLeftButtonDown + Handled로 DragMove 충돌 해결 | | **ESC 키 닫기** | GuideViewerWindow, HelpDetailWindow에서 Escape 키로 창 닫기 지원 | ### v1.5.4 > **개발 범위**: Phase 12-3 완료 + 대화 UX 안정화 + 슬래시 팝업 고도화 + 설정 개선 | 구분 | 내용 | |------|------| | **Phase 12-3 완료** | 실행이력상세도를 개발자 탭으로 이동. Phase 12-3 (런타임 스킬 + 워크플로우 분석기 + 설정 개선) 전체 완료 | | **글로우 효과 지속** | 레인보우 글로우가 스트리밍 종료 시까지 지속 (기존 3초 자동 꺼짐 → StopRainbowGlow 페이드아웃). Chat/Cowork/Code 전체 적용 | | **스트리밍 경과 시간 표시** | 헤더 우측에 실시간 경과 시간 표시 (0s, 5s, 12s...). 완료 후 하단에 최종 시간 + 토큰 사용량 한 줄 TextBlock 표시 (줄바꿈 방지) | | **슬래시 팝업 UX 개선** | ↑/↓ 방향키 아이템 단위 이동 + 선택 하이라이트, Enter로 실행, 마우스 휠 스크롤 지원, 기본 표시 7개 (최대 20), `/help` 직접 입력 시 도움말 창 표시, 슬라이더에 현재 값 실시간 표시 | | **도움말 창 닫기 수정** | DragMove 충돌 해결 — MouseLeftButtonDown + Handled로 닫기 이벤트 우선 처리. 드래그는 헤더 영역에서만 동작 | | **설정 접기/열기 수정** | 도구 카테고리·스킬 그룹 접기/열기를 MouseLeftButtonDown으로 변경 (ScrollViewer 내 MouseUp 소실 WPF 이슈 해결) | | **설정 닫기 다이얼로그 제거** | 저장하지 않고 닫을 때 확인 팝업 + 하단 토스트 배너 제거, 바로 닫힘 (변경사항 자동 revert) | | **설정 스킬 로딩 지연 해결** | 스킬 미로드 시 백그라운드 Task로 RuntimeDetector 포함 비동기 로드 후 UI 구성 | | **탭 전환 시 대화 유지** | StopStreamingIfActive() — 탭 전환 시 스트리밍 즉시 중단 + 대화 즉시 저장. originTab 캡처로 올바른 탭에 ID 매핑. SendRegenerateAsync 이력 갱신 추가 | | **섹션 간 간격 개선** | 차단 확장자 → 도구/커넥터 간 16px 마진, 도움말 창 스킬 항목 간격 확대, 명령어 열 너비 120px | ### v1.5.3 > **개발 범위**: Phase L2 클립보드 고도화 + Phase 14 에이전트 도구/스킬 확장 + 설정 UI 개선 + 가이드 시스템 | 구분 | 내용 | |------|------| | 클립보드 이미지 원본 보존 | 원본 PNG를 `clipboard_images/` 캐시 폴더에 저장, 썸네일(80px)은 표시용으로만 사용. Enter 복원 시 원본 해상도로 클립보드 복사. 캐시 정리 정책 (30일/500MB) | | Shift+Enter 자동 복사 | 히스토리 미리보기(Shift+Enter) 시 시스템 클립보드에 자동 복사 (텍스트/이미지 원본 해상도) | | 스킬 갤러리 버그 수정 | YAML 아이콘 이스케이프 변환, DragMove 닫기 충돌 해결(3창), 카드 클릭 상세 팝업, 상단바 정렬 | | **에이전트 도구 12종 추가** | json_tool, regex_tool, diff_tool, clipboard_tool, notify_tool, env_tool, zip_tool, http_tool, sql_tool, base64_tool, hash_tool, datetime_tool | | **내장 스킬 3종 추가** | api-docs, db-schema, commit-review (총 13종 번들) | | **설정 UI 개선** | 독 바 탭 3번째 위치로 이동 (테마 뒤), 기타 탭 접기/열기 섹션 (등록된 도구·MCP 커넥터·슬래시 스킬 각각 접기/펼치기) | | **About 정보 변경** | 개발 정보에서 ".NET 8" 제거 → "Commander + Agent" 표시 (기술 스택 비노출) | | **가이드 시스템 신설** | 사용자 가이드 + 개발자 가이드 분리 (개발자 가이드에만 버전 이력 포함). AES-256-CBC 고정 키 암호화 (.enc). GuideViewerWindow 내장 뷰어 (WebView2 비동기 초기화). 개발자 모드 ON→개발자 가이드, OFF→사용자 가이드. 트레이 메뉴 → 외부 브라우저 대신 앱 내 뷰어로 전환 | | **가이드 암호화 도구** | GuideEncryptor.cs (AES-256-CBC 암호화/복호화 유틸리티), encrypt_guides.ps1 (빌드 전 암호화 스크립트) | ### v1.5.2 > **개발 범위**: Phase 12-4/12-5 런타임 스킬 + 워크플로우 분석기 + 개발자 탭 + 설정 개선 | 구분 | 내용 | |------|------| | **런타임 의존 스킬 (12-4)** | RuntimeDetector — Python/Node.js 설치 감지 (where.exe + --version, 5분 캐시). SkillDefinition.Requires/IsAvailable/UnavailableHint. 고급 스킬 4종 번들 (docx-creator, xlsx-analyzer, pdf-processor, pptx-creator). 슬래시 팝업에서 비가용 스킬 회색 표시. 기타 탭에 스킬 목록 카드 | | **워크플로우 분석기 (12-5)** | WorkflowAnalyzerWindow — 세로 타임라인 실시간 시각화. AgentEvent 확장 (ElapsedMs/InputTokens/OutputTokens/ToolInput/Iteration). Stopwatch 타이밍 + LastTokenUsage 토큰. AgentLogLevel 3단계 분기 (simple/detailed/debug) | | **개발자 탭 분리** | 설정 › 에이전트에 개발자 서브탭 신설. 비밀번호 보호 세션 전용. 개발자모드/실행이력상세도/스텝바이스텝/워크플로우 시각화/감사로그/에이전트고급/모델폴백/MCP서버 배치 | | **설정 개선** | AgentLogLevel 기본값 simple, DevMode 세션 전용화 (매번 재인증), WorkflowVisualizer 토글 추가, 개발자모드 ? 툴팁 제거 | | **UI 개선** | 훅/MCP 서버 추가 다이얼로그에 플레이스홀더 입력 예시, 좌우 패딩 증가, 훅 ESC 닫기, 코드 리뷰 툴팁 오탈자(변경사항) 수정 | | **설정 기능 탭 개편** | 기능 설정 페이지를 3개 서브탭(AI 기능 / AX Commander / 디자인·기타)으로 분류. 클립보드 확장을 디자인·기타로 이동, 실행이력상세도를 코워크/코드 탭으로 복귀 | | **Phase 13 계획 수립** | 스킬 생태계 + 에이전트 분석 고도화 5개 항목 (스킬 갤러리/편집기/가져오기·내보내기/통계 대시보드/AgentLogLevel 연동). AGENT_ROADMAP 문서 반영 | | **스킬 시각적 편집기 (13-2)** | SkillEditorWindow — 폼 기반 스킬 생성/편집 GUI. 아이콘 선택기(MDL2 20종), 도구 체크리스트(ToolRegistry 연동), 템플릿 삽입(도구목록/출력형식/단계별), 토큰 예상 미리보기, YAML 프론트매터 + 마크다운 본문 자동 생성, 사용자 스킬 폴더 저장. 스킬 갤러리 연동 (새 스킬 → 편집기, 사용자 스킬 편집 → 시각적 편집기) | ### v1.5.1 > **개발 범위**: Phase 12 스킬/커넥터 고도화 + UI 개선 + 버그 수정 | 구분 | 내용 | |------|------| | **슬래시 명령 영어 전환** | 내장 슬래시 명령 11개를 한국어(/요약,/번역)에서 영어(/summary,/translate,/review,/pr 등)로 전환. IME 전환 없이 즉시 입력 가능 | | **도구/커넥터 관리 UI (12-1)** | 설정 › 에이전트 › 기타 탭에 등록된 도구 29종을 5개 카테고리(파일/프로세스/코드분석/문서생성/에이전트)로 분류하여 표시. MCP 커넥터 안내 섹션 | | **SKILL.md 표준 호환 (12-2)** | SkillService — *.skill.md (기존) + 폴더/SKILL.md (표준) 2형식 동시 지원. YAML metadata 맵 파싱, license/compatibility/allowed-tools 필드. SkillDefinition 확장 | | **커스텀 ComboBox** | 전역 ComboBox/ComboBoxItem 스타일 — ControlTemplate 기반 모던 드롭다운, 호버/선택 효과, Slide 애니메이션. 설정창 전체(27개소) 자동 적용 | | **BlockedPaths 패턴 수정** | `*\Documents\*` → `*Documents*` — 백슬래시 없는 패턴으로 수정하여 정상 차단 동작 | | **사용자 가이드 정리** | v1.5.1 이력 추가, v1.4.0 이하 이전 이력으로 접기, 내부 기술 용어 제거(DPAPI, Ollama/vLLM, 클래스명 등), 푸터 버전 갱신 | ### v1.5.0 > **개발 범위**: 대화 서비스 Phase 9~11 완료 + 런처 Phase L1 추가 + 저장 공간 관리 + 문서 체계화 | 구분 | 내용 | |------|------| | **LSP 코드 인텔리전스 (9-1)** | LspClientService — C#/TS/Python/C++/Java 언어 서버 자동 감지. `lsp_code_intel` 도구 (goto_definition, find_references, symbols). 설정 `EnableLsp` 토글 | | **서브에이전트 (9-2)** | SubAgentTool (`spawn_agent`) + WaitAgentsTool (`wait_agents`). 읽기 전용 격리 실행. `MaxSubAgents` 설정으로 동시 실행 제한 | | **코드 시맨틱 검색 (9-3)** | CodeIndexService — TF-IDF 인덱싱 (camelCase 분할, 50라인 청크). `search_codebase` 도구. `EnableCodeIndex`/`CodeIndexMaxFileKb` 설정 | | **자동 테스트 루프 (9-4)** | TestLoopTool — generate/run/analyze 3단계. .NET/Python/Node.js/Go 프레임워크 자동 감지 | | **이벤트 트리거 (9-5)** | AgentTriggerService — FileSystemWatcher(파일 변경) + DispatcherTimer(스케줄). triggers.json 규칙 기반 | | **PDF 내보내기 (9-6)** | PdfExportService — HTML 인쇄 최적화 + 브라우저 자동 인쇄. 대화 내보내기에 "PDF 인쇄용 HTML" 옵션 추가 | | **diff 뷰어 (9-7)** | DiffViewerPanel — 라인 기반 diff (Added/Removed/Equal), 라인 번호, Accept/Reject 버튼 | | **탐색기 셸 확장** | ShellExtensionService — HKCU 레지스트리 우클릭 메뉴 등록/해제. 파일/폴더/폴더배경 3종 | | **저장 공간 관리** | StorageAnalyzer — 앱 데이터 사용량 분석 (대화/감사/로그/인덱스/클립보드), 드라이브 여유 공간, 7/14/30일 정리. 설정 공통 탭에 UI | | **설정 도움말 아이콘** | AI 관련 설정 17개에 `?` 아이콘 + `HelpTooltipStyle` 커스텀 다크 툴팁 | | **폴백 모델 개선** | 서비스별 그룹화 (Ollama/vLLM/Gemini/Claude). ViewModel과 AppSettings 동시 읽기로 저장 전 즉시 반영 | | **클립보드 붙여넣기** | Alt+SetForegroundWindow 우회. TryGetSelectedText 후크 스레드 분리 | | **독 바 개선** | 버튼 히트 테스트 수정 (MouseLeftButtonDown), 시작 시 자동 표시, 설정 실시간 반영 | | **포맷 메뉴** | AI 자동 선택 맨 위로 이동 | | **코드 탭 아이콘** | 파일(앰버)/권한(파랑·빨강)/데이터활용(녹·앰버·회) 색상 구분 | | **사내 환경 원칙** | CLAUDE.md에 외부 의존 최소화, 데이터 로컬 저장, 텔레메트리 금지 지침 추가 | | **문서 체계화** | CLAUDE.md 문서 관리 원칙 추가, AGENT/LAUNCHER ROADMAP Phase 9/L1 완료 표시, NEXT_ROADMAP 차기 계획 전면 업데이트 | | **자동 모델 선택 (10-1)** | AutoRouterService — 질문 유형(코딩/번역/분석) 감지 → 최적 모델 자동 라우팅. 잠금 모드 지원 | | **에이전트 메모리 (10-2)** | MemoryTool — 프로젝트 규칙, 코딩 선호도 자동 기억. 대화 간 영속 유지 | | **멀티모달 입력 (10-4)** | 이미지/스크린샷 Ctrl+V 붙여넣기 → base64 인코딩 → Gemini/Claude/Ollama/OpenAI Vision API 직접 전달. 이미지 미리보기 UI | | **코드 검색 개선 (10-5)** | TF-IDF + SQLite 영속 인덱스, 증분 업데이트, 바이그램 토큰, 스톱워드 필터링 | | **에이전트 훅 시스템 (10-6)** | 도구 호출 전/후 사용자 정의 스크립트 실행. hooks.json 규칙 기반 | | **스킬 시스템 (11-1)** | SkillService — *.skill.md YAML 프론트매터 파싱 → 슬래시 명령 자동 등록. 3폴더 우선순위(앱→%APPDATA%→커스텀). 기본 스킬 3종(daily-standup/bug-hunt/code-explain) 자동 생성. `skill_manager` 도구 | | **AI 코드 리뷰 (11-2)** | CodeReviewTool — diff_review/file_review/pr_summary. 정적 분석(빈 catch/동기 대기/하드코딩 키/긴 메서드). Git diff 파서. 리뷰 초점(bugs/performance/security/style) | | **드래그&드롭 AI (11-3)** | 파일 드래그 시 유형별 AI 액션 팝업(코드→리뷰/설명/리팩토링, 문서→요약/번역, 데이터→분석/시각화, 이미지→설명). "첨부만" 옵션. `EnableDragDropAiActions` 설정 | | **프로젝트 지침 (11 추가)** | ProjectRuleTool — AX.md read/append/write. 사용자 승인 후 저장. 상위 3단계 탐색 | | **슬래시 명령어 강화 (11 추가)** | 탭별 필터링(Chat=공통, Cowork/Code=공통+개발). `/help` 도움말 창. 총 12개 내장 명령 | | **사용 통계 차트 확장** | 메인 탭 미니차트 2종, 커맨더 탭 요일별 평균차트, 에이전트 탭 탭비율+토큰비율 차트 | | **인사 문구 외부화** | greetings.json 외부 파일 로딩 + 임베디드 리소스 폴백 + 5분 캐시 | | **캡처 알림 개선** | 지연 캡처 카운트다운 알림 제거 (시작/초단위 모두). 완료 알림만 유지 | | **알림 아이콘 수정** | ToolTipIcon.Info → ToolTipIcon.None 변경으로 앱 트레이 아이콘 표시 | ### v1.4.0 > **개발 범위**: 런처 고도화 Phase L1 (LAUNCHER_ROADMAP) + 대화 서비스 고도화 Phase 9 (AGENT_ROADMAP) 병행 > > | 영역 | 문서 | 완료 항목 | > |------|------|----------| > | 런처 | `LAUNCHER_ROADMAP.md` | L1-1(선택 텍스트 AI), L1-5(독 바), L1-6(대화상자 통합), L1-7(클립보드 핀/카테고리) | > | 대화 서비스 | `AGENT_ROADMAP.md` | Phase 8 완료, 기술부채 해결 | | 구분 | 내용 | |------|------| | **선택 텍스트 AI 명령 (L1-1)** | TextActionPopup — 핫키 시 선택 텍스트 감지 (Ctrl+C 시뮬레이션), 커서 위치에 액션 팝업 표시 (번역/요약/교정/설명/다시쓰기), ↑↓/마우스 선택, Enter 실행 → AX Agent에 `!` 프리픽스로 전달 | | **독 바 (L1-5)** | DockBarWindow — 화면 하단 고정 미니 바. 설정 기반 동적 아이템 빌드 (`DockBarItems`). CPU(PerformanceCounter)/RAM(GlobalMemoryStatusEx)/시계 실시간 표시. 무지개 글로우, 투명도(0.3~1.0), 위치 기억(`DockBarLeft/Top`), 드래그 이동. 트레이 메뉴 토글 | | **대화상자 통합 (L1-6)** | FileDialogWatcher — `SetWinEventHook(EVENT_OBJECT_SHOW)` + `#32770` 클래스 감지. 열기/저장 대화상자 감지 시 런처 자동 열기 (`cd ` 프리픽스) | | **클립보드 핀/카테고리 (L1-7)** | ClipboardEntry에 `IsPinned`/`Category` 추가. 자동 카테고리 분류 (URL/코드/경로/일반). 핀 항목 상단 고정 + 삭제 보호. `#pin`/`#url`/`#코드`/`#경로` 필터. Ctrl+P 핀 토글 | | **아이콘 교체** | 다이아몬드 픽셀 ICO (7 sizes, 25% block, rounded) 생성. 상=파랑/하=빨강/좌=녹/우=녹. AboutWindow/LauncherWindow/SetupForm/SVG 전체 색상 통일. 모든 Window에 `Icon=` 속성 추가. 바로가기에 `IconLocation` 명시 | | **독 바 설정 탭** | SettingsWindow에 독 바 탭 추가 — 자동 표시, 글로우 효과, 투명도 슬라이더, 위치 초기화 버튼, 표시 항목 토글 (8종) | | **인스톨러** | UAC `requireAdministrator` 유지. SetupForm 다이아몬드 아이콘 `FillRoundRect`로 둥근 모서리. 바로가기 `IconLocation` 설정 | | **UI 통일** | 알림 카테고리 CheckBox → ToggleSwitch. Ollama/vLLM 서버 주소 라벨 "기본 서버 주소"로 통일. 개발자 정보창 기여자 표시 (`about.json` contributors). 창 높이 조정 | ### v1.3.1 | 구분 | 내용 | |------|------| | **SnapHandler 레이아웃 확장** | 기존 11개 → 22개 스냅 옵션. 3등분(third-l/c/r), 2/3+1/3(two3-l/r), 3분할 조합(l-rt, l-rb, r-lt, r-lb) 추가 | | **Everything SDK 연동** | `es` 프리픽스로 Everything 초고속 파일 검색 통합. Everything 미설치 시 graceful fallback. 파일 타입별 아이콘 구분 | | **플러그인 자동 설치** | `PluginHost.InstallFromZip()` — 로컬 zip에서 DLL/JSON 스킬 자동 추출·등록·로드. `UninstallPlugin()` 제거 기능 포함. URL 기반 설치는 사내 보안 정책으로 제외 | | **이미지 클립보드 영속화** | 클립보드 히스토리 이미지 항목을 PNG→Base64로 DPAPI 암호화 저장/복원. 앱 재시작 후에도 이미지 히스토리 유지 | | **다크 테마 대비 강화** | 6종 다크 테마 SecondaryText/PlaceholderText/HintText 밝기 +12~20 추가 개선. 헬프/단축키 창 텍스트 가독성 향상 | | **인스톨러 버전 동기화** | SetupForm.cs `AppVer` 1.2.2→1.3.1 수정. 버전 관리 체크리스트에 MCP 버전·로드맵 문서 항목 추가 | | **사용자 가이드 업데이트** | version-tag v1.2.2→v1.3.1, v1.3.0/v1.3.1 버전 이력 추가, version-tag에 `color:#fff` 추가 | | **헬프 창 업데이트** | v1.3.1 신기능 항목 추가, 파일 타입별 심볼 12종 추가 (Excel/Word/Pdf/Image/Video/Music/Archive/Code 등) | | **문서 정비** | AI_Service_Review.html → AGENT_ROADMAP.html 병합 후 삭제, 기술부채 항목 완료 표시, LAUNCHER_ROADMAP 생성 | ### v1.3.0 | 구분 | 내용 | |------|------| | **MCP 클라이언트** | McpClientService (stdio/JSON-RPC 2.0). ConnectAsync → initialize → tools/list → tools/call. McpTool이 IAgentTool로 래핑 | | **모델 폴백** | LlmService.SendAsync에 FallbackModels 순차 시도. 실패 시 토스트 알림으로 폴백 모델 안내 | | **대화 분기** | ChatConversation.ParentId/BranchLabel, ForkConversation(). 우클릭 "여기서 분기" 메뉴. 사이드바 들여쓰기 표시 | | **커맨드 팔레트** | CommandPaletteWindow (Ctrl+Shift+P). 16개 명령, 한글 초성 검색 | | **보안 감사 로그** | AuditLogService — JSON 영속화, 30일 보관, 설정 토글 + 폴더 열기 버튼 | | **에이전트 자율성** | 동적 반복 한도 (도구 15+회 → 한도 2배, 최대 50). 다단계 반성 | | **토큰 관리** | TokenEstimator (모델별 비용, CJK 가중치). 상태바 비용 표시 | | **스플릿 뷰** | Code 탭 파일 수정 시 자동 프리뷰, AutoPreview 설정 | | **다중 서버** | RegisteredModel에 endpoint/apiKey 필드. 모델별 서버 라우팅 (Ollama/vLLM) | | **대화별 설정** | Permission/DataUsage/Mood를 대화별 독립 저장·복원 | | **DiffService** | LCS 기반 라인 diff (Added/Removed/Equal). GetSummary() 통계 | ### v1.2.2 | 구분 | 내용 | |------|------| | **AX.md 프로젝트 문맥 파일** | 작업 폴더에 AX.md를 만들면 Cowork/Code 시스템 프롬프트에 자동 주입. 상위 3단계까지 탐색, 최대 8000자 | | **팁 알림 시스템** | Cowork/Code 탭 전환 시 24개 사용법 팁 랜덤 표시. 설정: 표시 여부(ShowTips) + 자동 사라짐 시간(TipDurationSeconds, 0~30초) | | **개발자 모드** | 설정 → 공통 → 개발자 모드 (비밀번호 보호). 도구 호출 파라미터/결과 상세 표시 + 스텝별 승인/건너뛰기/중단 | | **통계 강화** | DailyUsageStats에 ChatCounts(탭별), TotalTokens/PromptTokens/CompletionTokens 추가. 통계 윈도우에 대화 빈도 + 토큰 사용량 14일 막대 차트 | | **무지개 글로우** | 메시지 전송 시 입력창 테두리에 7색 무지개 그라데이션 회전 애니메이션 (2초, LinearGradientBrush 회전) | | **런처 중복 제거** | IndexService: Path 기반 중복 방지. CommandResolver: 검색 결과에서 같은 Path 필터링 (2중 방어) | ### v1.2.1 | 구분 | 내용 | |------|------| | **Code 시스템 프롬프트 고도화** | Claude Code/OpenCode 벤치마크 기반 8단계 워크플로우 (ORIENT→BASELINE→ANALYZE→PLAN→IMPLEMENT→VERIFY→GIT→REPORT). 테스트 우선, 변경 영향 분석, 자기 검증 | | **GitTool** | 사내 GitHub Enterprise 연동. status/diff/log/add/commit/branch/checkout/stash/remote 지원. push/pull/fetch/rebase 차단 (사용자 직접 수행) | | **BuildRunTool lint/format** | action="lint", action="format" 추가. ESLint/Prettier(JS), Ruff/Black(Python), dotnet format(C#), checkstyle(Maven) 자동 매핑 | | **Grep 강화** | context_lines(0~5줄) 파라미터로 매치 전후 코드 표시, case_sensitive 파라미터로 대소문자 구분 제어 | | **FileEdit replace_all** | replace_all=true 시 모든 매치 일괄 교체. false면 기존 유일성 검증 유지 | | **루트 드라이브 차단** | C:\, D:\ 등 최상위 드라이브를 작업공간으로 설정하는 것을 차단 (하위 폴더 선택 필수) | | **프리셋 순서 정렬** | TopicPreset.Order 필드 추가, JSON에서 order 값으로 표시 순서 제어 | | **카테고리 필터 개선** | Cowork/Code: 프리셋 카테고리 기반 필터, 커스텀 프리셋 `__custom__` 통합 분류 | | **에이전트 이름 매핑** | Code 카테고리별 에이전트 이름 (코드개발/리팩터링/코드리뷰/보안점검/테스트) + 대화 이력 아이콘 정확 표시 | | **AI Agent 상세 가이드** | 사용자 가이드에 Chat/Cowork/Code 3탭 상세 설명, 경고 문구 (백업 필수), 공통 기능 안내 | | **보안 점검 리네이밍** | "보안 취약점 점검" → "보안 점검"으로 간결하게 변경 | ### v1.2.0 | 구분 | 내용 | |------|------| | **Code 탭 활성화** | 코딩 에이전트 탭 활성화 — 코드 개발, 리팩터링, 코드 리뷰, 보안 점검, 테스트 작성 5개 프리셋 | | **DevEnvDetectTool** | IDE(VS Code, Visual Studio, IntelliJ, PyCharm) + 런타임(dotnet, python/conda, java, node, gcc) + 빌드도구(MSBuild, Maven, Gradle, CMake) 자동 감지. 레지스트리+PATH+환경변수, 60초 캐시 | | **BuildRunTool** | 프로젝트 타입 감지(*.csproj, pom.xml, package.json 등 7종) + 빌드/테스트/실행 명령 자동 매핑 | | **CodeSettings** | Nexus URL, NuGet/PyPI/Maven/npm 저장소 설정, 선호 IDE 경로, 빌드 타임아웃(30~300초), 완료 알림 | | **Code 시스템 프롬프트** | 분석→계획→구현→검증→보고 5단계 워크플로우, 언어별 가이드라인(C#/Python/Java/C++/JS), 패키지 저장소 주입 | | **설정 UI** | Code 탭 전용 설정 패널 — Nexus 저장소, 언어별 소스 URL, IDE 경로, 빌드 타임아웃, 완료 알림 | | **마크다운 렌더러 완성** | 테이블(`\|`), 인용(`>`), 취소선(`~~`), 링크(`[text](url)`) 지원 추가 | | **메시지 삭제** | 우클릭 → "이후 메시지 모두 삭제" (확인 다이얼로그 + 재렌더링) | | **탭 단축키** | Ctrl+1=Chat, Ctrl+2=Cowork, Ctrl+3=Code | | **에러 복구 UI** | LLM 오류 시 "재시도" 버튼 자동 표시 | | **카테고리 필터 개선** | Cowork/Code: 프리셋 카테고리 기반 필터, 커스텀 프리셋 통합 분류 | | **에이전트 이름 확장** | Code 프리셋별 에이전트 이름 매핑 (코드 개발/리팩터링/리뷰/보안/테스트) | | **최대화 버튼** | 타이틀바에 최소화-최대화-닫기 3버튼 | | **서브 바** | 탭 바 아래에 대화 제목(좌) + 미리보기 버튼(우) 분리 배치 | | **완료 알림** | Cowork/Code 에이전트 완료 시 시스템 트레이 알림 | ### v1.1.1 | 구분 | 내용 | |------|------| | **WebView2 프리뷰** | IE 기반 WebBrowser → Chromium 기반 WebView2 교체. AppData에 데이터 디렉터리 지정 | | **Markdown 프리뷰** | Markdig NuGet으로 .md 파일을 무드 CSS 적용 HTML 렌더링 | | **코드 블록 강화** | 라인 번호, 전체화면 팝업, 파일 저장 버튼, 언어별 확장자 자동 추천 | | **무드 갤러리** | 텍스트 목록 → 2열 비주얼 카드 레이아웃으로 무드 미리보기 선택 | | **에이전트 진행률 스티키 바** | 메시지 상단 고정 바 — 단계/퍼센트/경과시간, 완료 시 페이드아웃 | | **파일 빠른 작업** | 생성 파일 배너에 [프리뷰][열기][폴더][복사] 4개 인라인 액션 버튼 | | **작업 폴더 파일 탐색기** | 접이식 TreeView, 지연 로딩, 우클릭 메뉴(열기/삭제/이름변경), 에이전트 파일 생성 시 자동 새로고침, 상태 저장 | | **document_review 도구** | 빈 섹션, 플레이스홀더, 날짜 정합성, HTML 태그 균형, 반복 텍스트, 기대 섹션 누락 검사 | | **format_convert 도구** | md→html, html→txt, csv→html, md→txt 변환. 미지원 변환은 대안 워크플로우 안내 | | **대화 내 검색** | Ctrl+F 검색 바, 이전/다음 탐색, 결과 개수 표시, ESC 닫기 | | **메시지 우클릭 메뉴** | 텍스트 복사, 마크다운 복사, 인용 답장, 재생성 | | **토스트 알림** | 복사/저장 등 액션 시 하단 중앙 페이드인-아웃 알림 | | **대화 목록 성능** | 레이지 로딩 (50개 단위 + "더 보기"), 제목+내용 통합 검색 (Preview 필드) | | **의사결정 UI** | 승인/수정/취소 버튼 선택 후 자동 숨김 + 결과 라벨 표시 | | **채팅 반응형 너비** | 창 크기에 비례하여 메시지 버블 MaxWidth 자동 조절 (최소 500, 최대 1200) | | **커스텀 프리셋/무드** | 아이콘 셋 선택 UI (5카테고리×8아이콘), 커스텀 무드 CSS 편집, 프리셋 배지 | | **탭 전환 안정화** | Auto 권한 경고 초기화, 파일 탐색기 상태 복원, 안내문구 갱신 | | **런처 개선** | 퍼지 검색 Shift+Enter로 폴더 열기, 웹검색 경고문 수정 | ### v1.1.0 | 구분 | 내용 | |------|------| | **Cowork 에이전트 루프 엔진** | LLM Function Calling 기반 Plan→Tool Execute→Observe→Re-evaluate 반복 루프. 최대 25회 반복, 실패 시 Self-Reflection 자동 재시도 (최대 3회) | | **도구 시스템 (8종)** | file_read, file_write, file_edit, glob, grep, process, folder_map, document_read | | **문서 생성 스킬 (6종)** | excel_create (.xlsx), docx_create (.docx), csv_create (.csv), markdown_create (.md), html_create (.html), script_create (.bat/.ps1) | | **디자인 템플릿 시스템** | 10종 CSS 무드 템플릿 (modern, professional, creative, minimal, elegant, dark, colorful, corporate, magazine, dashboard). 대화창 하단 무드 아이콘 바로 선택 | | **Task Decomposition** | LLM 응답에서 계획 단계 자동 추출 → 진행률 UI (단계 카드 + 프로그레스 바) | | **Thinking UI** | LLM 추론 과정을 "Thinking..." 배너로 실시간 표시 | | **Context Condenser** | 토큰 초과 시 이전 대화를 LLM으로 자동 요약하여 컨텍스트 윈도우 관리 | | **Folder Map 도구** | 작업 폴더 디렉토리 트리 자동 생성 (depth/filter 지원, 빌드 산출물 자동 제외) | | **Diff Preview** | file_edit 도구 실행 시 unified diff 생성 + 색상 하이라이팅 UI (추가=초록, 삭제=빨강) | | **문서 읽기 도구** | PDF (PdfPig), DOCX, XLSX (OpenXml), CSV/TXT 등 다양한 형식 텍스트 추출. 보고서 작성 시 폴더 데이터 자동 참조 | | **폴더 데이터 활용 설정** | 적극 활용(자동 탐색) / 소극 활용(요청 시) / 활용하지 않음 — 설정 + 대화창 하단 메뉴에서 전환 | | **Cowork 설정 UI** | 파일 접근 권한, 출력 형식, 자동 미리보기, 에이전트 반복/재시도 횟수, 로그 상세도, 데이터 활용 수준 | | **커스텀 폴더 메뉴** | 시스템 ContextMenu → 커스텀 Popup (Border+MouseLeftButtonUp 패턴, 14px 폰트) | | **모델 선택기 개선** | 서비스 변경 시 팝업 유지, 모델 목록 동적 재구성 (closeOnClick 패턴) | | **Gemini 모델 수정** | 존재하지 않는 모델 ID(gemini-3-flash 등) → 실제 모델(gemini-2.5-pro/flash 등)로 교체 | | **에이전트 이벤트 UI** | Planning/StepStart/StepDone/ToolCall/ToolResult 배너 + 접이식 상세 보기 | ### v1.0.7 | 구분 | 내용 | |------|------| | **Chat/Cowork/Code 3탭 UI** | 상단 탭을 Agent 단일 → Chat \| Cowork \| Code 3탭으로 전환. Cowork/Code 탭 활성화 (Phase 2/3 준비) | | **작업 폴더 선택 바** | 입력 바 상단에 폴더 경로 표시 + 선택/해제 버튼. Cowork/Code 탭에서 자동 표시. 최근 폴더 10개 기억 | | **파일 컨텍스트 첨부** | 파일 첨부 버튼 + 드래그 앤 드롭으로 파일을 대화 컨텍스트에 추가 (최대 10MB). 텍스트 파일 내용 자동 삽입 | | **권한 시스템 설계** | 3단계 파일 접근 권한: Ask(매번 확인) / Auto(자동 허용) / Deny(차단). 설정에서 기본값 변경 가능 | | **대화 주제 프리셋 7종** | 일반/경영/연구개발/제품분석/수율분석/제조기술/시스템 — JSON 기반 프리셋 동적 로드 (EmbeddedResource) | | **대화 내보내기 확장** | Markdown + JSON + HTML + Text 4종 포맷 지원. HTML은 다크 테마 스타일 내장 | | **메시지 타임스탬프** | 사용자/AI 메시지에 HH:mm 시간 표시 | | **격려 알림 주기 타이머** | 주기적 타이머 추가 — 화면 잠금 없이도 설정 간격마다 격려 문구 팝업 표시 | | **커스텀 메시지 박스** | 앱 전체 기본 MessageBox를 테마 통합 커스텀 다이얼로그로 교체 (인스톨러 포함) | ### v1.0.6 | 구분 | 내용 | |------|------| | **스트리밍 실시간 표시 수정** | 80ms 쓰로틀 + Task.Delay → 청크 단위 갱신 + `Dispatcher.InvokeAsync(Background)` 방식으로 전환. 응답이 실시간으로 부드럽게 표시 | | **Shift+Enter 줄바꿈** | `AcceptsReturn="True"` + PreviewKeyDown 핸들러. Shift+Enter=줄바꿈, Enter=전송. 입력 영역 자동 수직 확장 (MinHeight 40 → MaxHeight 160) | | **프롬프트 카드 워터마크** | 프롬프트 카드 선택 시 안내 문구를 실제 텍스트가 아닌 워터마크(placeholder) 오버레이로 표시. 입력 시 자동 사라짐 | | **좋아요/싫어요 상호 배타 토글** | 좋아요↔싫어요 상호 배타 — 하나를 누르면 다른 쪽 자동 해제. `resetSibling`/`registerReset` 콜백 패턴 | | **디스크 용량 초과 자동 삭제** | 드라이브 사용률 98% 초과 시 핀 고정 제외 오래된 대화부터 자동 삭제 (`PurgeForDiskSpace`). 2% 여유 확보 후 중단 | | **우클릭 컨텍스트 메뉴** | 대화 제목에서 우클릭 시 커스텀 메뉴 바로 표시 (펜 아이콘 클릭 불필요). `MouseRightButtonDown` 이벤트 | | **대화 더블클릭 오류 수정** | Visual 자식 인덱스 충돌 오류 — `RemoveAt`+`Insert` 패턴으로 안전 교체 + 스트리밍 중 대화 전환 시 `_streamCts?.Cancel()` 처리 | ### v1.0.5 | 구분 | 내용 | |------|------| | **AX Agent 대화 창** | `!` 예약어로 AI 대화 창 (ChatWindow) 구현. 좌측 대화 목록 + 우측 메시지 영역 2패널 구조. Claude Desktop 스타일 디자인 | | **LLM 4종 서비스 지원** | Ollama, vLLM(OpenAI 호환), Gemini, Claude API 통합. 설정 창에서 서비스/모델 등록 및 전환 | | **스트리밍 + 타이핑 효과** | SSE 기반 스트리밍 응답. 12ms 타이머로 1~3글자씩 타이핑 효과 표시. 커서 깜빡임 애니메이션 | | **마크다운 + 코드 구문 강조** | 코드 블록(10개 언어 키워드 하이라이팅), 목록, 볼드, 인라인 코드, 복사 버튼 | | **토큰 사용량 표시** | 각 서비스별 실제 토큰 파싱. k/m 단위 표기 (1.2k, 2.3m). 응답 소요시간(초) 실시간 표시 | | **프롬프트 카드** | 개발자 미리 설정 시스템 프롬프트 (Tag 형식). 카드 클릭 시 SystemCommand 자동 삽입 + placeholder 안내 | | **사용자 프롬프트 템플릿** | 설정에서 추가/삭제 가능한 사용자 정의 프롬프트 템플릿. 입력 바 왼쪽 버튼으로 접근 | | **대화 관리** | 고정/이름변경/분류(6종 카테고리)/삭제. 커스텀 Popup 메뉴. 인라인 제목 편집 (클릭 → 입력 → Enter) | | **피드백 영속성** | 메시지별 좋아요/싫어요 상태 저장 및 대화 로드 시 복원 | | **사용자 메시지 편집/복사** | 사용자 메시지에 편집/복사 버튼 추가. 편집 시 해당 메시지 이후 재생성 | | **커스텀 Popup 메뉴 통일** | 모든 드롭다운 메뉴를 ContextMenu → 커스텀 Popup (12px 라운드, 호버, 드롭섀도) 으로 전환 | | **캡처 순서 변경** | cap 명령 아이템 순서: 영역 선택 → 활성 창 → 스크롤 → 전체 화면 (사용 빈도순) | | **지연 캡처** | Shift+Enter로 캡처 아이템 선택 시 타이머(3초/5초/10초) 선택 후 카운트다운 캡처 | | **버그 수정** | 목록 텍스트 오버플로(StackPanel→Grid), 편집 Visual 자식 오류, + 버튼 클릭 불가, 제목 편집 이중 커밋 크래시 | ### v1.0.4 | 구분 | 내용 | |------|------| | **설정 알림 바로보기 버튼** | 알림 탭 하단에 "바로보기" 버튼 추가. 시간 미도래 시에도 설정한 위치·표시 시간으로 팝업 즉시 확인 가능 | | **런처 안내 문구 랜덤화** | 고정 플레이스홀더 "무엇을 도와드릴까요?" → 25종 랜덤 문구. 정중한 인사 + 기능 홍보(계산기·클립보드·웹검색·즐겨찾기·스니펫·워크스페이스·캡처 등). 런처 열릴 때마다 교체. 5개국어 대응(ko/en/ja/zh/vi) | | **다이아몬드 픽셀 아이콘 애니메이션** | 런처 입력창 좌측 4개 픽셀이 순차적으로 Opacity 점멸 (4초 주기 Forever). 디스플레이 패널 픽셀 점등 형상화 | | **글로벌 단축키 콤보박스** | 불안정한 키 녹화 방식 제거 → 검증된 12종 키 조합 콤보박스 선택으로 변경. Alt+Space, Ctrl+Space, Ctrl+Alt+Space, Alt+X/A/Z, Ctrl+Shift+Space, Ctrl+`, Win+Space, Ctrl+Alt+A, Ctrl+;, F12 | | **트레이 메뉴 개편** | "사용 가이드 문서보기" 항목 신규 추가 (GlyphGuide = `\uE736`). "정보" → "개발자 정보"로 이름 변경 + 종료 바로 위로 위치 이동 | | **사용 통계 화면 FHD 최적화** | 창 높이 640→900px, MinHeight 540→700px. 차트 막대 높이 110→88px (MaxBarHeight 80→66). 자주 쓴 명령어 표시 개수 8→10개. 인기 명령어·즐겨찾기 섹션 간 마진 추가 | | **사용 가이드 문서 배포** | `Assets/AX Commander 사용가이드.htm` 빌드 시 출력 폴더에 자동 복사. 트레이 메뉴에서 기본 브라우저로 열기. 버전 이력 섹션 포함 (v1.0.0 ~ v1.0.4) | ### v1.0.3 | 구분 | 내용 | |------|------| | **키보드 단축키 16종 추가** | 1차: F1(도움말), F5(인덱스 새로 고침), Delete(항목 제거+확인), Ctrl+L(입력 초기화), Ctrl+C(이름 복사), Ctrl+Shift+C(경로 복사), Ctrl+Shift+E(탐색기 열기), Ctrl+Enter(관리자 실행), Alt+Enter(속성 보기). 2차: Ctrl+H(히스토리), Ctrl+R(최근), Ctrl+B(즐겨찾기), Ctrl+K(단축키 도움말), Ctrl+1~9(N번째 실행), F2(이름 바꾸기), PageUp/Down(페이지 스크롤) | | **결과 목록 번호 뱃지** | 1~9 번호 표시 (IndexToNumberConverter). Ctrl+N으로 즉시 실행 연동 | | **토스트 오버레이** | 별도 ToastOverlay Border (녹색 배경+체크 아이콘). 경로 복사 등 결과 표시, 2초 자동 숨김 | | **도움말 검색** | HelpDetailWindow 상단에 SearchBox 추가. 실시간 키워드 필터링 (제목/명령/설명/카테고리) | | **액션 모드 확장** | → 진입 시 7개 옵션: 경로 복사, 전체 경로 복사, 탐색기, 관리자, 터미널, 속성 보기, 이름 바꾸기 | | **도움말 창 3탭 메뉴 재설계** | 상단 메뉴를 개요/단축키 현황/예약어 현황 3탭으로 분리. 하위 카테고리 탭 유지. 숫자키 1/2/3으로 탭 전환 | | **프리픽스 변경** | `~` → 워크스페이스 관리 (기존 `!`), `cd` → 폴더 별칭 (기존 `~`), `!` → 비어있음 (신기능 배정 가능) | | **설정 버전 마이그레이션** | SettingsService에 `MigrateIfNeeded()` 프레임워크 추가. 이전 버전 settings.json을 최신 스키마로 자동 마이그레이션. 신규 프로퍼티는 C# 기본값 자동 적용. 구조 변경(키 이름 변경 등)은 버전별 마이그레이션 로직 순차 실행 | | **파괴적 동작 확인** | Delete 키 실행 시 MessageBox 확인 다이얼로그 (OK/Cancel) | | **토스트 알림** | LauncherWindow에 ShowToast() 메서드 추가. 경로 복사 등 결과를 IndexStatusText에 임시 표시 | | **Windows 실행 명령 (`^`)** | `^ notepad`, `^ cmd`, `^ calc` 등 Win+R 실행 창과 동일한 명령 실행. RunHandler 신규 추가 | | **기본 앱 별칭 강화** | `note`, `txt` → 메모장, `msword`/`msexcel`/`mspowerpoint` + 확장자(`docx`, `xlsx`, `pptx`, `csv`, `doc`, `xls`, `ppt`) → 해당 Office 앱. Score 부스트(95)로 항상 최상단 표시 | | **인스톨러 UI 아이콘** | 폼 아이콘(타이틀바+작업표시줄)에 다이아몬드 픽셀 아이콘 반영 | | **Help 창 확대** | 880→1020px 너비 확대 + 카테고리 탭 패딩 축소 → 가로 스크롤 없이 모든 탭 표시 | | **Help 개요 갱신** | 개요 문구에 v1.0.3 표기, 폴더 검색·루틴·일지·한글 앱 실행 기능 반영, 웹검색 예시(`?n` 네이버) 추가 | | **코드 품질 개선** | ShowIndexingProgress 오버레이 누수 수정(finally 제거), RunHandler Process.Dispose, IndexService volatile, HelpDetailWindow 상수 추출, SetupForm Icon null 체크 | ### v1.0.2 | 구분 | 내용 | |------|------| | **빠른 실행 Placeholder** | 입력 필드에 힌트 텍스트 표시 (키워드, 표시 이름, 경로). ModernTextBox 템플릿에 `Tag` 기반 워터마크 추가 | | **기본 앱 별칭 19종** | 한글+영문 이름으로 즉시 실행: 메모장/notepad, 계산기/calc, 엑셀/excel, 워드/word, 파워포인트/ppt, 탐색기/explorer, cmd, powershell, 그림판/paint, 캡처/snip, Edge, Teams, VS Code, Outlook, 원격/rdp, 작업관리자/taskmgr 등. 실제 설치된 앱만 자동 감지 | ### v1.0.1 | 구분 | 내용 | |------|------| | **인스톨러 통합** | 온라인/오프라인 2종 → 오프라인 1종으로 통합. .NET Framework 4.8 기반 (Windows 기본 포함). 관리자 권한 자동 요청 (app.manifest `requireAdministrator`) | | **검색 확장자 설정** | 설정 → 일반 탭에 태그형 확장자 UI. 기본 30+종 (실행/문서/텍스트/이미지). 사용자 추가/삭제 가능 | | **폴더 인덱싱** | 인덱스 경로의 1단계 하위 폴더도 검색·열기 가능 | | **인덱싱 현황 표시** | 런처 하단에 `✓ N개 항목 색인됨 (X.X초)` 자동 표시 → 5초 후 사라짐. 설정 저장 시 프로그레스 오버레이 | | **Help 인기 탭** | ⭐ 인기 탭 추가 (2번째 위치). 파일검색/웹검색/클립보드 핵심 기능만 필터 | | **다이아몬드 픽셀 아이콘** | 런처 입력창 좌측 + 정보 창 + 트레이 + 인스톨러 헤더에 벡터 다이아몬드 아이콘 적용 | | **정보 창 아이콘** | 비트맵 ICO → 벡터 Canvas 렌더링 (해상도 독립, DPI 무관 선명) | | **언어 라벨** | 설정 → Language (영어 표기로 변경, 다국어 사용자 접근성) | | **버그 수정** | HelpDetailWindow 인기 탭 연산자 우선순위 버그 (`&&`/`||`), DispatcherTimer 중복 생성 방지, Installer nullable 경고 13개 해소 | ### v1.0.0 정식 릴리즈. 40개+ 명령어, 9종 테마, 11개 설정 탭, 클립보드 DPAPI 암호화, 잠금 해제 알림, 화면 캡처, 모던 트레이 메뉴, 설정 가져오기/내보내기. --- ## 개발 검토 — 워크플로우 병목 분석 그래프 > **상태**: 검토 완료 · 구현 대기 > **검토일**: 2026-03-30 > **대상**: 개발자 모드 전용 기능 ### 배경 WorkflowAnalyzerWindow(타임라인 뷰)와 AgentStatsDashboardWindow(통계 대시보드)가 이미 구현되어 있으나, **실시간으로 어디가 병목인지 시각적으로 보여주는 그래프**가 없음. 에이전트 실행 중 "LLM 호출이 느린 건지, 특정 도구가 느린 건지" 판단이 어려움. ### 현재 보유 기반 | 구성요소 | 상태 | 위치 | |----------|:----:|------| | WorkflowAnalyzerWindow | ✅ | `Views/WorkflowAnalyzerWindow.xaml(.cs)` — 이벤트 타임라인, 요약 카드 | | AgentEvent.ElapsedMs | ✅ | 각 도구 실행 소요시간 수집중 | | AgentEvent.InputTokens/OutputTokens | ✅ | LLM 호출별 토큰량 수집중 | | AgentEvent.Iteration | ✅ | 반복 번호 수집중 | | AgentStatsDashboardWindow | ✅ | `Views/AgentStatsDashboardWindow.xaml(.cs)` — 일별 바 차트, 도구 빈도 | | LLM 호출 자체의 소요시간 | ❌ 미수집 | `SendWithToolsAsync` 전후 Stopwatch 추가 필요 | | 차트 라이브러리 | ❌ 불필요 | 모든 차트를 WPF Canvas+Rectangle 직접 구현 | ### 추가 구현 대상 — 3종 시각화 #### ① 워터폴 차트 (시간 흐름 + 병목 색상) ``` 시간 → 0s 2s 4s 6s 8s 10s ├───────┼───────┼───────┼───────┼───────┤ LLM 1 ████████ 2.1s (토큰 1.2K) Tool 1 ███ 0.8s folder_map LLM 2 ████████████ 3.5s (토큰 2.8K) ← 🔴 병목! Tool 2 █ 0.2s file_read LLM 3 ████ 1.2s (토큰 1.5K) Tool 3 ██████ 1.8s html_create ``` - **빨간 바**: 가장 긴 구간 (병목), **주황**: 평균 이상, **녹색**: 정상 - LLM 호출과 도구 실행을 구분하여 시간 소비 패턴을 직관적으로 표현 - **구현**: Canvas + Rectangle, 색상 임계값 자동 계산 (평균 × 1.5 = 주황, × 2.0 = 빨강) - **전제 조건**: LLM 호출 소요시간 수집 (`SendWithToolsAsync` 전후 Stopwatch) #### ② 도구별 누적 소요시간 바 차트 ``` 도구별 소요시간 (이번 세션) ───────────────────────────────────── html_create ████████████████████ 4.2s ← 🔴 최다 file_read ████████ 1.8s folder_map ████ 0.9s grep ██ 0.4s LLM 호출 ██████████████████████████ 7.1s ``` - 현재 AgentStatsDashboardWindow의 도구 빈도 바 차트와 동일 패턴 - ElapsedMs 기준 내림차순 정렬 - 실시간: 이벤트 수신 시 `Dictionary`에 누적 후 바 재렌더링 - **구현 난이도**: 낮음 — 기존 코드 복제 수준 #### ③ 반복별 토큰 추세선 ``` 토큰 ↑ 3000 │ ● │ ● ● 2000 │ ● ● │● ● 1000 │ 0 └───┬───┬───┬───┬───┬───┬──→ 반복 1 2 3 4 5 6 ``` - 꺾은선 그래프: Canvas + WPF `Polyline` (기본 도형) - 입력 토큰 지속 증가 패턴 감지 → **"⚠ 컨텍스트 크기 급증"** 경고 배지 - **구현 난이도**: 중간 ### 구현 비용 분석 | 항목 | 예상 코드량 | 앱 크기 영향 | 비고 | |------|------------|:----------:|------| | LLM 호출 시간 수집 | ~5줄 | 0 | AgentLoopService에 Stopwatch 추가 | | 워터폴 차트 | ~150줄 | 0 | Canvas+Rectangle | | 도구별 바 차트 | ~80줄 | 0 | 기존 바 차트 패턴 복제 | | 토큰 추세선 | ~100줄 | 0 | Canvas+Polyline | | 외부 차트 라이브러리 | 불필요 | 0 | WPF 기본 기능으로 충분 | | **합계** | **~335줄** | **0KB** | | ### 권장 구현 순서 | Phase | 범위 | 효과 | |-------|------|------| | **Phase 1** (즉시 가능) | LLM 호출 시간 수집 + 도구별 바 차트 | "어떤 도구가 느린지" 즉시 파악 | | **Phase 2** (다음) | 워터폴 차트 | 시간 흐름에서 LLM vs 도구 비율 시각화 | | **Phase 3** (선택) | 토큰 추세선 + 컨텍스트 폭발 경고 | 고급 디버깅용 | ### 결론 | 관점 | 평가 | |------|------| | 기술 가능성 | ✅ 높음 — 데이터 수집 90% 완성, 차트는 기존 패턴 재활용 | | 구현 난이도 | 중~하 — 외부 라이브러리 불필요 | | 사용자 가치 | 높음 — "왜 느린지" 원인 즉시 파악 가능 | | 앱 크기 | 0 영향 — 코드만 추가 | | 배치 위치 | WorkflowAnalyzerWindow 내부 (요약 카드 아래, 타임라인 위) | --- ## 개발 검토 — 에이전트 루프 검증 강제 (Post-Tool Verification) > **상태**: 구현 완료 > **검토일**: 2026-03-31 > **대상**: Cowork/Code 모드 에이전트 루프 ### 배경 — 업계 오픈소스와의 비교 에이전트 루프가 문서 생성 후 검수를 하지 않는 문제가 관찰됨. OpenHands(구 OpenDevin), Claude Code, Cursor 등 주요 오픈소스/상용 서비스의 에이전트 루프를 분석한 결과, **업계 전체가 동일한 구조적 한계**를 가지고 있음을 확인. #### 아키텍처 비교 | 항목 | AX Copilot | OpenHands | Claude Code | |------|-----------|-----------|-------------| | 루프 구조 | while + SendWithToolsAsync | while + agent.step(state) | while + tool_use | | **반복당 LLM 호출** | **1회** | **1회** | **1회** | | **검증 강제** | **✅ v1.7.1 구현** | ❌ 없음 | ❌ 없음 | | 계획 단계 | PlanMode 3모드 | 없음 (implicit) | 없음 | | 종료 조건 | 도구 호출 없음 | AgentFinishAction | 도구 호출 없음 | | 자기 반성 | Self-Reflection 프롬프트 | 없음 | 없음 | | 사용자 승인 | UserDecisionCallback | SecurityAnalyzer | 권한 프롬프트 | | 컨텍스트 압축 | ContextCondenser | 요약 기반 | 없음 | #### OpenHands 루프 의사코드 ```python # OpenHands: agent.step() = 1 LLM 호출 + 1 도구 실행 while budget > 0: action = agent.step(state) # 1 LLM call observation = runtime.run(action) # 1 tool execution state.update(action, observation) if action == AgentFinishAction: break # 검증 없음 — LLM이 자율적으로 다음 반복에서 확인 여부 결정 ``` #### AX Copilot 검증 강제 루프 (개선 후) ``` 반복 1: LLM → "계획 수립" + file_read → 기존 파일 확인 반복 2: LLM → "실행" + html_create → 문서 생성 ↳ ★검증 LLM 호출★ → file_read로 내용 확인 → 수정 필요 시 도구 호출 반복 3: LLM → 완료 응답 또는 추가 수정 ``` ### 구현 상세 | 구성요소 | 파일 | 내용 | |----------|------|------| | 설정 | `AppSettings.cs` | `EnablePostToolVerification` (bool, 기본 false) | | UI | `SettingsWindow.xaml` | "고품질 문서" 섹션에 토글 추가 | | 바인딩 | `SettingsViewModel.cs` | Load/Save 매핑 | | 엔진 | `AgentLoopService.cs` | `RunPostToolVerificationAsync()` + `IsDocumentCreationTool()` | #### 검증 대상 도구 | 도구명 | 설명 | |--------|------| | `file_write` | 일반 파일 쓰기 | | `docx_create` | Word 문서 생성 | | `html_create` | HTML 보고서 생성 | | `excel_create` | Excel 파일 생성 | | `csv_create` | CSV 파일 생성 | | `script_create` | Python 스크립트 생성 | | `pptx_create` | PowerPoint 생성 | #### 검증 프롬프트 구조 검증 LLM 호출 시 다음 4단계 체크리스트를 주입: 1. `file_read`로 생성된 파일 내용 읽기 2. 사용자 요청 대비 완전성 확인 3. 구조·형식 올바름 확인 4. 문제 발견 시 즉시 수정 도구 호출 ### 효과 | 관점 | Before (v1.7.0) | After (v1.7.1) | |------|-----------------|-----------------| | 문서 생성 후 확인 | LLM 자율 판단 (대부분 생략) | 강제 확인 + 수정 | | 반복당 최소 LLM 호출 | 1회 | 문서 생성 시 2회 | | 누락 섹션 | 사용자가 직접 발견 | AI가 자동 감지 | | 업계 비교 | OpenHands와 동일 | **차별화 포인트** | --- ## 양식 기반 문서 생성 (Template Mode) > **상태**: 구현 완료 > **적용일**: 2026-03-30 > **대상 스킬**: docx-creator, pptx-creator, xlsx-analyzer ### 개요 작업 폴더에 양식 파일(`.docx`, `.pptx`, `.xlsx`)을 넣어두면, 런타임 고급 스킬(`/docx-creator`, `/pptx-creator`, `/xlsx-analyzer`) 실행 시 **양식의 스타일·레이아웃을 자동으로 상속**하여 문서를 생성합니다. ### 동작 원리 ``` 사용자: "이번 달 보고서 작성해줘" ┌─ 스킬 시스템 프롬프트 ─────────────────────┐ │ 1. folder_map → 작업 폴더 스캔 │ │ 2. 양식 후보 탐색 (파일명 키워드 매칭) │ │ 3. 양식 발견 → document_read로 구조 파악 │ │ 4. Document('양식.docx') 기반 생성 │ │ (양식 없으면 → Document() 새 문서) │ └──────────────────────────────────────────┘ ``` ### 양식 감지 키워드 파일명에 다음 키워드가 포함되면 양식으로 자동 인식: | 키워드 | 예시 파일명 | |--------|------------| | 양식 | `월간보고_양식.docx` | | template | `report_template.pptx` | | 서식 | `서식_공문.docx` | | 표준 | `표준_발표자료.pptx` | | 기본 | `기본양식.xlsx` | 사용자가 명시적으로 파일명을 지정하면 키워드 무관하게 해당 파일을 양식으로 사용합니다. ### 스킬별 양식 활용 방식 | 스킬 | 양식 로드 | 상속되는 요소 | |------|----------|-------------| | **docx-creator** | `Document('양식.docx')` | 스타일, 머리글/바닥글, 로고, 페이지 설정, 글꼴 | | **pptx-creator** | `Presentation('양식.pptx')` | 마스터 슬라이드, 배경, 색 테마, 폰트, 레이아웃 | | **xlsx-analyzer** | `load_workbook('양식.xlsx')` | 셀 서식, 병합, 테두리, 열 너비, 차트 영역 | ### 구현 방식 C# 코드 변경 없이 **스킬 프롬프트(`.skill.md`)만 확장**하여 구현: - `skills/docx-creator.skill.md` — `## 양식 활용 (템플릿 모드)` 섹션 추가 - `skills/pptx-creator.skill.md` — `## 양식 활용 (마스터 슬라이드 템플릿)` 섹션 추가 - `skills/xlsx-analyzer.skill.md` — `## 양식 활용 (Excel 보고서 템플릿)` 섹션 추가 각 스킬의 Python 스크립트 템플릿에 양식 자동 감지 로직 포함: ```python template_keywords = ['양식', 'template', '서식', '표준', '기본'] template_file = None for f in os.listdir('.'): if f.endswith('.docx') and any(kw in f.lower() for kw in template_keywords): template_file = f break if template_file: doc = Document(template_file) # 양식 스타일 상속 else: doc = Document() # 새 문서 ``` ### 사내 활용 시나리오 | 시나리오 | 양식 파일 | 결과 | |---------|----------|------| | 월간 보고서 | `월간보고_양식.docx` (사내 표준 헤더·로고·페이지 설정) | 동일 규격의 보고서 자동 생성 | | 팀 발표 | `팀발표_양식.pptx` (부서 마스터 슬라이드) | 부서 디자인 유지 + 새 내용 | | 수율 분석 | `수율보고_양식.xlsx` (셀 서식·차트 영역 설정) | 양식에 데이터만 삽입 | | 공문 작성 | `공문_서식.docx` (사내 공문 규격) | 규격 유지 + 내용 작성 | ### 향후 고도화 | 단계 | 내용 | 공수 | |------|------|------| | 현재 (v1.6.1) | 스킬 프롬프트에서 양식 자동 감지 안내 | 완료 | | 다음 | 시스템 프롬프트에 양식 목록 자동 주입 (BuildCoworkSystemPrompt) | 낮음 | | 장기 | `.ax/templates/` 공용 양식 폴더 + 프로젝트 규칙에서 기본 양식 지정 | 중간 |