Files
AX-Copilot/docs/DEVELOPMENT.md
lacvet 05539b0d83 [v2.0.0] Phase 17/18 완료 — 멀티에이전트·Reflexion·훅·스킬 고도화 릴리즈
Phase 17 완료 표시 (AGENT_ROADMAP.md 갱신):
- 17-A1/A2: Reflexion 자기성찰 메모리 + 검증 강제 확대
- 17-B1/B2: TaskState Working Memory + AgentEventLog .jsonl 영속화
- 17-C1/C2/C3: 훅 11개 이벤트·4타입(Command/Http/Prompt/Agent) 완비
- 17-D1/D2/D3: 스킬 fork 격리·paths 자동활성화·user-invocable 필터

Phase 18 완료 표시:
- 18-C2 (AiSnippetHandler), 18-C3 (QuickLinkHandler)

버전 v1.8.0 → v2.0.0:
- AxCopilot.csproj, Installer.csproj, SetupForm.cs, McpClientService.cs

DEVELOPMENT.md 버전 이력 v2.0.0 추가
Phase 17 섹션 헤더: 차기 개발 →  완료

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-04 02:12:21 +09:00

2725 lines
179 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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<LauncherItem>`에 바인딩
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<ClipboardEntry>` 병합 대기 큐
- `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``<Resource Include="Themes/MyTheme.xaml"/>` 추가
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<ClipboardEntry>` 동등성 | ✅ 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` | `<Using Remove="System.Windows.Forms"/>` 추가 — 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<string, string> 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<T>()` 제공 |
| `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` | `<AllowUnsafeBlocks>true</AllowUnsafeBlocks>` 추가 |
**스크롤 캡처 동작 방식**:
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<IEnumerable<LauncherItem>> GetItemsAsync(string query, CancellationToken ct)
{
// query: 프리픽스 이후의 입력 텍스트
// LauncherItem의 Data 필드에 실행 시 필요한 데이터를 담아 반환
return Task.FromResult<IEnumerable<LauncherItem>>(
[
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<IEnumerable<LauncherItem>> 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` → `<Version>` | 버전 번호 변경 (설정 창·Windows 속성에 자동 반영) |
> | 2 | **인스톨러 프로젝트 버전** | `src/AxCopilot.Installer/AxCopilot.Installer.csproj` → `<Version>` | 인스톨러 어셈블리 버전 일치 |
> | 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 `<Version>`과 동일하게 유지하세요.**
>
> 설정 창(`SettingsWindow.xaml.cs → SetVersionText()`)과 정보 창(`AboutWindow.xaml.cs`)은
> 앱 본체 csproj `<Version>`을 리플렉션으로 읽으므로 별도 수정 불필요합니다.
> **⚠ 사용자 노출 문서 작성 원칙 (사용자 가이드 · 헬프 창)**
>
> 사용자 가이드(`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\<string\>) |
### 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<string, long>`에 누적 후 바 재렌더링
- **구현 난이도**: 낮음 — 기존 코드 복제 수준
#### ③ 반복별 토큰 추세선
```
토큰 ↑
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/` 공용 양식 폴더 + 프로젝트 규칙에서 기본 양식 지정 | 중간 |