From e747032501a07d51264685ab66b17dd2489ba0a6 Mon Sep 17 00:00:00 2001 From: lacvet Date: Mon, 6 Apr 2026 12:57:15 +0900 Subject: [PATCH] =?UTF-8?q?=EB=8F=84=EA=B5=AC=C2=B7=EA=B6=8C=ED=95=9C?= =?UTF-8?q?=C2=B7=EC=8A=A4=ED=82=AC=20=ED=91=9C=ED=98=84=20=EC=A0=95?= =?UTF-8?q?=EA=B5=90=ED=99=94=201=EC=B0=A8=20=EB=B0=98=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 권한 요청 카탈로그를 bash/powershell/web_fetch/mcp/skill/file_edit/file_write/git/document/filesystem 수준으로 세분화했습니다. - 도구 결과 카탈로그에 approval_required, partial, follow-up hint, attention 메타를 추가해 후속 renderer 고도화 기반을 마련했습니다. - 스킬 갤러리에 모델, 추론 강도, 실행 컨텍스트, 에이전트, 모델 호출 비활성화, 추천 상황을 표시하도록 확장했습니다. - README, DEVELOPMENT, parity plan, regression prompts 문서를 2026-04-06 11:52 (KST) 기준으로 갱신했습니다. - 검증: dotnet build src/AxCopilot/AxCopilot.csproj -c Release -v minimal -p:OutputPath=bin\\verify\\ -p:IntermediateOutputPath=obj\\verify\\ (경고 0 / 오류 0) --- README.md | 4 + docs/AX_AGENT_REGRESSION_PROMPTS.md | 18 ++ docs/DEVELOPMENT.md | 3 + docs/claw-code-parity-plan.md | 2 + .../PermissionRequestPresentationCatalog.cs | 165 ++++++++++-------- .../Agent/ToolResultPresentationCatalog.cs | 126 +++++++++++-- .../Views/SkillGalleryWindow.xaml.cs | 12 ++ 7 files changed, 248 insertions(+), 82 deletions(-) diff --git a/README.md b/README.md index ebeb531..f8f37f5 100644 --- a/README.md +++ b/README.md @@ -1206,3 +1206,7 @@ MIT License - 업데이트: 2026-04-06 11:34 (KST) - footer 작업 바의 chip 버튼 시각 언어를 맞췄다. [ChatWindow.xaml](/E:/AX%20Copilot%20-%20Codex/src/AxCopilot/Views/ChatWindow.xaml)에 `FooterChipBtn` 스타일을 추가하고, 하단의 `권한`, `Git 브랜치` 버튼이 같은 라운드/테두리/패딩 규칙을 쓰도록 정리했다. - 이 단계는 구조 분리 이후의 visual polish 후속 작업으로, footer의 기능 버튼이 각각 다른 컨트롤처럼 보이던 차이를 줄이고 작업 바 전체를 하나의 도구 행처럼 느끼게 만드는 데 초점을 맞췄다. +- 업데이트: 2026-04-06 11:52 (KST) + - `claw-code` 대비 남아 있던 `도구/권한/스킬 표현 정교화` 1차를 반영했다. [PermissionRequestPresentationCatalog.cs](/E:/AX%20Copilot%20-%20Codex/src/AxCopilot/Services/Agent/PermissionRequestPresentationCatalog.cs)는 `bash`, `powershell`, `command`, `web_fetch`, `mcp`, `skill`, `question`, `file_edit`, `file_write`, `git`, `document`, `filesystem`까지 세분화하고 `ActionHint`, `Severity`, `RequiresPreview` 메타를 추가했다. + - [ToolResultPresentationCatalog.cs](/E:/AX%20Copilot%20-%20Codex/src/AxCopilot/Services/Agent/ToolResultPresentationCatalog.cs)는 기존 `success / error / reject / cancel`에 더해 `approval_required`, `partial` 상태와 `FollowUpHint`, `NeedsAttention` 메타를 추가해 후속 안내 품질을 높일 기반을 마련했다. + - [SkillGalleryWindow.xaml.cs](/E:/AX%20Copilot%20-%20Codex/src/AxCopilot/Views/SkillGalleryWindow.xaml.cs)는 스킬 상세에 `모델`, `추론 강도`, `실행 컨텍스트`, `에이전트`, `모델 호출 비활성화`, `추천 상황`을 표시하도록 확장해, AX 스킬도 `claw-code`처럼 실행 정책이 보이는 방향으로 정리했다. diff --git a/docs/AX_AGENT_REGRESSION_PROMPTS.md b/docs/AX_AGENT_REGRESSION_PROMPTS.md index 458fe75..98708f4 100644 --- a/docs/AX_AGENT_REGRESSION_PROMPTS.md +++ b/docs/AX_AGENT_REGRESSION_PROMPTS.md @@ -108,3 +108,21 @@ - Cowork 변경: 3, 4, 7, 8 - Code 변경: 5, 6, 7, 9, 10 - 체크 후 문서 이력에는 “어떤 묶음을 확인했는지”를 간단히 남깁니다. +## Tool / Permission Follow-up + +11. 권한 거부 후 재시도 +- 프롬프트 순서: + - `src 폴더에서 설정 파일을 수정해줘` + - 첫 권한 요청은 거부 + - 같은 작업을 다시 요청 +- 확인: + - `reject`와 `approval_required`가 같은 결과 카드처럼 보이지 않음 + - 재시도 시 권한 메시지와 도구 결과가 중복되지 않음 + - `bad-approval-flow` + +12. 부분 성공 / 후속 안내 +- 프롬프트: `여러 문서 파일을 한 번에 읽고 요약해줘` +- 확인: + - 일부 실패가 있으면 `partial` 계열 안내가 보이는지 + - 후속 안내 문구가 단순 실패와 다르게 보이는지 + - `status-noise` diff --git a/docs/DEVELOPMENT.md b/docs/DEVELOPMENT.md index b56a79e..e747c68 100644 --- a/docs/DEVELOPMENT.md +++ b/docs/DEVELOPMENT.md @@ -4941,3 +4941,6 @@ ow + toggle ?쒓컖 ?몄뼱濡??ㅼ떆 ?뺣젹?덈떎. - Document update: 2026-04-06 11:27 (KST) - At this point preview, file browser, worktree chooser, and permission-mode popup surfaces all share nearly the same visual language; remaining work is minor spacing/color polish rather than another behavior or structure change. - Document update: 2026-04-06 11:34 (KST) - Added `FooterChipBtn` to `ChatWindow.xaml` and aligned the footer work-bar buttons (`권한`, `Git 브랜치`) to the same rounded border, padding, and hover language instead of mixing outline and ghost button styles. - Document update: 2026-04-06 11:34 (KST) - This is a footer polish follow-up after the structure split, aimed at making the bottom work bar feel like one coherent tool row rather than a set of unrelated controls. +- Document update: 2026-04-06 11:52 (KST) - Expanded `PermissionRequestPresentationCatalog.cs` into an action-level permission taxonomy (`bash`, `powershell`, `command`, `web_fetch`, `mcp`, `skill`, `question`, `file_edit`, `file_write`, `git`, `document`, `filesystem`) and added `ActionHint`, `Severity`, `RequiresPreview` metadata for later renderer refinement. +- Document update: 2026-04-06 11:52 (KST) - Expanded `ToolResultPresentationCatalog.cs` with richer result taxonomy and post-result guidance. AX now distinguishes `approval_required` and `partial` in addition to `success / error / reject / cancel`, and each result carries `FollowUpHint` and `NeedsAttention`. +- Document update: 2026-04-06 11:52 (KST) - Extended `SkillGalleryWindow.xaml.cs` to expose runtime-policy metadata (`model`, `effort`, `execution context`, `agent`, `disable model invocation`, `when to use`) so AX skills are easier to inspect and maintain like `claw-code` bundled skills. diff --git a/docs/claw-code-parity-plan.md b/docs/claw-code-parity-plan.md index 5dfd472..aa8dc1e 100644 --- a/docs/claw-code-parity-plan.md +++ b/docs/claw-code-parity-plan.md @@ -19,6 +19,8 @@ - Formalized the regression ritual in `docs/AX_AGENT_REGRESSION_PROMPTS.md` by adding failure classes (`blank-reply`, `duplicate-banner`, `bad-approval-flow`, `queue-drift`, `restore-drift`, `status-noise`) and required prompt bundles per change area. - Updated: 2026-04-06 10:07 (KST) - Continued the maintainability track by moving topic preset rendering, custom preset context menus, and topic-selection application flow into `ChatWindow.TopicPresetPresentation.cs`. This reduces mixed preset UI logic inside `ChatWindow.xaml.cs` and keeps the main window closer to orchestration-only responsibility. +- Updated: 2026-04-06 11:52 (KST) +- Continued the tool/permission/skill sophistication track by expanding AX presentation catalogs toward `claw-code` specificity. `PermissionRequestPresentationCatalog.cs` now models action-level permission kinds plus severity/action hints, `ToolResultPresentationCatalog.cs` now models `approval_required`/`partial` result states plus follow-up guidance, and the AX skill gallery now exposes runtime-policy metadata that was previously hidden. ## Preserved History (Summary) - Core loop guards and post-tool verification gates are already partially implemented. diff --git a/src/AxCopilot/Services/Agent/PermissionRequestPresentationCatalog.cs b/src/AxCopilot/Services/Agent/PermissionRequestPresentationCatalog.cs index e2e609e..dd84b9e 100644 --- a/src/AxCopilot/Services/Agent/PermissionRequestPresentationCatalog.cs +++ b/src/AxCopilot/Services/Agent/PermissionRequestPresentationCatalog.cs @@ -5,8 +5,11 @@ internal sealed record PermissionRequestPresentation( string Icon, string Label, string Description, + string ActionHint, string BackgroundHex, - string ForegroundHex); + string ForegroundHex, + string Severity, + bool RequiresPreview); internal static class PermissionRequestPresentationCatalog { @@ -14,88 +17,108 @@ internal static class PermissionRequestPresentationCatalog { var tool = (toolName ?? string.Empty).Trim().ToLowerInvariant(); - if (tool.Contains("bash") || tool.Contains("powershell") || tool.Contains("process")) - return Build( - "command", - pending, - "\uE756", - "명령 실행 권한 요청", - "명령 실행 권한 확인", - "터미널 명령을 실행하기 전에 확인이 필요합니다.", + if (tool.Contains("bash")) + return Build("bash", pending, "\uE756", + "Bash 실행 권한 요청", "Bash 실행 확인", + "셸 명령을 실행하기 전에 확인이 필요합니다.", + "Bash 실행이 승인되어 계속 진행합니다.", + "명령과 작업 위치를 확인하세요.", + "#FEF2F2", "#DC2626", "high", false); + + if (tool.Contains("powershell")) + return Build("powershell", pending, "\uE756", + "PowerShell 권한 요청", "PowerShell 실행 확인", + "PowerShell 명령을 실행하기 전에 확인이 필요합니다.", + "PowerShell 실행이 승인되어 계속 진행합니다.", + "스크립트와 실행 범위를 확인하세요.", + "#FEF2F2", "#DC2626", "high", false); + + if (tool.Contains("process") || tool.Contains("build") || tool.Contains("test")) + return Build("command", pending, "\uE756", + "명령 실행 권한 요청", "명령 실행 확인", + "명령 또는 빌드 작업 실행 전에 확인이 필요합니다.", "명령 실행이 승인되어 계속 진행합니다.", - "#FEF2F2", - "#DC2626"); + "실행 명령과 영향 범위를 확인하세요.", + "#FEF2F2", "#DC2626", "high", false); if (tool.Contains("web") || tool.Contains("fetch") || tool.Contains("http")) - return Build( - "web", - pending, - "\uE774", - "웹 요청 권한 요청", - "웹 요청 권한 확인", - "외부 웹 요청 전 사용자 확인이 필요합니다.", + return Build("web_fetch", pending, "\uE774", + "웹 요청 권한 요청", "웹 요청 확인", + "외부 요청을 보내기 전에 확인이 필요합니다.", "웹 요청이 승인되어 계속 진행합니다.", - "#FFF7ED", - "#C2410C"); + "조회 URL과 전송 범위를 확인하세요.", + "#FFF7ED", "#C2410C", "medium", false); + + if (tool.Contains("mcp")) + return Build("mcp", pending, "\uE943", + "MCP 도구 권한 요청", "MCP 도구 확인", + "연결된 MCP 도구 사용 전에 확인이 필요합니다.", + "MCP 도구 사용이 승인되어 계속 진행합니다.", + "서버와 호출 의도를 확인하세요.", + "#F5F3FF", "#7C3AED", "medium", false); if (tool.Contains("skill")) - return Build( - "skill", - pending, - "\uE8A5", - "스킬 실행 권한 요청", - "스킬 실행 권한 확인", - "연결된 스킬 실행 전 확인이 필요합니다.", + return Build("skill", pending, "\uE8A5", + "스킬 실행 권한 요청", "스킬 실행 확인", + "연결된 스킬을 실행하기 전에 확인이 필요합니다.", "스킬 실행이 승인되어 계속 진행합니다.", - "#F5F3FF", - "#7C3AED"); + "허용 도구와 실행 컨텍스트를 확인하세요.", + "#F5F3FF", "#7C3AED", "medium", false); if (tool.Contains("ask")) - return Build( - "question", - pending, - "\uE897", - "의견 요청 확인", - "의견 요청 완료", + return Build("question", pending, "\uE897", + "의견 요청 확인", "의견 요청 완료", "사용자에게 선택이나 답변을 요청합니다.", - "사용자 의견을 받아 다음 단계로 진행합니다.", - "#EFF6FF", - "#2563EB"); + "사용자 답변을 받아 다음 단계로 진행합니다.", + "질문 의도와 선택지를 확인하세요.", + "#EFF6FF", "#2563EB", "low", false); - if (tool.Contains("file_edit") || tool.Contains("file_write") || tool.Contains("edit")) - return Build( - "file_edit", - pending, - "\uE70F", - "파일 수정 권한 요청", - "파일 수정 권한 확인", - "파일을 만들거나 수정하기 전에 확인이 필요합니다.", + if (tool.Contains("file_edit") || tool.Contains("edit")) + return Build("file_edit", pending, "\uE70F", + "파일 수정 권한 요청", "파일 수정 확인", + "파일을 변경하기 전에 확인이 필요합니다.", "파일 수정이 승인되어 계속 진행합니다.", - "#FFF7ED", - "#C2410C"); + "변경 diff와 대상 파일을 확인하세요.", + "#FFF7ED", "#C2410C", "high", true); + + if (tool.Contains("file_write") || tool.Contains("write")) + return Build("file_write", pending, "\uE70F", + "파일 쓰기 권한 요청", "파일 쓰기 확인", + "새 파일 작성 또는 덮어쓰기 전에 확인이 필요합니다.", + "파일 쓰기가 승인되어 계속 진행합니다.", + "작성 위치와 새 내용 미리보기를 확인하세요.", + "#FFF7ED", "#C2410C", "high", true); + + if (tool.Contains("git")) + return Build("git", pending, "\uE8A7", + "Git 작업 권한 요청", "Git 작업 확인", + "브랜치나 커밋 상태를 바꾸기 전에 확인이 필요합니다.", + "Git 작업이 승인되어 계속 진행합니다.", + "브랜치와 변경 범위를 확인하세요.", + "#EFF6FF", "#2563EB", "medium", false); + + if (tool.Contains("document") || tool.Contains("template") || tool.Contains("format")) + return Build("document", pending, "\uE8A5", + "문서 작업 권한 요청", "문서 작업 확인", + "문서 생성 또는 변환 작업 전에 확인이 필요합니다.", + "문서 작업이 승인되어 계속 진행합니다.", + "출력 형식과 저장 위치를 확인하세요.", + "#FFF7ED", "#C2410C", "medium", false); if (tool.Contains("file") || tool.Contains("glob") || tool.Contains("grep") || tool.Contains("folder")) - return Build( - "file_access", - pending, - "\uE8A5", - "파일 접근 권한 요청", - "파일 접근 권한 확인", - "폴더와 파일 내용을 읽기 전에 확인이 필요합니다.", + return Build("filesystem", pending, "\uE8A5", + "파일 접근 권한 요청", "파일 접근 확인", + "폴더나 파일 내용을 읽기 전에 확인이 필요합니다.", "파일 접근이 승인되어 계속 진행합니다.", - "#FFF7ED", - "#C2410C"); + "읽기 범위와 접근 경로를 확인하세요.", + "#FFF7ED", "#C2410C", "medium", false); - return Build( - "generic", - pending, - "\uE897", - "권한 요청", - "권한 확인", - "계속 진행하기 전에 사용자 확인이 필요합니다.", + return Build("generic", pending, "\uE897", + "권한 요청", "권한 확인", + "계속 진행하기 전에 사용자의 확인이 필요합니다.", "요청이 승인되어 계속 진행합니다.", - "#FFF7ED", - "#C2410C"); + "실행 의도와 대상 범위를 확인하세요.", + "#FFF7ED", "#C2410C", "medium", false); } private static PermissionRequestPresentation Build( @@ -106,15 +129,21 @@ internal static class PermissionRequestPresentationCatalog string resolvedLabel, string pendingDescription, string resolvedDescription, + string actionHint, string backgroundHex, - string foregroundHex) + string foregroundHex, + string severity, + bool requiresPreview) { return new PermissionRequestPresentation( kind, pending ? icon : "\uE73E", pending ? pendingLabel : resolvedLabel, pending ? pendingDescription : resolvedDescription, + actionHint, pending ? backgroundHex : "#ECFDF5", - pending ? foregroundHex : "#059669"); + pending ? foregroundHex : "#059669", + severity, + requiresPreview); } } diff --git a/src/AxCopilot/Services/Agent/ToolResultPresentationCatalog.cs b/src/AxCopilot/Services/Agent/ToolResultPresentationCatalog.cs index 8307d41..2b48b0e 100644 --- a/src/AxCopilot/Services/Agent/ToolResultPresentationCatalog.cs +++ b/src/AxCopilot/Services/Agent/ToolResultPresentationCatalog.cs @@ -5,9 +5,11 @@ internal sealed record ToolResultPresentation( string Icon, string Label, string Description, + string FollowUpHint, string BackgroundHex, string ForegroundHex, - string StatusKind); + string StatusKind, + bool NeedsAttention); internal static class ToolResultPresentationCatalog { @@ -27,9 +29,11 @@ internal static class ToolResultPresentationCatalog "\uE711", $"{baseLabel} 취소", "요청이 중단되어 결과가 취소되었습니다.", + "필요하면 같은 요청을 다시 실행하세요.", "#F8FAFC", "#475569", - "cancel"); + "cancel", + false); } if (summary.Contains("거부", StringComparison.OrdinalIgnoreCase) || @@ -41,9 +45,41 @@ internal static class ToolResultPresentationCatalog "\uE783", $"{baseLabel} 거부", "권한이 거부되어 작업이 중단되었습니다.", + "권한 모드를 바꾸거나 다시 승인하면 이어서 진행할 수 있습니다.", "#FEF2F2", "#DC2626", - "reject"); + "reject", + true); + } + + if (summary.Contains("승인 필요", StringComparison.OrdinalIgnoreCase) || + summary.Contains("확인 필요", StringComparison.OrdinalIgnoreCase)) + { + return new ToolResultPresentation( + kind, + "\uE8D7", + $"{baseLabel} 승인 대기", + "다음 단계로 진행하려면 사용자 승인이 필요합니다.", + "승인 후 같은 작업 흐름이 이어집니다.", + "#FFF7ED", + "#C2410C", + "approval_required", + true); + } + + if (summary.Contains("부분", StringComparison.OrdinalIgnoreCase) || + summary.Contains("일부", StringComparison.OrdinalIgnoreCase)) + { + return new ToolResultPresentation( + kind, + "\uE7BA", + $"{baseLabel} 부분 완료", + "일부 단계만 완료되어 후속 확인이나 재실행이 필요할 수 있습니다.", + "남은 단계나 누락된 결과를 확인하세요.", + "#FFFBEA", + "#A16207", + "partial", + true); } if (!evt.Success || evt.Type == AgentEventType.Error) @@ -53,9 +89,11 @@ internal static class ToolResultPresentationCatalog "\uE783", BuildFailureLabel(kind, baseLabel), BuildFailureDescription(kind), + BuildFailureFollowUp(kind), "#FEF2F2", "#DC2626", - "error"); + "error", + true); } return new ToolResultPresentation( @@ -63,23 +101,35 @@ internal static class ToolResultPresentationCatalog "\uE73E", BuildSuccessLabel(kind, baseLabel), BuildSuccessDescription(kind), + BuildSuccessFollowUp(kind), "#ECFDF5", "#16A34A", - "success"); + "success", + false); } private static string ResolveKind(string tool) { + if (tool.Contains("file_edit")) + return "file_edit"; + if (tool.Contains("file_write")) + return "file_write"; + if (tool.Contains("file_read") || tool.Contains("glob") || tool.Contains("grep")) + return "filesystem"; if (tool.Contains("file")) return "file"; if (tool.Contains("build") || tool.Contains("test")) - return "build"; + return "build_test"; if (tool.Contains("git") || tool.Contains("diff")) return "git"; if (tool.Contains("document") || tool.Contains("format") || tool.Contains("template")) return "document"; if (tool.Contains("skill")) return "skill"; + if (tool.Contains("mcp")) + return "mcp"; + if (tool.Contains("ask")) + return "question"; if (tool.Contains("web") || tool.Contains("fetch") || tool.Contains("http")) return "web"; if (tool.Contains("process") || tool.Contains("bash") || tool.Contains("powershell")) @@ -91,11 +141,16 @@ internal static class ToolResultPresentationCatalog { return kind switch { + "file_edit" => "파일 수정 완료", + "file_write" => "파일 쓰기 완료", + "filesystem" => "파일 탐색 완료", "file" => "파일 작업 완료", - "build" => "빌드/테스트 완료", + "build_test" => "빌드/테스트 완료", "git" => "Git 작업 완료", "document" => "문서 작업 완료", "skill" => "스킬 실행 완료", + "mcp" => "MCP 도구 완료", + "question" => "의견 요청 완료", "web" => "웹 요청 완료", "command" => "명령 실행 완료", _ => baseLabel, @@ -106,11 +161,16 @@ internal static class ToolResultPresentationCatalog { return kind switch { + "file_edit" => "파일 수정 실패", + "file_write" => "파일 쓰기 실패", + "filesystem" => "파일 탐색 실패", "file" => "파일 작업 실패", - "build" => "빌드/테스트 실패", + "build_test" => "빌드/테스트 실패", "git" => "Git 작업 실패", "document" => "문서 작업 실패", "skill" => "스킬 실행 실패", + "mcp" => "MCP 도구 실패", + "question" => "의견 요청 실패", "web" => "웹 요청 실패", "command" => "명령 실행 실패", _ => $"{baseLabel} 실패", @@ -121,12 +181,17 @@ internal static class ToolResultPresentationCatalog { return kind switch { - "file" => "파일 처리 결과가 정상적으로 반영되었습니다.", - "build" => "빌드나 테스트 단계가 성공적으로 끝났습니다.", - "git" => "Git 관련 작업이 정상적으로 완료되었습니다.", + "file_edit" => "파일 수정 결과가 저장되었습니다.", + "file_write" => "새 파일 작성 결과가 저장되었습니다.", + "filesystem" => "파일과 폴더 정보를 성공적으로 읽었습니다.", + "file" => "파일 관련 작업이 정상적으로 끝났습니다.", + "build_test" => "빌드 또는 테스트 단계가 성공적으로 끝났습니다.", + "git" => "Git 관련 작업이 정상적으로 끝났습니다.", "document" => "문서 생성 또는 변환 작업이 완료되었습니다.", - "skill" => "선택된 스킬이 정상적으로 실행되었습니다.", - "web" => "웹 요청이 정상적으로 완료되었습니다.", + "skill" => "선택한 스킬이 정상적으로 실행되었습니다.", + "mcp" => "등록된 MCP 도구 호출이 성공적으로 끝났습니다.", + "question" => "사용자 응답을 받아 다음 단계로 넘어갈 수 있습니다.", + "web" => "웹 요청이 정상적으로 끝났습니다.", "command" => "명령 실행이 정상적으로 끝났습니다.", _ => "요청한 작업이 정상적으로 완료되었습니다.", }; @@ -136,14 +201,47 @@ internal static class ToolResultPresentationCatalog { return kind switch { + "file_edit" => "파일 변경 과정에서 문제가 발생했습니다.", + "file_write" => "파일 작성 또는 저장 과정에서 문제가 발생했습니다.", + "filesystem" => "파일/폴더 접근 중 문제가 발생했습니다.", "file" => "파일 처리 중 문제가 발생했습니다.", - "build" => "빌드나 테스트 단계에서 실패가 발생했습니다.", + "build_test" => "빌드 또는 테스트 단계에서 실패가 발생했습니다.", "git" => "Git 관련 작업이 실패했습니다.", "document" => "문서 생성 또는 변환 작업이 실패했습니다.", "skill" => "스킬 실행 중 문제가 발생했습니다.", + "mcp" => "MCP 도구 호출 중 문제가 발생했습니다.", + "question" => "사용자 의견 요청 과정에서 문제가 발생했습니다.", "web" => "웹 요청 처리에 실패했습니다.", "command" => "명령 실행 중 오류가 발생했습니다.", _ => "작업 처리 중 오류가 발생했습니다.", }; } + + private static string BuildSuccessFollowUp(string kind) + { + return kind switch + { + "file_edit" or "file_write" => "변경 내용을 preview나 diff에서 다시 확인할 수 있습니다.", + "build_test" => "출력 로그와 후속 수정 필요 여부를 확인하세요.", + "git" => "브랜치 상태나 변경 요약을 이어서 확인하세요.", + "document" => "생성된 산출물 경로를 열어 결과를 확인하세요.", + "skill" => "같은 스킬을 다른 입력으로 이어서 실행할 수 있습니다.", + _ => "필요하면 후속 요청을 이어서 실행할 수 있습니다.", + }; + } + + private static string BuildFailureFollowUp(string kind) + { + return kind switch + { + "file_edit" or "file_write" => "대상 파일 경로와 권한, diff를 다시 확인하세요.", + "build_test" => "실패 로그와 컴파일 오류 메시지를 먼저 확인하세요.", + "git" => "현재 브랜치, 잠금 상태, 충돌 여부를 확인하세요.", + "document" => "입력 데이터와 출력 형식, 저장 위치를 다시 확인하세요.", + "skill" => "허용 도구와 런타임 요구사항을 다시 확인하세요.", + "web" => "연결 상태와 요청 대상 URL을 다시 확인하세요.", + "mcp" => "MCP 서버 연결 상태와 도구 등록 상태를 다시 확인하세요.", + _ => "같은 요청을 재시도하기 전에 원인 메시지를 먼저 확인하세요.", + }; + } } diff --git a/src/AxCopilot/Views/SkillGalleryWindow.xaml.cs b/src/AxCopilot/Views/SkillGalleryWindow.xaml.cs index 52baf5e..946d520 100644 --- a/src/AxCopilot/Views/SkillGalleryWindow.xaml.cs +++ b/src/AxCopilot/Views/SkillGalleryWindow.xaml.cs @@ -578,6 +578,18 @@ public partial class SkillGalleryWindow : Window AddMetaRow("런타임", skill.Requires, metaRow++); if (!string.IsNullOrEmpty(skill.AllowedTools)) AddMetaRow("허용 도구", skill.AllowedTools, metaRow++); + if (!string.IsNullOrEmpty(skill.Model)) + AddMetaRow("모델", skill.Model, metaRow++); + if (!string.IsNullOrEmpty(skill.Effort)) + AddMetaRow("추론 강도", skill.Effort, metaRow++); + if (!string.IsNullOrEmpty(skill.ExecutionContext)) + AddMetaRow("실행 컨텍스트", skill.ExecutionContext, metaRow++); + if (!string.IsNullOrEmpty(skill.Agent)) + AddMetaRow("에이전트", skill.Agent, metaRow++); + if (skill.DisableModelInvocation) + AddMetaRow("모델 호출", "비활성화", metaRow++); + if (!string.IsNullOrEmpty(skill.WhenToUse)) + AddMetaRow("추천 상황", skill.WhenToUse, metaRow++); AddMetaRow("상태", skill.IsAvailable ? "✓ 사용 가능" : $"✗ {skill.UnavailableHint}", metaRow++); AddMetaRow("경로", skill.FilePath, metaRow++);