From 64be0e082d1f81178436b78beda928ae9479e6cf Mon Sep 17 00:00:00 2001 From: lacvet Date: Sat, 4 Apr 2026 16:12:52 +0900 Subject: [PATCH] =?UTF-8?q?=EA=B6=8C=ED=95=9C=20=EC=8B=9C=EA=B0=81=20?= =?UTF-8?q?=EC=B2=B4=EA=B3=84=20=ED=86=B5=EC=9D=BC:=20=EC=9A=94=EC=95=BD?= =?UTF-8?q?=EC=B9=B4=EB=93=9C/=EC=83=81=EB=8B=A8=EB=B0=B0=EB=84=88=20?= =?UTF-8?q?=EC=83=89=EC=83=81=20=EC=A0=95=EB=A0=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - GetPermissionModePalette 모드별 색상 매핑을 팝업 체계와 일치 - BypassPermissions(주황)와 DontAsk(빨강) 배너 렌더링 분리 - README/DEVELOPMENT 이력(2026-04-04 16:12 KST) 동기화 --- README.md | 3 ++- docs/DEVELOPMENT.md | 23 ++++++++++++++++++++ src/AxCopilot/Views/ChatWindow.xaml.cs | 30 ++++++++++++++++++++------ 3 files changed, 48 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index b6b2c69..c068630 100644 --- a/README.md +++ b/README.md @@ -222,7 +222,7 @@ public class MyHandler : IActionHandler ### v0.7.3 — AX Agent 권한 코어 재구성 + 입력 계층 정리 -업데이트: 2026-04-04 15:52 (KST) +업데이트: 2026-04-04 16:12 (KST) | 분류 | 내용 | |------|------| @@ -291,6 +291,7 @@ public class MyHandler : IActionHandler | 권한 기본값 정책 정렬 | 신규/초기 상태의 기본 권한을 `활용하지 않음(Deny)`으로 변경하고 AppState 기본/요약 상태와 slash 사용 가이드를 동일 체계로 정렬 | | 탭 전환 빈 대화 누적 방지 | 탭 전환 중 생성되는 무의미한 빈 대화를 저장 대상에서 제외하고, 목록에서도 빈 노이즈 항목을 숨겨 이력 누적 체감 버그를 완화 | | 권한 팝업 즉시반영 정렬 | 권한 팝업에 `활용하지 않음`을 핵심 영역 맨 위에 배치하고, 대화 권한이 없을 때도 탭 기본값(Deny/DefaultAgentPermission)을 즉시 반영하도록 로딩 경로를 보강 | +| 권한 색상 체계 통일 | 권한 요약 카드/상단 배너에서 모드별 색상(Deny=녹색, Passive=파랑, Active=녹색, Plan=보라, FullAuto=주황, Silent=빨강)을 팝업 체계와 일치시킴 | | Slash palette 상태 분리 시작 | `ChatWindow`에 몰려 있던 slash 상태를 `SlashPaletteState`로 분리해 이후 Codex/Claude형 composer 개편 기반 마련 | | 런처 이미지 미리보기 추가 | `#` 클립보드 이미지 항목에서 `Shift+Enter`로 전용 미리보기 창을 열고, 줌·원본 해상도 확인·PNG/JPEG/BMP 저장·클립보드 복사를 지원 | | 검증 | `dotnet build` 경고 0 / 오류 0, `dotnet test` 436 passed / 0 failed | diff --git a/docs/DEVELOPMENT.md b/docs/DEVELOPMENT.md index fa1d0d5..346932d 100644 --- a/docs/DEVELOPMENT.md +++ b/docs/DEVELOPMENT.md @@ -3627,3 +3627,26 @@ else: ### 4) 품질 게이트 - `dotnet build src/AxCopilot/AxCopilot.csproj -c Debug -p:UseSharedCompilation=false -nodeReuse:false` 통과 (경고 0, 오류 0). - `dotnet test src/AxCopilot.Tests/AxCopilot.Tests.csproj --filter "FullyQualifiedName~PermissionModePresentationCatalogTests|FullyQualifiedName~PermissionModeCatalogTests|FullyQualifiedName~ChatWindowSlashPolicyTests|FullyQualifiedName~ChatSessionStateServiceTests"` 통과 (111 passed, 0 failed). + +## 2026-04-04 추가 진행 기록 (연속 실행 41차: 권한 색상 체계 통일) + +업데이트: 2026-04-04 16:12 (KST) + +### 1) 권한 요약 카드 색상 매핑 정렬 +- `GetPermissionModePalette`의 모드별 색상을 팝업/배너 기준과 통일: + - Deny: 녹색 + - Default: 중립/파랑 계열(기존 유지) + - AcceptEdits: 녹색 + - Plan: 보라 + - BypassPermissions: 주황 + - DontAsk: 빨강 + +### 2) 상단 권한 배너 시각 통일 +- `BypassPermissions`와 `DontAsk`를 분리 렌더링: + - 완전 자동: 주황 배너 + 주황 아이콘 + - 질문 없이 진행: 빨강 배너 + 빨강 아이콘 +- 기존처럼 두 모드를 동일 위험색으로 처리하던 혼선을 제거. + +### 3) 품질 게이트 +- `dotnet build src/AxCopilot/AxCopilot.csproj -c Debug -p:UseSharedCompilation=false -nodeReuse:false` 통과 (경고 0, 오류 0). +- `dotnet test src/AxCopilot.Tests/AxCopilot.Tests.csproj --filter "FullyQualifiedName~PermissionModePresentationCatalogTests|FullyQualifiedName~PermissionModeCatalogTests|FullyQualifiedName~ChatSessionStateServiceTests"` 통과 (72 passed, 0 failed). diff --git a/src/AxCopilot/Views/ChatWindow.xaml.cs b/src/AxCopilot/Views/ChatWindow.xaml.cs index 9934036..c94adfd 100644 --- a/src/AxCopilot/Views/ChatWindow.xaml.cs +++ b/src/AxCopilot/Views/ChatWindow.xaml.cs @@ -2207,7 +2207,23 @@ public partial class ChatWindow : Window PermissionTopBanner.Visibility = _permissionTopBannerDismissed ? Visibility.Collapsed : Visibility.Visible; } } - else if (perm == PermissionModeCatalog.BypassPermissions || perm == PermissionModeCatalog.DontAsk) + else if (perm == PermissionModeCatalog.BypassPermissions) + { + var autoColor = new SolidColorBrush(Color.FromRgb(0xC2, 0x41, 0x0C)); + PermissionLabel.Foreground = autoColor; + PermissionIcon.Foreground = autoColor; + if (PermissionTopBanner != null) + { + PermissionTopBanner.BorderBrush = BrushFromHex("#FDBA74"); + PermissionTopBannerIcon.Text = "\uE814"; + PermissionTopBannerIcon.Foreground = autoColor; + PermissionTopBannerTitle.Text = "현재 권한 모드 · 완전 자동"; + PermissionTopBannerTitle.Foreground = autoColor; + PermissionTopBannerText.Text = "권한 확인을 대부분 생략합니다. 민감한 작업 전에는 설정을 다시 확인하세요."; + PermissionTopBanner.Visibility = _permissionTopBannerDismissed ? Visibility.Collapsed : Visibility.Visible; + } + } + else if (perm == PermissionModeCatalog.DontAsk) { var dangerColor = new SolidColorBrush(Color.FromRgb(0xDC, 0x26, 0x26)); PermissionLabel.Foreground = dangerColor; @@ -2215,9 +2231,9 @@ public partial class ChatWindow : Window if (PermissionTopBanner != null) { PermissionTopBanner.BorderBrush = BrushFromHex("#FCA5A5"); - PermissionTopBannerIcon.Text = "\uE814"; + PermissionTopBannerIcon.Text = "\uE8A5"; PermissionTopBannerIcon.Foreground = dangerColor; - PermissionTopBannerTitle.Text = $"현재 권한 모드 · {PermissionModeCatalog.ToDisplayLabel(perm)}"; + PermissionTopBannerTitle.Text = "현재 권한 모드 · 질문 없이 진행"; PermissionTopBannerTitle.Foreground = dangerColor; PermissionTopBannerText.Text = "권한 확인을 거의 생략합니다. 민감한 작업 전에는 설정을 다시 확인하세요."; PermissionTopBanner.Visibility = _permissionTopBannerDismissed ? Visibility.Collapsed : Visibility.Visible; @@ -16428,15 +16444,15 @@ private static (string icon, string label, string bgHex, string fgHex) GetDecisi return normalized switch { var x when string.Equals(x, PermissionModeCatalog.Deny, StringComparison.OrdinalIgnoreCase) - => (BrushFromHex("#FEF2F2"), BrushFromHex("#FCA5A5"), BrushFromHex("#991B1B")), + => (BrushFromHex("#ECFDF5"), BrushFromHex("#86EFAC"), BrushFromHex("#166534")), var x when string.Equals(x, PermissionModeCatalog.AcceptEdits, StringComparison.OrdinalIgnoreCase) - => (BrushFromHex("#FFF7ED"), BrushFromHex("#FDBA74"), BrushFromHex("#C2410C")), + => (BrushFromHex("#ECFDF5"), BrushFromHex("#BBF7D0"), BrushFromHex("#166534")), var x when string.Equals(x, PermissionModeCatalog.Plan, StringComparison.OrdinalIgnoreCase) => (BrushFromHex("#EEF2FF"), BrushFromHex("#C7D2FE"), BrushFromHex("#3730A3")), var x when string.Equals(x, PermissionModeCatalog.BypassPermissions, StringComparison.OrdinalIgnoreCase) - => (BrushFromHex("#ECFDF5"), BrushFromHex("#BBF7D0"), BrushFromHex("#166534")), + => (BrushFromHex("#FFF7ED"), BrushFromHex("#FDBA74"), BrushFromHex("#C2410C")), var x when string.Equals(x, PermissionModeCatalog.DontAsk, StringComparison.OrdinalIgnoreCase) - => (BrushFromHex("#ECFDF5"), BrushFromHex("#86EFAC"), BrushFromHex("#166534")), + => (BrushFromHex("#FEF2F2"), BrushFromHex("#FCA5A5"), BrushFromHex("#991B1B")), _ => (BrushFromHex("#F8FAFC"), BrushFromHex("#CBD5E1"), BrushFromHex("#334155")), }; }