slash 입력 계층 1차 모듈화와 Codex/Claude 추격 계획을 반영
Some checks failed
Release Gate / gate (push) Has been cancelled

- ChatWindow 내부 대형 slash 사전을 신규 파일 SlashCommandCatalog로 분리하여 결합도를 낮춤

- ChatWindow slash 조회 경로를 카탈로그 API(MatchBuiltinCommands, TryGetEntry)로 전환

- slash 탐색/실행 동작 회귀를 build + ChatWindowSlashPolicyTests(39건)로 검증

- docs/NEXT_ROADMAP.md에 claw-code 기준 Codex/Claude 추격 로드맵(L1~L5)과 완료 기준을 추가

- docs/DEVELOPMENT.md에 연속 실행 26차 이력(2026-04-04 13:24 KST) 기록

- README.md 업데이트 시각 및 변경 이력 항목을 최신 상태로 갱신
This commit is contained in:
2026-04-04 13:24:27 +09:00
parent b7431146c8
commit 14534af2e9
5 changed files with 182 additions and 109 deletions

View File

@@ -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 |

View File

@@ -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 실행으로 테스트를 검증함.

View File

@@ -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 확장/정리 시 변경 범위 축소.

View File

@@ -5037,101 +5037,6 @@ public partial class ChatWindow : Window
// ── 슬래시 명령어 (탭별 분류) ──
/// <summary>공통 슬래시 명령어 — 모든 탭에서 사용 가능.</summary>
private static readonly Dictionary<string, (string Label, string SystemPrompt, string Tab)> 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
}
}

View File

@@ -0,0 +1,113 @@
namespace AxCopilot.Views;
internal static class SlashCommandCatalog
{
internal static readonly IReadOnlyDictionary<string, (string Label, string SystemPrompt, string Tab)> Commands = new Dictionary<string, (string Label, string SystemPrompt, string Tab)>(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);
}