diff --git a/README.md b/README.md index 883b7a7..027915c 100644 --- a/README.md +++ b/README.md @@ -222,7 +222,7 @@ public class MyHandler : IActionHandler ### v0.7.3 — AX Agent 권한 코어 재구성 + 입력 계층 정리 -업데이트: 2026-04-04 13:07 (KST) +업데이트: 2026-04-04 13:24 (KST) | 분류 | 내용 | |------|------| @@ -275,6 +275,8 @@ public class MyHandler : IActionHandler | 모델 라벨 반응형 보강 | 컴포저 상단 모델 라벨에 말줄임(`MaxWidth` + `CharacterEllipsis`)을 적용해 좁은 폭에서 레이아웃 깨짐을 방지 | | 슬래시 탐색 순서 정합화 | `/` 팝업의 방향키/휠/Home/End 이동 기준을 렌더 순서(핀/최근 정렬 적용 순서)로 통일해 스크롤·선택 체감 불일치를 해소 | | 권한 요청창 한국어/인코딩 복구 | `PermissionRequestWindow`의 깨진 문자열을 복구하고 권한 선택/위험도/미리보기 문구를 한국어 기준으로 정리 | +| slash 명령 카탈로그 분리 | `ChatWindow` 내부 대형 slash 사전을 `SlashCommandCatalog`로 분리해 입력 계층 결합도를 낮추고 유지보수 범위를 축소 | +| slash 조회 API 전환 | 내장 slash 매칭/조회 경로를 `SlashCommandCatalog.MatchBuiltinCommands`/`TryGetEntry`로 통일 | | 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 e6cedb7..936d23f 100644 --- a/docs/DEVELOPMENT.md +++ b/docs/DEVELOPMENT.md @@ -3304,3 +3304,21 @@ else: ### 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). +## 2026-04-04 추가 진행 기록 (연속 실행 26차: slash 입력 계층 모듈화 1단계) + +업데이트: 2026-04-04 13:24 (KST) + +### 1) slash 명령 카탈로그 분리 +- ChatWindow 내부에 있던 대형 슬래시 명령 정의를 Views/SlashCommandCatalog.cs로 분리. +- 카탈로그에 다음 API를 추가: + - MatchBuiltinCommands(input, isDevTab) + - TryGetEntry(commandToken, out entry) +- ChatWindow는 카탈로그 API를 호출하는 방식으로 전환해 입력 계층 결합도를 낮춤. + +### 2) slash 탐색 회귀 검증 +- dotnet build src/AxCopilot/AxCopilot.csproj 통과 (경고 0, 오류 0). +- dotnet test src/AxCopilot.Tests/AxCopilot.Tests.csproj --no-build --filter "FullyQualifiedName~ChatWindowSlashPolicyTests" 통과 (39 passed, 0 failed). + +### 3) 참고 +- 테스트 재빌드 시점에 AxCopilot.dll 파일 잠금(CS2012)이 간헐 발생하여, + 빌드 산출물 기준 --no-build 실행으로 테스트를 검증함. diff --git a/docs/NEXT_ROADMAP.md b/docs/NEXT_ROADMAP.md index a727d90..27ec5e7 100644 --- a/docs/NEXT_ROADMAP.md +++ b/docs/NEXT_ROADMAP.md @@ -1,9 +1,9 @@ # AX Copilot 통합 로드맵 (전면 재작성) ## 1. 보존 이력 (요약만 유지) -- v1.5.x: 에이전트/런처 핵심 기능 확장, MCP/스킬/검증 체계 도입. -- v1.6.0: 문서 생성 및 업무 자동화 도구군 확장. -- v1.7.0~v1.7.2: Plan Mode, 병렬 도구, 검증 게이트 및 안정화 강화. +- v0.5.x: 에이전트/런처 핵심 기능 확장, MCP/스킬/검증 체계 도입. +- v0.6.0: 문서 생성 및 업무 자동화 도구군 확장. +- v0.7.0~v0.7.2: Plan Mode, 병렬 도구, 검증 게이트 및 안정화 강화. ## 2. 재작성 목표 - claw-code 수준의 실행 신뢰성, 세션 내구성, 결과 품질 확보. @@ -13,10 +13,10 @@ | 마일스톤 | 참조 대상 (`claw-code`) | AX 적용 위치 | 완료 조건 | 품질 판정 시나리오 | |---|---|---|---|---| -| M1 (v1.7.3) Hook 계약 정식화 | `src/utils/hooks.ts`, `src/utils/hooks/hookEvents.ts`, `src/utils/permissions/PermissionUpdate.ts` | `src/AxCopilot/Services/Agent/AgentHookRunner.cs`, `src/AxCopilot/Services/Agent/AgentLoopService.cs`, `src/AxCopilot/Models/AppSettings.cs`, `src/AxCopilot/ViewModels/SettingsViewModel.cs`, `src/AxCopilot/Views/SettingsWindow.xaml` | Hook 출력 계약(`updatedInput`, `updatedPermissions`, `additionalContext`) 반영. 설정값-실행코드-UI 동시 반영. | JSON 훅/텍스트 훅 혼합 환경에서 실행 품질과 하위호환 유지 확인. | -| M2 (v1.7.4~v1.7.5) 세션/로그 내구성 | `src/utils/plans.ts`, `src/utils/sessionStorage.ts` | `src/AxCopilot/Services/ChatSessionStateService.cs`, `src/AxCopilot/Services/TaskRunService.cs`, `src/AxCopilot/Services/TaskRunStore.cs`, `src/AxCopilot/Views/ChatWindow.xaml.cs`, `src/AxCopilot/Models/ChatModels.cs` | Plan/Run 상태 영속화. 이벤트 로그 표준화 및 replay 안정성 확보. | 앱 재시작/강제종료 후 동일 세션 재개 시 상태/이력 불일치 0건. | -| M3 (v1.7.6) 도구 선택/복구 안정화 | `src/commands.ts`, `src/Tool.ts`, `src/query.ts` | `src/AxCopilot/Services/Agent/AgentLoopService.cs`, `src/AxCopilot/Services/Agent/AgentLoopParallelExecution.cs`, `src/AxCopilot/Services/LlmService.ToolUse.cs` | 도구 선택 실패 루프 억제. 실패 유형별 복구 흐름 정형화. | 오타/비활성/별칭 도구 요청이 반복 실패 없이 정상 경로로 수렴하는지 확인. | -| M4 (v1.8.0) 품질 게이트 최종 정렬 | `src/query.ts`, `src/QueryEngine.ts`, `src/utils/sessionStorage.ts` | `src/AxCopilot/Services/Agent/AgentLoopService.cs`, `src/AxCopilot/Services/Agent/AgentLoopTransitions.Execution.cs`, `src/AxCopilot/Services/Agent/AgentLoopTransitions.cs` | 증거 기반 완료 판정 고정. 내부 벤치마크에서 claw-code 동급 품질 달성. | 코드수정/문서생성/권한거부/복구 혼합 시나리오에서 조기완료 없이 근거 기반 종료 확인. | +| M1 (v0.7.3) Hook 계약 정식화 | `src/utils/hooks.ts`, `src/utils/hooks/hookEvents.ts`, `src/utils/permissions/PermissionUpdate.ts` | `src/AxCopilot/Services/Agent/AgentHookRunner.cs`, `src/AxCopilot/Services/Agent/AgentLoopService.cs`, `src/AxCopilot/Models/AppSettings.cs`, `src/AxCopilot/ViewModels/SettingsViewModel.cs`, `src/AxCopilot/Views/SettingsWindow.xaml` | Hook 출력 계약(`updatedInput`, `updatedPermissions`, `additionalContext`) 반영. 설정값-실행코드-UI 동시 반영. | JSON 훅/텍스트 훅 혼합 환경에서 실행 품질과 하위호환 유지 확인. | +| M2 (v0.7.4~v0.7.5) 세션/로그 내구성 | `src/utils/plans.ts`, `src/utils/sessionStorage.ts` | `src/AxCopilot/Services/ChatSessionStateService.cs`, `src/AxCopilot/Services/TaskRunService.cs`, `src/AxCopilot/Services/TaskRunStore.cs`, `src/AxCopilot/Views/ChatWindow.xaml.cs`, `src/AxCopilot/Models/ChatModels.cs` | Plan/Run 상태 영속화. 이벤트 로그 표준화 및 replay 안정성 확보. | 앱 재시작/강제종료 후 동일 세션 재개 시 상태/이력 불일치 0건. | +| M3 (v0.7.6) 도구 선택/복구 안정화 | `src/commands.ts`, `src/Tool.ts`, `src/query.ts` | `src/AxCopilot/Services/Agent/AgentLoopService.cs`, `src/AxCopilot/Services/Agent/AgentLoopParallelExecution.cs`, `src/AxCopilot/Services/LlmService.ToolUse.cs` | 도구 선택 실패 루프 억제. 실패 유형별 복구 흐름 정형화. | 오타/비활성/별칭 도구 요청이 반복 실패 없이 정상 경로로 수렴하는지 확인. | +| M4 (v0.8.0) 품질 게이트 최종 정렬 | `src/query.ts`, `src/QueryEngine.ts`, `src/utils/sessionStorage.ts` | `src/AxCopilot/Services/Agent/AgentLoopService.cs`, `src/AxCopilot/Services/Agent/AgentLoopTransitions.Execution.cs`, `src/AxCopilot/Services/Agent/AgentLoopTransitions.cs` | 증거 기반 완료 판정 고정. 내부 벤치마크에서 claw-code 동급 품질 달성. | 코드수정/문서생성/권한거부/복구 혼합 시나리오에서 조기완료 없이 근거 기반 종료 확인. | ## 4. 측정 지표 - 반복 실패 루프 발생률. @@ -71,3 +71,41 @@ 3. hook 예외/실패는 non-blocking으로 처리하고 권한 흐름은 지속. 4. `additionalContext`는 가능한 경로에서 실행 메시지 컨텍스트에 병합. + + + +## 2026-04-04 추가 계획 (Codex/Claude 추격 로드맵 재정렬) + +업데이트: 2026-04-04 13:24 (KST) + +### 기준 소스 +- claw-code/src/commands.ts +- claw-code/src/utils/permissions/PermissionMode.ts +- claw-code/src/components/PromptInput/PromptInput.tsx + +### 현재 AX 격차 요약 +1. 입력/슬래시/권한 처리 로직이 ChatWindow 단일 파일에 상대적으로 집중되어 변경 파급도가 큼. +2. 설정-런타임-UI 동기화는 기능은 많지만 구조적 분리가 부족해 회귀 리스크가 높음. +3. Agent loop 품질 게이트는 확보됐으나, UI 상호작용 회귀 시나리오와 결합된 자동 검증이 더 필요함. + +### 연속 실행 목표 (L1~L5) +- **L1. 입력 계층 모듈화** + - 목표: slash 명령 카탈로그/매칭/선택 상태를 분리해 ChatWindow 결합도 축소 + - 완료 기준: slash 관련 핵심 로직을 독립 파일로 분리하고 기존 slash 테스트 통과 +- **L2. 권한 UX/로직 단일 카탈로그화** + - 목표: 권한 모드 명칭/설명/색/정렬 순서를 단일 소스에서 제공 + - 완료 기준: 팝업/상태 배너/슬래시 출력에서 동일 용어·동일 순서 유지 +- **L3. 설정 동기화 강화** + - 목표: Cowork/Code 설정 분기를 실행 코드 경로까지 일치시켜 회귀 감소 + - 완료 기준: 설정 변경 즉시 반영 시나리오 체크리스트 전건 통과 +- **L4. Agentic loop + UI 결합 회귀 테스트 보강** + - 목표: internal/external, permission deny/recover, mcp reconnect, compact 수동/자동 흐름을 통합 검증 + - 완료 기준: 릴리즈 게이트용 통합 테스트 세트 추가 및 통과 +- **L5. Codex/Claude형 UI 마감** + - 목표: 좌측 패널/컴포저/권한 팝업 밀도와 탐색 동작을 단순·일관 패턴으로 정리 + - 완료 기준: UI 체크리스트 주요 항목 100% 충족 + 빌드 경고/오류 0 + +### 이번 턴 즉시 반영 (L1 시작) +- ChatWindow의 대형 slash 명령 사전을 SlashCommandCatalog로 분리. +- ChatWindow는 카탈로그 API(MatchBuiltinCommands, TryGetEntry)를 통해 조회하도록 전환. +- 결과: 입력 계층 결합도 감소 + 향후 slash 확장/정리 시 변경 범위 축소. diff --git a/src/AxCopilot/Views/ChatWindow.xaml.cs b/src/AxCopilot/Views/ChatWindow.xaml.cs index 5416403..01058a8 100644 --- a/src/AxCopilot/Views/ChatWindow.xaml.cs +++ b/src/AxCopilot/Views/ChatWindow.xaml.cs @@ -5037,101 +5037,6 @@ public partial class ChatWindow : Window // ── 슬래시 명령어 (탭별 분류) ── - /// 공통 슬래시 명령어 — 모든 탭에서 사용 가능. - private static readonly Dictionary SlashCommands = new(StringComparer.OrdinalIgnoreCase) - { - // 공통 - ["/clear"] = ("Clear", "__CLEAR__", "all"), - ["/new"] = ("New", "__NEW__", "all"), - ["/reset"] = ("Reset", "__RESET__", "all"), - ["/status"] = ("Status", "__STATUS__", "all"), - ["/model"] = ("Model", "__MODEL__", "all"), - ["/permissions"] = ("Permissions", "__PERMISSIONS__", "all"), - ["/allowed-tools"] = ("Allowed Tools", "__ALLOWED_TOOLS__", "all"), - ["/theme"] = ("Theme", "__THEME__", "all"), - ["/color"] = ("Color", "현재 테마/색상 구성을 점검하고 가독성 중심 개선안을 제시하세요.", "all"), - ["/config"] = ("Config", "현재 설정 상태를 점검하고, 목적에 맞는 권장 설정 변경안을 제시하세요.", "all"), - ["/settings"] = ("Settings", "__SETTINGS__", "all"), - ["/session"] = ("Session", "현재 세션의 핵심 맥락과 이어서 할 일을 5개 이내로 정리하세요.", "all"), - ["/usage"] = ("Usage", "현재 사용 흐름을 개선할 수 있는 사용 팁을 간결히 제시하세요.", "all"), - ["/upgrade"] = ("Upgrade", "현재 작업/구성 기준으로 안전한 업그레이드 체크리스트를 제시하세요.", "all"), - ["/copy"] = ("Copy", "사용자가 바로 복사해 쓸 수 있는 최종 결과 형태로 간결하게 답변하세요.", "all"), - ["/rename"] = ("Rename", "__RENAME__", "all"), - ["/feedback"] = ("Feedback", "__FEEDBACK__", "all"), - ["/skills"] = ("Skills", "__SKILLS__", "all"), - ["/sandbox-toggle"] = ("Sandbox Toggle", "__SANDBOX_TOGGLE__", "all"), - ["/statusline"] = ("Statusline", "__STATUSLINE__", "all"), - ["/heapdump"] = ("Heap Dump", "__HEAPDUMP__", "all"), - ["/passes"] = ("Passes", "__PASSES__", "all"), - ["/chrome"] = ("Chrome", "__CHROME__", "all"), - ["/stickers"] = ("Stickers", "__STICKERS__", "all"), - ["/thinkback"] = ("Thinkback", "__THINKBACK__", "all"), - ["/thinkback-play"] = ("Thinkback Play", "__THINKBACK_PLAY__", "all"), - ["/exit"] = ("Exit", "현재 대화를 마무리하기 위한 요약과 다음 재개 지점을 3줄 이내로 제시하세요.", "all"), - ["/login"] = ("Login", "인증/연결 점검 절차를 단계별로 안내하세요.", "all"), - ["/logout"] = ("Logout", "안전한 로그아웃 및 세션 정리 체크리스트를 안내하세요.", "all"), - ["/desktop"] = ("Desktop", "데스크톱 실행/연결 환경 점검 체크리스트를 제시하세요.", "all"), - ["/mobile"] = ("Mobile", "모바일 연동/사용 시 주의사항과 권장 구성을 제시하세요.", "all"), - ["/ide"] = ("IDE", "IDE 연동 상태를 점검하고 생산성 향상 팁을 제시하세요.", "all"), - ["/terminal-setup"] = ("Terminal Setup", "터미널 환경 초기 설정 체크리스트를 제시하세요.", "all"), - ["/add-dir"] = ("Add Dir", "작업 디렉터리 추가 시 권장 구조와 주의사항을 제시하세요.", "all"), - ["/advisor"] = ("Advisor", "현재 요청에 대한 실행 전략을 조언자 관점으로 간결히 제시하세요.", "all"), - ["/mcp"] = ("MCP", "__MCP__", "all"), - ["/agents"] = ("Agents", "현재 작업에 적합한 에이전트 분담 전략을 제시하세요.", "all"), - ["/plugin"] = ("Plugin", "플러그인 사용/구성 상태를 점검하고 권장 구성을 제시하세요.", "all"), - ["/reload-plugins"] = ("Reload Plugins", "플러그인 재로드 전후 점검 체크리스트를 제시하세요.", "all"), - ["/output-style"] = ("Output Style", "현재 작업 목적에 맞는 출력 스타일 가이드를 제시하세요.", "all"), - ["/remote-env"] = ("Remote Env", "원격 환경 연결 시 필수 점검 항목을 제시하세요.", "all"), - ["/install-github-app"] = ("Install GitHub App", "GitHub 앱 연동 절차와 점검 항목을 제시하세요.", "all"), - ["/install-slack-app"] = ("Install Slack App", "Slack 앱 연동 절차와 점검 항목을 제시하세요.", "all"), - ["/btw"] = ("BTW", "현재 맥락에서 추가로 유용한 보조 팁을 짧게 제시하세요.", "all"), - ["/keybindings"] = ("Keybindings", "주요 단축키/입력 효율화 팁을 현재 작업 기준으로 정리하세요.", "all"), - ["/privacy-settings"] = ("Privacy", "보안/개인정보 관점의 권장 설정을 점검표 형태로 제시하세요.", "all"), - ["/rate-limit-options"] = ("Rate Limit", "요청 한도 이슈를 줄이기 위한 설정/사용 전략을 제시하세요.", "all"), - ["/release-notes"] = ("Release Notes", "최근 변경사항을 릴리즈 노트 형식으로 정리하세요.", "all"), - ["/rewind"] = ("Rewind", "직전 변경 이전 상태로 되돌릴 때의 안전 절차를 제시하세요.", "all"), - ["/tag"] = ("Tag", "현재 작업 결과를 태깅/분류하는 기준을 제안하세요.", "all"), - ["/vim"] = ("Vim", "Vim 스타일 작업 효율 팁을 현재 작업에 맞춰 제시하세요.", "all"), - ["/plan"] = ("Plan", "요청을 바로 실행하지 말고 먼저 3~7단계 실행 계획을 간결히 제시한 뒤, 사용자 승인 후 실행하세요.", "all"), - ["/memory"] = ("Memory", "대화 맥락에서 지속적으로 참고할 핵심 사실을 정리하고, 필요한 경우 memory 도구 저장/갱신 관점으로 답변하세요.", "all"), - ["/context"] = ("Context", "현재 작업 컨텍스트(목표, 제약, 현재 상태, 다음 액션)를 구조화해 요약하세요.", "all"), - ["/stats"] = ("Stats", "__STATS__", "all"), - ["/cost"] = ("Cost", "__COST__", "all"), - ["/export"] = ("Export", "__EXPORT__", "all"), - ["/compact"] = ("Compact", "__COMPACT__", "all"), - ["/summary"] = ("Summary", "사용자가 제공한 내용을 핵심 포인트 위주로 간결하게 요약해 주세요. 불릿 포인트 형식을 사용하세요.", "all"), - ["/translate"] = ("Translate", "사용자가 제공한 텍스트를 영어로 번역해 주세요. 원문의 톤과 뉘앙스를 유지하세요.", "all"), - ["/explain"] = ("Explain", "사용자가 제공한 내용을 쉽고 자세하게 설명해 주세요. 필요하면 예시를 포함하세요.", "all"), - ["/fix"] = ("Fix", "사용자가 제공한 텍스트의 맞춤법, 문법, 자연스러운 표현을 교정해 주세요. 수정 사항을 명확히 표시하세요.", "all"), - - // Cowork/Code 전용 - ["/review"] = ("Code Review", "작업 폴더의 git diff를 분석하여 코드 리뷰를 수행해 주세요. code_review 도구를 사용하세요.", "dev"), - ["/commit"] = ("Commit", "__COMMIT__", "dev"), - ["/ultrareview"] = ("Ultra Review", "작업 폴더의 변경을 P0/P1 우선순위 기준으로 강도 높게 리뷰하고, 재현 조건/수정 방향/테스트 누락까지 제시하세요.", "dev"), - ["/security-review"] = ("Security Review", "작업 폴더 코드를 보안 중심으로 점검하고 취약점/개선안을 제시하세요.", "dev"), - ["/pr"] = ("PR Summary", "작업 폴더의 변경사항을 PR 설명 형식으로 요약해 주세요. code_review(action: pr_summary) 도구를 사용하세요.", "dev"), - ["/pr-comments"] = ("PR Comments", "변경사항을 검토하고 PR 코멘트 형태로 개선 의견을 작성하세요.", "dev"), - ["/test"] = ("Test", "작업 폴더의 코드에 대한 단위 테스트를 생성해 주세요. test_loop 도구를 사용하세요.", "dev"), - ["/verify"] = ("Verify", "__VERIFY__", "dev"), - ["/structure"] = ("Structure", "작업 폴더의 프로젝트 구조를 분석하고 설명해 주세요. folder_map 도구를 사용하세요.", "dev"), - ["/build"] = ("Build", "작업 폴더의 프로젝트를 빌드해 주세요. build_run 도구를 사용하세요.", "dev"), - ["/search"] = ("Search", "작업 폴더에서 관련 코드를 검색해 주세요. search_codebase 도구를 사용하세요.", "dev"), - ["/diff"] = ("Diff", "현재 작업 폴더의 변경(diff)을 분석해 핵심 변경점과 리스크를 요약하세요.", "dev"), - ["/doctor"] = ("Doctor", "현재 프로젝트/환경의 잠재 이슈를 점검하고 우선순위별 개선안을 제시하세요.", "dev"), - ["/hooks"] = ("Hooks", "현재 훅/자동화 관련 설정을 점검하고 안전한 운영 가이드를 제시하세요.", "dev"), - ["/tasks"] = ("Tasks", "현재 작업을 태스크 단위로 분해해 우선순위와 다음 실행 항목을 제시하세요.", "dev"), - ["/branch"] = ("Branch", "현재 변경 기준으로 적절한 브랜치/커밋 전략을 제안하세요.", "dev"), - ["/files"] = ("Files", "현재 작업에서 핵심 파일과 변경 후보를 우선순위로 정리하세요.", "dev"), - ["/resume"] = ("Resume", "이전 작업 맥락을 복원한다고 가정하고 현재 상태/남은 작업을 이어서 정리하세요.", "dev"), - ["/init"] = ("Init", "프로젝트 온보딩 관점에서 초기 점검 체크리스트를 제시하세요.", "dev"), - ["/init-verifiers"] = ("Init Verifiers", "검증 자동화(빌드/테스트/리뷰) 초기 구성을 위한 체크리스트를 제시하세요.", "dev"), - ["/effort"] = ("Effort", "현재 요청의 난이도와 권장 추론 강도를 제안하세요.", "dev"), - ["/fast"] = ("Fast", "속도 우선 모드로 진행할 때의 최소 안전 절차를 제시하세요.", "dev"), - - // 특수 - ["/help"] = ("Help", "__HELP__", "all"), - }; - private void InputBox_TextChanged(object sender, TextChangedEventArgs e) { UpdateWatermarkVisibility(); @@ -5147,11 +5052,7 @@ public partial class ChatWindow : Window bool isDev = _activeTab is "Cowork" or "Code"; // 내장 슬래시 명령어 매칭 (탭 필터) - var matches = SlashCommands - .Where(kv => kv.Key.StartsWith(text, StringComparison.OrdinalIgnoreCase)) - .Where(kv => kv.Value.Tab == "all" || (isDev && kv.Value.Tab == "dev")) - .Select(kv => (Cmd: kv.Key, Label: kv.Value.Label, IsSkill: false)) - .ToList(); + var matches = SlashCommandCatalog.MatchBuiltinCommands(text, isDev); // 스킬 슬래시 명령어 매칭 (탭별 필터) if (_settings.Settings.Llm.EnableSkillSystem) @@ -5742,7 +5643,7 @@ public partial class ChatWindow : Window { var firstSpace = trimmed.IndexOf(' '); var commandToken = (firstSpace >= 0 ? trimmed[..firstSpace] : trimmed).Trim(); - if (SlashCommands.TryGetValue(commandToken, out var entry)) + if (SlashCommandCatalog.TryGetEntry(commandToken, out var entry)) { // __HELP__는 특수 처리 (ParseSlashCommand에서는 무시) if (entry.SystemPrompt == "__HELP__") return (null, input); @@ -16671,3 +16572,4 @@ private static (string icon, string label, string bgHex, string fgHex) GetDecisi } } + diff --git a/src/AxCopilot/Views/SlashCommandCatalog.cs b/src/AxCopilot/Views/SlashCommandCatalog.cs new file mode 100644 index 0000000..a674100 --- /dev/null +++ b/src/AxCopilot/Views/SlashCommandCatalog.cs @@ -0,0 +1,113 @@ +namespace AxCopilot.Views; + +internal static class SlashCommandCatalog +{ + internal static readonly IReadOnlyDictionary Commands = new Dictionary(StringComparer.OrdinalIgnoreCase) + { + // 공통 + ["/clear"] = ("Clear", "__CLEAR__", "all"), + ["/new"] = ("New", "__NEW__", "all"), + ["/reset"] = ("Reset", "__RESET__", "all"), + ["/status"] = ("Status", "__STATUS__", "all"), + ["/model"] = ("Model", "__MODEL__", "all"), + ["/permissions"] = ("Permissions", "__PERMISSIONS__", "all"), + ["/allowed-tools"] = ("Allowed Tools", "__ALLOWED_TOOLS__", "all"), + ["/theme"] = ("Theme", "__THEME__", "all"), + ["/color"] = ("Color", "현재 테마/색상 구성을 점검하고 가독성 중심 개선안을 제시하세요.", "all"), + ["/config"] = ("Config", "현재 설정 상태를 점검하고, 목적에 맞는 권장 설정 변경안을 제시하세요.", "all"), + ["/settings"] = ("Settings", "__SETTINGS__", "all"), + ["/session"] = ("Session", "현재 세션의 핵심 맥락과 이어서 할 일을 5개 이내로 정리하세요.", "all"), + ["/usage"] = ("Usage", "현재 사용 흐름을 개선할 수 있는 사용 팁을 간결히 제시하세요.", "all"), + ["/upgrade"] = ("Upgrade", "현재 작업/구성 기준으로 안전한 업그레이드 체크리스트를 제시하세요.", "all"), + ["/copy"] = ("Copy", "사용자가 바로 복사해 쓸 수 있는 최종 결과 형태로 간결하게 답변하세요.", "all"), + ["/rename"] = ("Rename", "__RENAME__", "all"), + ["/feedback"] = ("Feedback", "__FEEDBACK__", "all"), + ["/skills"] = ("Skills", "__SKILLS__", "all"), + ["/sandbox-toggle"] = ("Sandbox Toggle", "__SANDBOX_TOGGLE__", "all"), + ["/statusline"] = ("Statusline", "__STATUSLINE__", "all"), + ["/heapdump"] = ("Heap Dump", "__HEAPDUMP__", "all"), + ["/passes"] = ("Passes", "__PASSES__", "all"), + ["/chrome"] = ("Chrome", "__CHROME__", "all"), + ["/stickers"] = ("Stickers", "__STICKERS__", "all"), + ["/thinkback"] = ("Thinkback", "__THINKBACK__", "all"), + ["/thinkback-play"] = ("Thinkback Play", "__THINKBACK_PLAY__", "all"), + ["/exit"] = ("Exit", "현재 대화를 마무리하기 위한 요약과 다음 재개 지점을 3줄 이내로 제시하세요.", "all"), + ["/login"] = ("Login", "인증/연결 점검 절차를 단계별로 안내하세요.", "all"), + ["/logout"] = ("Logout", "안전한 로그아웃 및 세션 정리 체크리스트를 안내하세요.", "all"), + ["/desktop"] = ("Desktop", "데스크톱 실행/연결 환경 점검 체크리스트를 제시하세요.", "all"), + ["/mobile"] = ("Mobile", "모바일 연동/사용 시 주의사항과 권장 구성을 제시하세요.", "all"), + ["/ide"] = ("IDE", "IDE 연동 상태를 점검하고 생산성 향상 팁을 제시하세요.", "all"), + ["/terminal-setup"] = ("Terminal Setup", "터미널 환경 초기 설정 체크리스트를 제시하세요.", "all"), + ["/add-dir"] = ("Add Dir", "작업 디렉터리 추가 시 권장 구조와 주의사항을 제시하세요.", "all"), + ["/advisor"] = ("Advisor", "현재 요청에 대한 실행 전략을 조언자 관점으로 간결히 제시하세요.", "all"), + ["/mcp"] = ("MCP", "__MCP__", "all"), + ["/agents"] = ("Agents", "현재 작업에 적합한 에이전트 분담 전략을 제시하세요.", "all"), + ["/plugin"] = ("Plugin", "플러그인 사용/구성 상태를 점검하고 권장 구성을 제시하세요.", "all"), + ["/reload-plugins"] = ("Reload Plugins", "플러그인 재로드 전후 점검 체크리스트를 제시하세요.", "all"), + ["/output-style"] = ("Output Style", "현재 작업 목적에 맞는 출력 스타일 가이드를 제시하세요.", "all"), + ["/remote-env"] = ("Remote Env", "원격 환경 연결 시 필수 점검 항목을 제시하세요.", "all"), + ["/install-github-app"] = ("Install GitHub App", "GitHub 앱 연동 절차와 점검 항목을 제시하세요.", "all"), + ["/install-slack-app"] = ("Install Slack App", "Slack 앱 연동 절차와 점검 항목을 제시하세요.", "all"), + ["/btw"] = ("BTW", "현재 맥락에서 추가로 유용한 보조 팁을 짧게 제시하세요.", "all"), + ["/keybindings"] = ("Keybindings", "주요 단축키/입력 효율화 팁을 현재 작업 기준으로 정리하세요.", "all"), + ["/privacy-settings"] = ("Privacy", "보안/개인정보 관점의 권장 설정을 점검표 형태로 제시하세요.", "all"), + ["/rate-limit-options"] = ("Rate Limit", "요청 한도 이슈를 줄이기 위한 설정/사용 전략을 제시하세요.", "all"), + ["/release-notes"] = ("Release Notes", "최근 변경사항을 릴리즈 노트 형식으로 정리하세요.", "all"), + ["/rewind"] = ("Rewind", "직전 변경 이전 상태로 되돌릴 때의 안전 절차를 제시하세요.", "all"), + ["/tag"] = ("Tag", "현재 작업 결과를 태깅/분류하는 기준을 제안하세요.", "all"), + ["/vim"] = ("Vim", "Vim 스타일 작업 효율 팁을 현재 작업에 맞춰 제시하세요.", "all"), + ["/plan"] = ("Plan", "요청을 바로 실행하지 말고 먼저 3~7단계 실행 계획을 간결히 제시한 뒤, 사용자 승인 후 실행하세요.", "all"), + ["/memory"] = ("Memory", "대화 맥락에서 지속적으로 참고할 핵심 사실을 정리하고, 필요한 경우 memory 도구 저장/갱신 관점으로 답변하세요.", "all"), + ["/context"] = ("Context", "현재 작업 컨텍스트(목표, 제약, 현재 상태, 다음 액션)를 구조화해 요약하세요.", "all"), + ["/stats"] = ("Stats", "__STATS__", "all"), + ["/cost"] = ("Cost", "__COST__", "all"), + ["/export"] = ("Export", "__EXPORT__", "all"), + ["/compact"] = ("Compact", "__COMPACT__", "all"), + ["/summary"] = ("Summary", "사용자가 제공한 내용을 핵심 포인트 위주로 간결하게 요약해 주세요. 불릿 포인트 형식을 사용하세요.", "all"), + ["/translate"] = ("Translate", "사용자가 제공한 텍스트를 영어로 번역해 주세요. 원문의 톤과 뉘앙스를 유지하세요.", "all"), + ["/explain"] = ("Explain", "사용자가 제공한 내용을 쉽고 자세하게 설명해 주세요. 필요하면 예시를 포함하세요.", "all"), + ["/fix"] = ("Fix", "사용자가 제공한 텍스트의 맞춤법, 문법, 자연스러운 표현을 교정해 주세요. 수정 사항을 명확히 표시하세요.", "all"), + + // Cowork/Code 전용 + ["/review"] = ("Code Review", "작업 폴더의 git diff를 분석하여 코드 리뷰를 수행해 주세요. code_review 도구를 사용하세요.", "dev"), + ["/commit"] = ("Commit", "__COMMIT__", "dev"), + ["/ultrareview"] = ("Ultra Review", "작업 폴더의 변경을 P0/P1 우선순위 기준으로 강도 높게 리뷰하고, 재현 조건/수정 방향/테스트 누락까지 제시하세요.", "dev"), + ["/security-review"] = ("Security Review", "작업 폴더 코드를 보안 중심으로 점검하고 취약점/개선안을 제시하세요.", "dev"), + ["/pr"] = ("PR Summary", "작업 폴더의 변경사항을 PR 설명 형식으로 요약해 주세요. code_review(action: pr_summary) 도구를 사용하세요.", "dev"), + ["/pr-comments"] = ("PR Comments", "변경사항을 검토하고 PR 코멘트 형태로 개선 의견을 작성하세요.", "dev"), + ["/test"] = ("Test", "작업 폴더의 코드에 대한 단위 테스트를 생성해 주세요. test_loop 도구를 사용하세요.", "dev"), + ["/verify"] = ("Verify", "__VERIFY__", "dev"), + ["/structure"] = ("Structure", "작업 폴더의 프로젝트 구조를 분석하고 설명해 주세요. folder_map 도구를 사용하세요.", "dev"), + ["/build"] = ("Build", "작업 폴더의 프로젝트를 빌드해 주세요. build_run 도구를 사용하세요.", "dev"), + ["/search"] = ("Search", "작업 폴더에서 관련 코드를 검색해 주세요. search_codebase 도구를 사용하세요.", "dev"), + ["/diff"] = ("Diff", "현재 작업 폴더의 변경(diff)을 분석해 핵심 변경점과 리스크를 요약하세요.", "dev"), + ["/doctor"] = ("Doctor", "현재 프로젝트/환경의 잠재 이슈를 점검하고 우선순위별 개선안을 제시하세요.", "dev"), + ["/hooks"] = ("Hooks", "현재 훅/자동화 관련 설정을 점검하고 안전한 운영 가이드를 제시하세요.", "dev"), + ["/tasks"] = ("Tasks", "현재 작업을 태스크 단위로 분해해 우선순위와 다음 실행 항목을 제시하세요.", "dev"), + ["/branch"] = ("Branch", "현재 변경 기준으로 적절한 브랜치/커밋 전략을 제안하세요.", "dev"), + ["/files"] = ("Files", "현재 작업에서 핵심 파일과 변경 후보를 우선순위로 정리하세요.", "dev"), + ["/resume"] = ("Resume", "이전 작업 맥락을 복원한다고 가정하고 현재 상태/남은 작업을 이어서 정리하세요.", "dev"), + ["/init"] = ("Init", "프로젝트 온보딩 관점에서 초기 점검 체크리스트를 제시하세요.", "dev"), + ["/init-verifiers"] = ("Init Verifiers", "검증 자동화(빌드/테스트/리뷰) 초기 구성을 위한 체크리스트를 제시하세요.", "dev"), + ["/effort"] = ("Effort", "현재 요청의 난이도와 권장 추론 강도를 제안하세요.", "dev"), + ["/fast"] = ("Fast", "속도 우선 모드로 진행할 때의 최소 안전 절차를 제시하세요.", "dev"), + + // 특수 + ["/help"] = ("Help", "__HELP__", "all"), + }; + + internal static List<(string Cmd, string Label, bool IsSkill)> MatchBuiltinCommands(string input, bool isDevTab) + { + if (string.IsNullOrWhiteSpace(input)) + return []; + + return Commands + .Where(kv => kv.Key.StartsWith(input, StringComparison.OrdinalIgnoreCase)) + .Where(kv => kv.Value.Tab == "all" || (isDevTab && kv.Value.Tab == "dev")) + .Select(kv => (Cmd: kv.Key, Label: kv.Value.Label, IsSkill: false)) + .ToList(); + } + + internal static bool TryGetEntry(string commandToken, out (string Label, string SystemPrompt, string Tab) entry) + => Commands.TryGetValue(commandToken, out entry); +}