// IPC contract types — typed request/response pairs for every channel import type { GitDetectionResult, RepoStatus, ChangedFile, Commit, CommitDetail, CommitFile, Branch, Tag, Remote, StashEntry, FileDiff, GraphData, ConflictFile, BlameEntry, Repository, } from './git.types' import type { ProviderAccount, ProviderRepo, PullRequest, CreatePRInput } from './provider.types' // Generic IPC result wrapper export interface IpcResult { success: boolean data?: T error?: string code?: string } // App settings shape export interface AppSettings { gitPath: string | null // null = auto-detect theme: 'dark' // only dark for now diffLayout: 'split' | 'unified' preferredEditor: string | null preferredTerminal: string | null autoFetch: boolean autoFetchInterval: number // minutes pullStrategy: 'merge' | 'rebase' | 'ff-only' showHiddenFiles: boolean confirmDestructive: boolean } // Clone progress export interface CloneProgress { phase: string percent: number receivedObjects: number totalObjects: number } // Operation progress (fetch/pull/push) export interface OperationProgress { operation: 'fetch' | 'pull' | 'push' phase: string percent: number message: string } // The complete, strongly typed API surface exposed to the renderer via window.flowgit export interface FlowGitApi { getVersion: () => Promise window: { minimize: () => Promise maximize: () => Promise close: () => Promise isMaximized: () => Promise } openDirectory: (options?: { title?: string }) => Promise openPath: (path: string) => Promise detectGit: () => Promise getGitVersion: () => Promise repo: { open: (path: string) => Promise> init: (path: string) => Promise> clone: (url: string, targetPath: string, onProgress?: (p: unknown) => void) => Promise> getStatus: (repoPath: string) => Promise> list: () => Promise> add: (repoPath: string) => Promise> remove: (repoId: string) => Promise> refresh: (repoPath: string) => Promise> } changes: { get: (repoPath: string) => Promise> stage: (repoPath: string, filePath: string) => Promise> unstage: (repoPath: string, filePath: string) => Promise> stageAll: (repoPath: string) => Promise> unstageAll: (repoPath: string) => Promise> discard: (repoPath: string, filePath: string) => Promise> discardAll: (repoPath: string) => Promise> stageHunk: (repoPath: string, filePath: string, hunkIndex: number) => Promise> unstageHunk: (repoPath: string, filePath: string, hunkIndex: number) => Promise> } commit: { create: (repoPath: string, message: string, options?: { amend?: boolean }) => Promise> amend: (repoPath: string, message: string) => Promise> cherryPick: (repoPath: string, hash: string) => Promise> revert: (repoPath: string, hash: string) => Promise> } diff: { file: (repoPath: string, filePath: string, options?: { staged?: boolean; ref?: string }) => Promise> commit: (repoPath: string, hash: string) => Promise> commits: (repoPath: string, fromHash: string, toHash: string) => Promise> branch: (repoPath: string, branchA: string, branchB: string) => Promise> } history: { log: (repoPath: string, options?: { skip?: number; limit?: number; ref?: string; author?: string; search?: string }) => Promise> graph: (repoPath: string, options?: { limit?: number }) => Promise> getCommit: (repoPath: string, hash: string) => Promise> getCommitFiles: (repoPath: string, hash: string) => Promise> } branch: { list: (repoPath: string) => Promise> create: (repoPath: string, name: string, from?: string) => Promise> rename: (repoPath: string, oldName: string, newName: string) => Promise> switch: (repoPath: string, name: string) => Promise> delete: (repoPath: string, name: string, force?: boolean) => Promise> merge: (repoPath: string, source: string, options?: { strategy?: string }) => Promise> rebase: (repoPath: string, onto: string) => Promise> } tag: { list: (repoPath: string) => Promise> create: (repoPath: string, name: string, ref: string, message?: string) => Promise> delete: (repoPath: string, name: string) => Promise> push: (repoPath: string, remote: string, tagName: string) => Promise> } stash: { list: (repoPath: string) => Promise> create: (repoPath: string, message?: string, includeUntracked?: boolean) => Promise> apply: (repoPath: string, index: number) => Promise> pop: (repoPath: string, index: number) => Promise> drop: (repoPath: string, index: number) => Promise> } remote: { list: (repoPath: string) => Promise> add: (repoPath: string, name: string, url: string) => Promise> remove: (repoPath: string, name: string) => Promise> fetch: (repoPath: string, remote?: string) => Promise> pull: (repoPath: string, remote?: string, branch?: string) => Promise> push: (repoPath: string, remote?: string, branch?: string, force?: boolean) => Promise> } conflict: { list: (repoPath: string) => Promise> markResolved: (repoPath: string, filePath: string) => Promise> continue: (repoPath: string) => Promise> abort: (repoPath: string) => Promise> } provider: { list: () => Promise> connect: (type: string, token: string, baseUrl?: string) => Promise> disconnect: (id: string) => Promise> getRepos: (accountId: string) => Promise> getPRs: (repoPath: string, accountId: string) => Promise> createPR: (repoPath: string, accountId: string, input: CreatePRInput) => Promise> } settings: { get: () => Promise set: (key: keyof AppSettings, value: unknown) => Promise<{ success: boolean; error?: string }> } terminal: { create: (repoPath: string) => Promise sendInput: (id: string, data: string) => void resize: (id: string, cols: number, rows: number) => void destroy: (id: string) => void onData: (id: string, callback: (data: string) => void) => () => void } blame: { file: (repoPath: string, filePath: string, ref?: string) => Promise> } }