refactor(main): IPC 채널 SSOT 일원화 + AppConfig 타입 강화 (WS2)
- ipc-channels.ts SSOT에 9개 그룹/키 추가: INSTRUCTION, SYSTEM_AUDIO, POPUP_RESULT/HISTORY/COMMAND/CAPTION, VOICE_PARTIAL, CLIPBOARD, APP, VOICE_CONVERSATION.FINISH_LISTENING - WindowManager/handlers/bootstrap 하드코딩 채널 -> IPC_CHANNELS 교체. 불일치 4건(result:* vs window:tip*)은 preload 재검증 후 SSOT로 통일. notifyRenderer channel: string -> IPCChannel 타입 좁힘. - AppConfig에 7개 누락 키 추가(customInstructions, llmChains, voiceCommandRules, voiceCommandsEnabled, activeInstructionId, activeChainId, captionAudioSource) -> as never 16건 제거. - ChainService/CustomInstructionService/WindowManager dynamic require -> static import. - services/index.ts 데드 레지스트리 제거 (import 0건). SKIP: ipcSuccess/ipcError 헬퍼 통일, catch 패턴(별도) 정책: docs/REFACTOR_POLICY.md DP2, DP9
This commit is contained in:
parent
b820c789bb
commit
aef44289a5
15 changed files with 161 additions and 126 deletions
|
|
@ -33,6 +33,8 @@ import {
|
|||
} from './windows/WindowManager'
|
||||
import { createTray } from './windows/TrayManager'
|
||||
import { registerAllIpcHandlers } from './ipc'
|
||||
import { IPC_CHANNELS } from '@d3ro/core/ipc-channels'
|
||||
import type { IPCChannel } from '@d3ro/core/ipc-channels'
|
||||
|
||||
const logger = getLogger('bootstrap')
|
||||
|
||||
|
|
@ -171,7 +173,7 @@ async function initPopupWindows(): Promise<void> {
|
|||
unregisterPopupNavKeys()
|
||||
} else {
|
||||
const instructions = getCustomInstructionService().getAll()
|
||||
const activeId = configGet('activeInstructionId' as keyof import('@d3ro/core/types').AppConfig) as unknown as string
|
||||
const activeId = configGet('activeInstructionId') as string | null
|
||||
showCommandPopup(instructions as unknown as Array<Record<string, unknown>>, activeId || null)
|
||||
registerPopupNavKeys('command')
|
||||
}
|
||||
|
|
@ -250,7 +252,7 @@ async function initVoiceMode(): Promise<void> {
|
|||
}
|
||||
|
||||
// 렌더러 UI 갱신 알림 (Dashboard 통계 + History 목록)
|
||||
notifyRenderer('app:dataChanged', { type: 'session-completed' })
|
||||
notifyRenderer(IPC_CHANNELS.APP.DATA_CHANGED, { type: 'session-completed' })
|
||||
})
|
||||
|
||||
voiceMode.on('session-cancelled', ({ reason }) => {
|
||||
|
|
@ -268,7 +270,7 @@ async function initVoiceMode(): Promise<void> {
|
|||
}
|
||||
|
||||
/** 메인 윈도우 렌더러에 UI 갱신 이벤트 전송 */
|
||||
function notifyRenderer(channel: string, data?: Record<string, unknown>): void {
|
||||
function notifyRenderer(channel: IPCChannel, data?: Record<string, unknown>): void {
|
||||
const win = getMainWindow()
|
||||
if (win && !win.isDestroyed()) {
|
||||
win.webContents.send(channel, data ?? {})
|
||||
|
|
@ -330,13 +332,13 @@ async function initMeetingMode(): Promise<void> {
|
|||
|
||||
function setupHistoryPopupIPC(): void {
|
||||
// 히스토리 팝업 열기 (핫키에서 호출)
|
||||
ipcMainRef.on('history:showPopup', () => {
|
||||
ipcMainRef.on(IPC_CHANNELS.POPUP_HISTORY.SHOW_POPUP, () => {
|
||||
const entries = getHistoryService().list({ page: 0, pageSize: 10 }).entries
|
||||
showHistoryPopup(entries as unknown as Array<Record<string, unknown>>)
|
||||
})
|
||||
|
||||
// 아이템 선택 → 텍스트 삽입
|
||||
ipcMainRef.on('history:itemSelected', (_event: Electron.IpcMainEvent, data: { text: string }) => {
|
||||
ipcMainRef.on(IPC_CHANNELS.POPUP_HISTORY.ITEM_SELECTED, (_event: Electron.IpcMainEvent, data: { text: string }) => {
|
||||
hideHistoryPopup()
|
||||
unregisterPopupNavKeys()
|
||||
setTimeout(async () => {
|
||||
|
|
@ -349,7 +351,7 @@ function setupHistoryPopupIPC(): void {
|
|||
})
|
||||
|
||||
// 팝업 닫기
|
||||
ipcMainRef.on('history:popupDismissed', () => {
|
||||
ipcMainRef.on(IPC_CHANNELS.POPUP_HISTORY.POPUP_DISMISSED, () => {
|
||||
hideHistoryPopup()
|
||||
unregisterPopupNavKeys()
|
||||
})
|
||||
|
|
@ -359,28 +361,28 @@ function setupHistoryPopupIPC(): void {
|
|||
|
||||
function setupCommandPopupIPC(): void {
|
||||
// 명령어 선택 → 활성 명령어로 설정
|
||||
ipcMainRef.on('command:selected', (_event: Electron.IpcMainEvent, data: { id: string; name: string }) => {
|
||||
ipcMainRef.on(IPC_CHANNELS.POPUP_COMMAND.SELECTED, (_event: Electron.IpcMainEvent, data: { id: string; name: string }) => {
|
||||
hideCommandPopup()
|
||||
unregisterPopupNavKeys()
|
||||
|
||||
if (data.id) {
|
||||
// 명령어 선택 → 활성 명령어로 설정
|
||||
configSet('activeInstructionId' as keyof import('@d3ro/core/types').AppConfig, data.id as never)
|
||||
configSet('activeInstructionId', data.id)
|
||||
configSet('defaultLLMAction', 'custom')
|
||||
logger.info(`Active command set: ${data.name} (${data.id})`)
|
||||
} else {
|
||||
// 선택 해제 → 명령어 없음 (원본 삽입)
|
||||
configSet('activeInstructionId' as keyof import('@d3ro/core/types').AppConfig, '' as never)
|
||||
configSet('activeInstructionId', '')
|
||||
configSet('defaultLLMAction', 'none')
|
||||
logger.info('Active command cleared (none)')
|
||||
}
|
||||
|
||||
// CMD 페이지 UI 갱신 알림
|
||||
notifyRenderer('app:dataChanged', { type: 'command-changed', activeId: data.id })
|
||||
notifyRenderer(IPC_CHANNELS.APP.DATA_CHANGED, { type: 'command-changed', activeId: data.id })
|
||||
})
|
||||
|
||||
// 팝업 닫기
|
||||
ipcMainRef.on('command:dismissed', () => {
|
||||
ipcMainRef.on(IPC_CHANNELS.POPUP_COMMAND.DISMISSED, () => {
|
||||
hideCommandPopup()
|
||||
unregisterPopupNavKeys()
|
||||
})
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue