import { contextBridge, ipcRenderer } from "electron"; interface SetupState { needsSetup: boolean; sourceDir: string | null; sourceRepoUrl: string; imageRepoUrl: string; imageBaseUrl: string; } interface SetupRunInput { mode: "url" | "zip"; sourceRepoUrl?: string; sourceZipPath?: string; imageRepoUrl?: string; imageBaseUrl?: string; downloadImages?: boolean; } interface SetupRunResult { ok: boolean; error?: string; } type CharacterEntityType = "class" | "background" | "species"; type CharacterSourceBucket = "homebrew" | "core2024" | "expanded2024" | "core2014" | "expanded2014"; interface CharacterSelectionOption { entityType: CharacterEntityType; name: string; source: string; hash: string; entityRef: string; details: string; sourceName: string; sourceGroup: string | null; sourcePublished: string | null; sourceBucket: CharacterSourceBucket; sourceEdition: "2014" | "2024" | null; imagePath: string | null; summary: string; } interface CharacterFeatureOption { name: string; source: string; hash: string; entityRef: string; details: string; } interface CharacterFeatureCard { id: string; title: string; level: number | null; summary: string; options?: CharacterFeatureOption[]; } interface CharacterSelectionDetail extends CharacterSelectionOption { featureCards: CharacterFeatureCard[]; rawJson: string; } interface CharacterSelectionOptionSets { classes: CharacterSelectionOption[]; backgrounds: CharacterSelectionOption[]; species: CharacterSelectionOption[]; } interface CharacterEntityRef { entityType: "class" | "subclass" | "background" | "species" | "item" | "feat" | "spell"; name: string; source: string; hash: string; entityRef: string; } interface CharacterProfile { name: string; level: number; alignment: string; faith: string; lifestyle: string; age: string; gender: string; height: string; weight: string; eyes: string; skin: string; hair: string; } interface CharacterPreferencesStep { sourceBuckets: string[]; useOptionalClassFeatures: boolean; customizeOrigin: boolean; advancementType: "milestone" | "xp"; hpMode: "average" | "maximum" | "rolled"; usePrerequisitesFeats: boolean; usePrerequisitesMulticlass: boolean; } interface CharacterAbilityScoresStep { method: "standardArray" | "pointBuy" | "manual" | "rolled"; scores: Record<"str" | "dex" | "con" | "int" | "wis" | "cha", number>; rolledValues: [number, number, number, number, number, number]; assignments: Record<"str" | "dex" | "con" | "int" | "wis" | "cha", number>; backgroundBonusModeIndex: number; backgroundBonusSelections: Array<"str" | "dex" | "con" | "int" | "wis" | "cha">; } interface CharacterFeatsStep { selected: string[]; notes: string; } interface CharacterSkillsStep { selected: string[]; notes: string; } interface CharacterSpellsStep { selected: string[]; notes: string; } interface CharacterEquipmentStep { startingEquipmentText: string; inventoryText: string; possessionsText: string; currency: Record<"cp" | "sp" | "ep" | "gp" | "pp", number>; } interface CharacterAboutStep { personality: string; ideals: string; bonds: string; flaws: string; backstory: string; notes: string; } interface CharacterDocument { schema: "5etd.character"; version: 1; id: string; createdAt: string; updatedAt: string; profile: CharacterProfile; selections: { class: CharacterEntityRef | null; subclass: CharacterEntityRef | null; background: CharacterEntityRef | null; species: CharacterEntityRef | null; }; steps: { preferences: CharacterPreferencesStep; abilityScores: CharacterAbilityScoresStep; feats: CharacterFeatsStep; skills: CharacterSkillsStep; spells: CharacterSpellsStep; equipment: CharacterEquipmentStep; about: CharacterAboutStep; }; notes: string; } interface CharacterSummary { id: string; name: string; level: number; className: string | null; backgroundName: string | null; speciesName: string | null; createdAt: string; updatedAt: string; } interface CharacterUpsertInput { id?: string; profile?: Partial; selections?: Partial; steps?: Partial; notes?: string; createdAt?: string; } contextBridge.exposeInMainWorld("desktopApi", { getWikiUrl: () => ipcRenderer.invoke("wiki:get-url") as Promise, getSetupState: () => ipcRenderer.invoke("setup:get-state") as Promise, pickSourceZip: () => ipcRenderer.invoke("setup:pick-source-zip") as Promise, runSetup: (input: SetupRunInput) => ipcRenderer.invoke("setup:run", input) as Promise, resetOnboarding: () => ipcRenderer.invoke("setup:reset-onboarding") as Promise, listCharacters: () => ipcRenderer.invoke("characters:list") as Promise, getCharacter: (id: string) => ipcRenderer.invoke("characters:get", id) as Promise, saveCharacter: (input: CharacterUpsertInput) => ipcRenderer.invoke("characters:save", input) as Promise, deleteCharacter: (id: string) => ipcRenderer.invoke("characters:delete", id) as Promise, getCharacterOptions: () => ipcRenderer.invoke("characters:get-options") as Promise, getCharacterOptionDetail: (entityRef: string) => ipcRenderer.invoke("characters:get-option-detail", entityRef) as Promise, pickCharacterJson: () => ipcRenderer.invoke("characters:pick-json") as Promise, importCharacterJson: (filePath: string) => ipcRenderer.invoke("characters:import-json", filePath) as Promise });