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)