mirror of
https://github.com/ZSeven-W/openpencil.git
synced 2026-06-01 03:14:29 +07:00
* feat(electron): update electron-builder.yml to specify artifact naming convention for Windows builds. This change enhances clarity and consistency in the build output.
* feat(electron): implement a file logger for the main process
- Added a new logger module that writes logs to `{userData}/logs/main.log` with daily rotation and retains logs for the last 7 days.
- Integrated logging functionality into the main process, replacing console error messages with log entries for better error tracking and debugging.
- Introduced IPC handlers to retrieve the log directory path for user access.
- Updated the preload and main files to utilize the new logging system, enhancing overall application reliability and maintainability.
* feat(mcp): introduce layered design workflow and selection management
- Added a new layered design workflow with tools: `design_skeleton`, `design_content`, and `design_refine` for improved multi-section design generation.
- Implemented segmented prompt retrieval in `get_design_prompt` to allow focused access to design knowledge.
- Created new API endpoints for managing canvas selection state with `selection.get` and `selection.post`, enabling real-time updates and synchronization.
- Enhanced document management with live selection fetching and improved node operations for better design content handling.
- Updated README and CLAUDE.md to reflect new features and usage guidelines for the layered design process.
113 lines
3.7 KiB
TypeScript
113 lines
3.7 KiB
TypeScript
import { contextBridge, ipcRenderer, type IpcRendererEvent } from 'electron'
|
|
|
|
export type UpdaterStatus =
|
|
| 'disabled'
|
|
| 'idle'
|
|
| 'checking'
|
|
| 'available'
|
|
| 'downloading'
|
|
| 'downloaded'
|
|
| 'not-available'
|
|
| 'error'
|
|
|
|
export interface UpdaterState {
|
|
status: UpdaterStatus
|
|
currentVersion: string
|
|
latestVersion?: string
|
|
downloadProgress?: number
|
|
releaseDate?: string
|
|
error?: string
|
|
}
|
|
|
|
export interface ElectronAPI {
|
|
isElectron: true
|
|
openFile: () => Promise<{ filePath: string; content: string } | null>
|
|
saveFile: (
|
|
content: string,
|
|
defaultPath?: string,
|
|
) => Promise<string | null>
|
|
saveToPath: (filePath: string, content: string) => Promise<string>
|
|
onMenuAction: (callback: (action: string) => void) => () => void
|
|
onOpenFile: (callback: (filePath: string) => void) => () => void
|
|
readFile: (filePath: string) => Promise<{ filePath: string; content: string } | null>
|
|
getPendingFile: () => Promise<string | null>
|
|
getLogDir: () => Promise<string>
|
|
setTheme: (theme: 'dark' | 'light', colors?: { bg: string; fg: string }) => void
|
|
getPreferences: () => Promise<Record<string, string>>
|
|
setPreference: (key: string, value: string) => Promise<void>
|
|
removePreference: (key: string) => Promise<void>
|
|
updater: {
|
|
getState: () => Promise<UpdaterState>
|
|
checkForUpdates: () => Promise<UpdaterState>
|
|
quitAndInstall: () => Promise<boolean>
|
|
getAutoCheck: () => Promise<boolean>
|
|
setAutoCheck: (enabled: boolean) => Promise<boolean>
|
|
onStateChange: (callback: (state: UpdaterState) => void) => () => void
|
|
}
|
|
}
|
|
|
|
const api: ElectronAPI = {
|
|
isElectron: true,
|
|
|
|
openFile: () => ipcRenderer.invoke('dialog:openFile'),
|
|
|
|
saveFile: (content: string, defaultPath?: string) =>
|
|
ipcRenderer.invoke('dialog:saveFile', { content, defaultPath }),
|
|
|
|
saveToPath: (filePath: string, content: string) =>
|
|
ipcRenderer.invoke('dialog:saveToPath', { filePath, content }),
|
|
|
|
setTheme: (theme: 'dark' | 'light', colors?: { bg: string; fg: string }) =>
|
|
ipcRenderer.invoke('theme:set', theme, colors),
|
|
|
|
getPreferences: () => ipcRenderer.invoke('prefs:getAll'),
|
|
|
|
setPreference: (key: string, value: string) => ipcRenderer.invoke('prefs:set', key, value),
|
|
|
|
removePreference: (key: string) => ipcRenderer.invoke('prefs:remove', key),
|
|
|
|
onMenuAction: (callback: (action: string) => void) => {
|
|
const listener = (_event: IpcRendererEvent, action: string) => {
|
|
callback(action)
|
|
}
|
|
ipcRenderer.on('menu:action', listener)
|
|
return () => {
|
|
ipcRenderer.removeListener('menu:action', listener)
|
|
}
|
|
},
|
|
|
|
onOpenFile: (callback: (filePath: string) => void) => {
|
|
const listener = (_event: IpcRendererEvent, filePath: string) => {
|
|
callback(filePath)
|
|
}
|
|
ipcRenderer.on('file:open', listener)
|
|
return () => {
|
|
ipcRenderer.removeListener('file:open', listener)
|
|
}
|
|
},
|
|
|
|
readFile: (filePath: string) => ipcRenderer.invoke('file:read', filePath),
|
|
|
|
getPendingFile: () => ipcRenderer.invoke('file:getPending'),
|
|
|
|
getLogDir: () => ipcRenderer.invoke('log:getDir'),
|
|
|
|
updater: {
|
|
getState: () => ipcRenderer.invoke('updater:getState'),
|
|
checkForUpdates: () => ipcRenderer.invoke('updater:checkForUpdates'),
|
|
quitAndInstall: () => ipcRenderer.invoke('updater:quitAndInstall'),
|
|
getAutoCheck: () => ipcRenderer.invoke('updater:getAutoCheck'),
|
|
setAutoCheck: (enabled: boolean) => ipcRenderer.invoke('updater:setAutoCheck', enabled),
|
|
onStateChange: (callback: (state: UpdaterState) => void) => {
|
|
const listener = (_event: IpcRendererEvent, state: UpdaterState) => {
|
|
callback(state)
|
|
}
|
|
ipcRenderer.on('updater:state', listener)
|
|
return () => {
|
|
ipcRenderer.removeListener('updater:state', listener)
|
|
}
|
|
},
|
|
},
|
|
}
|
|
|
|
contextBridge.exposeInMainWorld('electronAPI', api)
|