Some checks failed
deploy-site / deploy (push) Failing after 1m15s
Auto-update could not work at all: the installer was 189 MB because it carried the local speech engine and ffmpeg, and the download feed rejects uploads over about 100 MiB, so update metadata could never be published. The installer now leaves those components out and the app fetches them the first time they are needed, verifying every part and the joined archive before installing. The installer is 90.6 MiB, the update feed is published again, and updates stay small because the engine is not re-sent on every release. The fetch is visible and recoverable: the download runs with progress, a failed install cleans up after itself, and Settings > STT shows the runtime status with a manual download action for when the automatic one cannot run.
891 lines
42 KiB
TypeScript
891 lines
42 KiB
TypeScript
// src/preload/index.ts
|
|
// contextBridge로 렌더러에 노출할 API 정의
|
|
|
|
import { contextBridge, ipcRenderer } from 'electron'
|
|
import { IPC_CHANNELS } from '@d3ro/core/ipc-channels'
|
|
import type {
|
|
AudioDevice,
|
|
SetDeviceParams,
|
|
TestDeviceParams,
|
|
TestDeviceResult,
|
|
AudioDeviceChangedEvent,
|
|
AppConfig,
|
|
ConfigGetParams,
|
|
ConfigSetParams,
|
|
ConfigResetParams,
|
|
SetThemeParams,
|
|
SetLanguageParams,
|
|
ThemeMode,
|
|
ConfigChangedEvent,
|
|
VoiceState,
|
|
VoiceMode,
|
|
AudioLevelEvent,
|
|
VoiceStateChangedEvent,
|
|
TranscriptionDeltaEvent,
|
|
TranscriptionCompleteEvent,
|
|
VoiceErrorEvent,
|
|
StartRecordingParams,
|
|
StartRecordingResult,
|
|
StopRecordingParams,
|
|
StopRecordingResult,
|
|
CancelRecordingParams,
|
|
SetVoiceModeParams,
|
|
STTStatus,
|
|
STTModel,
|
|
SetSTTModelParams,
|
|
SetSTTLanguageParams,
|
|
STTStatusChangedEvent,
|
|
DownloadModelParams,
|
|
DownloadProgressEvent,
|
|
STTProviderType,
|
|
STTProviderInfo,
|
|
STTProviderConfig,
|
|
SetSTTProviderParams,
|
|
SetSTTProviderConfigParams,
|
|
TestSTTConnectionParams,
|
|
TestSTTConnectionResult,
|
|
HotkeyBinding,
|
|
SetHotkeyParams,
|
|
SetEnabledParams,
|
|
HotkeyTriggeredEvent,
|
|
LLMStatus,
|
|
LLMModel,
|
|
LLMProcessParams,
|
|
LLMProcessResult,
|
|
SetLLMModelParams,
|
|
SetServerUrlParams,
|
|
LLMStatusChangedEvent,
|
|
LLMProcessProgressEvent,
|
|
HistoryQueryParams,
|
|
HistoryPage,
|
|
HistoryGetByIdParams,
|
|
HistoryEntry,
|
|
HistoryDeleteParams,
|
|
HistorySearchParams,
|
|
DictionaryQueryParams,
|
|
DictionaryPage,
|
|
DictionaryEntry,
|
|
DictionaryAddParams,
|
|
DictionaryUpdateParams,
|
|
DictionaryDeleteParams,
|
|
DictionarySearchParams,
|
|
DictionaryImportParams,
|
|
DictionaryImportResult,
|
|
DictionaryExportParams,
|
|
StatsSummary,
|
|
PermissionStatus,
|
|
// Phase 10
|
|
MemoTag,
|
|
AddTagParams,
|
|
RemoveTagParams,
|
|
GetTagsParams,
|
|
SearchByTagParams,
|
|
ExportMemoParams,
|
|
TagCount,
|
|
VoiceCommandRule,
|
|
VoiceCommandMatch,
|
|
SetVoiceCommandKeywordsParams,
|
|
SetVoiceCommandEnabledParams,
|
|
CaptureContextResult,
|
|
LLMChain,
|
|
CreateChainParams,
|
|
UpdateChainParams,
|
|
DeleteChainParams,
|
|
ExecuteChainParams,
|
|
ChainExecutionResult,
|
|
ChainProgress,
|
|
CaptionState,
|
|
CaptionSegment,
|
|
CaptionConfig,
|
|
// Phase 11
|
|
LicenseInfo,
|
|
ActivateLicenseParams,
|
|
ActivateLicenseResult,
|
|
FeatureAccess,
|
|
UsageQuota,
|
|
UpgradePromptEvent,
|
|
TierComparison,
|
|
// Phase 12
|
|
FileTranscriptionStartParams,
|
|
// Phase 13.1
|
|
ConversationSessionInfo,
|
|
ConversationMessage,
|
|
ConversationSendParams,
|
|
ConversationAssistantDelta,
|
|
ConversationAssistantMessage,
|
|
ConversationError,
|
|
RealtimeTokenParams,
|
|
RealtimeTokenResult,
|
|
// Phase 13.2
|
|
RAGDocument,
|
|
RAGQueryParams,
|
|
RAGQueryResult,
|
|
RAGStateInfo,
|
|
RAGIndexProgress,
|
|
RAGAddDocumentParams,
|
|
RAGRemoveDocumentParams,
|
|
// Phase 13.3
|
|
VoiceActionExecuteParams,
|
|
VoiceActionPreset,
|
|
VoiceActionHistoryEntry,
|
|
VoiceActionPlannedEvent,
|
|
VoiceActionExecutedEvent,
|
|
VoiceActionErrorEvent,
|
|
FileTranscriptionProgress,
|
|
FileTranscriptionResult,
|
|
FileTranscriptionStateInfo,
|
|
MeetingSummarizeParams,
|
|
MeetingSummaryResult,
|
|
MeetingSummaryGetParams,
|
|
MeetingSummaryExportParams,
|
|
MeetingSummaryProgress,
|
|
DictationTemplate,
|
|
CreateTemplateParams,
|
|
UpdateTemplateParams,
|
|
DeleteTemplateParams,
|
|
StartTemplateSessionParams,
|
|
SetFieldValueParams,
|
|
TemplateSessionInfo,
|
|
TemplateFieldCompletedEvent,
|
|
TemplateSessionCompletedEvent,
|
|
MeetingStartResult,
|
|
MeetingMemo,
|
|
MeetingAddMemoParams,
|
|
MeetingModeStateInfo,
|
|
MeetingSessionPage,
|
|
MeetingGetSessionsParams,
|
|
MeetingSessionDetail,
|
|
MeetingGetSessionParams,
|
|
MeetingDeleteSessionParams,
|
|
MeetingExportParams,
|
|
MeetingProcessingProgress,
|
|
MeetingDocument,
|
|
MeetingDocTemplate,
|
|
MeetingGenerateDocParams,
|
|
MeetingUpdateDocParams,
|
|
MeetingDeleteDocParams,
|
|
MeetingGetDocsParams,
|
|
MeetingUpdateTranscriptParams,
|
|
MeetingExportDocParams,
|
|
MeetingExportTranscriptParams,
|
|
MeetingDocGeneratingProgress,
|
|
CreateMeetingDocTemplateParams,
|
|
UpdateMeetingDocTemplateParams,
|
|
DeleteMeetingDocTemplateParams,
|
|
MeetingChatMessage,
|
|
MeetingChatSendParams,
|
|
MeetingChatDelta,
|
|
DiarizeSessionParams,
|
|
} from '@d3ro/core/types'
|
|
import { Feature } from '@d3ro/core/types'
|
|
import type { IPCResult } from '@d3ro/core/errors'
|
|
|
|
/** 로컬 AI 런타임(사이드카 엔진/ffmpeg) 상태 — RuntimeProvisioner가 제공한다 */
|
|
type RuntimeComponentName = 'sidecar' | 'ffmpeg'
|
|
|
|
interface RuntimeStatusPayload {
|
|
component: RuntimeComponentName
|
|
installed: boolean
|
|
path: string
|
|
sizeBytes: number
|
|
}
|
|
|
|
interface RuntimeProgressPayload {
|
|
component: RuntimeComponentName
|
|
phase: 'index' | 'downloading' | 'extracting' | 'done'
|
|
percent: number
|
|
downloadedBytes: number
|
|
totalBytes: number
|
|
bytesPerSecond: number
|
|
}
|
|
|
|
type Unsubscribe = () => void
|
|
|
|
function invoke<TResult>(channel: string, ...args: unknown[]): Promise<IPCResult<TResult>> {
|
|
return ipcRenderer.invoke(channel, ...args)
|
|
}
|
|
|
|
function send(channel: string, ...args: unknown[]): void {
|
|
ipcRenderer.send(channel, ...args)
|
|
}
|
|
|
|
function on<T>(channel: string, callback: (data: T) => void): Unsubscribe {
|
|
const listener = (_event: Electron.IpcRendererEvent, data: T) => callback(data)
|
|
ipcRenderer.on(channel, listener)
|
|
return () => ipcRenderer.removeListener(channel, listener)
|
|
}
|
|
|
|
const electronAPI = {
|
|
// ── Platform ───────────────────────────────────────────
|
|
// 'darwin' | 'win32' | 'linux' — 렌더러에서 키바인딩/단축키 표기 분기
|
|
platform: process.platform as NodeJS.Platform,
|
|
|
|
// ── Audio ──────────────────────────────────────────────
|
|
audio: {
|
|
getDevices: () => invoke<AudioDevice[]>(IPC_CHANNELS.AUDIO.GET_DEVICES),
|
|
getSelectedDevice: () => invoke<string | null>(IPC_CHANNELS.AUDIO.GET_SELECTED_DEVICE),
|
|
setSelectedDevice: (params: SetDeviceParams) =>
|
|
invoke<void>(IPC_CHANNELS.AUDIO.SET_SELECTED_DEVICE, params),
|
|
testDevice: (params: TestDeviceParams) =>
|
|
invoke<TestDeviceResult>(IPC_CHANNELS.AUDIO.TEST_DEVICE, params),
|
|
stopTest: () => invoke<void>(IPC_CHANNELS.AUDIO.STOP_TEST),
|
|
onDeviceChanged: (cb: (e: AudioDeviceChangedEvent) => void): Unsubscribe =>
|
|
on(IPC_CHANNELS.AUDIO.DEVICE_CHANGED, cb),
|
|
onTestLevel: (cb: (e: { level: number; done: boolean }) => void): Unsubscribe =>
|
|
on(IPC_CHANNELS.AUDIO.TEST_LEVEL, cb),
|
|
},
|
|
|
|
// ── Config ─────────────────────────────────────────────
|
|
config: {
|
|
get: (params: ConfigGetParams) => invoke<unknown>(IPC_CHANNELS.CONFIG.GET, params),
|
|
set: (params: ConfigSetParams) => invoke<void>(IPC_CHANNELS.CONFIG.SET, params),
|
|
getAll: () => invoke<AppConfig>(IPC_CHANNELS.CONFIG.GET_ALL),
|
|
reset: (params: ConfigResetParams) => invoke<void>(IPC_CHANNELS.CONFIG.RESET, params),
|
|
getTheme: () => invoke<ThemeMode>(IPC_CHANNELS.CONFIG.GET_THEME),
|
|
setTheme: (params: SetThemeParams) => invoke<void>(IPC_CHANNELS.CONFIG.SET_THEME, params),
|
|
getLanguage: () => invoke<string>(IPC_CHANNELS.CONFIG.GET_LANGUAGE),
|
|
setLanguage: (params: SetLanguageParams) =>
|
|
invoke<void>(IPC_CHANNELS.CONFIG.SET_LANGUAGE, params),
|
|
onChanged: (cb: (e: ConfigChangedEvent) => void): Unsubscribe =>
|
|
on(IPC_CHANNELS.CONFIG.CHANGED, cb)
|
|
},
|
|
|
|
// ── Voice ──────────────────────────────────────────────
|
|
voice: {
|
|
startRecording: (params: StartRecordingParams) =>
|
|
invoke<StartRecordingResult>(IPC_CHANNELS.VOICE.START_RECORDING, params),
|
|
stopRecording: (params: StopRecordingParams) =>
|
|
invoke<StopRecordingResult>(IPC_CHANNELS.VOICE.STOP_RECORDING, params),
|
|
cancelRecording: (params: CancelRecordingParams) =>
|
|
invoke<void>(IPC_CHANNELS.VOICE.CANCEL_RECORDING, params),
|
|
getState: () => invoke<VoiceState>(IPC_CHANNELS.VOICE.GET_STATE),
|
|
setMode: (params: SetVoiceModeParams) =>
|
|
invoke<void>(IPC_CHANNELS.VOICE.SET_MODE, params),
|
|
getMode: () => invoke<VoiceMode>(IPC_CHANNELS.VOICE.GET_MODE),
|
|
onStateChanged: (cb: (e: VoiceStateChangedEvent) => void): Unsubscribe =>
|
|
on(IPC_CHANNELS.VOICE.STATE_CHANGED, cb),
|
|
onTranscriptionDelta: (cb: (e: TranscriptionDeltaEvent) => void): Unsubscribe =>
|
|
on(IPC_CHANNELS.VOICE.TRANSCRIPTION_DELTA, cb),
|
|
onTranscriptionComplete: (cb: (e: TranscriptionCompleteEvent) => void): Unsubscribe =>
|
|
on(IPC_CHANNELS.VOICE.TRANSCRIPTION_COMPLETE, cb),
|
|
onError: (cb: (e: VoiceErrorEvent) => void): Unsubscribe =>
|
|
on(IPC_CHANNELS.VOICE.ERROR, cb),
|
|
onAudioLevel: (cb: (e: AudioLevelEvent) => void): Unsubscribe =>
|
|
on(IPC_CHANNELS.VOICE.AUDIO_LEVEL, cb)
|
|
},
|
|
|
|
// ── STT ────────────────────────────────────────────────
|
|
stt: {
|
|
getStatus: () => invoke<STTStatus>(IPC_CHANNELS.STT.GET_STATUS),
|
|
getModels: () => invoke<STTModel[]>(IPC_CHANNELS.STT.GET_MODELS),
|
|
getActiveModel: () => invoke<string | null>(IPC_CHANNELS.STT.GET_ACTIVE_MODEL),
|
|
setModel: (params: SetSTTModelParams) =>
|
|
invoke<void>(IPC_CHANNELS.STT.SET_MODEL, params),
|
|
downloadModel: (params: DownloadModelParams) =>
|
|
invoke<void>(IPC_CHANNELS.STT.DOWNLOAD_MODEL, params),
|
|
cancelDownload: () => invoke<void>(IPC_CHANNELS.STT.CANCEL_DOWNLOAD),
|
|
getLanguage: () => invoke<string>(IPC_CHANNELS.STT.GET_LANGUAGE),
|
|
setLanguage: (params: SetSTTLanguageParams) =>
|
|
invoke<void>(IPC_CHANNELS.STT.SET_LANGUAGE, params),
|
|
getProviders: () => invoke<STTProviderInfo[]>(IPC_CHANNELS.STT.GET_PROVIDERS),
|
|
getActiveProvider: () => invoke<STTProviderType>(IPC_CHANNELS.STT.GET_ACTIVE_PROVIDER),
|
|
setProvider: (params: SetSTTProviderParams) =>
|
|
invoke<void>(IPC_CHANNELS.STT.SET_PROVIDER, params),
|
|
getProviderConfig: (params: { provider: STTProviderType }) =>
|
|
invoke<STTProviderConfig>(IPC_CHANNELS.STT.GET_PROVIDER_CONFIG, params),
|
|
setProviderConfig: (params: SetSTTProviderConfigParams) =>
|
|
invoke<void>(IPC_CHANNELS.STT.SET_PROVIDER_CONFIG, params),
|
|
testConnection: (params: TestSTTConnectionParams) =>
|
|
invoke<TestSTTConnectionResult>(IPC_CHANNELS.STT.TEST_CONNECTION, params),
|
|
onStatusChanged: (cb: (e: STTStatusChangedEvent) => void): Unsubscribe =>
|
|
on(IPC_CHANNELS.STT.STATUS_CHANGED, cb),
|
|
onDownloadProgress: (cb: (e: DownloadProgressEvent) => void): Unsubscribe =>
|
|
on(IPC_CHANNELS.STT.DOWNLOAD_PROGRESS, cb)
|
|
},
|
|
|
|
// ── Local AI runtime (엔진/ffmpeg — 필요할 때 내려받음) ──
|
|
runtime: {
|
|
getStatus: () => invoke<RuntimeStatusPayload[]>(IPC_CHANNELS.RUNTIME.GET_STATUS),
|
|
ensure: (params: { component: RuntimeComponentName }) =>
|
|
invoke<{ component: RuntimeComponentName; binaryPath: string }>(
|
|
IPC_CHANNELS.RUNTIME.ENSURE,
|
|
params,
|
|
),
|
|
onProgress: (cb: (e: RuntimeProgressPayload) => void): Unsubscribe =>
|
|
on(IPC_CHANNELS.RUNTIME.PROGRESS, cb)
|
|
},
|
|
|
|
// ── Hotkey ─────────────────────────────────────────────
|
|
hotkey: {
|
|
getDictationShortcut: () =>
|
|
invoke<HotkeyBinding>(IPC_CHANNELS.HOTKEY.GET_DICTATION_SHORTCUT),
|
|
setDictationShortcut: (params: SetHotkeyParams) =>
|
|
invoke<void>(IPC_CHANNELS.HOTKEY.SET_DICTATION_SHORTCUT, params),
|
|
getHandsFreeShortcut: () =>
|
|
invoke<HotkeyBinding>(IPC_CHANNELS.HOTKEY.GET_HANDS_FREE_SHORTCUT),
|
|
setHandsFreeShortcut: (params: SetHotkeyParams) =>
|
|
invoke<void>(IPC_CHANNELS.HOTKEY.SET_HANDS_FREE_SHORTCUT, params),
|
|
getCommandShortcut: () =>
|
|
invoke<HotkeyBinding>(IPC_CHANNELS.HOTKEY.GET_COMMAND_SHORTCUT),
|
|
setCommandShortcut: (params: SetHotkeyParams) =>
|
|
invoke<void>(IPC_CHANNELS.HOTKEY.SET_COMMAND_SHORTCUT, params),
|
|
getCaptionShortcut: () =>
|
|
invoke<HotkeyBinding>(IPC_CHANNELS.HOTKEY.GET_CAPTION_SHORTCUT),
|
|
setCaptionShortcut: (params: SetHotkeyParams) =>
|
|
invoke<void>(IPC_CHANNELS.HOTKEY.SET_CAPTION_SHORTCUT, params),
|
|
isEnabled: () => invoke<boolean>(IPC_CHANNELS.HOTKEY.IS_ENABLED),
|
|
setEnabled: (params: SetEnabledParams) =>
|
|
invoke<void>(IPC_CHANNELS.HOTKEY.SET_ENABLED, params),
|
|
onTriggered: (cb: (e: HotkeyTriggeredEvent) => void): Unsubscribe =>
|
|
on(IPC_CHANNELS.HOTKEY.TRIGGERED, cb)
|
|
},
|
|
|
|
// ── LLM ────────────────────────────────────────────────
|
|
llm: {
|
|
getStatus: () => invoke<LLMStatus>(IPC_CHANNELS.LLM.GET_STATUS),
|
|
getModels: () => invoke<LLMModel[]>(IPC_CHANNELS.LLM.GET_MODELS),
|
|
getActiveModel: () => invoke<string | null>(IPC_CHANNELS.LLM.GET_ACTIVE_MODEL),
|
|
setModel: (params: SetLLMModelParams) =>
|
|
invoke<void>(IPC_CHANNELS.LLM.SET_MODEL, params),
|
|
process: (params: LLMProcessParams) =>
|
|
invoke<LLMProcessResult>(IPC_CHANNELS.LLM.PROCESS, params),
|
|
cancelProcess: () => invoke<void>(IPC_CHANNELS.LLM.CANCEL_PROCESS),
|
|
getServerUrl: () => invoke<string>(IPC_CHANNELS.LLM.GET_SERVER_URL),
|
|
setServerUrl: (params: SetServerUrlParams) =>
|
|
invoke<void>(IPC_CHANNELS.LLM.SET_SERVER_URL, params),
|
|
onStatusChanged: (cb: (e: LLMStatusChangedEvent) => void): Unsubscribe =>
|
|
on(IPC_CHANNELS.LLM.STATUS_CHANGED, cb),
|
|
onProcessProgress: (cb: (e: LLMProcessProgressEvent) => void): Unsubscribe =>
|
|
on(IPC_CHANNELS.LLM.PROCESS_PROGRESS, cb),
|
|
pullModel: (params: { modelId: string }) =>
|
|
invoke<void>(IPC_CHANNELS.LLM.PULL_MODEL, params),
|
|
startServer: () =>
|
|
invoke<'running' | 'starting' | 'not-installed' | 'failed'>(
|
|
IPC_CHANNELS.LLM.START_SERVER
|
|
),
|
|
checkConnection: () =>
|
|
invoke<{ available: boolean; version: string | null; models: LLMModel[] }>(
|
|
IPC_CHANNELS.LLM.CHECK_CONNECTION
|
|
),
|
|
onPullProgress: (
|
|
cb: (e: {
|
|
modelId: string
|
|
status: string
|
|
digest: string | null
|
|
total: number
|
|
completed: number
|
|
percent: number
|
|
}) => void
|
|
): Unsubscribe => on(IPC_CHANNELS.LLM.PULL_PROGRESS, cb),
|
|
// Phase 3.2: Premium LLM
|
|
premium: {
|
|
getStatus: () =>
|
|
invoke<{ available: boolean; backend: 'local' | 'premium' }>(
|
|
IPC_CHANNELS.LLM.PREMIUM_GET_STATUS
|
|
),
|
|
getQuota: () =>
|
|
invoke<{
|
|
tier: 'free' | 'pro' | 'pro_plus'
|
|
current: number
|
|
limit: number
|
|
overageCredits: number
|
|
} | null>(IPC_CHANNELS.LLM.PREMIUM_GET_QUOTA),
|
|
onFallback: (cb: (e: { reason: string }) => void): Unsubscribe =>
|
|
on(IPC_CHANNELS.LLM.PREMIUM_FALLBACK, cb),
|
|
onQuotaWarning: (
|
|
cb: (e: { current: number; limit: number; overageCredits: number }) => void
|
|
): Unsubscribe => on(IPC_CHANNELS.LLM.PREMIUM_QUOTA_WARNING, cb),
|
|
onUpgradeRequired: (
|
|
cb: (e: { reason: 'quota_exceeded' | 'model_not_allowed' | 'auth_required' }) => void
|
|
): Unsubscribe => on(IPC_CHANNELS.LLM.PREMIUM_UPGRADE_REQUIRED, cb),
|
|
},
|
|
},
|
|
|
|
// ── History ────────────────────────────────────────────
|
|
history: {
|
|
getAll: (params: HistoryQueryParams) =>
|
|
invoke<HistoryPage>(IPC_CHANNELS.HISTORY.GET_ALL, params),
|
|
getById: (params: HistoryGetByIdParams) =>
|
|
invoke<HistoryEntry | null>(IPC_CHANNELS.HISTORY.GET_BY_ID, params),
|
|
delete: (params: HistoryDeleteParams) =>
|
|
invoke<void>(IPC_CHANNELS.HISTORY.DELETE, params),
|
|
deleteAll: () => invoke<void>(IPC_CHANNELS.HISTORY.DELETE_ALL),
|
|
search: (params: HistorySearchParams) =>
|
|
invoke<HistoryPage>(IPC_CHANNELS.HISTORY.SEARCH, params),
|
|
onAdded: (cb: (e: HistoryEntry) => void): Unsubscribe =>
|
|
on(IPC_CHANNELS.HISTORY.ADDED, cb)
|
|
},
|
|
|
|
// ── Dictionary ─────────────────────────────────────────
|
|
dictionary: {
|
|
getAll: (params: DictionaryQueryParams) =>
|
|
invoke<DictionaryPage>(IPC_CHANNELS.DICTIONARY.GET_ALL, params),
|
|
add: (params: DictionaryAddParams) =>
|
|
invoke<DictionaryEntry>(IPC_CHANNELS.DICTIONARY.ADD, params),
|
|
update: (params: DictionaryUpdateParams) =>
|
|
invoke<DictionaryEntry>(IPC_CHANNELS.DICTIONARY.UPDATE, params),
|
|
delete: (params: DictionaryDeleteParams) =>
|
|
invoke<void>(IPC_CHANNELS.DICTIONARY.DELETE, params),
|
|
search: (params: DictionarySearchParams) =>
|
|
invoke<DictionaryPage>(IPC_CHANNELS.DICTIONARY.SEARCH, params),
|
|
import: (params: DictionaryImportParams) =>
|
|
invoke<DictionaryImportResult>(IPC_CHANNELS.DICTIONARY.IMPORT, params),
|
|
export: (params: DictionaryExportParams) =>
|
|
invoke<string>(IPC_CHANNELS.DICTIONARY.EXPORT, params)
|
|
},
|
|
|
|
// ── Stats ──────────────────────────────────────────────
|
|
stats: {
|
|
getSummary: () => invoke<StatsSummary>(IPC_CHANNELS.STATS.GET_SUMMARY)
|
|
},
|
|
|
|
// ── Window ─────────────────────────────────────────────
|
|
window: {
|
|
minimize: () => send(IPC_CHANNELS.WINDOW.MINIMIZE),
|
|
maximize: () => send(IPC_CHANNELS.WINDOW.MAXIMIZE),
|
|
close: () => send(IPC_CHANNELS.WINDOW.CLOSE),
|
|
isMaximized: () => invoke<boolean>(IPC_CHANNELS.WINDOW.IS_MAXIMIZED)
|
|
},
|
|
|
|
// ── System ─────────────────────────────────────────────
|
|
system: {
|
|
getPlatform: () => invoke<NodeJS.Platform>(IPC_CHANNELS.SYSTEM.GET_PLATFORM),
|
|
getVersion: () => invoke<string>(IPC_CHANNELS.SYSTEM.GET_VERSION),
|
|
checkMicPermission: () =>
|
|
invoke<PermissionStatus>(IPC_CHANNELS.SYSTEM.CHECK_MIC_PERMISSION),
|
|
openExternal: (params: { url: string }) =>
|
|
invoke<void>(IPC_CHANNELS.SYSTEM.OPEN_EXTERNAL, params),
|
|
},
|
|
|
|
// ── Instruction (커스텀 명령어) ────────────────────────
|
|
instruction: {
|
|
getAll: () => invoke<unknown[]>('instruction:getAll'),
|
|
getById: (params: { id: string }) => invoke<unknown>('instruction:getById', params),
|
|
create: (params: { name: string; description: string; prompt: string }) =>
|
|
invoke<unknown>('instruction:create', params),
|
|
update: (params: { id: string; name?: string; description?: string; prompt?: string }) =>
|
|
invoke<unknown>('instruction:update', params),
|
|
delete: (params: { id: string }) => invoke<void>('instruction:delete', params),
|
|
reorder: (params: { ids: string[] }) => invoke<void>('instruction:reorder', params),
|
|
},
|
|
|
|
// ── App 이벤트 (실시간 UI 갱신) ────────────────────────
|
|
app: {
|
|
onDataChanged: (cb: (data: { type: string; activeId?: string }) => void): Unsubscribe =>
|
|
on('app:dataChanged', cb),
|
|
},
|
|
|
|
// ── Phase 10: Memo Tags ─────────────────────────────────
|
|
memo: {
|
|
getTags: (params: GetTagsParams) => invoke<MemoTag[]>(IPC_CHANNELS.MEMO.GET_TAGS, params),
|
|
addTag: (params: AddTagParams) => invoke<MemoTag>(IPC_CHANNELS.MEMO.ADD_TAG, params),
|
|
removeTag: (params: RemoveTagParams) => invoke<void>(IPC_CHANNELS.MEMO.REMOVE_TAG, params),
|
|
getAllTags: () => invoke<TagCount[]>(IPC_CHANNELS.MEMO.GET_ALL_TAGS),
|
|
searchByTag: (params: SearchByTagParams) => invoke<HistoryPage>(IPC_CHANNELS.MEMO.SEARCH_BY_TAG, params),
|
|
export: (params: ExportMemoParams) => invoke<string>(IPC_CHANNELS.MEMO.EXPORT, params),
|
|
},
|
|
|
|
// ── Phase 10: Voice Commands ────────────────────────────
|
|
voiceCommand: {
|
|
getAll: () => invoke<VoiceCommandRule[]>(IPC_CHANNELS.VOICE_COMMAND.GET_ALL),
|
|
setKeywords: (params: SetVoiceCommandKeywordsParams) => invoke<void>(IPC_CHANNELS.VOICE_COMMAND.SET_KEYWORDS, params),
|
|
setEnabled: (params: SetVoiceCommandEnabledParams) => invoke<void>(IPC_CHANNELS.VOICE_COMMAND.SET_ENABLED, params),
|
|
isEnabled: () => invoke<boolean>(IPC_CHANNELS.VOICE_COMMAND.IS_ENABLED),
|
|
onMatched: (cb: (data: VoiceCommandMatch) => void): Unsubscribe =>
|
|
on(IPC_CHANNELS.VOICE_COMMAND.MATCHED, cb),
|
|
},
|
|
|
|
// ── Phase 10: Screen Context ────────────────────────────
|
|
context: {
|
|
capture: (captureSelectedText?: boolean) => invoke<CaptureContextResult>(IPC_CHANNELS.CONTEXT.CAPTURE, { captureSelectedText }),
|
|
isEnabled: () => invoke<boolean>(IPC_CHANNELS.CONTEXT.IS_ENABLED),
|
|
setEnabled: (params: { enabled: boolean }) => invoke<void>(IPC_CHANNELS.CONTEXT.SET_ENABLED, params),
|
|
},
|
|
|
|
// ── Phase 10: LLM Chain ─────────────────────────────────
|
|
chain: {
|
|
getAll: () => invoke<LLMChain[]>(IPC_CHANNELS.CHAIN.GET_ALL),
|
|
create: (params: CreateChainParams) => invoke<LLMChain>(IPC_CHANNELS.CHAIN.CREATE, params),
|
|
update: (params: UpdateChainParams) => invoke<LLMChain>(IPC_CHANNELS.CHAIN.UPDATE, params),
|
|
delete: (params: DeleteChainParams) => invoke<void>(IPC_CHANNELS.CHAIN.DELETE, params),
|
|
execute: (params: ExecuteChainParams) => invoke<ChainExecutionResult>(IPC_CHANNELS.CHAIN.EXECUTE, params),
|
|
onProgress: (cb: (data: ChainProgress) => void): Unsubscribe =>
|
|
on(IPC_CHANNELS.CHAIN.PROGRESS, cb),
|
|
},
|
|
|
|
// ── Phase 10: Live Caption ──────────────────────────────
|
|
caption: {
|
|
start: () => invoke<void>(IPC_CHANNELS.CAPTION.START),
|
|
stop: () => invoke<void>(IPC_CHANNELS.CAPTION.STOP),
|
|
getState: () => invoke<CaptionState>(IPC_CHANNELS.CAPTION.GET_STATE),
|
|
setConfig: (params: Partial<CaptionConfig>) => invoke<void>(IPC_CHANNELS.CAPTION.SET_CONFIG, params),
|
|
getConfig: () => invoke<CaptionConfig>(IPC_CHANNELS.CAPTION.GET_CONFIG),
|
|
onSegment: (cb: (data: CaptionSegment) => void): Unsubscribe =>
|
|
on(IPC_CHANNELS.CAPTION.SEGMENT, cb),
|
|
onDelta: (cb: (data: { text: string }) => void): Unsubscribe =>
|
|
on(IPC_CHANNELS.CAPTION.DELTA, cb),
|
|
onStateChanged: (cb: (data: { state: CaptionState }) => void): Unsubscribe =>
|
|
on(IPC_CHANNELS.CAPTION.STATE_CHANGED, cb),
|
|
/** 시스템 오디오 PCM 데이터를 메인에 전달 (렌더러 → 메인) */
|
|
sendSystemAudioData: (data: ArrayBuffer) =>
|
|
send(IPC_CHANNELS.CAPTION.SYSTEM_AUDIO_DATA, data),
|
|
/** 메인에서 시스템 오디오 캡처 시작 요청 수신 */
|
|
onStartSystemAudio: (cb: () => void): Unsubscribe =>
|
|
on(IPC_CHANNELS.CAPTION.START_SYSTEM_AUDIO, cb),
|
|
/** 메인에서 시스템 오디오 캡처 중지 요청 수신 */
|
|
onStopSystemAudio: (cb: () => void): Unsubscribe =>
|
|
on(IPC_CHANNELS.CAPTION.STOP_SYSTEM_AUDIO, cb),
|
|
/** 시스템 오디오 루프백 활성화 (getDisplayMedia 전에 호출) */
|
|
enableLoopback: () => invoke<void>('system-audio:enable-loopback'),
|
|
/** 시스템 오디오 루프백 비활성화 */
|
|
disableLoopback: () => invoke<void>('system-audio:disable-loopback'),
|
|
},
|
|
|
|
// ── License (Phase 11) ────────────────────────────────
|
|
license: {
|
|
getInfo: () =>
|
|
invoke<LicenseInfo>(IPC_CHANNELS.LICENSE.GET_INFO),
|
|
activate: (params: ActivateLicenseParams) =>
|
|
invoke<ActivateLicenseResult>(IPC_CHANNELS.LICENSE.ACTIVATE, params),
|
|
deactivate: () =>
|
|
invoke<void>(IPC_CHANNELS.LICENSE.DEACTIVATE),
|
|
checkFeature: (feature: Feature) =>
|
|
invoke<FeatureAccess>(IPC_CHANNELS.LICENSE.CHECK_FEATURE, { feature }),
|
|
getUsage: (feature: Feature) =>
|
|
invoke<UsageQuota>(IPC_CHANNELS.LICENSE.GET_USAGE, { feature }),
|
|
getAllUsage: () =>
|
|
invoke<UsageQuota[]>(IPC_CHANNELS.LICENSE.GET_ALL_USAGE),
|
|
getTierComparison: () =>
|
|
invoke<TierComparison[]>(IPC_CHANNELS.LICENSE.GET_TIER_COMPARISON),
|
|
openBilling: (params: { tier: 'pro' | 'pro_plus' }) =>
|
|
invoke<void>(IPC_CHANNELS.LICENSE.OPEN_BILLING, params),
|
|
onUpgradePrompt: (cb: (e: UpgradePromptEvent) => void): Unsubscribe =>
|
|
on(IPC_CHANNELS.LICENSE.UPGRADE_PROMPT, cb),
|
|
onTierChanged: (cb: (e: LicenseInfo) => void): Unsubscribe =>
|
|
on(IPC_CHANNELS.LICENSE.TIER_CHANGED, cb),
|
|
},
|
|
// ── File Transcription (Phase 12.1) ────────────────────
|
|
fileTranscription: {
|
|
start: (params: FileTranscriptionStartParams) =>
|
|
invoke<FileTranscriptionResult>(IPC_CHANNELS.FILE_TRANSCRIPTION.START, params),
|
|
cancel: () =>
|
|
invoke<void>(IPC_CHANNELS.FILE_TRANSCRIPTION.CANCEL),
|
|
getState: () =>
|
|
invoke<FileTranscriptionStateInfo>(IPC_CHANNELS.FILE_TRANSCRIPTION.GET_STATE),
|
|
onProgress: (cb: (data: FileTranscriptionProgress) => void): Unsubscribe =>
|
|
on(IPC_CHANNELS.FILE_TRANSCRIPTION.PROGRESS, cb),
|
|
onComplete: (cb: (data: FileTranscriptionResult) => void): Unsubscribe =>
|
|
on(IPC_CHANNELS.FILE_TRANSCRIPTION.COMPLETE, cb),
|
|
onError: (cb: (data: { message: string }) => void): Unsubscribe =>
|
|
on(IPC_CHANNELS.FILE_TRANSCRIPTION.ERROR, cb),
|
|
},
|
|
|
|
// ── Meeting Summary (Phase 12.2) ─────────────────────
|
|
meetingSummary: {
|
|
summarize: (params: MeetingSummarizeParams) =>
|
|
invoke<MeetingSummaryResult>(IPC_CHANNELS.MEETING_SUMMARY.SUMMARIZE, params),
|
|
getSummary: (params: MeetingSummaryGetParams) =>
|
|
invoke<MeetingSummaryResult | null>(IPC_CHANNELS.MEETING_SUMMARY.GET_SUMMARY, params),
|
|
exportMarkdown: (params: MeetingSummaryExportParams) =>
|
|
invoke<string>(IPC_CHANNELS.MEETING_SUMMARY.EXPORT_MARKDOWN, params),
|
|
onSummaryReady: (cb: (data: MeetingSummaryResult) => void): Unsubscribe =>
|
|
on(IPC_CHANNELS.MEETING_SUMMARY.SUMMARY_READY, cb),
|
|
onProgress: (cb: (data: MeetingSummaryProgress) => void): Unsubscribe =>
|
|
on(IPC_CHANNELS.MEETING_SUMMARY.SUMMARY_PROGRESS, cb),
|
|
},
|
|
|
|
// ── Dictation Templates (Phase 12.3) ─────────────────
|
|
dictationTemplate: {
|
|
getAll: () =>
|
|
invoke<DictationTemplate[]>(IPC_CHANNELS.DICTATION_TEMPLATE.GET_ALL),
|
|
create: (params: CreateTemplateParams) =>
|
|
invoke<DictationTemplate>(IPC_CHANNELS.DICTATION_TEMPLATE.CREATE, params),
|
|
update: (params: UpdateTemplateParams) =>
|
|
invoke<DictationTemplate>(IPC_CHANNELS.DICTATION_TEMPLATE.UPDATE, params),
|
|
delete: (params: DeleteTemplateParams) =>
|
|
invoke<void>(IPC_CHANNELS.DICTATION_TEMPLATE.DELETE, params),
|
|
startSession: (params: StartTemplateSessionParams) =>
|
|
invoke<void>(IPC_CHANNELS.DICTATION_TEMPLATE.START_SESSION, params),
|
|
cancelSession: () =>
|
|
invoke<void>(IPC_CHANNELS.DICTATION_TEMPLATE.CANCEL_SESSION),
|
|
getSessionState: () =>
|
|
invoke<TemplateSessionInfo | null>(IPC_CHANNELS.DICTATION_TEMPLATE.GET_SESSION_STATE),
|
|
setFieldValue: (params: SetFieldValueParams) =>
|
|
invoke<void>(IPC_CHANNELS.DICTATION_TEMPLATE.SET_FIELD_VALUE, params),
|
|
onSessionStateChanged: (cb: (data: TemplateSessionInfo) => void): Unsubscribe =>
|
|
on(IPC_CHANNELS.DICTATION_TEMPLATE.SESSION_STATE_CHANGED, cb),
|
|
onFieldCompleted: (cb: (data: TemplateFieldCompletedEvent) => void): Unsubscribe =>
|
|
on(IPC_CHANNELS.DICTATION_TEMPLATE.FIELD_COMPLETED, cb),
|
|
onSessionCompleted: (cb: (data: TemplateSessionCompletedEvent) => void): Unsubscribe =>
|
|
on(IPC_CHANNELS.DICTATION_TEMPLATE.SESSION_COMPLETED, cb),
|
|
},
|
|
// ── RAG (Phase 13.2) ──────────────────────────────────
|
|
rag: {
|
|
addDocument: (params?: RAGAddDocumentParams) =>
|
|
invoke<RAGDocument>(IPC_CHANNELS.RAG.ADD_DOCUMENT, params ?? {}),
|
|
removeDocument: (params: RAGRemoveDocumentParams) =>
|
|
invoke<void>(IPC_CHANNELS.RAG.REMOVE_DOCUMENT, params),
|
|
getDocuments: () =>
|
|
invoke<RAGDocument[]>(IPC_CHANNELS.RAG.GET_DOCUMENTS),
|
|
query: (params: RAGQueryParams) =>
|
|
invoke<RAGQueryResult>(IPC_CHANNELS.RAG.QUERY, params),
|
|
getState: () =>
|
|
invoke<RAGStateInfo>(IPC_CHANNELS.RAG.GET_STATE),
|
|
reindex: (documentId: string) =>
|
|
invoke<void>(IPC_CHANNELS.RAG.REINDEX, { documentId }),
|
|
onIndexProgress: (cb: (data: RAGIndexProgress) => void): Unsubscribe =>
|
|
on(IPC_CHANNELS.RAG.INDEX_PROGRESS, cb),
|
|
onIndexComplete: (cb: (data: { documentId: string; fileName: string }) => void): Unsubscribe =>
|
|
on(IPC_CHANNELS.RAG.INDEX_COMPLETE, cb),
|
|
},
|
|
|
|
// ── Voice Action (Phase 13.3) ────────────────────────
|
|
voiceAction: {
|
|
execute: (params: VoiceActionExecuteParams) =>
|
|
invoke<void>(IPC_CHANNELS.VOICE_ACTION.EXECUTE, params),
|
|
getPresets: () =>
|
|
invoke<VoiceActionPreset[]>(IPC_CHANNELS.VOICE_ACTION.GET_PRESETS),
|
|
getHistory: () =>
|
|
invoke<VoiceActionHistoryEntry[]>(IPC_CHANNELS.VOICE_ACTION.GET_HISTORY),
|
|
clearHistory: () =>
|
|
invoke<void>(IPC_CHANNELS.VOICE_ACTION.CLEAR_HISTORY),
|
|
setEnabled: (enabled: boolean) =>
|
|
invoke<void>(IPC_CHANNELS.VOICE_ACTION.SET_ENABLED, { enabled }),
|
|
isEnabled: () =>
|
|
invoke<boolean>(IPC_CHANNELS.VOICE_ACTION.IS_ENABLED),
|
|
onActionPlanned: (cb: (data: VoiceActionPlannedEvent) => void): Unsubscribe =>
|
|
on(IPC_CHANNELS.VOICE_ACTION.ACTION_PLANNED, cb),
|
|
onActionExecuted: (cb: (data: VoiceActionExecutedEvent) => void): Unsubscribe =>
|
|
on(IPC_CHANNELS.VOICE_ACTION.ACTION_EXECUTED, cb),
|
|
onActionError: (cb: (data: VoiceActionErrorEvent) => void): Unsubscribe =>
|
|
on(IPC_CHANNELS.VOICE_ACTION.ACTION_ERROR, cb),
|
|
},
|
|
|
|
// ── Voice Conversation (Phase 13.1) ───────────────────
|
|
voiceConversation: {
|
|
startSession: () =>
|
|
invoke<void>(IPC_CHANNELS.VOICE_CONVERSATION.START_SESSION),
|
|
stopSession: () =>
|
|
invoke<void>(IPC_CHANNELS.VOICE_CONVERSATION.STOP_SESSION),
|
|
sendMessage: (params: ConversationSendParams) =>
|
|
invoke<void>(IPC_CHANNELS.VOICE_CONVERSATION.SEND_MESSAGE, params),
|
|
getState: () =>
|
|
invoke<ConversationSessionInfo>(IPC_CHANNELS.VOICE_CONVERSATION.GET_STATE),
|
|
getHistory: () =>
|
|
invoke<ConversationMessage[]>(IPC_CHANNELS.VOICE_CONVERSATION.GET_HISTORY),
|
|
clearHistory: () =>
|
|
invoke<void>(IPC_CHANNELS.VOICE_CONVERSATION.CLEAR_HISTORY),
|
|
cancelResponse: () =>
|
|
invoke<void>(IPC_CHANNELS.VOICE_CONVERSATION.CANCEL_RESPONSE),
|
|
getRealtimeToken: (params: RealtimeTokenParams) =>
|
|
invoke<RealtimeTokenResult>(
|
|
IPC_CHANNELS.VOICE_CONVERSATION.GET_REALTIME_TOKEN,
|
|
params
|
|
),
|
|
finishListening: () =>
|
|
invoke<void>('voiceConversation:finishListening'),
|
|
onStateChanged: (cb: (data: ConversationSessionInfo) => void): Unsubscribe =>
|
|
on(IPC_CHANNELS.VOICE_CONVERSATION.STATE_CHANGED, cb),
|
|
onUserMessage: (cb: (data: ConversationMessage) => void): Unsubscribe =>
|
|
on(IPC_CHANNELS.VOICE_CONVERSATION.USER_MESSAGE, cb),
|
|
onAssistantDelta: (cb: (data: ConversationAssistantDelta) => void): Unsubscribe =>
|
|
on(IPC_CHANNELS.VOICE_CONVERSATION.ASSISTANT_DELTA, cb),
|
|
onAssistantMessage: (cb: (data: ConversationAssistantMessage) => void): Unsubscribe =>
|
|
on(IPC_CHANNELS.VOICE_CONVERSATION.ASSISTANT_MESSAGE, cb),
|
|
onTTSStarted: (cb: () => void): Unsubscribe =>
|
|
on(IPC_CHANNELS.VOICE_CONVERSATION.TTS_STARTED, cb),
|
|
onTTSFinished: (cb: () => void): Unsubscribe =>
|
|
on(IPC_CHANNELS.VOICE_CONVERSATION.TTS_FINISHED, cb),
|
|
onError: (cb: (data: ConversationError) => void): Unsubscribe =>
|
|
on(IPC_CHANNELS.VOICE_CONVERSATION.ERROR, cb),
|
|
onAudioLevel: (cb: (e: { level: number }) => void): Unsubscribe =>
|
|
on(IPC_CHANNELS.VOICE_CONVERSATION.AUDIO_LEVEL, cb),
|
|
},
|
|
|
|
// ── Meeting Mode (Phase 14) ───────────────────────────
|
|
meetingMode: {
|
|
startRecording: (params?: { force?: boolean }) =>
|
|
invoke<MeetingStartResult>(IPC_CHANNELS.MEETING_MODE.START_RECORDING, params),
|
|
forceReset: () =>
|
|
invoke<void>('meetingMode:forceReset'),
|
|
stopRecording: () =>
|
|
invoke<void>(IPC_CHANNELS.MEETING_MODE.STOP_RECORDING),
|
|
addMemo: (params: MeetingAddMemoParams) =>
|
|
invoke<MeetingMemo>(IPC_CHANNELS.MEETING_MODE.ADD_MEMO, params),
|
|
getState: () =>
|
|
invoke<MeetingModeStateInfo>(IPC_CHANNELS.MEETING_MODE.GET_STATE),
|
|
getSessions: (params: MeetingGetSessionsParams) =>
|
|
invoke<MeetingSessionPage>(IPC_CHANNELS.MEETING_MODE.GET_SESSIONS, params),
|
|
getSession: (params: MeetingGetSessionParams) =>
|
|
invoke<MeetingSessionDetail>(IPC_CHANNELS.MEETING_MODE.GET_SESSION, params),
|
|
deleteSession: (params: MeetingDeleteSessionParams) =>
|
|
invoke<void>(IPC_CHANNELS.MEETING_MODE.DELETE_SESSION, params),
|
|
updateTitle: (params: { sessionId: string; title: string }) =>
|
|
invoke<void>(IPC_CHANNELS.MEETING_MODE.UPDATE_TITLE, params),
|
|
exportPdf: (params: MeetingExportParams) =>
|
|
invoke<string>(IPC_CHANNELS.MEETING_MODE.EXPORT_PDF, params),
|
|
exportMarkdown: (params: MeetingExportParams) =>
|
|
invoke<string>(IPC_CHANNELS.MEETING_MODE.EXPORT_MARKDOWN, params),
|
|
onStateChanged: (cb: (e: MeetingModeStateInfo) => void): Unsubscribe =>
|
|
on(IPC_CHANNELS.MEETING_MODE.STATE_CHANGED, cb),
|
|
onSegment: (cb: (e: CaptionSegment) => void): Unsubscribe =>
|
|
on(IPC_CHANNELS.MEETING_MODE.SEGMENT, cb),
|
|
onProcessingProgress: (cb: (e: MeetingProcessingProgress) => void): Unsubscribe =>
|
|
on(IPC_CHANNELS.MEETING_MODE.PROCESSING_PROGRESS, cb),
|
|
onSessionCompleted: (cb: (e: MeetingSessionDetail) => void): Unsubscribe =>
|
|
on(IPC_CHANNELS.MEETING_MODE.SESSION_COMPLETED, cb),
|
|
onError: (cb: (e: { code: number; message: string }) => void): Unsubscribe =>
|
|
on(IPC_CHANNELS.MEETING_MODE.ERROR, cb),
|
|
onAudioLevel: (cb: (e: { level: number }) => void): Unsubscribe =>
|
|
on('meetingMode:audioLevel', cb),
|
|
// Phase 14.5
|
|
updateTranscript: (params: MeetingUpdateTranscriptParams) =>
|
|
invoke<void>(IPC_CHANNELS.MEETING_MODE.UPDATE_TRANSCRIPT, params),
|
|
generateDocument: (params: MeetingGenerateDocParams) =>
|
|
invoke<MeetingDocument>(IPC_CHANNELS.MEETING_MODE.GENERATE_DOCUMENT, params),
|
|
getDocuments: (params: MeetingGetDocsParams) =>
|
|
invoke<MeetingDocument[]>(IPC_CHANNELS.MEETING_MODE.GET_DOCUMENTS, params),
|
|
updateDocument: (params: MeetingUpdateDocParams) =>
|
|
invoke<void>(IPC_CHANNELS.MEETING_MODE.UPDATE_DOCUMENT, params),
|
|
deleteDocument: (params: MeetingDeleteDocParams) =>
|
|
invoke<void>(IPC_CHANNELS.MEETING_MODE.DELETE_DOCUMENT, params),
|
|
exportDocument: (params: MeetingExportDocParams) =>
|
|
invoke<string>(IPC_CHANNELS.MEETING_MODE.EXPORT_DOCUMENT, params),
|
|
exportTranscript: (params: MeetingExportTranscriptParams) =>
|
|
invoke<string>(IPC_CHANNELS.MEETING_MODE.EXPORT_TRANSCRIPT, params),
|
|
editSegment: (params: { sessionId: string; segmentId: string; text: string }) =>
|
|
invoke<void>(IPC_CHANNELS.MEETING_MODE.EDIT_SEGMENT, params),
|
|
onDocGeneratingProgress: (cb: (e: MeetingDocGeneratingProgress) => void): Unsubscribe =>
|
|
on(IPC_CHANNELS.MEETING_MODE.DOC_GENERATING_PROGRESS, cb),
|
|
// Phase 15
|
|
polishTranscript: (params: { sessionId: string }) =>
|
|
invoke<string>(IPC_CHANNELS.MEETING_MODE.POLISH_TRANSCRIPT, params),
|
|
// Phase 15.5
|
|
diarize: (params: DiarizeSessionParams) =>
|
|
invoke<void>(IPC_CHANNELS.MEETING_MODE.DIARIZE, params),
|
|
onDiarizationProgress: (cb: (e: { sessionId: string; percent: number }) => void): Unsubscribe =>
|
|
on(IPC_CHANNELS.MEETING_MODE.DIARIZATION_PROGRESS, cb),
|
|
},
|
|
|
|
// ── Meeting Chat (Phase 15) ───────────────────────────
|
|
meetingChat: {
|
|
send: (params: MeetingChatSendParams) =>
|
|
invoke<void>(IPC_CHANNELS.MEETING_CHAT.SEND, params),
|
|
cancel: () =>
|
|
invoke<void>(IPC_CHANNELS.MEETING_CHAT.CANCEL),
|
|
clear: () =>
|
|
invoke<void>(IPC_CHANNELS.MEETING_CHAT.CLEAR),
|
|
onDelta: (cb: (e: MeetingChatDelta) => void): Unsubscribe =>
|
|
on(IPC_CHANNELS.MEETING_CHAT.DELTA, cb),
|
|
onMessage: (cb: (e: MeetingChatMessage) => void): Unsubscribe =>
|
|
on(IPC_CHANNELS.MEETING_CHAT.MESSAGE, cb),
|
|
onError: (cb: (e: { message: string }) => void): Unsubscribe =>
|
|
on(IPC_CHANNELS.MEETING_CHAT.ERROR, cb),
|
|
},
|
|
|
|
// ── Meeting Doc Templates (Phase 14.5) ───────────────
|
|
meetingDocTemplate: {
|
|
getAll: () =>
|
|
invoke<MeetingDocTemplate[]>(IPC_CHANNELS.MEETING_DOC_TEMPLATE.GET_ALL),
|
|
create: (params: CreateMeetingDocTemplateParams) =>
|
|
invoke<MeetingDocTemplate>(IPC_CHANNELS.MEETING_DOC_TEMPLATE.CREATE, params),
|
|
update: (params: UpdateMeetingDocTemplateParams) =>
|
|
invoke<MeetingDocTemplate>(IPC_CHANNELS.MEETING_DOC_TEMPLATE.UPDATE, params),
|
|
delete: (params: DeleteMeetingDocTemplateParams) =>
|
|
invoke<void>(IPC_CHANNELS.MEETING_DOC_TEMPLATE.DELETE, params),
|
|
},
|
|
|
|
cloudSync: {
|
|
getState: () =>
|
|
invoke<{
|
|
authenticated: boolean
|
|
userEmail: string | null
|
|
lastSyncAt: number | null
|
|
syncing: boolean
|
|
}>(IPC_CHANNELS.CLOUD_SYNC.GET_STATE),
|
|
signIn: (params: { provider: 'google' | 'github' }) =>
|
|
invoke<{ started: boolean }>(IPC_CHANNELS.CLOUD_SYNC.SIGN_IN, params),
|
|
signOut: () => invoke<unknown>(IPC_CHANNELS.CLOUD_SYNC.SIGN_OUT),
|
|
pushAll: () =>
|
|
invoke<{ pushed: number; errors: string[] }>(IPC_CHANNELS.CLOUD_SYNC.PUSH_ALL),
|
|
pullAll: () =>
|
|
invoke<{ pushed: number; errors: string[] }>(IPC_CHANNELS.CLOUD_SYNC.PULL_ALL),
|
|
onAuthChanged: (callback: (data: { user: { id: string; email: string | null } | null }) => void) =>
|
|
on<{ user: { id: string; email: string | null } | null }>(
|
|
IPC_CHANNELS.CLOUD_SYNC.AUTH_CHANGED,
|
|
callback
|
|
),
|
|
onSyncProgress: (callback: (data: { current: number; total: number; table: string }) => void) =>
|
|
on<{ current: number; total: number; table: string }>(
|
|
IPC_CHANNELS.CLOUD_SYNC.SYNC_PROGRESS,
|
|
callback
|
|
),
|
|
onSyncComplete: (callback: (data: { pushed: number; errors: string[] }) => void) =>
|
|
on<{ pushed: number; errors: string[] }>(IPC_CHANNELS.CLOUD_SYNC.SYNC_COMPLETE, callback),
|
|
onSyncError: (callback: (data: { error: string }) => void) =>
|
|
on<{ error: string }>(IPC_CHANNELS.CLOUD_SYNC.SYNC_ERROR, callback),
|
|
},
|
|
// ── Online Auth ────────────────────────────────────────
|
|
onlineAuth: {
|
|
register: (params: { email: string; password: string }) =>
|
|
invoke<unknown>(IPC_CHANNELS.ONLINE_AUTH.REGISTER, params),
|
|
login: (params: { email: string; password: string }) =>
|
|
invoke<unknown>(IPC_CHANNELS.ONLINE_AUTH.LOGIN, params),
|
|
logout: () => invoke<void>(IPC_CHANNELS.ONLINE_AUTH.LOGOUT),
|
|
getUser: () =>
|
|
invoke<{ email: string | null; isAuthenticated: boolean; mode: 'online' | 'local' | null }>(
|
|
IPC_CHANNELS.ONLINE_AUTH.GET_USER
|
|
)
|
|
},
|
|
// ── Ad Monetization & Mediation ────────────────────────
|
|
ads: {
|
|
getConfig: () => invoke<import('@d3ro/core/types').AdMediationConfig>(IPC_CHANNELS.ADS.GET_CONFIG),
|
|
setConfig: (config: Partial<import('@d3ro/core/types').AdMediationConfig>) =>
|
|
invoke<import('@d3ro/core/types').AdMediationConfig>(IPC_CHANNELS.ADS.SET_CONFIG, config),
|
|
requestAuction: (request: import('@d3ro/core/types').AdMediationAuctionRequest) =>
|
|
invoke<import('@d3ro/core/types').AdMediationAuctionResult>(IPC_CHANNELS.ADS.REQUEST_AUCTION, request),
|
|
recordImpression: (event: Omit<import('@d3ro/core/types').AdImpressionEvent, 'timestamp'>) =>
|
|
invoke<boolean>(IPC_CHANNELS.ADS.RECORD_IMPRESSION, event),
|
|
recordClick: (params: { adId: string; networkId: string }) =>
|
|
invoke<boolean>(IPC_CHANNELS.ADS.RECORD_CLICK, params),
|
|
claimReward: (params: { adId: string; networkId: string }) =>
|
|
invoke<import('@d3ro/core/types').AdRewardResult>(IPC_CHANNELS.ADS.CLAIM_REWARD, params),
|
|
getRevenueStats: (params?: { period?: string }) =>
|
|
invoke<import('@d3ro/core/types').AdRevenueStats>(IPC_CHANNELS.ADS.GET_REVENUE_STATS, params),
|
|
getSettlements: () =>
|
|
invoke<import('@d3ro/core/types').AdSettlementRecord[]>(IPC_CHANNELS.ADS.GET_SETTLEMENTS),
|
|
requestPayout: (params: { settlementId: string }) =>
|
|
invoke<{ success: boolean; message: string; settlement?: import('@d3ro/core/types').AdSettlementRecord }>(
|
|
IPC_CHANNELS.ADS.REQUEST_PAYOUT,
|
|
params
|
|
),
|
|
getPublisherAccount: () =>
|
|
invoke<import('@d3ro/core/types').PublisherAccountConfig>(IPC_CHANNELS.ADS.GET_PUBLISHER_ACCOUNT),
|
|
setPublisherAccount: (account: Partial<import('@d3ro/core/types').PublisherAccountConfig>) =>
|
|
invoke<import('@d3ro/core/types').PublisherAccountConfig>(IPC_CHANNELS.ADS.SET_PUBLISHER_ACCOUNT, account),
|
|
},
|
|
// ── Customer Assistance (CA/CS) & Diagnostics ──────────
|
|
support: {
|
|
getDiagnostics: () =>
|
|
invoke<import('@d3ro/core/types').SystemDiagnosticsPayload>(IPC_CHANNELS.SUPPORT.GET_DIAGNOSTICS),
|
|
queryAI: (params: import('@d3ro/core/types').AIAssistQuery) =>
|
|
invoke<import('@d3ro/core/types').AIAssistResponse>(IPC_CHANNELS.SUPPORT.QUERY_AI, params),
|
|
createTicket: (params: Partial<import('@d3ro/core/types').SupportTicket>) =>
|
|
invoke<import('@d3ro/core/types').SupportTicket>(IPC_CHANNELS.SUPPORT.CREATE_TICKET, params),
|
|
checkRefund: () =>
|
|
invoke<import('@d3ro/core/types').RefundEligibilityResult>(IPC_CHANNELS.SUPPORT.CHECK_REFUND),
|
|
},
|
|
// ── Multi-PG Payment & Billing ─────────────────────────
|
|
payment: {
|
|
createCheckoutSession: (params: import('@d3ro/core/types').CheckoutSessionParams) =>
|
|
invoke<import('@d3ro/core/types').CheckoutSessionResult>(IPC_CHANNELS.PAYMENT.CREATE_CHECKOUT_SESSION, params),
|
|
verifyPayment: () =>
|
|
invoke<import('@d3ro/core/types').VerifyPaymentResult>(IPC_CHANNELS.PAYMENT.VERIFY_PAYMENT),
|
|
getSubscriptionStatus: () =>
|
|
invoke<import('@d3ro/core/types').SubscriptionStatusResult>(IPC_CHANNELS.PAYMENT.GET_SUBSCRIPTION_STATUS),
|
|
},
|
|
} as const
|
|
|
|
contextBridge.exposeInMainWorld('electronAPI', electronAPI)
|
|
|
|
export type ElectronAPI = typeof electronAPI
|