Phase 10 킬러 피처: - MemoService: 태그 CRUD + 마크다운 내보내기 (memo_tags DB) - VoiceCommandService: 키워드→명령어 매칭, 프리셋 4종 - ScreenContextService: PowerShell 활성 윈도우 + Ctrl+C 선택 텍스트 - ChainService: LLM 명령어 순차 실행 파이프라인 - CaptionService: 6초 청크 연속 전사 + 시스템 오디오 루프백 VoiceModeService 파이프라인 통합: - 녹음 시작 → 컨텍스트 캡처 → STT → 키워드 매칭 → LLM(체인/컨텍스트 주입) → 삽입 시스템 오디오 캡처: - setDisplayMediaRequestHandler + audio: 'loopback' (IPC 브릿지) - electron-audio-loopback 패키지 contextIsolation 호환 불가 → 직접 구현 Phase 11 수익화: - LicenseService: Free/Pro/Pro+ 3티어, LemonSqueezy API - Feature Gate: requireFeature/checkFeature/consumeFeature - 일일 쿼터: Free dictation 20/일, LLM 10/일 (SQLite daily_usage) - LicenseModal, ProBadge, UpgradePromptModal UI 디자인 보강: - d3roTypo(13종), d3roShadow(10종), d3roRadius(7종) 토큰 시스템 - ScreenPanel, ButtonGroup DS 컴포넌트 신규 - PhosphorText 4→13종 변형, MetalDial conic-gradient 광택 - 공유 컴포넌트: EmptyStateCard, SearchInput, PageHeader, HistoryEntryCard 기타: - 자막 핫키 SSOT 전체 연동 (Config→Hotkey→VoiceMode→Caption→Settings) - StatusBar 자막 LED + 효과음, 자막 로딩 UI - LLM 상태 이벤트 전파 수정 (폴링 제거 → onStatusChanged) - 커맨드 팝업 "선택 해제" 항목 추가
104 lines
4.6 KiB
JSON
104 lines
4.6 KiB
JSON
{
|
|
"permissions": {
|
|
"allow": [
|
|
"Read",
|
|
"Glob",
|
|
"Grep",
|
|
"Bash(npm *)",
|
|
"Bash(npx *)",
|
|
"Bash(node *)",
|
|
"Bash(git *)",
|
|
"Bash(ls *)",
|
|
"Bash(mkdir *)",
|
|
"Bash(cat *)",
|
|
"Bash(which *)",
|
|
"Bash(python *)",
|
|
"Bash(pip *)",
|
|
"Bash(taskkill *)",
|
|
"Bash(sleep *)",
|
|
"Bash(mv *)",
|
|
"Bash(tail *)",
|
|
"Bash(head *)",
|
|
"Bash(grep *)",
|
|
"Bash(wc *)",
|
|
"Edit(src/**)",
|
|
"Edit(tests/**)",
|
|
"Edit(docs/**)",
|
|
"Edit(*.md)",
|
|
"Edit(*.json)",
|
|
"Edit(*.ts)",
|
|
"Edit(*.tsx)",
|
|
"Edit(*.js)",
|
|
"Edit(*.css)",
|
|
"Edit(*.html)",
|
|
"Write(src/**)",
|
|
"Write(tests/**)",
|
|
"Write(docs/**)",
|
|
"Write(scripts/**)",
|
|
"Write(*.md)",
|
|
"Write(*.json)",
|
|
"Write(*.ts)",
|
|
"Write(*.tsx)"
|
|
],
|
|
"deny": [
|
|
"Bash(rm -rf /)",
|
|
"Bash(git push --force*)",
|
|
"Bash(npm publish*)",
|
|
"Edit(.env*)",
|
|
"Edit(secrets.*)"
|
|
]
|
|
},
|
|
"hooks": {
|
|
"UserPromptSubmit": [
|
|
{
|
|
"matcher": "",
|
|
"hooks": [
|
|
{
|
|
"type": "command",
|
|
"command": "cat <<'INJECT'\n[D3RO-VOICE 강제 규칙]\n1. 구현 전 반드시 설계서 참조: docs/design/00~03 (아키텍처, 서비스 명세, IPC 타입, DB/UI)\n2. 서비스: 싱글톤 + EventEmitter. 설계서 01의 인터페이스를 그대로 구현\n3. IPC: 설계서 02의 ipc-channels.ts 채널명/타입을 그대로 사용\n4. 에러: 설계서 02의 D3ROError + ErrorCode enum 사용\n5. DB: 설계서 03의 drizzle-orm 스키마를 그대로 사용\n6. UI: 설계서 03의 컴포넌트 Props/상태/IPC 명세를 그대로 따름\n7. 윈도우: 프리로딩 + 2-phase 리사이즈 (설계서 01 WindowManagerService)\n8. 상태머신: RecognitionState + AudioState 분리 (설계서 01 VoiceModeService)\n9. 팝업: Vanilla JS, 설계서 03의 HTML/CSS/애니메이션 스펙 준수\n10. any 타입 절대 금지, console.log 절대 금지\n11. 테마 SSOT: 색상은 d3roPalette/d3roShadow(CSS var) 사용, 렌더러 tsx/ts에 하드코딩 hex 금지 (theme.ts 제외)\n12. i18n: React 컴포넌트 UI 문자열은 t() 함수 사용, 하드코딩 한국어/영어 금지\n13. 작업 완료 즉시 memory/project_status.md 갱신 의무 — 미루지 말 것\nINJECT"
|
|
}
|
|
]
|
|
}
|
|
],
|
|
"PostToolUse": [
|
|
{
|
|
"matcher": "Write|Edit",
|
|
"hooks": [
|
|
{
|
|
"type": "command",
|
|
"command": "FILE=$(cat /dev/stdin | python -c \"import sys,json; d=json.load(sys.stdin); print(d.get('tool_input',{}).get('file_path',''))\" 2>/dev/null); if echo \"$FILE\" | grep -qE '\\.(ts|tsx)$'; then cd 'D:/workspace/D3ROVoice' && npx tsc --noEmit 2>&1 | head -20 || true; fi"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"matcher": "Write|Edit",
|
|
"hooks": [
|
|
{
|
|
"type": "command",
|
|
"command": "FILE=$(cat /dev/stdin | python -c \"import sys,json; d=json.load(sys.stdin); print(d.get('tool_input',{}).get('file_path',''))\" 2>/dev/null); if echo \"$FILE\" | grep -qE '\\.(ts|tsx)$'; then ISSUES=''; ANY=$(grep -nE ': any[^a-zA-Z]|<any>|as any' \"$FILE\" 2>/dev/null | grep -v '// eslint' | grep -v 'import' | head -3); if [ -n \"$ANY\" ]; then ISSUES=\"any 타입: $ANY\"; fi; LOG=$(grep -n 'console\\.log' \"$FILE\" 2>/dev/null | head -3); if [ -n \"$LOG\" ]; then ISSUES=\"$ISSUES | console.log: $LOG\"; fi; if [ -n \"$ISSUES\" ]; then echo \"[HARNESS VIOLATION] $ISSUES — 즉시 수정 필요\"; fi; fi"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"matcher": "Write|Edit",
|
|
"hooks": [
|
|
{
|
|
"type": "command",
|
|
"command": "FILE=$(cat /dev/stdin | python -c \"import sys,json; d=json.load(sys.stdin); print(d.get('tool_input',{}).get('file_path',''))\" 2>/dev/null); if echo \"$FILE\" | grep -qE 'src/renderer/.*\\.(tsx|ts)$' && ! echo \"$FILE\" | grep -q 'theme\\.ts' && ! echo \"$FILE\" | grep -q 'theme-vars'; then HC=$(grep -noE \"'#[0-9a-fA-F]{6}'\" \"$FILE\" 2>/dev/null | grep -v '//' | head -3); if [ -n \"$HC\" ]; then echo \"[SSOT WARN] 하드코딩 hex 색상 — d3roPalette/CSS var 사용:\"; echo \"$HC\"; fi; fi"
|
|
}
|
|
]
|
|
}
|
|
],
|
|
"PreToolUse": [
|
|
{
|
|
"matcher": "Write|Edit",
|
|
"hooks": [
|
|
{
|
|
"type": "command",
|
|
"command": "FILE=$(cat /dev/stdin | python -c \"import sys,json; d=json.load(sys.stdin); print(d.get('tool_input',{}).get('file_path',''))\" 2>/dev/null); if echo \"$FILE\" | grep -qE '\\.env|\\.secret|credentials'; then echo 'BLOCKED: 시크릿 파일 수정 금지' >&2; exit 2; fi; exit 0"
|
|
}
|
|
]
|
|
}
|
|
]
|
|
}
|
|
}
|