슬래시 탐색 정합화와 권한 요청창 문구 복구를 반영하고 개발문서 이력을 갱신
Some checks failed
Release Gate / gate (push) Has been cancelled
Some checks failed
Release Gate / gate (push) Has been cancelled
- ChatWindow: slash palette 이동 기준을 렌더 순서로 통일해 방향키/휠/Home/End 선택 체감 불일치를 해소 - ChatWindow: 최근 권한 거부 카드 액션 순서를 활용하지 않음→소극 활용→적극 활용→예외 해제로 정렬 - ChatWindow: /permissions, /allowed-tools 사용법 표기를 deny→default→acceptedits→plan→bypass→dontask→status 순서로 통일 - PermissionRequestWindow: 권한 선택/위험도/미리보기/명령 위험도 문구를 한국어 중심으로 정리하고 깨진 문자열을 복구 - README.md: 업데이트 시각을 2026-04-04 13:07(KST)로 갱신하고 이번 반영 항목 2건 추가 - docs/DEVELOPMENT.md: 연속 실행 25차 이력(슬래시 정합화, 권한 다이얼로그 복구, 품질 게이트 결과) 추가 - 검증: dotnet build 경고 0/오류 0, 슬래시/운영모드 필터 테스트 43건 통과
This commit is contained in:
@@ -222,7 +222,7 @@ public class MyHandler : IActionHandler
|
||||
|
||||
### v0.7.3 — AX Agent 권한 코어 재구성 + 입력 계층 정리
|
||||
|
||||
업데이트: 2026-04-04 12:41 (KST)
|
||||
업데이트: 2026-04-04 13:07 (KST)
|
||||
|
||||
| 분류 | 내용 |
|
||||
|------|------|
|
||||
@@ -273,6 +273,8 @@ public class MyHandler : IActionHandler
|
||||
| 권한 상태 표시 간소화 | 권한 상태 텍스트(`/permissions`, `/allowed-tools`)를 운영 모드 포함 축약형으로 정리하고 권한 버튼 툴팁에 동일 정보를 반영 |
|
||||
| 설정창 외부 진입 안정화 | AX Agent 설정창 오픈 시 리소스 병합 실패를 방어하고, 외부 진입 경로를 Dispatcher 기반으로 안정화 |
|
||||
| 모델 라벨 반응형 보강 | 컴포저 상단 모델 라벨에 말줄임(`MaxWidth` + `CharacterEllipsis`)을 적용해 좁은 폭에서 레이아웃 깨짐을 방지 |
|
||||
| 슬래시 탐색 순서 정합화 | `/` 팝업의 방향키/휠/Home/End 이동 기준을 렌더 순서(핀/최근 정렬 적용 순서)로 통일해 스크롤·선택 체감 불일치를 해소 |
|
||||
| 권한 요청창 한국어/인코딩 복구 | `PermissionRequestWindow`의 깨진 문자열을 복구하고 권한 선택/위험도/미리보기 문구를 한국어 기준으로 정리 |
|
||||
| Slash palette 상태 분리 시작 | `ChatWindow`에 몰려 있던 slash 상태를 `SlashPaletteState`로 분리해 이후 Codex/Claude형 composer 개편 기반 마련 |
|
||||
| 런처 이미지 미리보기 추가 | `#` 클립보드 이미지 항목에서 `Shift+Enter`로 전용 미리보기 창을 열고, 줌·원본 해상도 확인·PNG/JPEG/BMP 저장·클립보드 복사를 지원 |
|
||||
| 검증 | `dotnet build` 경고 0 / 오류 0, `dotnet test` 436 passed / 0 failed |
|
||||
|
||||
@@ -3282,3 +3282,25 @@ else:
|
||||
|
||||
|
||||
|
||||
## 2026-04-04 추가 진행 기록 (연속 실행 25차: 슬래시 탐색 정합화 + 권한 요청창 문구 복구)
|
||||
|
||||
업데이트: 2026-04-04 13:07 (KST)
|
||||
|
||||
### 1) slash palette 탐색 정합화
|
||||
- ChatWindow에 렌더 순서 전용 인덱스(_slashVisibleAbsoluteOrder)를 추가.
|
||||
- / 팝업 렌더 시 실제 표시 순서를 기록하고, 방향키/휠 이동이 원본 목록 인덱스가 아닌 렌더 순서를 기준으로 동작하도록 보정.
|
||||
- Home/End 키도 동일 기준(현재 화면에 표시된 첫/마지막 항목)으로 이동하도록 통일.
|
||||
|
||||
### 2) 권한 액션/표기 일관성 보강
|
||||
- 최근 권한 거부 카드의 빠른 액션 순서를 활용하지 않음 → 소극 활용 → 적극 활용 → 예외 해제로 정렬.
|
||||
- /permissions, /allowed-tools 사용법 표기를 동일 순서(deny|default|acceptedits|plan|bypass|dontask|status)로 정리.
|
||||
|
||||
### 3) 권한 요청 다이얼로그 한국어/인코딩 복구
|
||||
- PermissionRequestWindow의 옵션/도움말/헤더/위험도/미리보기 문구를 한국어 기준으로 통일.
|
||||
- 깨진 문자열(권한 확인/작업 허용/위험도 라벨) 복구.
|
||||
- 파일 요약 문구에서 인코딩 손상 텍스트를 정리(존재함 · 용량 · 수정 시각).
|
||||
- 명령 위험도 분류 문구를 한국어로 변환.
|
||||
|
||||
### 4) 품질 게이트
|
||||
- dotnet build src/AxCopilot/AxCopilot.csproj 통과 (경고 0, 오류 0).
|
||||
- dotnet test src/AxCopilot.Tests/AxCopilot.Tests.csproj --no-build --filter "FullyQualifiedName~ChatWindowSlashPolicyTests|FullyQualifiedName~OperationModeReadinessTests" 통과 (43 passed, 0 failed).
|
||||
|
||||
@@ -1882,9 +1882,9 @@ public partial class ChatWindow : Window
|
||||
return button;
|
||||
}
|
||||
|
||||
actionRow.Children.Add(CreateActionButton("활용하지 않음", "#FEF2F2", "#991B1B", () => SetToolPermissionOverride(latestDenied.ToolName!, PermissionModeCatalog.Deny)));
|
||||
actionRow.Children.Add(CreateActionButton("소극 활용", "#EEF2FF", "#1D4ED8", () => SetToolPermissionOverride(latestDenied.ToolName!, PermissionModeCatalog.Default)));
|
||||
actionRow.Children.Add(CreateActionButton("적극 활용", "#ECFDF5", "#166534", () => SetToolPermissionOverride(latestDenied.ToolName!, PermissionModeCatalog.AcceptEdits)));
|
||||
actionRow.Children.Add(CreateActionButton("활용하지 않음", "#FEF2F2", "#991B1B", () => SetToolPermissionOverride(latestDenied.ToolName!, PermissionModeCatalog.Deny)));
|
||||
actionRow.Children.Add(CreateActionButton("예외 해제", "#F3F4F6", "#374151", () => SetToolPermissionOverride(latestDenied.ToolName!, null)));
|
||||
deniedStack.Children.Add(actionRow);
|
||||
}
|
||||
@@ -5033,6 +5033,7 @@ public partial class ChatWindow : Window
|
||||
// ── 슬래시 명령어 팝업 상태 ──
|
||||
private readonly SlashPaletteState _slashPalette = new();
|
||||
private readonly Dictionary<int, FrameworkElement> _slashVisibleItemByAbsoluteIndex = new();
|
||||
private readonly List<int> _slashVisibleAbsoluteOrder = new();
|
||||
|
||||
// ── 슬래시 명령어 (탭별 분류) ──
|
||||
|
||||
@@ -5294,11 +5295,14 @@ public partial class ChatWindow : Window
|
||||
: GetSlashSectionExpanded("slash_commands", true);
|
||||
}
|
||||
|
||||
private IReadOnlyList<int> GetVisibleSlashOrderedIndices() => _slashVisibleAbsoluteOrder;
|
||||
|
||||
/// <summary>현재 슬래시 명령어 항목을 스크롤 리스트로 렌더링합니다.</summary>
|
||||
private void RenderSlashPage()
|
||||
{
|
||||
SlashItems.Items.Clear();
|
||||
_slashVisibleItemByAbsoluteIndex.Clear();
|
||||
_slashVisibleAbsoluteOrder.Clear();
|
||||
var total = _slashPalette.Matches.Count;
|
||||
var totalSkills = _slashPalette.Matches.Count(x => x.IsSkill);
|
||||
var totalCommands = total - totalSkills;
|
||||
@@ -5535,6 +5539,7 @@ public partial class ChatWindow : Window
|
||||
|
||||
SlashItems.Items.Add(item);
|
||||
_slashVisibleItemByAbsoluteIndex[absoluteIndex] = item;
|
||||
_slashVisibleAbsoluteOrder.Add(absoluteIndex);
|
||||
}
|
||||
|
||||
SlashItems.Items.Add(CreateSlashSectionHeader("slash_commands", "명령", totalCommands, commandsExpanded));
|
||||
@@ -5588,33 +5593,28 @@ public partial class ChatWindow : Window
|
||||
|
||||
private void MoveSlashSelection(int direction)
|
||||
{
|
||||
if (_slashPalette.Matches.Count == 0)
|
||||
var visibleOrder = GetVisibleSlashOrderedIndices();
|
||||
if (visibleOrder.Count == 0)
|
||||
return;
|
||||
|
||||
if (_slashPalette.SelectedIndex < 0 || !IsSlashItemVisibleByIndex(_slashPalette.SelectedIndex))
|
||||
_slashPalette.SelectedIndex = GetFirstVisibleSlashIndex(_slashPalette.Matches);
|
||||
|
||||
if (_slashPalette.SelectedIndex < 0)
|
||||
var currentPosition = -1;
|
||||
for (var i = 0; i < visibleOrder.Count; i++)
|
||||
{
|
||||
if (visibleOrder[i] != _slashPalette.SelectedIndex)
|
||||
continue;
|
||||
currentPosition = i;
|
||||
break;
|
||||
}
|
||||
if (currentPosition < 0)
|
||||
{
|
||||
_slashPalette.SelectedIndex = visibleOrder[0];
|
||||
return;
|
||||
}
|
||||
|
||||
if (direction < 0)
|
||||
{
|
||||
for (var i = _slashPalette.SelectedIndex - 1; i >= 0; i--)
|
||||
{
|
||||
if (!IsSlashItemVisibleByIndex(i)) continue;
|
||||
_slashPalette.SelectedIndex = i;
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (direction > 0)
|
||||
{
|
||||
for (var i = _slashPalette.SelectedIndex + 1; i < _slashPalette.Matches.Count; i++)
|
||||
{
|
||||
if (!IsSlashItemVisibleByIndex(i)) continue;
|
||||
_slashPalette.SelectedIndex = i;
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (direction < 0 && currentPosition > 0)
|
||||
_slashPalette.SelectedIndex = visibleOrder[currentPosition - 1];
|
||||
else if (direction > 0 && currentPosition < visibleOrder.Count - 1)
|
||||
_slashPalette.SelectedIndex = visibleOrder[currentPosition + 1];
|
||||
}
|
||||
|
||||
/// <summary>슬래시 팝업을 Delta 방향으로 스크롤합니다.</summary>
|
||||
@@ -7349,11 +7349,11 @@ public partial class ChatWindow : Window
|
||||
|
||||
if (permAction == "status")
|
||||
{
|
||||
AppendLocalSlashResult(_activeTab, "/permissions", $"{BuildPermissionStatusText()}\n사용법: /permissions default|acceptedits|plan|bypass|dontask|deny|status");
|
||||
AppendLocalSlashResult(_activeTab, "/permissions", $"{BuildPermissionStatusText()}\n사용법: /permissions deny|default|acceptedits|plan|bypass|dontask|status");
|
||||
return;
|
||||
}
|
||||
|
||||
OpenPermissionPanelFromSlash("/permissions", "사용법: /permissions default|acceptedits|plan|bypass|dontask|deny|status");
|
||||
OpenPermissionPanelFromSlash("/permissions", "사용법: /permissions deny|default|acceptedits|plan|bypass|dontask|status");
|
||||
return;
|
||||
}
|
||||
if (string.Equals(slashSystem, "__ALLOWED_TOOLS__", StringComparison.Ordinal))
|
||||
@@ -7367,11 +7367,11 @@ public partial class ChatWindow : Window
|
||||
|
||||
if (toolAction == "status")
|
||||
{
|
||||
AppendLocalSlashResult(_activeTab, "/allowed-tools", $"{BuildPermissionStatusText()}\n사용법: /allowed-tools default|acceptedits|plan|bypass|dontask|deny|status");
|
||||
AppendLocalSlashResult(_activeTab, "/allowed-tools", $"{BuildPermissionStatusText()}\n사용법: /allowed-tools deny|default|acceptedits|plan|bypass|dontask|status");
|
||||
return;
|
||||
}
|
||||
|
||||
OpenPermissionPanelFromSlash("/allowed-tools", "사용법: /allowed-tools default|acceptedits|plan|bypass|dontask|deny|status");
|
||||
OpenPermissionPanelFromSlash("/allowed-tools", "사용법: /allowed-tools deny|default|acceptedits|plan|bypass|dontask|status");
|
||||
return;
|
||||
}
|
||||
if (string.Equals(slashSystem, "__MODEL__", StringComparison.Ordinal))
|
||||
@@ -10961,18 +10961,15 @@ public partial class ChatWindow : Window
|
||||
}
|
||||
else if (e.Key == Key.Home)
|
||||
{
|
||||
_slashPalette.SelectedIndex = GetFirstVisibleSlashIndex(_slashPalette.Matches);
|
||||
var visible = GetVisibleSlashOrderedIndices();
|
||||
_slashPalette.SelectedIndex = visible.Count > 0 ? visible[0] : GetFirstVisibleSlashIndex(_slashPalette.Matches);
|
||||
RenderSlashPage();
|
||||
e.Handled = true;
|
||||
}
|
||||
else if (e.Key == Key.End)
|
||||
{
|
||||
for (var i = _slashPalette.Matches.Count - 1; i >= 0; i--)
|
||||
{
|
||||
if (!IsSlashItemVisibleByIndex(i)) continue;
|
||||
_slashPalette.SelectedIndex = i;
|
||||
break;
|
||||
}
|
||||
var visible = GetVisibleSlashOrderedIndices();
|
||||
_slashPalette.SelectedIndex = visible.Count > 0 ? visible[^1] : GetFirstVisibleSlashIndex(_slashPalette.Matches);
|
||||
RenderSlashPage();
|
||||
e.Handled = true;
|
||||
}
|
||||
|
||||
1171
src/AxCopilot/Views/PermissionRequestWindow.cs
Normal file
1171
src/AxCopilot/Views/PermissionRequestWindow.cs
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user