Phase 10~11 전체 구현: 킬러 피처 5종 + 수익화 시스템

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)
- 커맨드 팝업 "선택 해제" 항목 추가
This commit is contained in:
Yun Chan 2026-04-05 21:36:09 +09:00
parent 36d77ca224
commit a31f96bbb8
97 changed files with 11853 additions and 1143 deletions

View file

@ -1,58 +1,331 @@
{
"app.name": "D3RO Voice",
"app.tagline": "Local AI Voice Assistant",
"nav.dashboard": "Dashboard",
"nav.history": "History",
"nav.dictionary": "Dictionary",
"nav.commands": "Commands",
"nav.settings": "Settings",
"dashboard.title": "Dashboard",
"dashboard.totalSessions": "Total Sessions",
"dashboard.totalTime": "Total Time",
"dashboard.totalWords": "Total Words",
"dashboard.streak": "Streak",
"dashboard.today": "Today",
"dashboard.sessions": "Sessions",
"dashboard.time": "Time",
"dashboard.sessionOverview": "Session Overview",
"dashboard.systemStatus": "System Status",
"dashboard.sessionsToday": "Today's Sessions",
"dashboard.pressToRecord": "Press {{key}} to start recording",
"dashboard.hotkeyNotSet": "Hotkey not set",
"dashboard.words": "Words",
"history.title": "History",
"history.search": "Search transcriptions...",
"history.empty": "No history yet.",
"history.noResults": "No results found.",
"dictionary.title": "Dictionary",
"dictionary.search": "Search words...",
"dictionary.addWord": "Add Word",
"dictionary.empty": "No words yet. Add custom words for better STT accuracy.",
"dictionary.noResults": "No words found.",
"dashboard.total": "Total",
"dashboard.streak": "Streak",
"dashboard.days": "days",
"dashboard.recording": "Recording",
"dashboard.sessions": "Sessions",
"dashboard.today": "Today",
"dashboard.recentTranscriptions": "Recent Transcriptions",
"dashboard.noHistory": "No history — press your hotkey to start recording",
"dashboard.copy": "Copy",
"dashboard.entries": "{{count}} entries",
"dashboard.stat": "Stats",
"dashboard.sys": "System",
"history.title": "Transcription History",
"history.search": "Search...",
"history.entries": "{{count}} entries",
"history.loading": "Loading...",
"history.noResults": "No results found",
"history.noHistory": "No history — start recording",
"history.count": "{{count}} entries",
"dictionary.title": "Custom Dictionary",
"dictionary.words": "{{count}} words",
"dictionary.add": "Add",
"dictionary.search": "Search...",
"dictionary.loading": "Loading...",
"dictionary.noResults": "No results found",
"dictionary.noWords": "No words — add custom words to improve STT accuracy",
"dictionary.used": "Used {{count}} times",
"dictionary.editTitle": "Edit Word",
"dictionary.addTitle": "Add Word",
"dictionary.word": "Word",
"dictionary.pronunciation": "Pronunciation (optional)",
"commands.title": "Custom Commands",
"commands.add": "Add Command",
"commands.title": "LLM Commands",
"commands.count": "{{count}} commands",
"commands.add": "Add",
"commands.activeCommand": "Active Command",
"commands.none": "None",
"commands.loading": "Loading...",
"commands.noCommands": "No commands — click Add to create one",
"commands.editTitle": "Edit Command",
"commands.addTitle": "Add Command",
"commands.name": "Name",
"commands.description": "Description",
"commands.prompt": "Prompt",
"commands.builtin": "Built-in",
"commands.custom": "Custom",
"commands.promptTemplate": "Prompt Template",
"commands.promptHelp": "{{text}} will be replaced with the transcribed text",
"commands.defaultPrompt": "Please refine the following: {{text}}",
"settings.title": "Settings",
"settings.general": "General",
"settings.audio": "Audio",
"settings.stt": "STT",
"settings.llm": "LLM",
"settings.tabs.general": "General",
"settings.tabs.audio": "Audio",
"settings.tabs.stt": "STT",
"settings.tabs.llm": "LLM",
"settings.tabs.about": "About",
"settings.shortcuts": "Shortcuts",
"settings.dictation": "Dictation",
"settings.dictation.desc": "Hold to speak. Transcription begins when you release the key.",
"settings.agent": "Agent Mode",
"settings.agent.descWithKey": "Double-press {{key}} to enter Agent mode.",
"settings.agent.descNoKey": "Set a dictation hotkey first.",
"settings.oneTouch": "One-Touch Mode",
"settings.oneTouch.desc": "Press to start, press again to stop. Requires a separate shortcut.",
"settings.caption": "Live Caption",
"settings.caption.desc": "Toggle live caption mode with hotkey. Transcribes microphone input in real-time.",
"settings.captionAudio": "Caption Audio Source",
"settings.captionSource": "Audio Source",
"settings.captionSource.mic": "Microphone only",
"settings.captionSource.system": "System audio only (desktop sound)",
"settings.captionSource.both": "Microphone + System audio",
"settings.key": "Key",
"settings.notSet": "Not set",
"settings.enabled": "Enabled",
"settings.disabled": "Disabled",
"settings.interface": "Interface",
"settings.theme": "Theme",
"settings.theme.system": "System",
"settings.theme.light": "Light",
"settings.theme.dark": "Dark",
"settings.language": "Language",
"settings.closeToTray": "Close to tray",
"settings.appBehavior": "App Behavior",
"settings.closeToTray": "Minimize to tray on close",
"settings.autoLaunch": "Launch at system startup",
"settings.autoInsert": "Auto-insert text after transcription",
"settings.soundEffects": "Sound effects",
"settings.soundEffects": "Sound Effects",
"settings.microphone": "Microphone",
"settings.inputDevice": "Input Device",
"settings.deviceDefault": "(Default)",
"settings.textInsert": "Text Insertion",
"settings.insertMethod": "Insert Method",
"settings.insertClipboard": "Clipboard (Ctrl+V)",
"settings.insertKeyboard": "Keyboard Typing",
"settings.whisperModel": "Whisper Model",
"settings.model.tiny": "tiny (39 MB, fastest)",
"settings.model.base": "base (74 MB, balanced)",
"settings.model.small": "small (244 MB, good)",
"settings.model.medium": "medium (769 MB, great)",
"settings.model.large": "large-v3 (1.5 GB, best)",
"settings.sttLanguage": "Recognition Language",
"settings.sttLang.auto": "Auto-detect",
"settings.ollamaServer": "Ollama Server",
"settings.ollamaUrl": "Ollama Server URL",
"settings.ollamaHint": "Connects automatically when Ollama is running. Pull models directly in Ollama (e.g. ollama pull qwen3:4b).",
"settings.postProcess": "Voice Post-Processing",
"settings.defaultAction": "Default Post-Processing Command",
"settings.action.none": "None (raw transcription)",
"settings.action.refine": "Refine (grammar + fluency)",
"settings.action.translate": "Translate",
"settings.action.summarize": "Summarize",
"settings.action.grammar": "Grammar Correction",
"settings.action.custom": "Custom Prompt",
"settings.actionHint": "The selected LLM post-processing will be applied to your transcription after recording. Only works when Ollama is connected.",
"settings.about.version": "Version",
"settings.about.techStack": "Tech Stack",
"settings.about.techStackValue": "Electron + React 19 + MUI 7 + TypeScript",
"settings.about.voiceEngine": "Voice Engine",
"settings.about.voiceEngineValue": "STT: faster-whisper (local) / LLM: Ollama (local)",
"settings.about.description": "A fully local AI voice assistant built on Speakly reverse-engineering insights. Runs entirely offline with no cloud dependencies.",
"settings.about.restartOnboarding": "Restart Setup Wizard",
"status.ollama": "OLLAMA",
"status.offline": "OFFLINE",
"status.nudge.title": "Ollama is not running",
"status.nudge.desc": "Ollama is required for LLM post-processing (translation, summarization, etc.).",
"status.nudge.guide": "View setup guide →",
"onboarding.welcome.title": "D3RO-VOICE",
"onboarding.welcome.desc": "No typing needed — just speak. Your local AI voice assistant.",
"onboarding.welcome.start": "Get Started",
"onboarding.mic.title": "Microphone Setup",
"onboarding.mic.desc": "Choose a microphone to use. You can change this later in Settings.",
"onboarding.hotkey.title": "Shortcut Setup",
"onboarding.hotkey.desc": "Set your dictation shortcut. Hold the key while speaking to record.",
"onboarding.hotkey.notSet": "No shortcut set",
"onboarding.hotkey.change": "Change Shortcut",
"onboarding.hotkey.set": "Set Shortcut",
"onboarding.ollama.title": "Install Ollama (Optional)",
"onboarding.ollama.desc": "Ollama is required for LLM post-processing like translation and summarization. Voice dictation works without it.",
"onboarding.ollama.download": "Download Ollama",
"onboarding.ollama.modelHint": "After installation, download a model from your terminal",
"onboarding.done.title": "You're all set!",
"onboarding.done.descWithKey": "Hold {{key}} and speak — your voice will be converted to text.",
"onboarding.done.descNoKey": "Set a shortcut in Settings to start voice dictation.",
"onboarding.done.start": "Start Using",
"onboarding.back": "Back",
"onboarding.next": "Next",
"hotkey.title": "Set Shortcut",
"hotkey.dictationTitle": "Set Dictation Shortcut",
"hotkey.oneTouchTitle": "Set One-Touch Mode Shortcut",
"hotkey.captionTitle": "Set Live Caption Shortcut",
"hotkey.prompt": "Press a key combination...",
"hotkey.ready": "✓ {{keys}} — press Save to confirm",
"hotkey.noKey": "Please press a key",
"hotkey.reserved": "{{keys}} is a reserved system shortcut",
"hotkey.current": "Current: {{keys}}",
"hotkey.hint": "Enter a combination (e.g. Ctrl+Shift+Q) or a single key (e.g. F5)",
"hotkey.reset": "Clear",
"ollama.title": "OLLAMA SETUP GUIDE",
"ollama.step1.title": "STEP 1 — Install Ollama",
"ollama.step1.desc": "Ollama is a free tool for running LLMs locally.",
"ollama.step2.title": "STEP 2 — Download a Model",
"ollama.step2.desc": "Pull a model from your terminal. Recommended:",
"ollama.step2.alt": "Or a larger model: ollama pull qwen3:8b (more accurate, slower)",
"ollama.step3.title": "STEP 3 — Auto-Connect",
"ollama.step3.desc": "Once Ollama is running, D3RO-VOICE will detect it automatically. When the status bar LED turns from red to green, you're ready!",
"service.sttEngine": "STT ENGINE",
"service.ollamaLlm": "OLLAMA LLM",
"service.hotkeyHook": "HOTKEY HOOK",
"service.audioInput": "AUDIO INPUT",
"service.ready": "READY",
"service.connected": "CONNECTED",
"service.offline": "OFFLINE",
"service.active": "ACTIVE",
"service.standby": "STANDBY",
"common.cancel": "Cancel",
"common.save": "Save",
"common.delete": "Delete",
"common.add": "Add",
"common.edit": "Edit",
"common.close": "Close",
"common.confirm": "Confirm",
"common.loading": "Loading...",
"status.ollamaConnected": "Ollama Connected",
"status.ollamaOffline": "Ollama Offline"
"common.copy": "Copy",
"common.test": "Test",
"common.stop": "Stop",
"memo.tags": "Tags",
"memo.addTag": "Add Tag",
"memo.removeTag": "Remove Tag",
"memo.tagPlaceholder": "Type a tag and press Enter",
"memo.noTags": "No tags",
"memo.export": "Export as Markdown",
"memo.exportSuccess": "Export complete",
"memo.filterByTag": "Filter by tag",
"memo.allTags": "All Tags",
"memo.clearFilter": "Clear filter",
"voiceCommand.title": "Voice Commands",
"voiceCommand.enabled": "Voice Keyword Recognition",
"voiceCommand.enabledDesc": "Detects keywords at the start of transcription to auto-select commands.",
"voiceCommand.keywords": "Keywords",
"voiceCommand.keywordPlaceholder": "Type keyword and press Enter",
"voiceCommand.noKeywords": "No keywords",
"voiceCommand.matchMode": "Match Mode",
"voiceCommand.matchMode.prefix": "Starts with",
"voiceCommand.matchMode.suffix": "Ends with",
"voiceCommand.matchMode.contains": "Contains",
"chain.title": "LLM Chains",
"chain.count": "{{count}} chains",
"chain.add": "Add Chain",
"chain.editTitle": "Edit Chain",
"chain.addTitle": "Add Chain",
"chain.name": "Chain Name",
"chain.steps": "Steps",
"chain.addStep": "Add Step",
"chain.removeStep": "Remove",
"chain.inputSource": "Input Source",
"chain.inputSource.original": "Original Text",
"chain.inputSource.previous": "Previous Step Result",
"chain.selectInstruction": "Select Command",
"chain.execute": "Execute",
"chain.executing": "Executing...",
"chain.noChains": "No chains — create a pipeline to run multiple commands in sequence",
"chain.step": "Step {{n}}",
"chain.progress": "Processing step {{current}}/{{total}}",
"context.title": "Screen Context",
"context.enabled": "Screen Context",
"context.enabledDesc": "Captures active app and selected text when recording starts, and sends it to the LLM.",
"dashboard.caption": "Live Caption",
"dashboard.captionStart": "Start Caption",
"dashboard.captionStop": "Stop Caption",
"dashboard.captionActive": "Caption Active",
"settings.voiceCommands": "Voice Commands",
"settings.voiceCommands.desc": "Detects keywords in transcription to auto-select commands.",
"settings.screenContext": "Screen Context",
"settings.screenContext.desc": "Sends active app info and selected text to the LLM during recording.",
"date.today": "Today",
"date.yesterday": "Yesterday",
"license.title": "License",
"license.currentTier": "Current Tier",
"license.free": "FREE",
"license.pro": "PRO",
"license.proPlus": "PRO+",
"license.activate": "Activate License",
"license.deactivate": "Deactivate",
"license.keyPlaceholder": "Enter license key...",
"license.activating": "Activating...",
"license.activated": "Activated",
"license.activateError": "Activation failed: {{message}}",
"license.deactivated": "Deactivated",
"license.machineId": "Machine ID",
"license.activatedAt": "Activated At",
"license.manageLicense": "Manage License",
"license.upgrade": "Upgrade",
"license.upgradeTitle": "Upgrade to Pro",
"license.upgradeDesc": "Unlock all features",
"license.quotaUsed": "{{used}}/{{limit}} used",
"license.quotaUnlimited": "Unlimited",
"license.tierComparison": "Tier Comparison",
"license.dailyUsage": "Daily Usage",
"license.feature.dictation": "Dictation",
"license.feature.llm_process": "LLM Processing",
"license.feature.live_caption": "Live Caption",
"license.feature.screen_context": "Screen Context",
"license.feature.voice_command": "Voice Commands",
"license.feature.llm_chain": "LLM Chain",
"license.feature.voice_memo": "Voice Memo",
"license.feature.history_unlimited": "Unlimited History",
"license.feature.history_export": "History Export",
"license.feature.custom_instruction_create": "Custom Instruction Create",
"license.feature.file_transcription": "File Transcription",
"license.feature.voice_conversation": "Voice Conversation",
"license.feature.dictation_template": "Dictation Template",
"license.feature.meeting_summary": "Meeting Summary",
"license.feature.local_rag": "Local RAG",
"license.feature.os_automation": "OS Automation",
"license.pro.required": "PRO Required",
"license.proPlus.required": "PRO+ Required",
"license.included": "Included",
"license.notIncluded": "Not included",
"license.keyLabel": "License Key",
"license.quotaExceeded.title": "You've used all your daily {{feature}}",
"license.quotaExceeded.desc": "Upgrade to Pro for unlimited usage",
"license.tierRequired.title": "{{feature}} is a {{tier}} feature",
"license.tierRequired.desc": "Upgrade to {{tier}} to unlock",
"license.tryTomorrow": "Try again tomorrow",
"license.learnMore": "Learn more",
"license.upgradeBenefits": "Upgrade Benefits",
"license.benefit.unlimitedDictation": "Unlimited dictation",
"license.benefit.unlimitedLLM": "Unlimited AI polish",
"license.benefit.liveCaption": "Live captions",
"license.benefit.unlimitedHistory": "Unlimited history retention",
"license.usageToday": "Usage today",
"license.perDay": "/day",
"license.unlimited": "Unlimited",
"license.locked": "Locked",
"license.nav": "License"
}