fix: removed duplicated type declarations
This commit is contained in:
@@ -1,8 +1,9 @@
|
||||
import { contextBridge, ipcRenderer } from 'electron';
|
||||
import type { ElectronAPI } from './shared/electronApi';
|
||||
|
||||
// Expose protected methods that allow the renderer process to use
|
||||
// ipcRenderer without exposing the entire object
|
||||
contextBridge.exposeInMainWorld('electronAPI', {
|
||||
export const electronAPI: ElectronAPI = {
|
||||
// Projects
|
||||
projects: {
|
||||
create: (data: { name: string; description?: string; slug?: string; dataPath?: string }) => ipcRenderer.invoke('projects:create', data),
|
||||
@@ -82,6 +83,17 @@ contextBridge.exposeInMainWorld('electronAPI', {
|
||||
rebuild: () => ipcRenderer.invoke('postMedia:rebuild'),
|
||||
},
|
||||
|
||||
// Sync
|
||||
sync: {
|
||||
configure: (config: unknown) => ipcRenderer.invoke('sync:configure', config),
|
||||
start: (direction?: 'push' | 'pull' | 'bidirectional') => ipcRenderer.invoke('sync:start', direction),
|
||||
getStatus: () => ipcRenderer.invoke('sync:getStatus'),
|
||||
isConfigured: () => ipcRenderer.invoke('sync:isConfigured'),
|
||||
getPendingCount: () => ipcRenderer.invoke('sync:getPendingCount'),
|
||||
getLog: (limit?: number) => ipcRenderer.invoke('sync:getLog', limit),
|
||||
stopAutoSync: () => ipcRenderer.invoke('sync:stopAutoSync'),
|
||||
},
|
||||
|
||||
// Tasks
|
||||
tasks: {
|
||||
getAll: () => ipcRenderer.invoke('tasks:getAll'),
|
||||
@@ -242,8 +254,8 @@ contextBridge.exposeInMainWorld('electronAPI', {
|
||||
ipcRenderer.on('chat-stream-delta', subscription);
|
||||
return () => ipcRenderer.removeListener('chat-stream-delta', subscription);
|
||||
},
|
||||
onToolCall: (callback: (data: { conversationId: string; toolCall: unknown }) => void) => {
|
||||
const subscription = (_event: Electron.IpcRendererEvent, data: { conversationId: string; toolCall: unknown }) => callback(data);
|
||||
onToolCall: (callback: (data: { conversationId: string; toolCall: { name: string; arguments: Record<string, unknown> } }) => void) => {
|
||||
const subscription = (_event: Electron.IpcRendererEvent, data: { conversationId: string; toolCall: { name: string; arguments: Record<string, unknown> } }) => callback(data);
|
||||
ipcRenderer.on('chat-tool-call', subscription);
|
||||
return () => ipcRenderer.removeListener('chat-tool-call', subscription);
|
||||
},
|
||||
@@ -269,192 +281,6 @@ contextBridge.exposeInMainWorld('electronAPI', {
|
||||
once: (channel: string, callback: (...args: unknown[]) => void) => {
|
||||
ipcRenderer.once(channel, (_event, ...args) => callback(...args));
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
// Type definitions for the exposed API
|
||||
export interface ElectronAPI {
|
||||
projects: {
|
||||
create: (data: { name: string; description?: string; slug?: string; dataPath?: string }) => Promise<unknown>;
|
||||
update: (id: string, data: unknown) => Promise<unknown>;
|
||||
delete: (id: string) => Promise<boolean>;
|
||||
get: (id: string) => Promise<unknown>;
|
||||
getAll: () => Promise<unknown[]>;
|
||||
getActive: () => Promise<unknown>;
|
||||
setActive: (id: string) => Promise<unknown>;
|
||||
};
|
||||
posts: {
|
||||
create: (data: unknown) => Promise<unknown>;
|
||||
update: (id: string, data: unknown) => Promise<unknown>;
|
||||
delete: (id: string) => Promise<boolean>;
|
||||
get: (id: string) => Promise<unknown>;
|
||||
getAll: () => Promise<unknown[]>;
|
||||
getByStatus: (status: string) => Promise<unknown[]>;
|
||||
publish: (id: string) => Promise<unknown>;
|
||||
unpublish: (id: string) => Promise<unknown>;
|
||||
rebuildFromFiles: () => Promise<void>;
|
||||
search: (query: string) => Promise<unknown[]>;
|
||||
filter: (filter: unknown) => Promise<unknown[]>;
|
||||
getTags: () => Promise<string[]>;
|
||||
getCategories: () => Promise<string[]>;
|
||||
getByYearMonth: () => Promise<{ year: number; month: number; count: number }[]>;
|
||||
getTagsWithCounts: () => Promise<{ tag: string; count: number }[]>;
|
||||
getCategoriesWithCounts: () => Promise<{ category: string; count: number }[]>;
|
||||
getDashboardStats: () => Promise<{ totalPosts: number; draftCount: number; publishedCount: number; archivedCount: number }>;
|
||||
getLinksTo: (id: string) => Promise<{ id: string; title: string; slug: string }[]>;
|
||||
getLinkedBy: (id: string) => Promise<{ id: string; title: string; slug: string }[]>;
|
||||
rebuildLinks: () => Promise<void>;
|
||||
};
|
||||
media: {
|
||||
import: (sourcePath: string, metadata?: unknown) => Promise<unknown>;
|
||||
importDialog: () => Promise<unknown[]>;
|
||||
update: (id: string, data: unknown) => Promise<unknown>;
|
||||
delete: (id: string) => Promise<boolean>;
|
||||
get: (id: string) => Promise<unknown>;
|
||||
getAll: () => Promise<unknown[]>;
|
||||
rebuildFromFiles: () => Promise<void>;
|
||||
};
|
||||
dropbox: {
|
||||
configure: (config: unknown) => Promise<void>;
|
||||
isConfigured: () => Promise<boolean>;
|
||||
getStatus: () => Promise<string>;
|
||||
syncAll: () => Promise<unknown>;
|
||||
startWatching: () => Promise<void>;
|
||||
stopWatching: () => Promise<void>;
|
||||
startPolling: () => Promise<void>;
|
||||
stopPolling: () => Promise<void>;
|
||||
getConflicts: () => Promise<unknown[]>;
|
||||
resolveConflict: (conflictId: string, resolution: string) => Promise<void>;
|
||||
getLastSyncTime: () => Promise<string | null>;
|
||||
};
|
||||
tasks: {
|
||||
getAll: () => Promise<unknown[]>;
|
||||
getRunning: () => Promise<unknown[]>;
|
||||
cancel: (taskId: string) => Promise<boolean>;
|
||||
clearCompleted: () => Promise<void>;
|
||||
};
|
||||
app: {
|
||||
getDataPaths: () => Promise<{ database: string; posts: string; media: string }>;
|
||||
openFolder: (folderPath: string) => Promise<string>;
|
||||
showItemInFolder: (itemPath: string) => Promise<void>;
|
||||
selectFolder: (title?: string) => Promise<string | null>;
|
||||
getDefaultProjectPath: (projectId: string) => Promise<string>;
|
||||
};
|
||||
meta: {
|
||||
getTags: () => Promise<string[]>;
|
||||
getCategories: () => Promise<string[]>;
|
||||
addTag: (tag: string) => Promise<string[]>;
|
||||
removeTag: (tag: string) => Promise<string[]>;
|
||||
addCategory: (category: string) => Promise<string[]>;
|
||||
removeCategory: (category: string) => Promise<string[]>;
|
||||
syncOnStartup: () => Promise<{ tags: string[]; categories: string[] }>;
|
||||
};
|
||||
tags: {
|
||||
getAll: () => Promise<unknown[]>;
|
||||
getWithCounts: () => Promise<unknown[]>;
|
||||
get: (id: string) => Promise<unknown>;
|
||||
getByName: (name: string) => Promise<unknown>;
|
||||
create: (data: { name: string; color?: string }) => Promise<unknown>;
|
||||
update: (id: string, data: { name?: string; color?: string | null }) => Promise<unknown>;
|
||||
delete: (id: string) => Promise<boolean>;
|
||||
merge: (sourceTagIds: string[], targetTagId: string) => Promise<void>;
|
||||
rename: (id: string, newName: string) => Promise<unknown>;
|
||||
getPostsWithTag: (tagId: string) => Promise<unknown[]>;
|
||||
syncFromPosts: () => Promise<void>;
|
||||
};
|
||||
import: {
|
||||
selectAndAnalyze: (uploadsFolder?: string) => Promise<unknown>;
|
||||
analyzeFile: (filePath: string, uploadsFolder?: string) => Promise<unknown>;
|
||||
selectUploadsFolder: () => Promise<string | null>;
|
||||
execute: (reportJson: string, uploadsFolder?: string) => Promise<{ taskId: string; totalItems: number }>;
|
||||
onProgress: (callback: (data: { step: string; detail?: string }) => void) => () => void;
|
||||
onExecutionProgress: (callback: (data: {
|
||||
taskId: string;
|
||||
phase: string;
|
||||
current: number;
|
||||
total: number;
|
||||
detail?: string;
|
||||
eta?: number;
|
||||
}) => void) => () => void;
|
||||
};
|
||||
importDefinitions: {
|
||||
create: (name?: string) => Promise<unknown>;
|
||||
get: (id: string) => Promise<unknown>;
|
||||
getAll: () => Promise<unknown[]>;
|
||||
update: (id: string, updates: unknown) => Promise<unknown>;
|
||||
delete: (id: string) => Promise<boolean>;
|
||||
};
|
||||
metadataDiff: {
|
||||
getStats: () => Promise<{
|
||||
totalPosts: number;
|
||||
publishedPosts: number;
|
||||
draftPosts: number;
|
||||
totalMedia: number;
|
||||
}>;
|
||||
scan: () => Promise<{
|
||||
totalScanned: number;
|
||||
postsWithDifferences: number;
|
||||
differences: Array<{
|
||||
postId: string;
|
||||
title: string;
|
||||
slug: string;
|
||||
filePath?: string;
|
||||
hasDifferences: boolean;
|
||||
differences: Record<string, { dbValue: unknown; fileValue: unknown }>;
|
||||
}>;
|
||||
groups: Array<{
|
||||
field: string;
|
||||
label: string;
|
||||
posts: Array<{
|
||||
postId: string;
|
||||
title: string;
|
||||
slug: string;
|
||||
dbValue: unknown;
|
||||
fileValue: unknown;
|
||||
}>;
|
||||
}>;
|
||||
}>;
|
||||
syncDbToFile: (postIds: string[], groupLabel: string) => Promise<{ success: number; failed: number }>;
|
||||
syncFileToDb: (postIds: string[], field: string, groupLabel: string) => Promise<{ success: number; failed: number }>;
|
||||
};
|
||||
chat: {
|
||||
// API Key Management
|
||||
checkReady: () => Promise<{ ready: boolean; error?: string; backend?: string }>;
|
||||
validateApiKey: (apiKey: string) => Promise<{ isValid: boolean; models: Array<{ id: string; name: string }> }>;
|
||||
setApiKey: (apiKey: string) => Promise<{ success: boolean; error?: string }>;
|
||||
getApiKey: () => Promise<{ hasKey: boolean; maskedKey: string }>;
|
||||
|
||||
// Settings
|
||||
getAvailableModels: () => Promise<{ success: boolean; models?: Array<{ id: string; name: string }>; selectedModel?: string; error?: string }>;
|
||||
setDefaultModel: (modelId: string) => Promise<{ success: boolean; error?: string }>;
|
||||
getSystemPrompt: () => Promise<{ success: boolean; prompt?: string; error?: string }>;
|
||||
setSystemPrompt: (prompt: string) => Promise<{ success: boolean; error?: string }>;
|
||||
|
||||
// Conversations
|
||||
getConversations: () => Promise<unknown[]>;
|
||||
createConversation: (title?: string, model?: string) => Promise<unknown>;
|
||||
getConversation: (id: string) => Promise<unknown>;
|
||||
updateConversation: (id: string, updates: { title?: string; model?: string }) => Promise<unknown>;
|
||||
deleteConversation: (id: string) => Promise<boolean>;
|
||||
|
||||
// Messaging
|
||||
sendMessage: (conversationId: string, message: string) => Promise<string>;
|
||||
abortMessage: (conversationId: string) => Promise<void>;
|
||||
getHistory: (conversationId: string) => Promise<unknown[]>;
|
||||
clearMessages: (conversationId: string) => Promise<void>;
|
||||
setConversationModel: (conversationId: string, modelId: string) => Promise<void>;
|
||||
|
||||
// Event listeners
|
||||
onStreamDelta: (callback: (data: { conversationId: string; delta: string }) => void) => () => void;
|
||||
onToolCall: (callback: (data: { conversationId: string; toolCall: unknown }) => void) => () => void;
|
||||
onToolResult: (callback: (data: { conversationId: string; result: unknown }) => void) => () => void;
|
||||
onTitleUpdated: (callback: (data: { conversationId: string; title: string }) => void) => () => void;
|
||||
};
|
||||
on: (channel: string, callback: (...args: unknown[]) => void) => () => void;
|
||||
once: (channel: string, callback: (...args: unknown[]) => void) => void;
|
||||
}
|
||||
|
||||
declare global {
|
||||
interface Window {
|
||||
electronAPI: ElectronAPI;
|
||||
}
|
||||
}
|
||||
contextBridge.exposeInMainWorld('electronAPI', electronAPI);
|
||||
|
||||
486
src/main/shared/electronApi.ts
Normal file
486
src/main/shared/electronApi.ts
Normal file
@@ -0,0 +1,486 @@
|
||||
// Type definitions for the Electron API exposed via preload
|
||||
|
||||
export interface ImportExecuteResult {
|
||||
taskId: string;
|
||||
totalItems: number;
|
||||
}
|
||||
|
||||
export interface ImportExecutionProgress {
|
||||
taskId: string;
|
||||
phase: string;
|
||||
current: number;
|
||||
total: number;
|
||||
detail?: string;
|
||||
eta?: number;
|
||||
}
|
||||
|
||||
export interface ImportCompleteResult {
|
||||
taskId: string;
|
||||
success: boolean;
|
||||
posts: { imported: number; skipped: number; errors: number };
|
||||
media: { imported: number; skipped: number; errors: number };
|
||||
pages: { imported: number; skipped: number; errors: number };
|
||||
tags: { created: number; skipped: number };
|
||||
}
|
||||
|
||||
export interface ImportDefinitionData {
|
||||
id: string;
|
||||
projectId: string;
|
||||
name: string;
|
||||
wxrFilePath: string | null;
|
||||
uploadsFolderPath: string | null;
|
||||
lastAnalysisResult: unknown | null;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
}
|
||||
|
||||
export interface ProjectMetadata {
|
||||
name: string;
|
||||
description?: string;
|
||||
dataPath?: string;
|
||||
mainLanguage?: string;
|
||||
}
|
||||
|
||||
export interface ProjectData {
|
||||
id: string;
|
||||
name: string;
|
||||
slug: string;
|
||||
description?: string;
|
||||
dataPath?: string;
|
||||
isActive: boolean;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
}
|
||||
|
||||
export interface PostData {
|
||||
id: string;
|
||||
projectId: string;
|
||||
title: string;
|
||||
slug: string;
|
||||
excerpt?: string;
|
||||
content: string;
|
||||
status: 'draft' | 'published' | 'archived';
|
||||
author?: string;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
publishedAt?: string;
|
||||
tags: string[];
|
||||
categories: string[];
|
||||
}
|
||||
|
||||
export interface PostFilter {
|
||||
status?: 'draft' | 'published' | 'archived';
|
||||
tags?: string[];
|
||||
categories?: string[];
|
||||
year?: number;
|
||||
month?: number;
|
||||
from?: string;
|
||||
to?: string;
|
||||
}
|
||||
|
||||
export interface SearchResult {
|
||||
id: string;
|
||||
title: string;
|
||||
slug: string;
|
||||
excerpt?: string;
|
||||
}
|
||||
|
||||
export interface MediaData {
|
||||
id: string;
|
||||
projectId: string;
|
||||
filename: string;
|
||||
originalName: string;
|
||||
mimeType: string;
|
||||
size: number;
|
||||
width?: number;
|
||||
height?: number;
|
||||
title?: string;
|
||||
alt?: string;
|
||||
caption?: string;
|
||||
author?: string;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
tags: string[];
|
||||
}
|
||||
|
||||
export interface MediaFilter {
|
||||
tags?: string[];
|
||||
year?: number;
|
||||
month?: number;
|
||||
}
|
||||
|
||||
export interface MediaSearchResult {
|
||||
id: string;
|
||||
originalName: string;
|
||||
title?: string;
|
||||
mimeType: string;
|
||||
createdAt: string;
|
||||
}
|
||||
|
||||
export interface TaskProgress {
|
||||
taskId: string;
|
||||
status: 'pending' | 'running' | 'completed' | 'failed' | 'cancelled';
|
||||
progress: number;
|
||||
message: string;
|
||||
startTime: string;
|
||||
endTime?: string;
|
||||
error?: string;
|
||||
}
|
||||
|
||||
export interface SyncConfig {
|
||||
autoSync: boolean;
|
||||
syncInterval: number;
|
||||
}
|
||||
|
||||
export interface SyncResult {
|
||||
success: boolean;
|
||||
pushed: number;
|
||||
pulled: number;
|
||||
conflicts: number;
|
||||
errors: string[];
|
||||
}
|
||||
|
||||
export interface PaginatedPostsResult {
|
||||
items: PostData[];
|
||||
hasMore: boolean;
|
||||
total: number;
|
||||
}
|
||||
|
||||
export interface DashboardStats {
|
||||
totalPosts: number;
|
||||
draftCount: number;
|
||||
publishedCount: number;
|
||||
archivedCount: number;
|
||||
}
|
||||
|
||||
export interface TagCount {
|
||||
tag: string;
|
||||
count: number;
|
||||
}
|
||||
|
||||
export interface CategoryCount {
|
||||
category: string;
|
||||
count: number;
|
||||
}
|
||||
|
||||
export interface TagData {
|
||||
id: string;
|
||||
projectId: string;
|
||||
name: string;
|
||||
color?: string;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
}
|
||||
|
||||
export interface TagWithCount {
|
||||
name: string;
|
||||
color: string | null;
|
||||
count: number;
|
||||
}
|
||||
|
||||
export interface DeleteTagResult {
|
||||
success: boolean;
|
||||
postsUpdated: number;
|
||||
}
|
||||
|
||||
export interface MergeTagsResult {
|
||||
success: boolean;
|
||||
postsUpdated: number;
|
||||
tagsDeleted: number;
|
||||
targetTag: string;
|
||||
}
|
||||
|
||||
export interface RenameTagResult {
|
||||
success: boolean;
|
||||
postsUpdated: number;
|
||||
oldName: string;
|
||||
newName: string;
|
||||
}
|
||||
|
||||
export interface SyncTagsResult {
|
||||
discovered: number;
|
||||
added: string[];
|
||||
}
|
||||
|
||||
// Post-Media Link types
|
||||
export interface MediaLinkData {
|
||||
id: string;
|
||||
projectId: string;
|
||||
postId: string;
|
||||
mediaId: string;
|
||||
sortOrder: number;
|
||||
createdAt: string;
|
||||
}
|
||||
|
||||
// Chat/AI types
|
||||
export interface ChatConversation {
|
||||
id: string;
|
||||
title: string;
|
||||
model?: string;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
}
|
||||
|
||||
export interface ChatMessage {
|
||||
id: string;
|
||||
conversationId: string;
|
||||
role: 'user' | 'assistant' | 'system' | 'tool';
|
||||
content: string;
|
||||
toolCallId?: string;
|
||||
toolCalls?: string;
|
||||
createdAt: string;
|
||||
}
|
||||
|
||||
export interface ChatModel {
|
||||
id: string;
|
||||
name: string;
|
||||
provider?: string;
|
||||
}
|
||||
|
||||
export interface ChatReadyStatus {
|
||||
ready: boolean;
|
||||
error?: string;
|
||||
backend?: string;
|
||||
}
|
||||
|
||||
export interface ChatApiKeyStatus {
|
||||
hasKey: boolean;
|
||||
maskedKey: string;
|
||||
}
|
||||
|
||||
export interface ChatStreamDelta {
|
||||
conversationId: string;
|
||||
delta: string;
|
||||
}
|
||||
|
||||
export interface ChatToolCall {
|
||||
conversationId: string;
|
||||
toolCall: {
|
||||
name: string;
|
||||
arguments: Record<string, unknown>;
|
||||
};
|
||||
}
|
||||
|
||||
export interface ChatToolResult {
|
||||
conversationId: string;
|
||||
result: unknown;
|
||||
}
|
||||
|
||||
export interface ChatTitleUpdate {
|
||||
conversationId: string;
|
||||
title: string;
|
||||
}
|
||||
|
||||
export interface ElectronAPI {
|
||||
projects: {
|
||||
create: (data: { name: string; description?: string; slug?: string; dataPath?: string }) => Promise<ProjectData>;
|
||||
update: (id: string, data: Partial<ProjectData>) => Promise<ProjectData | null>;
|
||||
delete: (id: string) => Promise<boolean>;
|
||||
deleteWithData: (id: string) => Promise<boolean>;
|
||||
get: (id: string) => Promise<ProjectData | null>;
|
||||
getAll: () => Promise<ProjectData[]>;
|
||||
getActive: () => Promise<ProjectData | null>;
|
||||
setActive: (id: string) => Promise<ProjectData | null>;
|
||||
};
|
||||
posts: {
|
||||
create: (data: Partial<PostData>) => Promise<PostData>;
|
||||
update: (id: string, data: Partial<PostData>) => Promise<PostData | null>;
|
||||
delete: (id: string) => Promise<boolean>;
|
||||
get: (id: string) => Promise<PostData | null>;
|
||||
getAll: (options?: { limit?: number; offset?: number }) => Promise<PaginatedPostsResult>;
|
||||
getByStatus: (status: string) => Promise<PostData[]>;
|
||||
publish: (id: string) => Promise<PostData | null>;
|
||||
discard: (id: string) => Promise<PostData | null>;
|
||||
hasPublishedVersion: (id: string) => Promise<boolean>;
|
||||
rebuildFromFiles: () => Promise<void>;
|
||||
reindexText: () => Promise<void>;
|
||||
search: (query: string) => Promise<SearchResult[]>;
|
||||
filter: (filter: PostFilter) => Promise<PostData[]>;
|
||||
getTags: () => Promise<string[]>;
|
||||
getCategories: () => Promise<string[]>;
|
||||
getByYearMonth: () => Promise<{ year: number; month: number; count: number }[]>;
|
||||
getDashboardStats: () => Promise<DashboardStats>;
|
||||
getTagsWithCounts: () => Promise<TagCount[]>;
|
||||
getCategoriesWithCounts: () => Promise<CategoryCount[]>;
|
||||
getLinksTo: (id: string) => Promise<PostData[]>;
|
||||
getLinkedBy: (id: string) => Promise<PostData[]>;
|
||||
rebuildLinks: () => Promise<void>;
|
||||
isSlugAvailable: (slug: string, excludePostId?: string) => Promise<boolean>;
|
||||
generateUniqueSlug: (title: string, excludePostId?: string) => Promise<string>;
|
||||
};
|
||||
media: {
|
||||
import: (sourcePath: string, metadata?: Partial<MediaData>) => Promise<MediaData>;
|
||||
importDialog: () => Promise<MediaData[]>;
|
||||
update: (id: string, data: Partial<MediaData>) => Promise<MediaData | null>;
|
||||
replaceFile: (id: string, newSourcePath: string) => Promise<MediaData | null>;
|
||||
replaceFileDialog: (id: string) => Promise<MediaData | null>;
|
||||
delete: (id: string) => Promise<boolean>;
|
||||
get: (id: string) => Promise<MediaData | null>;
|
||||
getUrl: (id: string) => Promise<string | null>;
|
||||
getFilePath: (id: string) => Promise<string | null>;
|
||||
getAll: () => Promise<MediaData[]>;
|
||||
rebuildFromFiles: () => Promise<void>;
|
||||
reindexText: () => Promise<void>;
|
||||
getThumbnail: (id: string, size?: 'small' | 'medium' | 'large') => Promise<string | null>;
|
||||
regenerateThumbnails: (id: string) => Promise<Record<string, string> | null>;
|
||||
regenerateMissingThumbnails: () => Promise<{ processed: number; generated: number; failed: number }>;
|
||||
filter: (filter: MediaFilter) => Promise<MediaData[]>;
|
||||
search: (query: string) => Promise<MediaSearchResult[]>;
|
||||
getByYearMonth: () => Promise<{ year: number; month: number; count: number }[]>;
|
||||
getTags: () => Promise<string[]>;
|
||||
getTagsWithCounts: () => Promise<TagCount[]>;
|
||||
};
|
||||
postMedia: {
|
||||
link: (postId: string, mediaId: string) => Promise<MediaLinkData>;
|
||||
unlink: (postId: string, mediaId: string) => Promise<void>;
|
||||
linkMany: (postId: string, mediaIds: string[]) => Promise<{ linked: string[]; skipped: string[] }>;
|
||||
unlinkMany: (postId: string, mediaIds: string[]) => Promise<{ unlinked: string[] }>;
|
||||
getForPost: (postId: string) => Promise<MediaLinkData[]>;
|
||||
getForMedia: (mediaId: string) => Promise<MediaLinkData[]>;
|
||||
getMediaDataForPost: (postId: string) => Promise<Array<MediaLinkData & { media: MediaData }>>;
|
||||
reorder: (postId: string, mediaIds: string[]) => Promise<void>;
|
||||
isLinked: (postId: string, mediaId: string) => Promise<boolean>;
|
||||
import: (postId: string, filePath: string) => Promise<MediaLinkData>;
|
||||
rebuild: () => Promise<void>;
|
||||
};
|
||||
sync: {
|
||||
configure: (config: SyncConfig) => Promise<void>;
|
||||
start: (direction?: 'push' | 'pull' | 'bidirectional') => Promise<SyncResult>;
|
||||
getStatus: () => Promise<'idle' | 'syncing' | 'error'>;
|
||||
isConfigured: () => Promise<boolean>;
|
||||
getPendingCount: () => Promise<{ posts: number; media: number }>;
|
||||
getLog: (limit?: number) => Promise<unknown[]>;
|
||||
stopAutoSync: () => Promise<void>;
|
||||
};
|
||||
tasks: {
|
||||
getAll: () => Promise<TaskProgress[]>;
|
||||
getRunning: () => Promise<TaskProgress[]>;
|
||||
cancel: (taskId: string) => Promise<boolean>;
|
||||
clearCompleted: () => Promise<void>;
|
||||
};
|
||||
app: {
|
||||
getDataPaths: () => Promise<{ database: string; posts: string; media: string }>;
|
||||
openFolder: (folderPath: string) => Promise<string>;
|
||||
showItemInFolder: (itemPath: string) => Promise<void>;
|
||||
selectFolder: (title?: string) => Promise<string | null>;
|
||||
getDefaultProjectPath: (projectId: string) => Promise<string>;
|
||||
readProjectMetadata: (folderPath: string) => Promise<{ name?: string; description?: string; mainLanguage?: string } | null>;
|
||||
};
|
||||
meta: {
|
||||
getTags: () => Promise<string[]>;
|
||||
getCategories: () => Promise<string[]>;
|
||||
addTag: (tag: string) => Promise<string[]>;
|
||||
removeTag: (tag: string) => Promise<string[]>;
|
||||
addCategory: (category: string) => Promise<string[]>;
|
||||
removeCategory: (category: string) => Promise<string[]>;
|
||||
syncOnStartup: () => Promise<{ tags: string[]; categories: string[]; projectMetadata: ProjectMetadata | null }>;
|
||||
getProjectMetadata: () => Promise<ProjectMetadata | null>;
|
||||
setProjectMetadata: (metadata: { name: string; description?: string }) => Promise<ProjectMetadata | null>;
|
||||
updateProjectMetadata: (updates: { name?: string; description?: string; dataPath?: string; mainLanguage?: string }) => Promise<ProjectMetadata | null>;
|
||||
};
|
||||
tags: {
|
||||
getAll: () => Promise<TagData[]>;
|
||||
getWithCounts: () => Promise<TagWithCount[]>;
|
||||
get: (id: string) => Promise<TagData | null>;
|
||||
getByName: (name: string) => Promise<TagData | null>;
|
||||
create: (data: { name: string; color?: string }) => Promise<TagData>;
|
||||
update: (id: string, data: { name?: string; color?: string | null }) => Promise<TagData | null>;
|
||||
delete: (id: string) => Promise<DeleteTagResult>;
|
||||
merge: (sourceTagIds: string[], targetTagId: string) => Promise<MergeTagsResult>;
|
||||
rename: (id: string, newName: string) => Promise<RenameTagResult>;
|
||||
getPostsWithTag: (tagId: string) => Promise<string[]>;
|
||||
syncFromPosts: () => Promise<SyncTagsResult>;
|
||||
};
|
||||
import: {
|
||||
selectAndAnalyze: (uploadsFolder?: string) => Promise<unknown>;
|
||||
analyzeFile: (filePath: string, uploadsFolder?: string) => Promise<unknown>;
|
||||
selectUploadsFolder: () => Promise<string | null>;
|
||||
execute: (reportJson: string, uploadsFolder?: string) => Promise<ImportExecuteResult>;
|
||||
onProgress: (callback: (data: { step: string; detail?: string }) => void) => () => void;
|
||||
onExecutionProgress: (callback: (data: ImportExecutionProgress) => void) => () => void;
|
||||
onComplete: (callback: (data: ImportCompleteResult) => void) => () => void;
|
||||
};
|
||||
importDefinitions: {
|
||||
create: (name?: string) => Promise<ImportDefinitionData>;
|
||||
get: (id: string) => Promise<ImportDefinitionData | null>;
|
||||
getAll: () => Promise<ImportDefinitionData[]>;
|
||||
update: (id: string, updates: Partial<Pick<ImportDefinitionData, 'name' | 'wxrFilePath' | 'uploadsFolderPath' | 'lastAnalysisResult'>>) => Promise<ImportDefinitionData | null>;
|
||||
delete: (id: string) => Promise<boolean>;
|
||||
onNameUpdated: (callback: (data: { definitionId: string; name: string }) => void) => () => void;
|
||||
};
|
||||
metadataDiff: {
|
||||
getStats: () => Promise<{
|
||||
totalPosts: number;
|
||||
publishedPosts: number;
|
||||
draftPosts: number;
|
||||
totalMedia: number;
|
||||
}>;
|
||||
scan: () => Promise<{
|
||||
totalScanned: number;
|
||||
postsWithDifferences: number;
|
||||
differences: Array<{
|
||||
postId: string;
|
||||
title: string;
|
||||
slug: string;
|
||||
filePath?: string;
|
||||
hasDifferences: boolean;
|
||||
differences: Record<string, { dbValue: unknown; fileValue: unknown }>;
|
||||
}>;
|
||||
groups: Array<{
|
||||
field: string;
|
||||
label: string;
|
||||
posts: Array<{
|
||||
postId: string;
|
||||
title: string;
|
||||
slug: string;
|
||||
dbValue: unknown;
|
||||
fileValue: unknown;
|
||||
}>;
|
||||
}>;
|
||||
}>;
|
||||
syncDbToFile: (postIds: string[], groupLabel: string) => Promise<{ success: number; failed: number }>;
|
||||
syncFileToDb: (postIds: string[], field: string, groupLabel: string) => Promise<{ success: number; failed: number }>;
|
||||
};
|
||||
chat: {
|
||||
// API Key Management
|
||||
checkReady: () => Promise<ChatReadyStatus>;
|
||||
validateApiKey: (apiKey: string) => Promise<{ isValid: boolean; models: ChatModel[] }>;
|
||||
setApiKey: (apiKey: string) => Promise<{ success: boolean; error?: string }>;
|
||||
getApiKey: () => Promise<ChatApiKeyStatus>;
|
||||
|
||||
// Settings
|
||||
getAvailableModels: () => Promise<{ success: boolean; models?: ChatModel[]; selectedModel?: string; error?: string }>;
|
||||
setDefaultModel: (modelId: string) => Promise<{ success: boolean; error?: string }>;
|
||||
getSystemPrompt: () => Promise<{ success: boolean; prompt?: string; error?: string }>;
|
||||
setSystemPrompt: (prompt: string) => Promise<{ success: boolean; error?: string }>;
|
||||
|
||||
// Conversations
|
||||
getConversations: () => Promise<ChatConversation[]>;
|
||||
createConversation: (title?: string, model?: string) => Promise<ChatConversation>;
|
||||
getConversation: (id: string) => Promise<ChatConversation | null>;
|
||||
updateConversation: (id: string, updates: { title?: string; model?: string }) => Promise<ChatConversation | null>;
|
||||
deleteConversation: (id: string) => Promise<boolean>;
|
||||
|
||||
// Messaging
|
||||
sendMessage: (conversationId: string, message: string) => Promise<{ success: boolean; message?: string; error?: string }>;
|
||||
abortMessage: (conversationId: string) => Promise<void>;
|
||||
getHistory: (conversationId: string) => Promise<ChatMessage[]>;
|
||||
clearMessages: (conversationId: string) => Promise<void>;
|
||||
setConversationModel: (conversationId: string, modelId: string) => Promise<void>;
|
||||
|
||||
// Taxonomy Analysis
|
||||
analyzeTaxonomy: (categories: Array<{ name: string; slug: string; existsInProject: boolean }>, tags: Array<{ name: string; slug: string; existsInProject: boolean }>, modelId: string) => Promise<{ success: boolean; categoryMappings?: Record<string, string>; tagMappings?: Record<string, string>; error?: string }>;
|
||||
|
||||
// Media Analysis
|
||||
analyzeMediaImage: (mediaId: string, language?: string) => Promise<{ success: boolean; title?: string; alt?: string; caption?: string; error?: string }>;
|
||||
|
||||
// Event listeners for streaming/progress
|
||||
onStreamDelta: (callback: (data: ChatStreamDelta) => void) => () => void;
|
||||
onToolCall: (callback: (data: ChatToolCall) => void) => () => void;
|
||||
onToolResult: (callback: (data: ChatToolResult) => void) => () => void;
|
||||
onTitleUpdated: (callback: (data: ChatTitleUpdate) => void) => () => void;
|
||||
};
|
||||
on: (channel: string, callback: (...args: unknown[]) => void) => () => void;
|
||||
once: (channel: string, callback: (...args: unknown[]) => void) => void;
|
||||
}
|
||||
|
||||
453
src/renderer/types/electron.d.ts
vendored
453
src/renderer/types/electron.d.ts
vendored
@@ -1,455 +1,6 @@
|
||||
// Type definitions for the Electron API exposed via preload
|
||||
export * from '../../main/shared/electronApi';
|
||||
|
||||
export interface ImportExecuteResult {
|
||||
taskId: string;
|
||||
totalItems: number;
|
||||
}
|
||||
|
||||
export interface ImportExecutionProgress {
|
||||
taskId: string;
|
||||
phase: string;
|
||||
current: number;
|
||||
total: number;
|
||||
detail?: string;
|
||||
eta?: number;
|
||||
}
|
||||
|
||||
export interface ImportCompleteResult {
|
||||
taskId: string;
|
||||
success: boolean;
|
||||
posts: { imported: number; skipped: number; errors: number };
|
||||
media: { imported: number; skipped: number; errors: number };
|
||||
pages: { imported: number; skipped: number; errors: number };
|
||||
tags: { created: number; skipped: number };
|
||||
}
|
||||
|
||||
export interface ImportDefinitionData {
|
||||
id: string;
|
||||
projectId: string;
|
||||
name: string;
|
||||
wxrFilePath: string | null;
|
||||
uploadsFolderPath: string | null;
|
||||
lastAnalysisResult: unknown | null;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
}
|
||||
|
||||
export interface ProjectMetadata {
|
||||
name: string;
|
||||
description?: string;
|
||||
dataPath?: string;
|
||||
mainLanguage?: string;
|
||||
}
|
||||
|
||||
export interface ProjectData {
|
||||
id: string;
|
||||
name: string;
|
||||
slug: string;
|
||||
description?: string;
|
||||
dataPath?: string;
|
||||
isActive: boolean;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
}
|
||||
|
||||
export interface PostData {
|
||||
id: string;
|
||||
projectId: string;
|
||||
title: string;
|
||||
slug: string;
|
||||
excerpt?: string;
|
||||
content: string;
|
||||
status: 'draft' | 'published' | 'archived';
|
||||
author?: string;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
publishedAt?: string;
|
||||
tags: string[];
|
||||
categories: string[];
|
||||
}
|
||||
|
||||
export interface PostFilter {
|
||||
status?: 'draft' | 'published' | 'archived';
|
||||
tags?: string[];
|
||||
categories?: string[];
|
||||
year?: number;
|
||||
month?: number;
|
||||
from?: string;
|
||||
to?: string;
|
||||
}
|
||||
|
||||
export interface SearchResult {
|
||||
id: string;
|
||||
title: string;
|
||||
slug: string;
|
||||
excerpt?: string;
|
||||
}
|
||||
|
||||
export interface MediaData {
|
||||
id: string;
|
||||
projectId: string;
|
||||
filename: string;
|
||||
originalName: string;
|
||||
mimeType: string;
|
||||
size: number;
|
||||
width?: number;
|
||||
height?: number;
|
||||
title?: string;
|
||||
alt?: string;
|
||||
caption?: string;
|
||||
author?: string;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
tags: string[];
|
||||
}
|
||||
|
||||
export interface MediaFilter {
|
||||
tags?: string[];
|
||||
year?: number;
|
||||
month?: number;
|
||||
}
|
||||
|
||||
export interface MediaSearchResult {
|
||||
id: string;
|
||||
originalName: string;
|
||||
title?: string;
|
||||
mimeType: string;
|
||||
createdAt: string;
|
||||
}
|
||||
|
||||
export interface TaskProgress {
|
||||
taskId: string;
|
||||
status: 'pending' | 'running' | 'completed' | 'failed' | 'cancelled';
|
||||
progress: number;
|
||||
message: string;
|
||||
startTime: string;
|
||||
endTime?: string;
|
||||
error?: string;
|
||||
}
|
||||
|
||||
export interface SyncConfig {
|
||||
autoSync: boolean;
|
||||
syncInterval: number;
|
||||
}
|
||||
|
||||
export interface SyncResult {
|
||||
success: boolean;
|
||||
pushed: number;
|
||||
pulled: number;
|
||||
conflicts: number;
|
||||
errors: string[];
|
||||
}
|
||||
|
||||
export interface PaginatedPostsResult {
|
||||
items: PostData[];
|
||||
hasMore: boolean;
|
||||
total: number;
|
||||
}
|
||||
|
||||
export interface DashboardStats {
|
||||
totalPosts: number;
|
||||
draftCount: number;
|
||||
publishedCount: number;
|
||||
archivedCount: number;
|
||||
}
|
||||
|
||||
export interface TagCount {
|
||||
tag: string;
|
||||
count: number;
|
||||
}
|
||||
|
||||
export interface CategoryCount {
|
||||
category: string;
|
||||
count: number;
|
||||
}
|
||||
|
||||
export interface TagData {
|
||||
id: string;
|
||||
projectId: string;
|
||||
name: string;
|
||||
color?: string;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
}
|
||||
|
||||
export interface TagWithCount {
|
||||
name: string;
|
||||
color: string | null;
|
||||
count: number;
|
||||
}
|
||||
|
||||
export interface DeleteTagResult {
|
||||
success: boolean;
|
||||
postsUpdated: number;
|
||||
}
|
||||
|
||||
export interface MergeTagsResult {
|
||||
success: boolean;
|
||||
postsUpdated: number;
|
||||
tagsDeleted: number;
|
||||
targetTag: string;
|
||||
}
|
||||
|
||||
export interface RenameTagResult {
|
||||
success: boolean;
|
||||
postsUpdated: number;
|
||||
oldName: string;
|
||||
newName: string;
|
||||
}
|
||||
|
||||
export interface SyncTagsResult {
|
||||
discovered: number;
|
||||
added: string[];
|
||||
}
|
||||
|
||||
// Post-Media Link types
|
||||
export interface MediaLinkData {
|
||||
id: string;
|
||||
projectId: string;
|
||||
postId: string;
|
||||
mediaId: string;
|
||||
sortOrder: number;
|
||||
createdAt: string;
|
||||
}
|
||||
|
||||
// Chat/AI types
|
||||
export interface ChatConversation {
|
||||
id: string;
|
||||
title: string;
|
||||
model?: string;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
}
|
||||
|
||||
export interface ChatMessage {
|
||||
id: string;
|
||||
conversationId: string;
|
||||
role: 'user' | 'assistant' | 'system' | 'tool';
|
||||
content: string;
|
||||
toolCallId?: string;
|
||||
toolCalls?: string;
|
||||
createdAt: string;
|
||||
}
|
||||
|
||||
export interface ChatModel {
|
||||
id: string;
|
||||
name: string;
|
||||
provider?: string;
|
||||
}
|
||||
|
||||
export interface ChatReadyStatus {
|
||||
ready: boolean;
|
||||
error?: string;
|
||||
backend?: string;
|
||||
}
|
||||
|
||||
export interface ChatApiKeyStatus {
|
||||
hasKey: boolean;
|
||||
maskedKey: string;
|
||||
}
|
||||
|
||||
export interface ChatStreamDelta {
|
||||
conversationId: string;
|
||||
delta: string;
|
||||
}
|
||||
|
||||
export interface ChatToolCall {
|
||||
conversationId: string;
|
||||
toolCall: {
|
||||
name: string;
|
||||
arguments: Record<string, unknown>;
|
||||
};
|
||||
}
|
||||
|
||||
export interface ChatToolResult {
|
||||
conversationId: string;
|
||||
result: unknown;
|
||||
}
|
||||
|
||||
export interface ChatTitleUpdate {
|
||||
conversationId: string;
|
||||
title: string;
|
||||
}
|
||||
|
||||
export interface ElectronAPI {
|
||||
projects: {
|
||||
create: (data: { name: string; description?: string; slug?: string; dataPath?: string }) => Promise<ProjectData>;
|
||||
update: (id: string, data: Partial<ProjectData>) => Promise<ProjectData | null>;
|
||||
delete: (id: string) => Promise<boolean>;
|
||||
deleteWithData: (id: string) => Promise<boolean>;
|
||||
get: (id: string) => Promise<ProjectData | null>;
|
||||
getAll: () => Promise<ProjectData[]>;
|
||||
getActive: () => Promise<ProjectData | null>;
|
||||
setActive: (id: string) => Promise<ProjectData | null>;
|
||||
};
|
||||
posts: {
|
||||
create: (data: Partial<PostData>) => Promise<PostData>;
|
||||
update: (id: string, data: Partial<PostData>) => Promise<PostData | null>;
|
||||
delete: (id: string) => Promise<boolean>;
|
||||
get: (id: string) => Promise<PostData | null>;
|
||||
getAll: (options?: { limit?: number; offset?: number }) => Promise<PaginatedPostsResult>;
|
||||
getByStatus: (status: string) => Promise<PostData[]>;
|
||||
publish: (id: string) => Promise<PostData | null>;
|
||||
discard: (id: string) => Promise<PostData | null>;
|
||||
hasPublishedVersion: (id: string) => Promise<boolean>;
|
||||
rebuildFromFiles: () => Promise<void>;
|
||||
reindexText: () => Promise<void>;
|
||||
search: (query: string) => Promise<SearchResult[]>;
|
||||
filter: (filter: PostFilter) => Promise<PostData[]>;
|
||||
getTags: () => Promise<string[]>;
|
||||
getCategories: () => Promise<string[]>;
|
||||
getByYearMonth: () => Promise<{ year: number; month: number; count: number }[]>;
|
||||
getDashboardStats: () => Promise<DashboardStats>;
|
||||
getTagsWithCounts: () => Promise<TagCount[]>;
|
||||
getCategoriesWithCounts: () => Promise<CategoryCount[]>;
|
||||
getLinksTo: (id: string) => Promise<PostData[]>;
|
||||
getLinkedBy: (id: string) => Promise<PostData[]>;
|
||||
rebuildLinks: () => Promise<void>;
|
||||
isSlugAvailable: (slug: string, excludePostId?: string) => Promise<boolean>;
|
||||
generateUniqueSlug: (title: string, excludePostId?: string) => Promise<string>;
|
||||
};
|
||||
media: {
|
||||
import: (sourcePath: string, metadata?: Partial<MediaData>) => Promise<MediaData>;
|
||||
importDialog: () => Promise<MediaData[]>;
|
||||
update: (id: string, data: Partial<MediaData>) => Promise<MediaData | null>;
|
||||
replaceFile: (id: string, newSourcePath: string) => Promise<MediaData | null>;
|
||||
replaceFileDialog: (id: string) => Promise<MediaData | null>;
|
||||
delete: (id: string) => Promise<boolean>;
|
||||
get: (id: string) => Promise<MediaData | null>;
|
||||
getUrl: (id: string) => Promise<string | null>;
|
||||
getFilePath: (id: string) => Promise<string | null>;
|
||||
getAll: () => Promise<MediaData[]>;
|
||||
rebuildFromFiles: () => Promise<void>;
|
||||
reindexText: () => Promise<void>;
|
||||
getThumbnail: (id: string, size?: 'small' | 'medium' | 'large') => Promise<string | null>;
|
||||
regenerateThumbnails: (id: string) => Promise<Record<string, string> | null>;
|
||||
regenerateMissingThumbnails: () => Promise<{ processed: number; generated: number; failed: number }>;
|
||||
filter: (filter: MediaFilter) => Promise<MediaData[]>;
|
||||
search: (query: string) => Promise<MediaSearchResult[]>;
|
||||
getByYearMonth: () => Promise<{ year: number; month: number; count: number }[]>;
|
||||
getTags: () => Promise<string[]>;
|
||||
getTagsWithCounts: () => Promise<TagCount[]>;
|
||||
};
|
||||
postMedia: {
|
||||
link: (postId: string, mediaId: string) => Promise<MediaLinkData>;
|
||||
unlink: (postId: string, mediaId: string) => Promise<void>;
|
||||
linkMany: (postId: string, mediaIds: string[]) => Promise<{ linked: string[]; skipped: string[] }>;
|
||||
unlinkMany: (postId: string, mediaIds: string[]) => Promise<{ unlinked: string[] }>;
|
||||
getForPost: (postId: string) => Promise<MediaLinkData[]>;
|
||||
getForMedia: (mediaId: string) => Promise<MediaLinkData[]>;
|
||||
getMediaDataForPost: (postId: string) => Promise<Array<MediaLinkData & { media: MediaData }>>;
|
||||
reorder: (postId: string, mediaIds: string[]) => Promise<void>;
|
||||
isLinked: (postId: string, mediaId: string) => Promise<boolean>;
|
||||
import: (postId: string, filePath: string) => Promise<MediaLinkData>;
|
||||
rebuild: () => Promise<void>;
|
||||
};
|
||||
sync: {
|
||||
configure: (config: SyncConfig) => Promise<void>;
|
||||
start: (direction?: 'push' | 'pull' | 'bidirectional') => Promise<SyncResult>;
|
||||
getStatus: () => Promise<'idle' | 'syncing' | 'error'>;
|
||||
isConfigured: () => Promise<boolean>;
|
||||
getPendingCount: () => Promise<{ posts: number; media: number }>;
|
||||
getLog: (limit?: number) => Promise<unknown[]>;
|
||||
stopAutoSync: () => Promise<void>;
|
||||
};
|
||||
tasks: {
|
||||
getAll: () => Promise<TaskProgress[]>;
|
||||
getRunning: () => Promise<TaskProgress[]>;
|
||||
cancel: (taskId: string) => Promise<boolean>;
|
||||
clearCompleted: () => Promise<void>;
|
||||
};
|
||||
app: {
|
||||
getDataPaths: () => Promise<{ database: string; posts: string; media: string }>;
|
||||
openFolder: (folderPath: string) => Promise<string>;
|
||||
showItemInFolder: (itemPath: string) => Promise<void>;
|
||||
selectFolder: (title?: string) => Promise<string | null>;
|
||||
getDefaultProjectPath: (projectId: string) => Promise<string>;
|
||||
readProjectMetadata: (folderPath: string) => Promise<{ name?: string; description?: string; mainLanguage?: string } | null>;
|
||||
};
|
||||
meta: {
|
||||
getTags: () => Promise<string[]>;
|
||||
getCategories: () => Promise<string[]>;
|
||||
addTag: (tag: string) => Promise<string[]>;
|
||||
removeTag: (tag: string) => Promise<string[]>;
|
||||
addCategory: (category: string) => Promise<string[]>;
|
||||
removeCategory: (category: string) => Promise<string[]>;
|
||||
syncOnStartup: () => Promise<{ tags: string[]; categories: string[]; projectMetadata: ProjectMetadata | null }>;
|
||||
getProjectMetadata: () => Promise<ProjectMetadata | null>;
|
||||
setProjectMetadata: (metadata: { name: string; description?: string }) => Promise<ProjectMetadata | null>;
|
||||
updateProjectMetadata: (updates: { name?: string; description?: string; dataPath?: string; mainLanguage?: string }) => Promise<ProjectMetadata | null>;
|
||||
};
|
||||
tags: {
|
||||
getAll: () => Promise<TagData[]>;
|
||||
getWithCounts: () => Promise<TagWithCount[]>;
|
||||
get: (id: string) => Promise<TagData | null>;
|
||||
getByName: (name: string) => Promise<TagData | null>;
|
||||
create: (data: { name: string; color?: string }) => Promise<TagData>;
|
||||
update: (id: string, data: { name?: string; color?: string | null }) => Promise<TagData | null>;
|
||||
delete: (id: string) => Promise<DeleteTagResult>;
|
||||
merge: (sourceTagIds: string[], targetTagId: string) => Promise<MergeTagsResult>;
|
||||
rename: (id: string, newName: string) => Promise<RenameTagResult>;
|
||||
getPostsWithTag: (tagId: string) => Promise<string[]>;
|
||||
syncFromPosts: () => Promise<SyncTagsResult>;
|
||||
};
|
||||
import: {
|
||||
selectAndAnalyze: (uploadsFolder?: string) => Promise<unknown>;
|
||||
analyzeFile: (filePath: string, uploadsFolder?: string) => Promise<unknown>;
|
||||
selectUploadsFolder: () => Promise<string | null>;
|
||||
execute: (reportJson: string, uploadsFolder?: string) => Promise<ImportExecuteResult>;
|
||||
onProgress: (callback: (data: { step: string; detail?: string }) => void) => () => void;
|
||||
onExecutionProgress: (callback: (data: ImportExecutionProgress) => void) => () => void;
|
||||
onComplete: (callback: (data: ImportCompleteResult) => void) => () => void;
|
||||
};
|
||||
importDefinitions: {
|
||||
create: (name?: string) => Promise<ImportDefinitionData>;
|
||||
get: (id: string) => Promise<ImportDefinitionData | null>;
|
||||
getAll: () => Promise<ImportDefinitionData[]>;
|
||||
update: (id: string, updates: Partial<Pick<ImportDefinitionData, 'name' | 'wxrFilePath' | 'uploadsFolderPath' | 'lastAnalysisResult'>>) => Promise<ImportDefinitionData | null>;
|
||||
delete: (id: string) => Promise<boolean>;
|
||||
onNameUpdated: (callback: (data: { definitionId: string; name: string }) => void) => () => void;
|
||||
};
|
||||
chat: {
|
||||
// API Key Management
|
||||
checkReady: () => Promise<ChatReadyStatus>;
|
||||
validateApiKey: (apiKey: string) => Promise<{ isValid: boolean; models: ChatModel[] }>;
|
||||
setApiKey: (apiKey: string) => Promise<{ success: boolean; error?: string }>;
|
||||
getApiKey: () => Promise<ChatApiKeyStatus>;
|
||||
|
||||
// Settings
|
||||
getAvailableModels: () => Promise<{ success: boolean; models?: ChatModel[]; selectedModel?: string; error?: string }>;
|
||||
setDefaultModel: (modelId: string) => Promise<{ success: boolean; error?: string }>;
|
||||
getSystemPrompt: () => Promise<{ success: boolean; prompt?: string; error?: string }>;
|
||||
setSystemPrompt: (prompt: string) => Promise<{ success: boolean; error?: string }>;
|
||||
|
||||
// Conversations
|
||||
getConversations: () => Promise<ChatConversation[]>;
|
||||
createConversation: (title?: string, model?: string) => Promise<ChatConversation>;
|
||||
getConversation: (id: string) => Promise<ChatConversation | null>;
|
||||
updateConversation: (id: string, updates: { title?: string; model?: string }) => Promise<ChatConversation | null>;
|
||||
deleteConversation: (id: string) => Promise<boolean>;
|
||||
|
||||
// Messaging
|
||||
sendMessage: (conversationId: string, message: string) => Promise<{ success: boolean; message?: string; error?: string }>;
|
||||
abortMessage: (conversationId: string) => Promise<void>;
|
||||
getHistory: (conversationId: string) => Promise<ChatMessage[]>;
|
||||
clearMessages: (conversationId: string) => Promise<void>;
|
||||
setConversationModel: (conversationId: string, modelId: string) => Promise<void>;
|
||||
|
||||
// Taxonomy Analysis
|
||||
analyzeTaxonomy: (categories: Array<{ name: string; slug: string; existsInProject: boolean }>, tags: Array<{ name: string; slug: string; existsInProject: boolean }>, modelId: string) => Promise<{ success: boolean; categoryMappings?: Record<string, string>; tagMappings?: Record<string, string>; error?: string }>;
|
||||
|
||||
// Media Analysis
|
||||
analyzeMediaImage: (mediaId: string, language?: string) => Promise<{ success: boolean; title?: string; alt?: string; caption?: string; error?: string }>;
|
||||
|
||||
// Event listeners for streaming/progress
|
||||
onStreamDelta: (callback: (data: ChatStreamDelta) => void) => () => void;
|
||||
onToolCall: (callback: (data: ChatToolCall) => void) => () => void;
|
||||
onToolResult: (callback: (data: ChatToolResult) => void) => () => void;
|
||||
onTitleUpdated: (callback: (data: ChatTitleUpdate) => void) => () => void;
|
||||
};
|
||||
on: (channel: string, callback: (...args: unknown[]) => void) => () => void;
|
||||
once: (channel: string, callback: (...args: unknown[]) => void) => void;
|
||||
}
|
||||
import type { ElectronAPI } from '../../main/shared/electronApi';
|
||||
|
||||
declare global {
|
||||
interface Window {
|
||||
|
||||
Reference in New Issue
Block a user