import type { AttachmentsApi } from '@startsimpli/api' import type { ChatMessageData } from '../chat/types' import type { SlideData } from '../slide-deck/types' /** * @startsimpli/ui/presentations — the deck-builder page composer contract. * * `DeckBuilder` is the pure view-model interface the `DeckBuilderWorkspace` * composer consumes. It is deliberately engine-agnostic: any orchestrator that * satisfies this shape (a demo/no-backend engine, or the backend workflow-run * consumer) can drive the same dual-pane surface. The concrete orchestrators * live in the consuming app (present-web); this package owns only the surface + * the contract it renders against. */ export type DeckBuilderPhase = 'empty' | 'review_first' | 'walking' | 'ready' /** * The deck's ONE derived style spec, surfaced for display on the toolbar * (theme/palette/font/mood). `source: 'reference'` marks a style cloned from an * uploaded reference image (the design-cloning path). Display-only — the * orchestrator owns styling. */ export interface DeckStyle { theme?: string palette?: string font?: string mood?: string source?: string } /** * The orchestrator contract driving the dual-pane deck builder. Required fields * are what every engine must provide; the rest are optional capabilities the * surface lights up when present (per-slide actions, export urls, reference * attachments, a derived style chip). */ export interface DeckBuilder { deckTitle: string phase: DeckBuilderPhase messages: ChatMessageData[] slides: SlideData[] activeId?: string pptxUrl?: string pdfUrl?: string /** True while a turn is being processed (agent thinking / slides generating). */ isWorking?: boolean /** The backend-derived style spec, surfaced for a compact toolbar chip. */ deckStyle?: DeckStyle /** * True when this engine has a real backend document that reference uploads can * land on. A local/demo engine omits it, so the composer suppresses the attach * affordance and never strands a file as a forever-queued chip. */ supportsAttachments?: boolean /** * The active document id (the deck being edited), once one exists. Drives * document-scoped reference-attachment uploads + reopen hydration. Undefined * for a brand-new deck until the first turn creates it, and for a demo engine. */ documentId?: string /** * Reference-attachments client (e.g. `@startsimpli/api` `api.attachments`). * Ride it on the builder so the composer stays a `{ builder }`-only surface: * the composer wires it as the chat composer's uploader and reads persisted * references off it on reopen. Omit on engines without a backend document. */ attachments?: AttachmentsApi setActiveId: (id: string) => void sendMessage: (text: string) => void regenerate: (slide: SlideData) => void /** Delete a slide (dispatched as an agent turn). Optional — demo engine omits it. */ deleteSlide?: (slide: SlideData) => void /** Move a slide one position left/right (dispatched as an agent turn). Optional. */ moveSlide?: (slide: SlideData, direction: 'left' | 'right') => void /** Insert a blank slide after the given slide (dispatched as an agent turn). Optional. */ insertSlide?: (afterSlide: SlideData) => void /** Edit a slide's title/content then regenerate it (dispatched as an agent turn). Optional. */ editSlide?: (slide: SlideData, edits: { title?: string; content?: string }) => void /** Drag-reorder: move the slide at fromIndex to toIndex (0-based; agent turn). Optional. */ reorderSlide?: (fromIndex: number, toIndex: number) => void }