Files
AX-Copilot/CLAUDE.md
lacvet 795ce835e2 [Phase 42-보완] CLAUDE.md 커밋 메시지 작성 규칙 추가
커밋 메시지 관련 지침 추가:
- 언어: 반드시 한글로 작성
- 제목: [PhaseXX] 한글 요약 형식
- 본문: 변경 파일·줄 수·주요 내용 항목별 상세 기술
- 모호한 영문 단독 커밋 금지

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-03 19:45:52 +09:00

814 lines
43 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 Copilot 개발 지시사항
이 파일은 모든 개발 세션에서 일관된 품질의 결과물을 보장하기 위한 필수 지시사항입니다.
---
## 0. 작업 완료 후 깃 푸시 규칙
### 매 작업 단위 완료 시 반드시 깃 푸시
- Phase 작업(기능 개발, 리팩터링 등) 완료 → `dotnet build` 확인 → 소스 파일만 스테이징 → 커밋 → 푸시
- **빌드 오류 없이 커밋** — `경고 0, 오류 0` 상태에서만 푸시
### 커밋 메시지 작성 규칙 (필수)
- **언어**: 반드시 **한글**로 작성
- **제목**: `[PhaseXX] 한글 요약 제목` 형식, 50자 이내
- **본문**: 작업 내용을 **항목별로 자세히** 기술 — 변경된 파일, 줄 수 변화, 주요 메서드/클래스 목록 포함
- **형식 예시**:
```
[Phase 42] ChatWindow.ResponseHandling·LlmService 파셜 분할
ChatWindow.ResponseHandling (1,494줄 → 741줄, 50% 감소):
- ChatWindow.MessageActions.cs (277줄): 버튼이벤트, 메시지검색, 에러복구
- ChatWindow.StatusAndUI.cs (498줄): 우클릭, 팁, AX.md, 글로우, 토스트, 하단바
LlmService (1,010줄 → 263줄, 74% 감소):
- LlmService.Streaming.cs (516줄): 스트리밍 응답, 백엔드별 구현
- LlmService.Helpers.cs (252줄): 헬퍼, 토큰 파싱, Dispose
- 빌드: 경고 0, 오류 0
```
- **금지**: 영문 단독 커밋 메시지, "fix", "update" 같은 모호한 한 단어 제목
### 오류 복구 불가 시 이전 버전 롤백
작업 중 오류가 복구되지 않으면 깃에서 이전 버전을 받아 작업:
```bash
# 마지막 커밋으로 전체 복구
git reset --hard HEAD
# 특정 커밋으로 복구 (git log로 커밋 해시 확인)
git reset --hard <커밋해시>
# 원격 최신 버전으로 완전 복구
git fetch origin
git reset --hard origin/main
```
- 복구 시도 2회 이상 실패 → 즉시 롤백, 사용자에게 알림
- 롤백 후 원인 분석 → 더 작은 단위로 재작업
### 스테이징 규칙 (빌드 산출물 제외)
```bash
# 소스 코드만 스테이징 (bin/, obj/ 제외)
git add src/AxCopilot/Views/
git add src/AxCopilot/Services/
git add src/AxCopilot/Models/
git add src/AxCopilot/Handlers/
git add src/AxCopilot/ViewModels/
git add src/AxCopilot/Themes/
git add src/AxCopilot/Core/
git add docs/
git add CLAUDE.md
# 절대 추가 금지: bin/, obj/, *.dll, *.exe, *.pdb
```
---
## 1. UI/UX 디자인 원칙
### 기본 컨트롤 사용 금지
- **ContextMenu, MenuItem** 사용 금지 → 커스텀 `Popup` (Border + MouseLeftButtonUp, 12px 라운드, 호버, 드롭섀도)
- **MessageBox** 사용 금지 → `CustomMessageBox.Show()` 사용
- **기본 CheckBox** 사용 금지 → `Style="{StaticResource ToggleSwitch}"` 좌우 슬라이드 토글
- **Popup 내부에 Button** 사용 금지 → `Border` + `MouseLeftButtonUp` 패턴 (포커스 캡처 방지)
- 수평 스크롤바 금지 → `WrapPanel` 자동 줄바꿈
### 테마 통일성
- 색상 하드코딩 금지 — XAML: `{DynamicResource PrimaryText}`, 코드비하인드: `TryFindResource("PrimaryText") as Brush ?? Brushes.White`
- 모든 UI 요소는 현재 적용된 테마 리소스(`LauncherBackground`, `ItemBackground`, `AccentColor`, `PrimaryText`, `SecondaryText` 등)를 사용
- 다크 테마 6종 모두에서 텍스트 가독성 확인 필수
### 코드비하인드 팝업/다이얼로그 테마 규칙
- **코드비하인드에서 생성하는 모든 팝업 Window/다이얼로그**도 현재 테마를 따라야 함
- 배경: `TryFindResource("LauncherBackground")`, 텍스트: `TryFindResource("PrimaryText")`, 보조 텍스트: `TryFindResource("SecondaryText")`
- 테두리: `TryFindResource("BorderColor")`, 아이템 배경: `TryFindResource("ItemBackground")`, 액센트: `TryFindResource("AccentColor")`
- 호버 효과 배경: `TryFindResource("ItemHoverBackground")`
- `#1A1B2E`, `Brushes.White` 등 고정 색상을 팝업에 직접 사용하는 것은 **금지** — 라이트/다크 테마 전환 시 색상 불일치 발생
- 팝업 Window에 테마 적용 패턴:
```csharp
// 팝업 생성 후 부모 창의 Resources를 팝업에 전달
popup.Resources.MergedDictionaries.Add(this.Resources);
// 또는 직접 리소스 조회
var bg = TryFindResource("LauncherBackground") as Brush ?? Brushes.White;
var fg = TryFindResource("PrimaryText") as Brush ?? Brushes.Black;
```
### 인터랙티브 요소
- 클릭 가능 영역 최소 36px, FontSize 최소 12px, Padding 최소 6px
- 호버/클릭 효과 필수 — `#18FFFFFF` 반투명 배경 + 핸드 커서
- 팝업은 `PopupAnimation="Fade"` 기본 적용
- 메뉴 항목 FontSize 13px 이상
### 아이콘 색상
- Segoe MDL2 Assets 아이콘은 가능한 한 **의미에 맞는 색상**을 적용 (단색 `SecondaryText` 지양)
- 메뉴 항목: 아이콘 + 라벨에 동일 색상 적용 (예: Ask=파랑, Auto=앰버, Deny=빨강)
- 하단 바: 각 버튼 아이콘에 기능별 색상 (포맷=보라, 파일=앰버, 권한=파랑, 데이터=녹색)
- 활성 상태 항목: `AccentColor` 또는 해당 기능 고유 색상으로 강조
### 설정 UI 패턴
- 켜기/끄기: ToggleSwitch 스타일 (Grid 좌: 라벨, 우: 토글)
- 선택형: 커스텀 Popup 드롭다운 (`[라벨: 현재값 ▾]`)
- AI/고급 설정 항목 옆에 `?` 도움말 아이콘 + 커스텀 다크 툴팁 (`HelpTooltipStyle`)
- 설정 저장 시 `CustomMessageBox`로 완료 알림
### 헬프 화면 (HelpDetailWindow) 규칙
- **버전 정보 금지** — 헬프에 버전별 신기능(예: "v1.6.0 신기능") 항목을 넣지 않으며, 앞으로도 추가하지 않음
- **영역별 핵심 기능만 표시** — 개요, AI, 업무 보조 등 영역별로 사용자가 "무엇을 할 수 있는지"만 간결히 설명
- **기술 보호 (IP 보호)** — 설명에서 내부 기술·구현 방식을 유추할 수 없어야 함. 아래 용어를 헬프에 직접 노출하는 것은 **금지**:
| 사용 금지 (내부 기술) | 대신 사용 (사용자 관점) |
|---------------------|----------------------|
| SSE, Server-Sent Events | "실시간 응답" |
| AES-256-GCM, DPAPI, 암호화 알고리즘명 | "암호화 저장", "안전하게 보호" |
| OpenXML, python-docx, openpyxl | "문서 생성", "파일 생성" |
| MCP, JSON-RPC, stdio | "외부 도구 연결" |
| LINQ, TF-IDF, LCS, Mustache | 기능 설명으로 대체 |
| Ollama, vLLM, Gemini, Claude (모델명) | "AI 서비스", "AI 모델" |
| OWASP, CVE | "보안 점검", "취약점 분석" |
| system_prompt.txt, 클래스명, 파일명 | 기능 설명으로 대체 |
---
## 2. 설정값 관리 원칙
### 신규 기능 → 설정 검토 필수
신규 기능 추가 시 사용자/개발자가 제어할 수 있는 설정값을 반드시 검토하고 추가합니다:
1. `AppSettings.cs`에 프로퍼티 + JsonPropertyName + 기본값 추가
2. `SettingsViewModel.cs`에 바인딩 프로퍼티 + Load/Save 매핑
3. `SettingsWindow.xaml`에 적절한 탭에 UI 컨트롤 배치
4. 도구(Tool) 클래스에서 설정값을 실제로 체크하여 동작에 반영
### Cowork / Code 설정 분리 원칙
에이전트 동작 설정은 **공통(LlmSettings)에 넣지 말고, Cowork/Code 각각에 배치**합니다:
- **Cowork 전용 설정**: `LlmSettings`에 직접 프로퍼티 추가 → SettingsWindow의 `AgentPanelCowork` 패널에 배치
- **Code 전용 설정**: `CodeSettings` 클래스에 프로퍼티 추가 → SettingsWindow의 `AgentPanelCode` 패널에 배치. XAML 바인딩은 `{Binding Code.PropertyName}`
- **진짜 공통인 경우만** `AgentPanelCoworkCode` 패널에 배치 (예: MaxAgentIterations, MaxRetryOnError)
- 검증 강제, 출력 형식, 폴더 데이터 활용 등 **탭마다 다르게 동작하는 기능**은 반드시 분리
- AgentLoopService에서 `ActiveTab == "Code"` 분기로 탭별 설정 참조
```csharp
// 탭별 설정 참조 패턴
var shouldVerify = ActiveTab == "Code"
? llm.Code.EnableCodeVerification
: llm.EnableCoworkVerification;
```
### 설정값이 코드에서 실제 동작해야 함
설정을 정의만 하고 코드에서 읽지 않는 것은 금지. 설정 체크 패턴:
```csharp
var app = System.Windows.Application.Current as App;
var enabled = app?.SettingsService?.Settings.Llm.Code.EnableLsp ?? true;
if (!enabled) return ToolResult.Ok("비활성 상태입니다. 설정에서 활성화하세요.");
```
---
## 3. 버전 관리 및 배포
### 버전 번호 규칙
- **소규모 배포** (버그 수정, 설정 추가, UI 개선): `+0.0.1` (예: 1.4.0 → 1.4.1)
- **대규모 기능 배포** (Phase 완료, 새 에이전트 도구, 핵심 기능): `+0.1.0` (예: 1.4.0 → 1.5.0)
### 버전 변경 시 반드시 수정할 파일 (체크리스트)
| # | 대상 | 파일 경로 | 수정 내용 |
|---|------|----------|----------|
| 1 | 앱 버전 | `src/AxCopilot/AxCopilot.csproj``<Version>` | 버전 번호 |
| 2 | 인스톨러 프로젝트 | `src/AxCopilot.Installer/AxCopilot.Installer.csproj``<Version>` | 동일 |
| 3 | 인스톨러 표시 | `src/AxCopilot.Installer/SetupForm.cs``AppVer` | 동일 |
| 4 | MCP 클라이언트 | `src/AxCopilot/Services/McpClientService.cs``clientInfo.version` | 동일 |
| 5 | 개발자 가이드 | `src/AxCopilot/Assets/AX Copilot 개발자가이드.htm` | 버전 이력 항목 추가만 (**헤더/푸터에 버전 번호 표기 금지**) |
| 6 | 사용자 가이드 | `src/AxCopilot/Assets/AX Copilot 사용가이드.htm` | 개발자 가이드에서 버전이력 섹션 제거 후 복사 (**헤더/푸터 버전 표기 없음**) |
| 7 | 가이드 암호화 | `src/AxCopilot/Assets/guide_dev.enc`, `guide_user.enc` | 가이드 수정 후 반드시 암호화 재실행 |
| 8 | 개발 문서 | `docs/DEVELOPMENT.md` | 버전 이력 추가 |
| 9 | 로드맵 문서 | `docs/AGENT_ROADMAP.md/html`, `docs/LAUNCHER_ROADMAP.md/html` | 버전 번호 갱신 |
### 가이드 문서 관리 워크플로우
가이드 문서는 **개발자 가이드가 마스터**이며, 사용자 가이드는 이를 기반으로 생성합니다:
1. **개발자 가이드 수정** (`AX Copilot 개발자가이드.htm`) — 버전 이력 항목 추가. **헤더 `version-tag` div 및 푸터 버전 번호는 표기하지 않음**
2. **사용자 가이드 생성** — 개발자 가이드를 복사한 뒤 **버전 이력 섹션 제거** (`<!-- 버전 이력 -->` ~ `</div><!-- /.version-section -->`). 헤더/푸터에 버전 번호 없음
3. **암호화 실행**`encrypt_guides.ps1` 스크립트 실행하여 `.enc` 파일 생성
4. **빌드**`.enc` 파일이 출력 폴더에 복사됨 (평문 .htm은 출력에 포함되지 않음)
```bash
# 가이드 암호화 명령 (프로젝트 루트에서)
powershell -ExecutionPolicy Bypass -File encrypt_guides.ps1
```
- 앱에서는 `GuideViewerWindow`가 암호화된 가이드를 복호화하여 내장 뷰어로 표시
- 개발자 모드 ON → 개발자 가이드 (버전이력 포함), OFF → 사용자 가이드 (버전이력 없음)
- 암호화 키: `GuideEncryptor.cs`에 고정 AES-256-CBC 키 내장 (모든 PC 동일)
### 사용자 노출 문서 작성 원칙 (사용가이드 · 헬프)
사용자 가이드와 헬프 화면은 **내부 기술이 노출되지 않도록** 작성합니다:
| 구분 | 사용 금지 (내부 기술) | 대신 사용 (사용자 관점) |
|------|---------------------|----------------------|
| 프로토콜 | MCP, JSON-RPC, stdio, P/Invoke, DPAPI | "외부 도구 연결", "암호화 저장" |
| 클래스명 | McpClientService, TokenEstimator, DiffService | 기능 설명으로 대체 |
| 내부 구조 | FallbackModels, SettingsViewModel, ParentId | "자동 전환", "설정", "분기" |
| 코드 패턴 | CJK 가중치, SWE-bench, LCS, TF-IDF | "더 정확한 분석", "검색 개선" |
**원칙**: 사용자에게는 "무엇을 할 수 있는지"만 전달합니다.
---
## 4. 코드 품질
### 빌드 기준
- 모든 변경 후 `dotnet build` 실행 → **경고 0, 오류 0** 필수
- CS8603 (nullable) 경고 즉시 수정
### 리소스 관리
- `IDisposable` 구현 객체는 반드시 해제 (PerformanceCounter, LspClientService 등)
- P/Invoke 메모리: `Marshal.AllocHGlobal``finally`에서 `FreeHGlobal`
- WinEvent 훅: `UnhookWinEvent` 보장
### 에이전트 도구 등록
-`IAgentTool` 구현 시 `ToolRegistry.CreateDefault()``Register()` 추가 필수
- 도구의 `Parameters` 스키마가 LLM function calling 명세에 정확히 맞는지 확인
---
## 5. AI 차단 버전 (클로드 버전) 패턴
AI 기능이 필요 없는 환경에 배포하거나, AI 기능 문의를 차단해야 할 때 사용하는 패턴입니다.
### 활성화/비활성화 제어 방법
`AppSettings.AiEnabled` (기본값 **`false`**) 한 곳만 바꾸면 전체 AI 기능이 제어됩니다.
| 조건 | 동작 |
|------|------|
| `AiEnabled = false` | **기본값 (배포 기본)** — AI 전체 차단 |
| `AiEnabled = true` | AI 활성화 — 비밀번호 인증 후 설정 가능 |
### AI 활성화 비밀번호
- 설정 창 > 일반 탭 > AI 기능 토글 ON 시 비밀번호 다이얼로그 표시
- 비밀번호: **`axgo123!`**
- 비밀번호 틀리거나 취소 시 토글 자동 복구 (OFF 유지)
- 비활성화(OFF)는 비밀번호 없이 즉시 적용
- 구현 위치: `SettingsWindow.xaml.cs` `AiEnabled_Changed()`
### AI 차단 시 적용되는 항목
| 항목 | 구현 위치 | 설명 |
|------|----------|------|
| `!` prefix 배지 숨김 | `LauncherViewModel.cs` `ActivePrefix`/`HasActivePrefix` | `!` prefix 인식 안 함 |
| `!` 입력 시 결과 없음 | `ChatHandler.cs` `GetItemsAsync` | 빈 리스트 반환 (항목 자체 미표시) |
| `!` 실행 차단 | `ChatHandler.cs` `ExecuteAsync` | 실행 불가 |
| 트레이 메뉴 항목 숨김 | `App.xaml.cs` `Opening` 이벤트 | "AX Agent 대화하기" 항목 `Collapsed` |
| AX Agent 설정 탭 숨김 | `SettingsWindow.xaml.cs` `ApplyAiEnabledState()` | 설정 창의 AX Agent 탭 `Collapsed` |
### 설정 토글 UI
- 위치: 설정 창 > 일반 탭 > **AI 기능** 섹션 > "AX Agent (AI 기능) 활성화" 토글
- 저장 위치: `%APPDATA%\AxCopilot\settings.dat``"ai_enabled": true/false`
### 신규 AI 기능 추가 시 체크리스트
AI 관련 기능을 새로 추가하면 `AiEnabled` 체크를 반드시 연동합니다:
```csharp
// 핸들러/도구에서 AI 차단 체크 패턴
var settings = (System.Windows.Application.Current as App)?.SettingsService?.Settings;
if (settings?.AiEnabled == false) return; // 또는 빈 결과 반환
```
---
## 6. 사내/사외 모드 (Network Access Mode)
### 개요
배포 환경에 따라 외부 인터넷 접속 허용 여부를 제어합니다.
| 구분 | 모드 이름 | 기본값 | 설명 |
|------|----------|--------|------|
| `InternalModeEnabled = true` | **사내 모드** | ✅ 기본 | 외부 인터넷 접속 차단. 사내망 + LLM API만 허용 |
| `InternalModeEnabled = false` | **사외 모드** | — | 인터넷 검색, 외부 HTTP 허용 (비밀번호 인증 필요) |
### 제어 방법
`AppSettings.InternalModeEnabled` (기본값 **`true`**) 한 곳만 바꾸면 모든 외부 접속 제어가 변경됩니다.
- 설정 창 > 일반 탭 > **네트워크 모드** 섹션 > "사외 모드 활성화" 토글
- 사외 모드 ON 시 비밀번호 다이얼로그 표시 → **`axgo123!`**
- 사내 모드 복귀(OFF)는 비밀번호 없이 즉시 적용
### 모드별 허용/차단 항목
| 기능 | 사내 모드 | 사외 모드 |
|------|---------|---------|
| LLM API 호출 (Ollama/Gemini/Claude) | ✅ 허용 | ✅ 허용 |
| 사내 MCP 서버 연결 | ✅ 허용 | ✅ 허용 |
| 웹 검색 (? 프리픽스) | ❌ 차단 | ✅ 허용 |
| `http_request` 도구 외부 URL | ❌ 차단 | ✅ 허용 |
| 외부 MCP 서버 연결 | ❌ 차단 | ✅ 허용 (명시적 등록 시) |
### 코드 체크 패턴
```csharp
// 외부 접속이 필요한 기능에서 반드시 체크
var settings = (System.Windows.Application.Current as App)?.SettingsService?.Settings;
if (settings?.InternalModeEnabled == true)
return ToolResult.Fail("사내 모드에서는 외부 인터넷 접속이 차단됩니다. 설정에서 사외 모드를 활성화하세요.");
// URL이 내부 주소인지 검사 (사내 모드에서 허용 가능한 경우)
bool IsInternalUrl(string url) =>
url.StartsWith("http://localhost", StringComparison.OrdinalIgnoreCase) ||
url.StartsWith("http://127.", StringComparison.OrdinalIgnoreCase) ||
url.StartsWith("http://192.168.", StringComparison.OrdinalIgnoreCase) ||
url.StartsWith("http://10.", StringComparison.OrdinalIgnoreCase) ||
url.StartsWith("http://172.", StringComparison.OrdinalIgnoreCase);
```
### 신규 외부 접속 기능 추가 시 체크리스트
외부 인터넷에 접속하는 기능을 추가하면 반드시 `InternalModeEnabled` 체크를 연동합니다:
1. 도구 또는 핸들러 실행 초반에 모드 체크
2. 사내 모드에서는 명확한 오류 메시지 반환
3. SettingsWindow에 해당 기능의 모드 의존성 설명 추가
---
## 7. 공통 비밀번호 정책
앱 내 보호된 설정은 모두 동일한 비밀번호를 사용합니다:
| 보호 항목 | 비밀번호 | 구현 위치 |
|----------|---------|---------|
| AI 기능 활성화 | `axgo123!` | `SettingsWindow.xaml.cs` `AiEnabled_Changed()` |
| 사외 모드 활성화 | `axgo123!` | `SettingsWindow.xaml.cs` `NetworkMode_Changed()` |
**구현 규칙**:
- 비밀번호를 코드에 하드코딩 — 암호화 불필요 (배포 제어용, 보안 목적 아님)
- 상수로 분리: `private const string SettingsPassword = "axgo123!";`
- 비밀번호 일치 시만 토글 활성화 유지, 불일치/취소 시 토글 자동 복구
---
## 8. 프로젝트 명칭 체계
| 구분 | 명칭 | 용도 |
|------|------|------|
| 앱 전체 | **AX Copilot** | 제품명, 설정, 정보 |
| 런처 | **AX Commander** | 명령 입력창 |
| AI 대화 | **AX Agent** | Chat/Cowork/Code 대화 |
---
## 9. 사내 환경 개발 원칙
### 외부 의존 최소화 (항상 적용)
- **데이터 로컬 저장** — 설정, 대화, 클립보드, 인덱스, 로그 등 모든 데이터는 `%APPDATA%\AxCopilot\` 로컬에 저장. 클라우드 동기화 없음
- **플러그인 설치** — URL 기반 다운로드 금지. 로컬 zip 파일 기반 설치만 허용
- **코드 검색/인덱싱** — 외부 임베딩 API 사용 금지. 로컬 TF-IDF 또는 로컬 임베딩 엔진(ONNX) 사용
- **업데이트 확인** — 외부 서버 자동 업데이트 체크 금지. 인스톨러를 통한 수동 업그레이드만 지원
- **텔레메트리** — 사용 통계를 외부로 전송하지 않음. 모든 통계는 로컬 파일에만 기록
### 항상 허용되는 외부 접속
- LLM API 호출 (Ollama/vLLM은 사내 서버, Gemini/Claude는 설정에 따라)
- 사내 MCP 서버 연결 (설정에서 명시적 등록된 것만)
### 사외 모드에서만 허용 (섹션 6 참조)
- 인터넷 웹 검색 (? 프리픽스)
- `http_request` 도구의 외부 URL 호출
- 외부 MCP 서버 연결
---
## 10. 문서 관리 원칙
### 기본 원칙: .md 파일이 마스터
- **모든 로드맵·계획 문서는 `.md` 파일로 관리**합니다. 기본 작업(기능 개발·계획 수립·완료 기록)은 항상 `.md` 파일만 업데이트합니다.
- **HTML 웹 문서는 명시적으로 요청할 때만 업데이트**합니다. ("웹 문서도 업데이트해줘" 또는 "HTML 문서 갱신해줘" 요청 시에만 작업)
- HTML 문서는 `.md` 마스터를 기반으로 생성되는 **파생 문서**입니다. 자동으로 동기화하지 않습니다.
### 문서 체계
| 문서 (.md 마스터) | HTML (파생) | 관리 대상 | .md 업데이트 시점 |
|-----------------|------------|----------|-----------------|
| `docs/AGENT_ROADMAP.md` | `docs/AGENT_ROADMAP.html` | **대화 서비스** Phase별 기능, 완료 이력, 기술부채 | Phase 완료 시, 기능 추가 시 |
| `docs/LAUNCHER_ROADMAP.md` | `docs/LAUNCHER_ROADMAP.html` | **런처** Phase별 기능, 완료 이력, 경쟁 비교 | Phase 완료 시, 기능 추가 시 |
| `docs/NEXT_ROADMAP.md` | `docs/NEXT_ROADMAP.html` | **종합** 경쟁 분석, 기술 동향, 차기 계획 | 분기별 또는 대규모 계획 변경 시 |
| `docs/DEVELOPMENT.md` | — | **개발 상세** 아키텍처, 핸들러, 버전 이력, 코드 패턴 | 매 버전 배포 시 |
### 문서 업데이트 규칙
- **기능 개발 완료 시**: 해당 영역 .md 로드맵(AGENT/LAUNCHER)에 완료 표시 + 구현 내용 기록
- **배포 시**: DEVELOPMENT.md 버전 이력 추가, 사용자 가이드/헬프 갱신
- **차기 계획 수립 시**: NEXT_ROADMAP.md 업데이트 (경쟁 분석 반영)
- **HTML 동기화 요청 시에만**: 해당 .md 내용을 기반으로 HTML 파일 갱신 (열고/닫기 토글, badge 스타일 done/plan/hold 통일)
---
## 11. 고도화 계획 수립 원칙
### 외부 동향 기반 계획 수립
고도화 계획(Phase)을 수립할 때는 **내부 개발 필요성만이 아닌 외부 동향**을 종합적으로 반영합니다:
| 관점 | 검토 사항 |
|------|----------|
| **경쟁 서비스** | Claude Code, Cursor, Windsurf, GitHub Copilot, Raycast 등 최신 기능/UX 비교 |
| **최신 논문/기술** | Agentic Coding Survey, SWE-Agent, CodeAct, Reflexion 등 에이전트 코딩 연구 동향 |
| **업계 표준** | MCP 프로토콜, SKILL.md 오픈 포맷, LSP, DAP 등 표준 프로토콜 채택 여부 |
| **사내 환경** | 네트워크 제한, 보안 정책, Python/Node 설치 현황, 사용 빈도가 높은 워크플로우 |
| **커뮤니티 스킬** | Anthropic 공식 스킬, 오픈소스 프롬프트 엔지니어링 기법, 검증된 에이전트 패턴 |
### 앱 크기 관리
배포 앱(인스톨러)의 크기가 과도하게 커지지 않도록 관리합니다:
- **기본 배포 크기 목표**: 인스톨러 **150MB 이하** 유지 (현재 ~80MB)
- **대형 의존성 추가 시**: ONNX 모델, 임베딩 엔진, 사전 데이터 등은 **별도 선택적 다운로드** 또는 **로컬 zip 설치** 방식 검토
- **스킬 파일**: 내장 스킬(`.skill.md`)은 텍스트 기반이므로 크기 부담 없음 (수십 KB 단위). 적극 번들 가능
- **NuGet 패키지**: 새 패키지 추가 시 DLL 크기 확인. 단일 기능에 10MB+ 패키지는 대안 검토
- **런타임 의존**: Python/Node 스크립트 기반 기능은 사용자 PC 런타임에 의존 → 앱 크기 증가 없음
- **리소스 파일**: 이미지/아이콘은 SVG 또는 시스템 폰트(Segoe MDL2 Assets) 우선. 대형 비트맵 금지
---
## 12. 코드 설계 원칙 (SOLID + 디자인 패턴)
### SOLID 원칙 준수 (필수)
#### S — 단일 책임 원칙 (SRP)
- **클래스 하나 = 책임 하나**. 에이전트 도구 클래스는 도구 로직만, UI 코드비하인드는 UI만 담당
- 500줄 이상 클래스는 분리 검토. 메서드는 20줄 이하 권장
- 파일 I/O, 비즈니스 로직, UI 렌더링이 같은 클래스에 섞이는 것 금지
```csharp
// 금지: AgentLoopService가 UI도 업데이트
// 허용: AgentLoopService → 이벤트 발행 → ViewModel이 UI 갱신
```
#### O — 개방/폐쇄 원칙 (OCP)
- 새 도구 추가 시 기존 `AgentLoopService` 수정 없이 `IAgentTool` 구현 + Registry 등록만으로 확장
- 새 훅 이벤트 추가 시 기존 훅 처리기 수정 없이 새 핸들러 등록으로 확장
- `switch/if-else` 체인으로 타입 분기하는 것 지양 → 다형성 또는 전략 패턴으로 대체
#### L — 리스코프 치환 원칙 (LSP)
- `IAgentTool` 구현체는 항상 교환 가능해야 함 — 특정 구현에만 의존하는 코드 금지
- `ToolResult.Ok()` / `ToolResult.Error()` 반환 규약은 모든 도구 구현체에서 일관 유지
#### I — 인터페이스 분리 원칙 (ISP)
- 거대 인터페이스 금지. `IAgentTool``Execute`, `Parameters`, `Name`만 정의
- 추가 기능(검증, 로깅, 캐시)은 별도 인터페이스(`IVerifiable`, `IAuditable`)로 분리
- 구현체가 사용하지 않는 메서드를 강제하는 인터페이스 금지
#### D — 의존성 역전 원칙 (DIP)
- 구체 클래스가 아닌 **인터페이스/추상 클래스에 의존**
- `AgentLoopService``IAgentTool[]`, `ILlmService`, `IHookRunner`에만 의존 (구체 구현 직접 참조 금지)
- 의존성 주입: 생성자 주입 우선. `App.SettingsService`처럼 전역 싱글턴 직접 접근은 서비스 계층에만 허용
### 적극 사용할 디자인 패턴
#### Strategy 패턴 — 에이전트 도구, 훅 타입, 권한 모드
```csharp
// 훅 타입별 전략 분리
public interface IHookExecutor { Task<HookResult> ExecuteAsync(HookContext ctx); }
public class CommandHookExecutor : IHookExecutor { ... }
public class PromptHookExecutor : IHookExecutor { ... } // NEW: LLM 검사
public class AgentHookExecutor : IHookExecutor { ... } // NEW: 에이전트 루프
```
#### Observer 패턴 — 에이전트 이벤트, 훅 이벤트
```csharp
// AgentLoopService에서 이벤트 발행 → 다수 구독자 (UI, 훅, 감사 로그)
public event EventHandler<AgentEvent> AgentEventOccurred;
// 구독: WorkflowAnalyzer, HookRunner, AuditLogService 각각 독립 구독
```
#### Factory 패턴 — 도구 생성, 훅 생성, 에이전트 생성
```csharp
// 도구 팩토리: 타입 기반 생성, 외부에서 new 금지
public static class AgentToolFactory
{
public static IAgentTool Create(string toolName, LlmSettings settings) { ... }
}
```
#### Decorator 패턴 — 도구 검증·로깅·위험도 래핑
```csharp
// 기존 도구에 검증/로깅 기능 추가 — 도구 자체 수정 없이
public class VerifiedToolDecorator : IAgentTool
{
private readonly IAgentTool _inner;
public VerifiedToolDecorator(IAgentTool inner) { _inner = inner; }
public async Task<ToolResult> ExecuteAsync(...)
{
var result = await _inner.ExecuteAsync(...);
await RunPostVerificationAsync(result);
return result;
}
}
```
#### Chain of Responsibility — 훅 체인, 권한 규칙 체인
```csharp
// 권한 규칙을 체인으로 처리: Allow규칙 → Deny규칙 → 모드 기본값
public abstract class PermissionRule
{
protected PermissionRule? _next;
public abstract PermissionDecision Evaluate(ToolCall call);
}
```
#### Repository 패턴 — 설정, 대화 이력, 에이전트 메모리
```csharp
public interface IAgentMemoryRepository
{
Task<AgentMemory?> GetAsync(string agentType, string projectId);
Task SaveAsync(AgentMemory memory);
}
```
#### Command 패턴 — 슬래시 명령, 커맨드 팔레트
```csharp
public interface ISlashCommand
{
string Name { get; }
string Description { get; }
Task ExecuteAsync(string arguments, IChatContext context);
}
```
### 구조 분리 원칙
#### 계층 분리 규칙
```
UI 계층 (Views/ViewModels)
↓ 이벤트/명령 (Commands, Events)
서비스 계층 (Services)
↓ 인터페이스 (IAgentTool, IHookExecutor 등)
도메인 계층 (Models, Tools)
↓ 데이터 접근 (Repositories)
인프라 계층 (외부 API, 파일 시스템)
```
- **계층 역방향 의존 금지**: 도메인 계층이 UI를 참조하는 것 금지
- **서비스 계층 간 직접 호출 지양**: 이벤트/메시지 버스로 느슨한 결합
#### 에이전트 도구 분리 원칙
- 도구 클래스는 `Services/AgentTools/` 하위의 **카테고리별 폴더**에 배치
- 각 도구는 `독립 파일` 1개 — 여러 도구를 하나의 파일에 합치는 것 금지
- 도구 간 직접 호출 금지 — 공통 로직은 `Services/AgentToolHelpers/`에 분리
#### 설정 분리 원칙 (기존 원칙 강화)
- Cowork/Code 전용 설정은 반드시 분리 (공통 설정에 넣지 않음)
- 새 기능 추가 시 설정 클래스 → ViewModel → UI → 코드 순서로 구현
### 새 기능 구현 체크리스트
새 Phase 기능을 구현하기 전 확인:
1. **인터페이스 먼저**: 구체 구현 전 `IXxx` 인터페이스 정의
2. **단일 책임**: 클래스가 2가지 이상의 이유로 변경될 수 있으면 분리
3. **패턴 적합성**: Strategy/Observer/Decorator 중 적합한 패턴 선택
4. **의존성 방향**: 새 클래스의 의존성이 올바른 방향인지 확인
5. **설정 연동**: 설정 없이 하드코딩된 동작 금지
6. **테스트 가능성**: 외부 의존(파일, API)을 인터페이스로 추상화하여 단위 테스트 가능하게
---
## 13. AX Agent 채팅 화면 UI/UX 원칙 (Claude.ai + Codex 스타일)
### 핵심 패러다임: AX Agent = 독립 앱 공간
**절대 원칙**: AX Agent와 관련된 **모든** 설정은 ChatWindow 내부에서 처리한다.
- SettingsWindow에서 **AX Agent 탭을 완전 제거**. AX Agent 관련 설정은 ChatWindow 내 설정 패널로 이관.
- 사용자는 ChatWindow를 벗어나지 않고 모델 변경, 도구 토글, 권한 모드, 에이전트 파라미터, API 키까지 모두 설정 가능해야 함.
- SettingsWindow에는 앱 전역 설정(테마, 핫키, 런처, 인덱싱)만 남긴다.
> **레퍼런스**: Claude.ai — 대화 목록 + 채팅 + 설정이 단일 창 내 패널로 구성. Codex — 에이전트 제어 항목(모델, 도구, 권한, Plan) 전부 채팅 헤더/사이드바에 인라인 배치. 별도 설정 다이얼로그 없음.
---
### 전체 레이아웃 구조 (3-Pane)
```
┌──────────────────────────────────────────────────────────────────────┐
│ [좌측 사이드바 260px] │ [메인 채팅 영역 — 가변] │ [우측 패널 300px] │
│ │ │ (토글, 기본 접힘) │
│ ┌──────────────────┐ │ ┌─────────────────────┐ │ │
│ │ ≡ AX Agent ✕ │ │ │ 현재 탭 이름 │ │ ┌───────────────┐ │
│ └──────────────────┘ │ │ 모델▾ Plan▾ 권한▾ │ │ │ ⚙ 설정 패널 │ │
│ │ └─────────────────────┘ │ │ ───────────── │ │
│ [ Chat │ Cowork│Code] │ │ │ 탭별 에이전트 │ │
│ ──────────────────── │ [메시지 스트림] │ │ 파라미터 │ │
│ ▸ 프리셋1 │ │ │ 모델/API 설정 │ │
│ ▸ 프리셋2 │ │ │ 도구 토글 │ │
│ ▸ 프리셋3 │ │ │ MCP 서버 │ │
│ ──────────────────── │ │ └───────────────┘ │
│ [+ 새 대화] │ │ │
│ ──────────────────── │ ┌──────────────────────┐ │ ┌───────────────┐ │
│ 오늘 │ │ @멘션 /스킬 📎 ⚙ │ │ │ 🔀 워크플로우 │ │
│ · 대화 제목 1 │ │ [ 입력 텍스트 ] │ │ └───────────────┘ │
│ · 대화 제목 2 │ │ 모델칩 권한칩 [전송]│ │ ┌───────────────┐ │
│ 어제 │ └──────────────────────┘ │ │ 📄 Diff 뷰 │ │
│ · 대화 제목 3 │ │ └───────────────┘ │
└──────────────────────────────────────────────────────────────────────┘
```
---
### 좌측 사이드바 (AgentSidebarView) — Claude.ai 스타일
#### 구조 및 동작
- **헤더**: `≡ AX Agent` 로고 + 사이드바 접기 버튼 (최소 48px 아이콘 모드로 접힘)
- **탭 세그먼트**: `Chat | Cowork | Code` — 가로 3분할 세그먼트 컨트롤 (Border + MouseLeftButtonUp, 선택 탭 AccentColor 배경)
- **프리셋 목록**: 현재 탭의 프리셋 항목 직접 목록 표시. 클릭 시 즉시 적용. 우클릭 커스텀 Popup (편집/삭제)
- **새 대화 버튼**: `[ 새 대화]` — 전체 너비 Border 버튼, 호버 시 AccentColor 틴트
- **대화 이력**: 날짜 그룹(`오늘 / 어제 / 이전 7일 / 이전 30일`) 구분선 + 대화명. 클릭 시 해당 세션 복원. 우클릭 커스텀 Popup (이름변경/삭제/즐겨찾기)
- **하단**: ⚙ 설정 아이콘 → 우측 설정 패널 토글 (Claude.ai 프로필 메뉴 대응)
#### 크기/테마
- 기본 너비 260px, 접기 시 48px (아이콘만)
- 배경: `LauncherBackground`, 구분선: `BorderColor` 1px, 선택 항목: `ItemHoverBackground`
- 접기/펼치기: Width 애니메이션 260→48px, 180ms EaseInOut
---
### 메인 채팅 영역 — 탭별 콘텐츠
#### 세션 헤더 바 (탭당 고정)
탭 전환 시 해당 탭의 헤더로 교체됨. 항상 표시.
| 위치 | 컨트롤 | 구현 | 설명 |
|------|--------|------|------|
| 좌측 | 현재 탭 레이블 | TextBlock | "Chat", "Cowork", "Code" |
| 중앙 | 모델 선택칩 | Border + Popup | 현재 모델명 + ▾. 클릭 시 등록 모델 목록 팝업 |
| 중앙 | Plan 모드 칩 | Border 3-state | Off → Auto → Always 순환 클릭. 활성=AccentColor |
| 중앙 | 권한 모드 칩 | Border + Popup | Default / AcceptEdits / Plan / Bypass |
| 우측 | 도구 아이콘 열 | 아이콘 N개 | 활성=기능색, 비활성=SecondaryText 흐림. 클릭 토글 |
| 우측 | ⚙ 설정 버튼 | Border | 우측 설정 패널 슬라이드인 토글 |
| 우측 | 🔀 워크플로우 | Border | 워크플로우 분석기 우측 패널 열기 |
#### 메시지 스트림
- 사용자 메시지: 우측 정렬, `ItemBackground` 배경 버블, 최대 너비 70%
- AI 메시지: 좌측 정렬, 배경 없음 (Claude.ai 스타일), 마크다운 렌더링
- 도구 호출 블록: 접히는 `Border` (`▶ file_write` → 클릭 시 펼쳐서 파라미터/결과 표시)
- 스트리밍 중: 커서 깜빡임 애니메이션 (Opacity 0→1, 500ms 반복)
- 신규 메시지 SlideIn: TranslateTransform Y +20→0, Opacity 0→1, 120ms EaseOut
---
### 우측 설정 패널 (AgentSettingsPanel) — 필수 구현
**⚙ 클릭 시 우측에서 슬라이드인 (TranslateTransform X +300→0, 200ms EaseOut)**
**기존 SettingsWindow의 AX Agent 탭을 이 패널로 완전 대체.**
#### 패널 구성 (탭별 섹션 분기)
```
┌─────────────────── ⚙ 설정 ────── [✕] ┐
│ ── 현재 탭: Chat / Cowork / Code ── │
│ │
│ [모델 & 서비스] │
│ LLM 서비스 [Ollama ▾] │
│ 모델 [llama3:8b ▾] │
│ API 엔드포인트 [____________] │
│ API 키 [•••••••• 👁] │
│ │
│ [에이전트 동작] │
│ 최대 반복 횟수 [──────○──] 20 │
│ 오류 시 재시도 [──○──────] 3 │
│ 병렬 도구 실행 ◉──── (토글) │
│ │
│ [탭 전용 설정] ← 탭에 따라 다름 │
│ (Cowork) 검증 강제 ◉──── │
│ (Code) LSP 분석 ◉──── │
│ (Code) 작업 폴더 [경로... 📁] │
│ │
│ [도구 관리] │
│ file_write ◉──── 활성 │
│ file_read ◉──── 활성 │
│ git_tool ────◉ 비활성 │
│ … │
│ │
│ [MCP 서버] │
│ ● server1 연결됨 [비활성화] │
│ ○ server2 오프라인 [재연결] │
│ │
│ [프리셋] │
│ 현재 설정으로 저장 [저장] │
│ 프리셋 관리 [관리 →] │
│ │
│ [고급] │
│ 폴백 모델 목록 [편집] │
│ 프로젝트 규칙 ◉──── 활성 │
│ AX.md 편집 [열기 →] │
└───────────────────────────────────────┘
```
#### 설정 패널 구현 규칙
- 모든 컨트롤: ToggleSwitch 또는 Border+Popup 드롭다운 (Section 1 원칙 준수)
- API 키 필드: `PasswordBox` 스타일 + 👁 토글로 표시/숨김
- 탭별 분기: `ActiveTab == "Code"` 조건으로 탭 전용 섹션 표시/숨김
- 설정 변경 즉시 저장 (`SettingsService.Save()`) — 별도 저장 버튼 불필요
- 슬라이더: WPF `Slider` + 현재값 TextBlock 우측 표시
---
### SettingsWindow 잔류 원칙 (AX Agent 탭 제거)
SettingsWindow에 **남기는 항목** (앱 전역 설정만):
- **일반**: AI 활성화(비밀번호), 네트워크 모드(비밀번호), 앱 시작 설정, 개발자 모드
- **런처**: 인덱싱 경로/확장자, 핫키, 독 바, 테마 선택
- **플러그인**: 플러그인 설치/제거 (PluginGalleryViewModel)
- **퀵링크**: QuickLinkEntry 목록 관리
- **AI 스니펫**: AiSnippetTemplate 목록 관리
- **감사 로그**: 로그 파일 열기, 보존 기간 설정
SettingsWindow에서 **제거 (ChatWindow 이관 완료)**:
- AX Agent 탭 전체 → ChatWindow 우측 설정 패널
- 모델/LLM 서비스 설정 → 설정 패널 [모델 & 서비스] 섹션
- 에이전트 파라미터(반복, 재시도, 병렬) → 설정 패널 [에이전트 동작] 섹션
- 도구 개별 토글 → 설정 패널 [도구 관리] 섹션 + 헤더 바 아이콘
- MCP 서버 활성화 → 설정 패널 [MCP 서버] 섹션 (등록/삭제는 SettingsWindow)
- 프리셋 관리 → 설정 패널 [프리셋] 섹션
- 프로젝트 규칙, 작업 폴더 → 설정 패널 [고급] 섹션
---
### 입력 영역 (AgentInputArea) — Claude.ai + Codex 스타일
```
┌──────────────────────────────────────────────────────┐
│ @멘션 /스킬 📎 첨부 │
│ ┌──────────────────────────────────────────────────┐ │
│ │ 메시지를 입력하세요… │ │
│ │ │ │
│ └──────────────────────────────────────────────────┘ │
│ [모델명 칩] [권한 칩] [Plan 칩] ⚙설정 [▶전송] │
└──────────────────────────────────────────────────────┘
```
- **상단 툴바**: `@` (파일 멘션 자동완성) · `/` (스킬/슬래시 명령) · 📎 (파일/이미지 첨부)
- **텍스트 입력**: 최소 60px, 최대 220px 자동 확장, Ctrl+Enter 전송
- **하단 칩 열**: 현재 모델명 칩 (클릭 시 변경) + 권한 모드 칩 + Plan 칩 — 항상 현재 상태 표시
- **⚙ 버튼**: 우측 설정 패널 토글 (헤더 바와 동일 동작)
- **전송 버튼 [▶]**: 실행 중 → `[■ 중단]`으로 전환, Border + MouseLeftButtonUp 패턴
---
### 구현 클래스 구조
```
Views/
ChatWindow.xaml # 최상위 창 — 3-pane Grid 구조
ChatWindow.xaml.cs # 탭 전환, 패널 토글, 입력 처리
Controls/ # 재사용 UserControl
AgentSidebarView.xaml # 탭 세그먼트 + 프리셋 + 대화 이력
AgentSidebarView.xaml.cs
AgentSessionHeaderBar.xaml # 모델/Plan/권한/도구 칩 바
AgentSessionHeaderBar.xaml.cs
AgentSettingsPanel.xaml # 우측 슬라이드인 설정 패널 (전체 AX Agent 설정)
AgentSettingsPanel.xaml.cs
AgentInputArea.xaml # 멀티기능 입력 영역
AgentInputArea.xaml.cs
AgentDiffPanel.xaml # 우측 Diff 뷰 패널
AgentDiffPanel.xaml.cs
ViewModels/
ChatWindowViewModel.cs # 창 통합 VM (탭, 패널 상태)
AgentSidebarViewModel.cs # 사이드바 VM (탭/프리셋/이력)
AgentSessionHeaderViewModel.cs # 헤더 칩 VM
AgentSettingsPanelViewModel.cs # 설정 패널 VM (모든 AX Agent 설정)
```
#### 파일 배치 원칙
- 기존 `ChatWindow.xaml` / `ChatWindow.xaml.cs` 를 리팩터링. 새 파일을 신규 생성.
- `AgentSettingsPanel`은 독립 UserControl — `ChatWindow``Grid.Column="2"`로 배치.
- 우측 패널 3종 (설정/워크플로우/Diff)은 `Visibility` + `TranslateTransform`으로 전환.
---
### 애니메이션 / 전환 원칙
| 동작 | 구현 | 시간 |
|------|------|------|
| 사이드바 접기/펼치기 | Width 260→48px DoubleAnimation EaseInOut | 180ms |
| 우측 패널 슬라이드인 | TranslateTransform X +300→0 EaseOut | 200ms |
| 우측 패널 슬라이드아웃 | TranslateTransform X 0→+300 EaseIn | 150ms |
| 탭 전환 | Opacity 0→1 + TranslateY +8→0 | 120ms |
| 메시지 신규 등장 | Opacity 0→1 + TranslateY +16→0 EaseOut | 120ms |
| 스트리밍 커서 | Opacity 0↔1 RepeatForever | 500ms |
| 도구 블록 펼치기 | Height Auto DoubleAnimation | 150ms |
---
## 14. 관련 문서
| 문서 | 경로 | 설명 |
|------|------|------|
| 개발 문서 | `docs/DEVELOPMENT.md` | 아키텍처, 핸들러, 버전 이력, 개발 원칙 상세 |
| AX Agent 로드맵 | `docs/AGENT_ROADMAP.md` | 대화 서비스 고도화 계획 (Phase별) — HTML은 요청 시만 갱신 |
| 런처 로드맵 | `docs/LAUNCHER_ROADMAP.md` | 런처 고도화 계획 (Phase별) — HTML은 요청 시만 갱신 |
| 차기 종합 계획 | `docs/NEXT_ROADMAP.md` | v1.7.1~v2.0 CC 내부 문서 기반 전면 개정판 — HTML은 요청 시만 갱신 |
| Claude Code 참고 문서 | `docs/claude-code-docs-main/` | CC 훅·스킬·멀티에이전트·권한·메모리·SDK 내부 아키텍처 문서 |
| 사용자 가이드 | `src/AxCopilot/Assets/AX Copilot 사용가이드.htm` | 단축키/예약어 가이드 |
| 브랜딩 가이드 | `src/AxCopilot/Assets/BRANDING_가이드.md` | 아이콘/색상/명칭 규칙 |