From 6e65cf6026b8d9175043af99f952e2fbe0582d46 Mon Sep 17 00:00:00 2001 From: lacvet Date: Sat, 4 Apr 2026 12:42:49 +0900 Subject: [PATCH] =?UTF-8?q?=EC=97=B0=EC=86=8D=20=EA=B0=9C=EC=84=A0:=20?= =?UTF-8?q?=EA=B6=8C=ED=95=9C=20=EC=83=81=ED=83=9C=20=EA=B0=84=EC=86=8C?= =?UTF-8?q?=ED=99=94=C2=B7=EC=84=A4=EC=A0=95=EC=B0=BD=20=EC=99=B8=EB=B6=80?= =?UTF-8?q?=20=EC=A7=84=EC=9E=85=20=EC=95=88=EC=A0=95=ED=99=94=C2=B7?= =?UTF-8?q?=EC=BB=B4=ED=8F=AC=EC=A0=80=20=EB=B0=98=EC=9D=91=ED=98=95=20?= =?UTF-8?q?=EB=B3=B4=EA=B0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 권한 상태 텍스트(/permissions,/allowed-tools)를 운영 모드 포함 축약형으로 재정리 - 하단 권한 버튼 툴팁에 운영 모드/기본값/예외 개수 정보를 일관 반영 - 탭 전환 시 좌측 메뉴 Visibility 재할당을 최소화해 UI 흔들림 완화 - 상단 모델 라벨에 MaxWidth+말줄임 적용으로 긴 모델명 레이아웃 깨짐 방지 - AX Agent 설정창 오픈 시 리소스 병합 예외를 방어하고 외부 진입 경로를 Dispatcher 기반으로 안정화 - UI 체크리스트/개발문서/README에 2026-04-04 12:41 기준 점검 이력 업데이트 - 검증: build 경고0/오류0, 운영모드 필터 18건 통과, 전체 테스트 436건 통과 --- README.md | 5 ++- docs/DEVELOPMENT.md | 31 +++++++++++++++ docs/UI_UX_CHECKLIST.md | 9 +++++ src/AxCopilot/Views/ChatWindow.xaml | 2 + src/AxCopilot/Views/ChatWindow.xaml.cs | 52 ++++++++++++++++++-------- 5 files changed, 82 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index 80ab701..776d52b 100644 --- a/README.md +++ b/README.md @@ -222,7 +222,7 @@ public class MyHandler : IActionHandler ### v0.7.3 — AX Agent 권한 코어 재구성 + 입력 계층 정리 -업데이트: 2026-04-04 12:33 (KST) +업데이트: 2026-04-04 12:41 (KST) | 분류 | 내용 | |------|------| @@ -270,6 +270,9 @@ public class MyHandler : IActionHandler | 권한 팝업 밀도 재정돈 | 권한 섹션 헤더/카드/행의 패딩·폰트·줄간격을 조정해 과밀 영역을 완화하고 Codex/Claude형 스캔 속도에 맞춤 | | 좌측/컴포저 라벨 정리 | 좌측 기본 카테고리 라벨을 `주제 선택/작업 선택`으로 통일하고, 입력 상단 바 패딩·간격을 미세 조정해 단일 라인 정돈 강화 | | 체크리스트 실행 결과 기록 | `docs/UI_UX_CHECKLIST.md`에 2026-04-04 12:22 기준 점검 결과(운영모드 필터 18건 + 전체 436건 통과)를 기록 | +| 권한 상태 표시 간소화 | 권한 상태 텍스트(`/permissions`, `/allowed-tools`)를 운영 모드 포함 축약형으로 정리하고 권한 버튼 툴팁에 동일 정보를 반영 | +| 설정창 외부 진입 안정화 | AX Agent 설정창 오픈 시 리소스 병합 실패를 방어하고, 외부 진입 경로를 Dispatcher 기반으로 안정화 | +| 모델 라벨 반응형 보강 | 컴포저 상단 모델 라벨에 말줄임(`MaxWidth` + `CharacterEllipsis`)을 적용해 좁은 폭에서 레이아웃 깨짐을 방지 | | 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 bc80b35..80105e7 100644 --- a/docs/DEVELOPMENT.md +++ b/docs/DEVELOPMENT.md @@ -3239,6 +3239,37 @@ else: - `dotnet build src/AxCopilot/AxCopilot.csproj` 통과 (경고 0, 오류 0). - `dotnet test src/AxCopilot.Tests/AxCopilot.Tests.csproj` 통과 (436 passed, 0 failed). +## 2026-04-04 추가 진행 기록 (연속 실행 24차: 권한/설정 안정화 보강 + 시나리오 점검) + +업데이트: 2026-04-04 12:41 (KST) + +### 1) 권한 상태 표시 간소화 +- `/permissions`, `/allowed-tools` 상태 텍스트를 축약형으로 재정리: + - 현재 권한 모드 + - 운영 모드 + - 기본값/예외 개수 + - 예외 미리보기(최대 3개) +- 하단 권한 버튼 툴팁에도 동일한 운영 모드/기본값/예외 정보를 반영. + +### 2) 좌측 패널 전환 안정화 +- `UpdateSidebarModeMenu()`에서 탭별 메뉴 표시를 동일 값 재할당하지 않도록 보강해 전환 시 불필요한 렌더 흔들림을 완화. + +### 3) 컴포저 반응형 보강 +- 상단 모델 라벨에 `MaxWidth=280`, `TextTrimming=CharacterEllipsis` 적용. +- 긴 모델명 선택 시 컴포저 레이아웃 깨짐을 방지. + +### 4) AX Agent 설정창 오픈 안정성 보강 +- 설정창 리소스 병합 실패 시에도 창 오픈이 유지되도록 예외 방어 추가. +- `OpenAgentSettingsFromExternal()`를 Dispatcher 경유로 변경해 트레이/외부 진입 시 타이밍 이슈를 완화. + +### 5) 시나리오/회귀 점검 +- 운영 모드 필터 테스트(18건) 재통과: + - `OperationModePolicyTests` + - `OperationModeReadinessTests` + - `LlmOperationModeTests` +- 전체 테스트 436건 재통과. +- `dotnet build` 경고 0 / 오류 0 유지. + diff --git a/docs/UI_UX_CHECKLIST.md b/docs/UI_UX_CHECKLIST.md index 4698a64..b443033 100644 --- a/docs/UI_UX_CHECKLIST.md +++ b/docs/UI_UX_CHECKLIST.md @@ -54,3 +54,12 @@ - [x] AX Agent 설정 권한 순환 순서와 `/sandbox-toggle` 순환 순서 일치 확인 - [x] 운영 모드 회귀 필터 테스트 18건 통과 (`OperationModePolicy/Readiness/LlmOperationMode`) - [x] 전체 테스트 436건 통과 + +점검 시각: 2026-04-04 12:41 (KST) + +- [x] 권한 버튼 툴팁에 운영 모드 + 기본 권한 + 예외 개수 표시 확인 +- [x] 권한 상태 텍스트(`/permissions`, `/allowed-tools`)를 축약형으로 정리 확인 +- [x] 모델 라벨 말줄임 처리(`MaxWidth`, `CharacterEllipsis`) 적용 확인 +- [x] 설정창 외부 진입(`OpenAgentSettingsFromExternal`) Dispatcher 경유 오픈 경로 확인 +- [x] 운영 모드 필터 테스트 18건 재통과 +- [x] 전체 테스트 436건 재통과 diff --git a/src/AxCopilot/Views/ChatWindow.xaml b/src/AxCopilot/Views/ChatWindow.xaml index 221c57b..040bdfe 100644 --- a/src/AxCopilot/Views/ChatWindow.xaml +++ b/src/AxCopilot/Views/ChatWindow.xaml @@ -1115,6 +1115,8 @@ VerticalAlignment="Center" Margin="0,0,5,0"/> "\uE8D7", }; if (BtnPermission != null) - BtnPermission.ToolTip = $"{summary.Description}\n기본값 {PermissionModeCatalog.ToDisplayLabel(summary.DefaultMode)} · override {summary.OverrideCount}개"; + { + var operationMode = OperationModePolicy.Normalize(_settings.Settings.OperationMode); + BtnPermission.ToolTip = $"{summary.Description}\n운영 모드: {operationMode}\n기본값 {PermissionModeCatalog.ToDisplayLabel(summary.DefaultMode)} · 예외 {summary.OverrideCount}개"; + } if (!string.Equals(_lastPermissionBannerMode, perm, StringComparison.OrdinalIgnoreCase)) { @@ -2275,10 +2281,11 @@ public partial class ChatWindow : Window lock (_convLock) currentConversation = _currentConversation; var summary = _appState.GetPermissionSummary(currentConversation); var mode = PermissionModeCatalog.NormalizeGlobalMode(summary.EffectiveMode); + var operationMode = OperationModePolicy.Normalize(_settings.Settings.OperationMode); var overrides = summary.TopOverrides.Count > 0 - ? string.Join(", ", summary.TopOverrides.Select(x => $"{x.Key}:{x.Value}")) + ? string.Join(", ", summary.TopOverrides.Take(3).Select(x => $"{x.Key}:{PermissionModeCatalog.ToDisplayLabel(x.Value)}")) : "없음"; - return $"현재 권한 모드: {PermissionModeCatalog.ToDisplayLabel(mode)} ({mode})\n설명: {summary.Description}\n기본값: {PermissionModeCatalog.ToDisplayLabel(summary.DefaultMode)} · override: {summary.OverrideCount}개\n상위 override: {overrides}"; + return $"현재 권한 모드: {PermissionModeCatalog.ToDisplayLabel(mode)}\n운영 모드: {operationMode}\n기본값: {PermissionModeCatalog.ToDisplayLabel(summary.DefaultMode)} · 예외 {summary.OverrideCount}개\n예외 미리보기: {overrides}"; } private void OpenPermissionPanelFromSlash(string command, string usageText) @@ -12972,13 +12979,19 @@ public partial class ChatWindow : Window _agentSettingsWindow = null; } - var win = new AgentSettingsWindow(_settings) - { - Owner = IsLoaded && IsVisible ? this : null, - }; + var win = new AgentSettingsWindow(_settings); + if (IsLoaded && IsVisible) + win.Owner = this; _agentSettingsWindow = win; win.Closed += (_, _) => _agentSettingsWindow = null; - win.Resources.MergedDictionaries.Add(Resources); + try + { + win.Resources.MergedDictionaries.Add(Resources); + } + catch + { + // 리소스 병합 실패 시에도 설정창 자체는 열리도록 유지 + } bool changed; try @@ -12988,8 +13001,12 @@ public partial class ChatWindow : Window catch { // 모달 창 오픈에 실패하면 일반 창으로라도 설정 접근을 보장 - win.Show(); - win.Activate(); + try + { + win.Show(); + win.Activate(); + } + catch { } return; } if (!changed) @@ -13006,9 +13023,12 @@ public partial class ChatWindow : Window public void OpenAgentSettingsFromExternal() { - Show(); - Activate(); - OpenAgentSettingsWindow(); + Dispatcher.BeginInvoke(() => + { + Show(); + Activate(); + OpenAgentSettingsWindow(); + }, DispatcherPriority.Input); } private void BtnInlineSettingsClose_Click(object sender, RoutedEventArgs e)