Several desktop paths quietly substituted defaults or partial results: a config write could fall back to a throwaway in-memory store, speech provider errors were absorbed into empty transcriptions, and meeting exports built file names from raw titles. Writes now fail explicitly when the store is unavailable, provider and model failures reach the UI as errors, and export names pass through one sanitizer. Settings, license, ad, and support surfaces use the shared theme tokens, unused hotkey helpers are gone, and the package gains strict node/renderer typecheck configs plus red-team e2e scenarios for these flows.
68 lines
2.5 KiB
TypeScript
68 lines
2.5 KiB
TypeScript
// src/main/ipc/instruction-handlers.ts
|
|
|
|
import { ipcMain } from 'electron'
|
|
import { IPC_CHANNELS } from '@d3ro/core/ipc-channels'
|
|
import { ipcSuccess, ipcError, ErrorCode } from '@d3ro/core/errors'
|
|
import { getCustomInstructionService } from '../services/CustomInstructionService'
|
|
import type { CustomInstruction } from '@d3ro/core/types'
|
|
|
|
export function registerInstructionHandlers(): void {
|
|
ipcMain.handle(IPC_CHANNELS.INSTRUCTION.GET_ALL, async () => {
|
|
return ipcSuccess(getCustomInstructionService().getAll())
|
|
})
|
|
|
|
ipcMain.handle(IPC_CHANNELS.INSTRUCTION.GET_BY_ID, async (_event, params: { id: string }) => {
|
|
return ipcSuccess(getCustomInstructionService().getById(params.id))
|
|
})
|
|
|
|
ipcMain.handle(
|
|
IPC_CHANNELS.INSTRUCTION.CREATE,
|
|
async (
|
|
_event,
|
|
params: { name: string; description: string; prompt: string; icon?: string }
|
|
) => {
|
|
try {
|
|
const result = getCustomInstructionService().create(params)
|
|
return ipcSuccess(result)
|
|
} catch (error) {
|
|
const message = error instanceof Error ? error.message : String(error)
|
|
return ipcError(ErrorCode.ConfigWriteFailed, `Failed to create instruction: ${message}`)
|
|
}
|
|
}
|
|
)
|
|
|
|
ipcMain.handle(
|
|
IPC_CHANNELS.INSTRUCTION.UPDATE,
|
|
async (
|
|
_event,
|
|
params: { id: string; data?: Partial<CustomInstruction>; name?: string; description?: string; prompt?: string; icon?: string }
|
|
) => {
|
|
try {
|
|
const { id, data, ...rest } = params
|
|
const updatePayload = data ?? rest
|
|
const result = getCustomInstructionService().update(id, updatePayload)
|
|
return ipcSuccess(result)
|
|
} catch (error) {
|
|
const message = error instanceof Error ? error.message : String(error)
|
|
return ipcError(ErrorCode.ConfigWriteFailed, `Failed to update instruction: ${message}`)
|
|
}
|
|
}
|
|
)
|
|
|
|
ipcMain.handle(IPC_CHANNELS.INSTRUCTION.DELETE, async (_event, params: { id: string }) => {
|
|
const existing = getCustomInstructionService().getById(params.id)
|
|
if (!existing) {
|
|
return ipcError(ErrorCode.ConfigKeyNotFound, `Instruction not found: ${params.id}`)
|
|
}
|
|
const result = getCustomInstructionService().delete(params.id)
|
|
if (!result) {
|
|
return ipcError(ErrorCode.ConfigWriteFailed, 'Cannot delete builtin instruction')
|
|
}
|
|
return ipcSuccess(undefined)
|
|
})
|
|
|
|
ipcMain.handle(IPC_CHANNELS.INSTRUCTION.REORDER, async (_event, params: { ids: string[] }) => {
|
|
getCustomInstructionService().reorder(params.ids)
|
|
return ipcSuccess(undefined)
|
|
})
|
|
}
|