/** * IPC API type definitions for Electron preload bridge. * * These types define the interface exposed to the renderer process * via contextBridge. The actual implementation lives in src/preload/index.ts. * * Shared between preload and renderer processes. */ import type { AppConfig, DetectedError, NotificationTrigger, TriggerTestResult, } from './notifications'; import type { WaterfallData } from './visualization'; import type { ConversationGroup, FileChangeEvent, PaginatedSessionsResult, Project, RepositoryGroup, SearchSessionsResult, Session, SessionDetail, SessionMetrics, SessionsByIdsOptions, SessionsPaginationOptions, SubagentDetail, } from '@main/types'; // ============================================================================= // Notifications API // ============================================================================= /** * Result of notifications:get with pagination. */ interface NotificationsResult { notifications: DetectedError[]; total: number; totalCount: number; unreadCount: number; hasMore: boolean; } /** * Notifications API exposed via preload. * Note: Event callbacks use `unknown` types because IPC data cannot be typed at the preload layer. * Consumers should cast to DetectedError or NotificationClickData as appropriate. */ export interface NotificationsAPI { get: (options?: { limit?: number; offset?: number }) => Promise; markRead: (id: string) => Promise; markAllRead: () => Promise; delete: (id: string) => Promise; clear: () => Promise; getUnreadCount: () => Promise; onNew: (callback: (event: unknown, error: unknown) => void) => () => void; onUpdated: ( callback: (event: unknown, payload: { total: number; unreadCount: number }) => void ) => () => void; onClicked: (callback: (event: unknown, data: unknown) => void) => () => void; } // ============================================================================= // Config API // ============================================================================= /** * Config API exposed via preload. */ export interface ConfigAPI { get: () => Promise; update: (section: string, data: object) => Promise; addIgnoreRegex: (pattern: string) => Promise; removeIgnoreRegex: (pattern: string) => Promise; addIgnoreRepository: (repositoryId: string) => Promise; removeIgnoreRepository: (repositoryId: string) => Promise; snooze: (minutes: number) => Promise; clearSnooze: () => Promise; // Trigger management methods addTrigger: (trigger: Omit) => Promise; updateTrigger: (triggerId: string, updates: Partial) => Promise; removeTrigger: (triggerId: string) => Promise; getTriggers: () => Promise; testTrigger: (trigger: NotificationTrigger) => Promise; /** Opens native folder selection dialog and returns selected paths */ selectFolders: () => Promise; /** Open native dialog to select local Claude root folder */ selectClaudeRootFolder: () => Promise; /** Get resolved Claude root path info for local mode */ getClaudeRootInfo: () => Promise; /** Find Windows WSL Claude root candidates (UNC paths) */ findWslClaudeRoots: () => Promise; /** Opens the config JSON file in an external editor */ openInEditor: () => Promise; /** Pin a session for a project */ pinSession: (projectId: string, sessionId: string) => Promise; /** Unpin a session for a project */ unpinSession: (projectId: string, sessionId: string) => Promise; /** Hide a session for a project */ hideSession: (projectId: string, sessionId: string) => Promise; /** Unhide a session for a project */ unhideSession: (projectId: string, sessionId: string) => Promise; /** Bulk hide sessions for a project */ hideSessions: (projectId: string, sessionIds: string[]) => Promise; /** Bulk unhide sessions for a project */ unhideSessions: (projectId: string, sessionIds: string[]) => Promise; } export interface ClaudeRootInfo { /** Auto-detected default Claude root path for this machine */ defaultPath: string; /** Effective path currently used by local context */ resolvedPath: string; /** Custom override path from settings (null means auto-detect) */ customPath: string | null; } export interface ClaudeRootFolderSelection { /** Selected directory absolute path */ path: string; /** Whether the selected folder name is exactly ".claude" */ isClaudeDirName: boolean; /** Whether selected folder contains a "projects" directory */ hasProjectsDir: boolean; } export interface WslClaudeRootCandidate { /** WSL distribution name (e.g. Ubuntu) */ distro: string; /** Candidate Claude root path in UNC format */ path: string; /** True if this root contains "projects" directory */ hasProjectsDir: boolean; } // ============================================================================= // Session API // ============================================================================= /** * Session navigation API exposed via preload. */ export interface SessionAPI { scrollToLine: (sessionId: string, lineNumber: number) => Promise; } // ============================================================================= // CLAUDE.md File Info // ============================================================================= /** * CLAUDE.md file information returned from reading operations. */ export interface ClaudeMdFileInfo { path: string; exists: boolean; charCount: number; estimatedTokens: number; } // ============================================================================= // Updater API // ============================================================================= /** * Status payload sent from the main process updater to the renderer. */ export interface UpdaterStatus { type: 'checking' | 'available' | 'not-available' | 'downloading' | 'downloaded' | 'error'; version?: string; releaseNotes?: string; progress?: { percent: number; transferred: number; total: number }; error?: string; } /** * Updater API exposed via preload. */ export interface UpdaterAPI { check: () => Promise; download: () => Promise; install: () => Promise; onStatus: (callback: (event: unknown, status: unknown) => void) => () => void; } // ============================================================================= // Context API // ============================================================================= /** * Context information for listing available contexts. */ export interface ContextInfo { id: string; type: 'local' | 'ssh'; } // ============================================================================= // SSH API // ============================================================================= /** * SSH connection state. */ export type SshConnectionState = 'disconnected' | 'connecting' | 'connected' | 'error'; /** * SSH authentication method. */ export type SshAuthMethod = 'password' | 'privateKey' | 'agent' | 'auto'; /** * SSH config host entry resolved from ~/.ssh/config. */ export interface SshConfigHostEntry { alias: string; hostName?: string; user?: string; port?: number; hasIdentityFile: boolean; } /** * SSH connection configuration sent from renderer. */ export interface SshConnectionConfig { host: string; port: number; username: string; authMethod: SshAuthMethod; password?: string; privateKeyPath?: string; } /** * Saved SSH connection profile (no password stored). */ export interface SshConnectionProfile { id: string; name: string; host: string; port: number; username: string; authMethod: SshAuthMethod; privateKeyPath?: string; } /** * SSH connection status returned from main process. */ export interface SshConnectionStatus { state: SshConnectionState; host: string | null; error: string | null; remoteProjectsPath: string | null; } /** * SSH API exposed via preload. */ /** * Saved SSH connection config (no password). */ export interface SshLastConnection { host: string; port: number; username: string; authMethod: SshAuthMethod; privateKeyPath?: string; } export interface SshAPI { connect: (config: SshConnectionConfig) => Promise; disconnect: () => Promise; getState: () => Promise; test: (config: SshConnectionConfig) => Promise<{ success: boolean; error?: string }>; getConfigHosts: () => Promise; resolveHost: (alias: string) => Promise; saveLastConnection: (config: SshLastConnection) => Promise; getLastConnection: () => Promise; onStatus: (callback: (event: unknown, status: SshConnectionStatus) => void) => () => void; } // ============================================================================= // HTTP Server API // ============================================================================= /** * HTTP server status returned from main process. */ export interface HttpServerStatus { running: boolean; port: number; } /** * HTTP Server API for controlling the sidecar server. */ export interface HttpServerAPI { start: () => Promise; stop: () => Promise; getStatus: () => Promise; } // ============================================================================= // Main Electron API // ============================================================================= /** * Complete Electron API exposed to the renderer process via preload script. */ export interface ElectronAPI { getAppVersion: () => Promise; getProjects: () => Promise; getSessions: (projectId: string) => Promise; getSessionsPaginated: ( projectId: string, cursor: string | null, limit?: number, options?: SessionsPaginationOptions ) => Promise; searchSessions: ( projectId: string, query: string, maxResults?: number ) => Promise; getSessionDetail: (projectId: string, sessionId: string) => Promise; getSessionMetrics: (projectId: string, sessionId: string) => Promise; getWaterfallData: (projectId: string, sessionId: string) => Promise; getSubagentDetail: ( projectId: string, sessionId: string, subagentId: string ) => Promise; getSessionGroups: (projectId: string, sessionId: string) => Promise; getSessionsByIds: ( projectId: string, sessionIds: string[], options?: SessionsByIdsOptions ) => Promise; // Repository grouping (worktree support) getRepositoryGroups: () => Promise; getWorktreeSessions: (worktreeId: string) => Promise; // Validation methods validatePath: ( relativePath: string, projectPath: string ) => Promise<{ exists: boolean; isDirectory?: boolean }>; validateMentions: ( mentions: { type: 'path'; value: string }[], projectPath: string ) => Promise>; // CLAUDE.md reading methods readClaudeMdFiles: (projectRoot: string) => Promise>; readDirectoryClaudeMd: (dirPath: string) => Promise; readMentionedFile: ( absolutePath: string, projectRoot: string, maxTokens?: number ) => Promise; // Notifications API notifications: NotificationsAPI; // Config API config: ConfigAPI; // Deep link navigation session: SessionAPI; // Window zoom sync (for traffic-light-safe layout) getZoomFactor: () => Promise; onZoomFactorChanged: (callback: (zoomFactor: number) => void) => () => void; // File change events (real-time updates) onFileChange: (callback: (event: FileChangeEvent) => void) => () => void; onTodoChange: (callback: (event: FileChangeEvent) => void) => () => void; // Shell operations openPath: ( targetPath: string, projectRoot?: string ) => Promise<{ success: boolean; error?: string }>; openExternal: (url: string) => Promise<{ success: boolean; error?: string }>; // Window controls (when title bar is hidden, e.g. Windows / Linux) windowControls: { minimize: () => Promise; maximize: () => Promise; close: () => Promise; isMaximized: () => Promise; }; // Updater API updater: UpdaterAPI; // SSH API ssh: SshAPI; // Context API context: { list: () => Promise; getActive: () => Promise; switch: (contextId: string) => Promise<{ contextId: string }>; onChanged: (callback: (event: unknown, data: ContextInfo) => void) => () => void; }; // HTTP Server API httpServer: HttpServerAPI; } // ============================================================================= // Window Type Extension // ============================================================================= declare global { interface Window { electronAPI: ElectronAPI; } }