d3ro-voice/src/shared/ipc-channels.ts
Yun Chan fc7628327a Phase 15.5 구현: 화자 구분 (Speaker Diarization)
- Sidecar: pyannote /diarize 엔드포인트 + requirements.txt 업데이트
- LLM 기반 화자 추정 (Phase 1 — 오디오 보존 없이 전사 텍스트 분석)
- CaptionSegment에 speaker 필드 추가
- EditableSegment: 화자별 색상 바 + 화자 Chip 표시
- TranscriptTab: 화자 구분 버튼 + 진행률
- 설정: HuggingFace 토큰 입력 + Diarization 토글
- IPC: DIARIZE + DIARIZATION_PROGRESS 채널
- 에러코드: 895-897
- 12개 locale i18n
2026-04-08 12:14:00 +09:00

381 lines
13 KiB
TypeScript

// src/shared/ipc-channels.ts
// IPC 채널명 중앙 정의 — 모든 채널명은 이 파일에서만 정의한다.
export const IPC_CHANNELS = {
VOICE: {
START_RECORDING: 'voice:startRecording',
STOP_RECORDING: 'voice:stopRecording',
CANCEL_RECORDING: 'voice:cancelRecording',
GET_STATE: 'voice:getState',
SET_MODE: 'voice:setMode',
GET_MODE: 'voice:getMode',
// Main → Renderer events
STATE_CHANGED: 'voice:stateChanged',
TRANSCRIPTION_DELTA: 'voice:transcriptionDelta',
TRANSCRIPTION_COMPLETE: 'voice:transcriptionComplete',
ERROR: 'voice:error',
AUDIO_LEVEL: 'voice:audioLevel'
},
AUDIO: {
GET_DEVICES: 'audio:getDevices',
GET_SELECTED_DEVICE: 'audio:getSelectedDevice',
SET_SELECTED_DEVICE: 'audio:setSelectedDevice',
TEST_DEVICE: 'audio:testDevice',
// Main → Renderer events
DEVICE_CHANGED: 'audio:deviceChanged'
},
STT: {
GET_STATUS: 'stt:getStatus',
GET_MODELS: 'stt:getModels',
GET_ACTIVE_MODEL: 'stt:getActiveModel',
SET_MODEL: 'stt:setModel',
DOWNLOAD_MODEL: 'stt:downloadModel',
CANCEL_DOWNLOAD: 'stt:cancelDownload',
GET_LANGUAGE: 'stt:getLanguage',
SET_LANGUAGE: 'stt:setLanguage',
// Main → Renderer events
STATUS_CHANGED: 'stt:statusChanged',
DOWNLOAD_PROGRESS: 'stt:downloadProgress'
},
TTS: {
SPEAK: 'tts:speak',
STOP: 'tts:stop',
GET_VOICES: 'tts:getVoices',
GET_ACTIVE_VOICE: 'tts:getActiveVoice',
SET_VOICE: 'tts:setVoice',
GET_STATUS: 'tts:getStatus',
DOWNLOAD_VOICE: 'tts:downloadVoice',
// Main → Renderer events
STATUS_CHANGED: 'tts:statusChanged',
SPEAKING_STATE_CHANGED: 'tts:speakingStateChanged'
},
LLM: {
GET_STATUS: 'llm:getStatus',
GET_MODELS: 'llm:getModels',
GET_ACTIVE_MODEL: 'llm:getActiveModel',
SET_MODEL: 'llm:setModel',
PROCESS: 'llm:process',
CANCEL_PROCESS: 'llm:cancelProcess',
GET_SERVER_URL: 'llm:getServerUrl',
SET_SERVER_URL: 'llm:setServerUrl',
PULL_MODEL: 'llm:pullModel',
// Main → Renderer events
STATUS_CHANGED: 'llm:statusChanged',
PROCESS_PROGRESS: 'llm:processProgress',
PULL_PROGRESS: 'llm:pullProgress'
},
HOTKEY: {
GET_DICTATION_SHORTCUT: 'hotkey:getDictationShortcut',
SET_DICTATION_SHORTCUT: 'hotkey:setDictationShortcut',
GET_HANDS_FREE_SHORTCUT: 'hotkey:getHandsFreeShortcut',
SET_HANDS_FREE_SHORTCUT: 'hotkey:setHandsFreeShortcut',
GET_COMMAND_SHORTCUT: 'hotkey:getCommandShortcut',
SET_COMMAND_SHORTCUT: 'hotkey:setCommandShortcut',
GET_CAPTION_SHORTCUT: 'hotkey:getCaptionShortcut',
SET_CAPTION_SHORTCUT: 'hotkey:setCaptionShortcut',
IS_ENABLED: 'hotkey:isEnabled',
SET_ENABLED: 'hotkey:setEnabled',
START_RECORDING: 'hotkey:startRecording',
STOP_RECORDING: 'hotkey:stopRecording',
// Main → Renderer events
TRIGGERED: 'hotkey:triggered',
RECORDING_RESULT: 'hotkey:recordingResult'
},
CONFIG: {
GET: 'config:get',
SET: 'config:set',
GET_ALL: 'config:getAll',
RESET: 'config:reset',
GET_THEME: 'config:getTheme',
SET_THEME: 'config:setTheme',
GET_LANGUAGE: 'config:getLanguage',
SET_LANGUAGE: 'config:setLanguage',
GET_AUTO_LAUNCH: 'config:getAutoLaunch',
SET_AUTO_LAUNCH: 'config:setAutoLaunch',
GET_CLOSE_TO_TRAY: 'config:getCloseToTray',
SET_CLOSE_TO_TRAY: 'config:setCloseToTray',
// Main → Renderer events
CHANGED: 'config:changed'
},
HISTORY: {
GET_ALL: 'history:getAll',
GET_BY_ID: 'history:getById',
DELETE: 'history:delete',
DELETE_ALL: 'history:deleteAll',
SEARCH: 'history:search',
EXPORT: 'history:export',
// Main → Renderer events
ADDED: 'history:added'
},
DICTIONARY: {
GET_ALL: 'dictionary:getAll',
ADD: 'dictionary:add',
UPDATE: 'dictionary:update',
DELETE: 'dictionary:delete',
IMPORT: 'dictionary:import',
EXPORT: 'dictionary:export',
SEARCH: 'dictionary:search'
},
WINDOW: {
MINIMIZE: 'window:minimize',
MAXIMIZE: 'window:maximize',
CLOSE: 'window:close',
IS_MAXIMIZED: 'window:isMaximized',
SHOW_RECORDING_TIP: 'window:showRecordingTip',
HIDE_RECORDING_TIP: 'window:hideRecordingTip',
SHOW_RESULT_POPUP: 'window:showResultPopup',
HIDE_RESULT_POPUP: 'window:hideResultPopup',
TIP_MEASURED: 'window:tipMeasured',
// Main → Renderer events
TIP_STATE_CHANGED: 'window:tipStateChanged',
TIP_PREPARE: 'window:tipPrepare',
TIP_SHOW: 'window:tipShow'
},
SYSTEM: {
GET_PLATFORM: 'system:getPlatform',
GET_VERSION: 'system:getVersion',
CHECK_MIC_PERMISSION: 'system:checkMicPermission',
REQUEST_MIC_PERMISSION: 'system:requestMicPermission',
SHOW_NOTIFICATION: 'system:showNotification',
OPEN_EXTERNAL: 'system:openExternal',
GET_ACTIVE_APP: 'system:getActiveApp',
INSERT_TEXT: 'system:insertText',
PLAY_SOUND: 'system:playSound',
SET_SOUND_ENABLED: 'system:setSoundEnabled',
IS_SOUND_ENABLED: 'system:isSoundEnabled'
},
STATS: {
GET_SUMMARY: 'stats:getSummary',
GET_DAILY: 'stats:getDaily',
GET_WEEKLY: 'stats:getWeekly',
// Main → Renderer events
UPDATED: 'stats:updated'
},
// ── Phase 10: Memo Tags (10.3) ──
MEMO: {
GET_TAGS: 'memo:getTags',
ADD_TAG: 'memo:addTag',
REMOVE_TAG: 'memo:removeTag',
GET_ALL_TAGS: 'memo:getAllTags',
SEARCH_BY_TAG: 'memo:searchByTag',
EXPORT: 'memo:export',
},
// ── Phase 10: Voice Commands (10.5) ──
VOICE_COMMAND: {
GET_ALL: 'voiceCommand:getAll',
SET_KEYWORDS: 'voiceCommand:setKeywords',
SET_ENABLED: 'voiceCommand:setEnabled',
IS_ENABLED: 'voiceCommand:isEnabled',
// Main → Renderer events
MATCHED: 'voiceCommand:matched',
},
// ── Phase 10: Screen Context (10.2) ──
CONTEXT: {
CAPTURE: 'context:capture',
GET_CONFIG: 'context:getConfig',
SET_ENABLED: 'context:setEnabled',
IS_ENABLED: 'context:isEnabled',
},
// ── Phase 10: LLM Chain (10.4) ──
CHAIN: {
GET_ALL: 'chain:getAll',
CREATE: 'chain:create',
UPDATE: 'chain:update',
DELETE: 'chain:delete',
EXECUTE: 'chain:execute',
// Main → Renderer events
PROGRESS: 'chain:progress',
},
// ── Phase 10: Live Caption (10.1) ──
CAPTION: {
START: 'caption:start',
STOP: 'caption:stop',
GET_STATE: 'caption:getState',
SET_CONFIG: 'caption:setConfig',
GET_CONFIG: 'caption:getConfig',
/** 렌더러 → 메인: 시스템 오디오 PCM 데이터 전달 */
SYSTEM_AUDIO_DATA: 'caption:systemAudioData',
// Main → Renderer events
SEGMENT: 'caption:segment',
DELTA: 'caption:delta',
STATE_CHANGED: 'caption:stateChanged',
SESSION_SAVED: 'caption:sessionSaved',
/** 메인 → 렌더러: 시스템 오디오 캡처 시작/정지 요청 */
START_SYSTEM_AUDIO: 'caption:startSystemAudio',
STOP_SYSTEM_AUDIO: 'caption:stopSystemAudio',
},
// ── Phase 12: File Transcription (12.1) ──
FILE_TRANSCRIPTION: {
START: 'fileTranscription:start',
CANCEL: 'fileTranscription:cancel',
GET_STATE: 'fileTranscription:getState',
// Main → Renderer events
PROGRESS: 'fileTranscription:progress',
COMPLETE: 'fileTranscription:complete',
ERROR: 'fileTranscription:error',
},
// ── Phase 12: Meeting Summary (12.2) ──
MEETING_SUMMARY: {
SUMMARIZE: 'meetingSummary:summarize',
GET_SUMMARY: 'meetingSummary:getSummary',
EXPORT_MARKDOWN: 'meetingSummary:exportMarkdown',
// Main → Renderer events
SUMMARY_READY: 'meetingSummary:summaryReady',
SUMMARY_PROGRESS: 'meetingSummary:progress',
},
// ── Phase 12: Dictation Templates (12.3) ──
DICTATION_TEMPLATE: {
GET_ALL: 'dictationTemplate:getAll',
CREATE: 'dictationTemplate:create',
UPDATE: 'dictationTemplate:update',
DELETE: 'dictationTemplate:delete',
START_SESSION: 'dictationTemplate:startSession',
CANCEL_SESSION: 'dictationTemplate:cancelSession',
GET_SESSION_STATE: 'dictationTemplate:getSessionState',
SET_FIELD_VALUE: 'dictationTemplate:setFieldValue',
// Main → Renderer events
SESSION_STATE_CHANGED: 'dictationTemplate:sessionStateChanged',
FIELD_COMPLETED: 'dictationTemplate:fieldCompleted',
SESSION_COMPLETED: 'dictationTemplate:sessionCompleted',
},
// ── Phase 13: Voice Conversation (13.1) ──
VOICE_CONVERSATION: {
START_SESSION: 'voiceConversation:startSession',
STOP_SESSION: 'voiceConversation:stopSession',
SEND_MESSAGE: 'voiceConversation:sendMessage',
GET_STATE: 'voiceConversation:getState',
GET_HISTORY: 'voiceConversation:getHistory',
CLEAR_HISTORY: 'voiceConversation:clearHistory',
CANCEL_RESPONSE: 'voiceConversation:cancelResponse',
// Main → Renderer events
STATE_CHANGED: 'voiceConversation:stateChanged',
USER_MESSAGE: 'voiceConversation:userMessage',
ASSISTANT_DELTA: 'voiceConversation:assistantDelta',
ASSISTANT_MESSAGE: 'voiceConversation:assistantMessage',
TTS_STARTED: 'voiceConversation:ttsStarted',
TTS_FINISHED: 'voiceConversation:ttsFinished',
ERROR: 'voiceConversation:error',
},
// ── Phase 13: Local RAG (13.2) ──
RAG: {
ADD_DOCUMENT: 'rag:addDocument',
REMOVE_DOCUMENT: 'rag:removeDocument',
GET_DOCUMENTS: 'rag:getDocuments',
QUERY: 'rag:query',
GET_STATE: 'rag:getState',
REINDEX: 'rag:reindex',
// Main → Renderer events
INDEX_PROGRESS: 'rag:indexProgress',
INDEX_COMPLETE: 'rag:indexComplete',
QUERY_RESULT: 'rag:queryResult',
},
// ── Phase 13: Voice Action / OS Automation (13.3) ──
VOICE_ACTION: {
EXECUTE: 'voiceAction:execute',
GET_PRESETS: 'voiceAction:getPresets',
GET_HISTORY: 'voiceAction:getHistory',
CLEAR_HISTORY: 'voiceAction:clearHistory',
SET_ENABLED: 'voiceAction:setEnabled',
IS_ENABLED: 'voiceAction:isEnabled',
// Main → Renderer events
ACTION_PLANNED: 'voiceAction:actionPlanned',
ACTION_EXECUTED: 'voiceAction:actionExecuted',
ACTION_ERROR: 'voiceAction:actionError',
},
// ── Phase 14: Meeting Mode ──
MEETING_MODE: {
START_RECORDING: 'meetingMode:startRecording',
STOP_RECORDING: 'meetingMode:stopRecording',
ADD_MEMO: 'meetingMode:addMemo',
GET_STATE: 'meetingMode:getState',
GET_SESSIONS: 'meetingMode:getSessions',
GET_SESSION: 'meetingMode:getSession',
DELETE_SESSION: 'meetingMode:deleteSession',
UPDATE_TITLE: 'meetingMode:updateTitle',
EXPORT_PDF: 'meetingMode:exportPdf',
EXPORT_MARKDOWN: 'meetingMode:exportMarkdown',
// Phase 14.5: 문서 생성/편집/내보내기
UPDATE_TRANSCRIPT: 'meetingMode:updateTranscript',
GENERATE_DOCUMENT: 'meetingMode:generateDocument',
GET_DOCUMENTS: 'meetingMode:getDocuments',
UPDATE_DOCUMENT: 'meetingMode:updateDocument',
DELETE_DOCUMENT: 'meetingMode:deleteDocument',
EXPORT_DOCUMENT: 'meetingMode:exportDocument',
EXPORT_TRANSCRIPT: 'meetingMode:exportTranscript',
EDIT_SEGMENT: 'meetingMode:editSegment',
// Main → Renderer events
STATE_CHANGED: 'meetingMode:stateChanged',
SEGMENT: 'meetingMode:segment',
PROCESSING_PROGRESS: 'meetingMode:processingProgress',
SESSION_COMPLETED: 'meetingMode:sessionCompleted',
DOC_GENERATING_PROGRESS: 'meetingMode:docGeneratingProgress',
POLISH_TRANSCRIPT: 'meetingMode:polishTranscript',
DIARIZE: 'meetingMode:diarize',
DIARIZATION_PROGRESS: 'meetingMode:diarizationProgress',
ERROR: 'meetingMode:error',
},
// ── Phase 14.5: Meeting Document Templates ──
MEETING_DOC_TEMPLATE: {
GET_ALL: 'meetingDocTemplate:getAll',
CREATE: 'meetingDocTemplate:create',
UPDATE: 'meetingDocTemplate:update',
DELETE: 'meetingDocTemplate:delete',
},
// ── Phase 15: Meeting AI Chat ──
MEETING_CHAT: {
SEND: 'meetingChat:send',
CANCEL: 'meetingChat:cancel',
CLEAR: 'meetingChat:clear',
DELTA: 'meetingChat:delta',
MESSAGE: 'meetingChat:message',
ERROR: 'meetingChat:error',
},
// ── Phase 11: License & Monetization ──
LICENSE: {
GET_INFO: 'license:getInfo',
ACTIVATE: 'license:activate',
DEACTIVATE: 'license:deactivate',
CHECK_FEATURE: 'license:checkFeature',
GET_USAGE: 'license:getUsage',
GET_ALL_USAGE: 'license:getAllUsage',
GET_TIER_COMPARISON: 'license:getTierComparison',
// Main → Renderer events
UPGRADE_PROMPT: 'license:upgradePrompt',
TIER_CHANGED: 'license:tierChanged',
},
} as const
// 타입 유틸리티: 채널명 유니온 추출
type NestedValues<T> = T extends Record<string, infer V>
? V extends string
? V
: NestedValues<V>
: never
export type IPCChannel = NestedValues<typeof IPC_CHANNELS>