권한 팝업 순서/즉시반영 정렬: Deny 상단 배치와 탭 기본값 강제
Some checks failed
Release Gate / gate (push) Has been cancelled
Some checks failed
Release Gate / gate (push) Has been cancelled
- 권한 팝업 핵심 영역에 Deny(활용하지 않음) 포함, 고급은 DontAsk만 유지 - LoadConversationSettings가 대화 권한 미설정 시 탭 기본권한(Chat=Deny, Cowork/Code=DefaultAgentPermission) 즉시 적용 - PermissionModePresentationCatalog 한글 라벨/설명 문자열 정리 - README/DEVELOPMENT 이력(2026-04-04 15:52 KST) 동기화
This commit is contained in:
@@ -222,7 +222,7 @@ public class MyHandler : IActionHandler
|
|||||||
|
|
||||||
### v0.7.3 — AX Agent 권한 코어 재구성 + 입력 계층 정리
|
### v0.7.3 — AX Agent 권한 코어 재구성 + 입력 계층 정리
|
||||||
|
|
||||||
업데이트: 2026-04-04 15:48 (KST)
|
업데이트: 2026-04-04 15:52 (KST)
|
||||||
|
|
||||||
| 분류 | 내용 |
|
| 분류 | 내용 |
|
||||||
|------|------|
|
|------|------|
|
||||||
@@ -290,6 +290,7 @@ public class MyHandler : IActionHandler
|
|||||||
| 권한 모드 별칭 정합 보강 | `/permissions`, `/allowed-tools`에서 `none/passive/active/planning/fullauto/silent` 별칭을 지원하고 카탈로그 정규화와 일치시킴 |
|
| 권한 모드 별칭 정합 보강 | `/permissions`, `/allowed-tools`에서 `none/passive/active/planning/fullauto/silent` 별칭을 지원하고 카탈로그 정규화와 일치시킴 |
|
||||||
| 권한 기본값 정책 정렬 | 신규/초기 상태의 기본 권한을 `활용하지 않음(Deny)`으로 변경하고 AppState 기본/요약 상태와 slash 사용 가이드를 동일 체계로 정렬 |
|
| 권한 기본값 정책 정렬 | 신규/초기 상태의 기본 권한을 `활용하지 않음(Deny)`으로 변경하고 AppState 기본/요약 상태와 slash 사용 가이드를 동일 체계로 정렬 |
|
||||||
| 탭 전환 빈 대화 누적 방지 | 탭 전환 중 생성되는 무의미한 빈 대화를 저장 대상에서 제외하고, 목록에서도 빈 노이즈 항목을 숨겨 이력 누적 체감 버그를 완화 |
|
| 탭 전환 빈 대화 누적 방지 | 탭 전환 중 생성되는 무의미한 빈 대화를 저장 대상에서 제외하고, 목록에서도 빈 노이즈 항목을 숨겨 이력 누적 체감 버그를 완화 |
|
||||||
|
| 권한 팝업 즉시반영 정렬 | 권한 팝업에 `활용하지 않음`을 핵심 영역 맨 위에 배치하고, 대화 권한이 없을 때도 탭 기본값(Deny/DefaultAgentPermission)을 즉시 반영하도록 로딩 경로를 보강 |
|
||||||
| Slash palette 상태 분리 시작 | `ChatWindow`에 몰려 있던 slash 상태를 `SlashPaletteState`로 분리해 이후 Codex/Claude형 composer 개편 기반 마련 |
|
| Slash palette 상태 분리 시작 | `ChatWindow`에 몰려 있던 slash 상태를 `SlashPaletteState`로 분리해 이후 Codex/Claude형 composer 개편 기반 마련 |
|
||||||
| 런처 이미지 미리보기 추가 | `#` 클립보드 이미지 항목에서 `Shift+Enter`로 전용 미리보기 창을 열고, 줌·원본 해상도 확인·PNG/JPEG/BMP 저장·클립보드 복사를 지원 |
|
| 런처 이미지 미리보기 추가 | `#` 클립보드 이미지 항목에서 `Shift+Enter`로 전용 미리보기 창을 열고, 줌·원본 해상도 확인·PNG/JPEG/BMP 저장·클립보드 복사를 지원 |
|
||||||
| 검증 | `dotnet build` 경고 0 / 오류 0, `dotnet test` 436 passed / 0 failed |
|
| 검증 | `dotnet build` 경고 0 / 오류 0, `dotnet test` 436 passed / 0 failed |
|
||||||
|
|||||||
@@ -3605,3 +3605,25 @@ else:
|
|||||||
### 4) 품질 게이트
|
### 4) 품질 게이트
|
||||||
- `dotnet build src/AxCopilot/AxCopilot.csproj -c Debug -p:UseSharedCompilation=false -nodeReuse:false` 통과 (경고 0, 오류 0).
|
- `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~ChatSessionStateServiceTests|FullyQualifiedName~AppStateServiceTests|FullyQualifiedName~OperationModePolicyTests|FullyQualifiedName~ChatWindowSlashPolicyTests"` 통과 (132 passed, 0 failed).
|
- `dotnet test src/AxCopilot.Tests/AxCopilot.Tests.csproj --filter "FullyQualifiedName~ChatSessionStateServiceTests|FullyQualifiedName~AppStateServiceTests|FullyQualifiedName~OperationModePolicyTests|FullyQualifiedName~ChatWindowSlashPolicyTests"` 통과 (132 passed, 0 failed).
|
||||||
|
|
||||||
|
## 2026-04-04 추가 진행 기록 (연속 실행 40차: 권한 팝업 순서/즉시반영 정렬)
|
||||||
|
|
||||||
|
업데이트: 2026-04-04 15:52 (KST)
|
||||||
|
|
||||||
|
### 1) 권한 팝업 표시 순서 정렬
|
||||||
|
- `ChatWindow` 권한 팝업의 핵심 모드 목록에 `활용하지 않음(Deny)`을 포함해 맨 위에서 선택 가능하도록 조정.
|
||||||
|
- 고급 모드는 `질문 없이 진행(DontAsk)`만 유지해 핵심/고급 구분을 단순화.
|
||||||
|
|
||||||
|
### 2) 탭/대화 전환 시 권한 즉시반영 보강
|
||||||
|
- `LoadConversationSettings`에서 대화 권한이 비어 있는 경우에도 명시적으로 탭 기본값을 적용:
|
||||||
|
- `Chat` 탭: `Deny`
|
||||||
|
- `Cowork/Code` 탭: `DefaultAgentPermission`
|
||||||
|
- 효과: 이전 대화의 권한 값이 남아 2번 눌러야 반영되는 현상 완화.
|
||||||
|
|
||||||
|
### 3) 권한 프리젠테이션 카탈로그 문자열 정리
|
||||||
|
- `PermissionModePresentationCatalog`의 권한 라벨/설명 문자열을 정상 한글 문구로 정리(깨짐 문자열 제거).
|
||||||
|
- 표시 문구와 실제 권한 의미를 일치시켜 UX 혼선을 줄임.
|
||||||
|
|
||||||
|
### 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).
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
namespace AxCopilot.Services.Agent;
|
namespace AxCopilot.Services.Agent;
|
||||||
|
|
||||||
internal sealed record PermissionModePresentation(
|
internal sealed record PermissionModePresentation(
|
||||||
string Mode,
|
string Mode,
|
||||||
@@ -15,37 +15,37 @@ internal static class PermissionModePresentationCatalog
|
|||||||
PermissionModeCatalog.Deny,
|
PermissionModeCatalog.Deny,
|
||||||
"\uE711",
|
"\uE711",
|
||||||
"활용하지 않음",
|
"활용하지 않음",
|
||||||
"파일 읽기만 허용하고 생성/수정/삭제를 차단합니다",
|
"파일 읽기만 허용하고 생성/수정/삭제는 차단합니다.",
|
||||||
"#107C10"),
|
"#107C10"),
|
||||||
new PermissionModePresentation(
|
new PermissionModePresentation(
|
||||||
PermissionModeCatalog.Default,
|
PermissionModeCatalog.Default,
|
||||||
"\uE8D7",
|
"\uE8D7",
|
||||||
"소극 활용",
|
"소극 활용",
|
||||||
"변경 전 확인하며 필요할 때만 파일 접근을 진행합니다",
|
"변경 전 확인하고, 필요한 경우에만 파일 접근을 진행합니다.",
|
||||||
"#2563EB"),
|
"#2563EB"),
|
||||||
new PermissionModePresentation(
|
new PermissionModePresentation(
|
||||||
PermissionModeCatalog.AcceptEdits,
|
PermissionModeCatalog.AcceptEdits,
|
||||||
"\uE73E",
|
"\uE73E",
|
||||||
"적극 활용",
|
"적극 활용",
|
||||||
"파일 편집 도구를 자동 승인하고 명령 실행은 계속 확인합니다",
|
"파일 편집 도구를 자동 승인하고 명령 실행은 계속 확인합니다.",
|
||||||
"#107C10"),
|
"#107C10"),
|
||||||
new PermissionModePresentation(
|
new PermissionModePresentation(
|
||||||
PermissionModeCatalog.Plan,
|
PermissionModeCatalog.Plan,
|
||||||
"\uE7C3",
|
"\uE7C3",
|
||||||
"계획 중심",
|
"계획 중심",
|
||||||
"쓰기 전 계획/승인 흐름을 우선합니다",
|
"쓰기 전 계획과 승인 흐름을 우선합니다.",
|
||||||
"#4338CA"),
|
"#4338CA"),
|
||||||
new PermissionModePresentation(
|
new PermissionModePresentation(
|
||||||
PermissionModeCatalog.BypassPermissions,
|
PermissionModeCatalog.BypassPermissions,
|
||||||
"\uE814",
|
"\uE814",
|
||||||
"완전 자동",
|
"완전 자동",
|
||||||
"권한 확인을 대부분 생략합니다. 민감 작업에 주의하세요",
|
"권한 확인을 대부분 생략합니다. 민감한 작업은 주의하세요.",
|
||||||
"#B45309"),
|
"#B45309"),
|
||||||
new PermissionModePresentation(
|
new PermissionModePresentation(
|
||||||
PermissionModeCatalog.DontAsk,
|
PermissionModeCatalog.DontAsk,
|
||||||
"\uE8A5",
|
"\uE8A5",
|
||||||
"질문 없이 진행",
|
"질문 없이 진행",
|
||||||
"권한 질문 없이 진행합니다. 자동 실행 범위를 점검하세요",
|
"권한 질문 없이 진행합니다. 자동 실행 범위를 점검하세요.",
|
||||||
"#B91C1C"),
|
"#B91C1C"),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1561,8 +1561,13 @@ public partial class ChatWindow : Window
|
|||||||
lock (_convLock) conv = _currentConversation;
|
lock (_convLock) conv = _currentConversation;
|
||||||
var llm = _settings.Settings.Llm;
|
var llm = _settings.Settings.Llm;
|
||||||
|
|
||||||
if (conv != null && conv.Permission != null)
|
var fallbackPermission = _activeTab == "Chat"
|
||||||
_settings.Settings.Llm.FilePermission = PermissionModeCatalog.NormalizeGlobalMode(conv.Permission);
|
? PermissionModeCatalog.Deny
|
||||||
|
: PermissionModeCatalog.NormalizeGlobalMode(llm.DefaultAgentPermission);
|
||||||
|
var conversationPermission = !string.IsNullOrWhiteSpace(conv?.Permission)
|
||||||
|
? PermissionModeCatalog.NormalizeGlobalMode(conv.Permission)
|
||||||
|
: fallbackPermission;
|
||||||
|
_settings.Settings.Llm.FilePermission = conversationPermission;
|
||||||
|
|
||||||
_folderDataUsage = conv?.DataUsage ?? llm.FolderDataUsage ?? "none";
|
_folderDataUsage = conv?.DataUsage ?? llm.FolderDataUsage ?? "none";
|
||||||
_selectedMood = conv?.Mood ?? llm.DefaultMood ?? "modern";
|
_selectedMood = conv?.Mood ?? llm.DefaultMood ?? "modern";
|
||||||
@@ -1903,15 +1908,14 @@ public partial class ChatWindow : Window
|
|||||||
|
|
||||||
var coreLevels = PermissionModePresentationCatalog.Ordered
|
var coreLevels = PermissionModePresentationCatalog.Ordered
|
||||||
.Where(x =>
|
.Where(x =>
|
||||||
|
string.Equals(x.Mode, PermissionModeCatalog.Deny, StringComparison.OrdinalIgnoreCase) ||
|
||||||
string.Equals(x.Mode, PermissionModeCatalog.Default, StringComparison.OrdinalIgnoreCase) ||
|
string.Equals(x.Mode, PermissionModeCatalog.Default, StringComparison.OrdinalIgnoreCase) ||
|
||||||
string.Equals(x.Mode, PermissionModeCatalog.AcceptEdits, StringComparison.OrdinalIgnoreCase) ||
|
string.Equals(x.Mode, PermissionModeCatalog.AcceptEdits, StringComparison.OrdinalIgnoreCase) ||
|
||||||
string.Equals(x.Mode, PermissionModeCatalog.Plan, StringComparison.OrdinalIgnoreCase) ||
|
string.Equals(x.Mode, PermissionModeCatalog.Plan, StringComparison.OrdinalIgnoreCase) ||
|
||||||
string.Equals(x.Mode, PermissionModeCatalog.BypassPermissions, StringComparison.OrdinalIgnoreCase))
|
string.Equals(x.Mode, PermissionModeCatalog.BypassPermissions, StringComparison.OrdinalIgnoreCase))
|
||||||
.ToList();
|
.ToList();
|
||||||
var advancedLevels = PermissionModePresentationCatalog.Ordered
|
var advancedLevels = PermissionModePresentationCatalog.Ordered
|
||||||
.Where(x =>
|
.Where(x => string.Equals(x.Mode, PermissionModeCatalog.DontAsk, StringComparison.OrdinalIgnoreCase))
|
||||||
string.Equals(x.Mode, PermissionModeCatalog.Deny, StringComparison.OrdinalIgnoreCase) ||
|
|
||||||
string.Equals(x.Mode, PermissionModeCatalog.DontAsk, StringComparison.OrdinalIgnoreCase))
|
|
||||||
.ToList();
|
.ToList();
|
||||||
var current = PermissionModeCatalog.NormalizeGlobalMode(_settings.Settings.Llm.FilePermission);
|
var current = PermissionModeCatalog.NormalizeGlobalMode(_settings.Settings.Llm.FilePermission);
|
||||||
void AddPermissionRows(Panel container, IEnumerable<PermissionModePresentation> levels)
|
void AddPermissionRows(Panel container, IEnumerable<PermissionModePresentation> levels)
|
||||||
|
|||||||
Reference in New Issue
Block a user