import type { PluginJsonValue } from "./index"; /** Public, portable contracts for structured note editing. */ export type PluginNoteKind = "text" | "mind-map" | "flowchart" | "architecture" | "table" | "poster" | "infographic" | "video"; export interface PluginContentNode { type: string; text?: string; attrs?: Record; marks?: Array<{ type: string; attrs?: Record; }>; content?: PluginContentNode[]; } export interface PluginContentDocument { type: "doc"; content: PluginContentNode[]; } export interface PluginStructuredEditInput { expectedRevision: number; expectedContentHash: string; /** Snapshot token from diagrams.get()/tables.get(); also detects unsynced local edits. */ expectedEditToken: string; /** Validate and preview without saving. */ dryRun?: boolean; } export type PluginDiagramNodeType = "topic" | "process" | "decision" | "start" | "end" | "terminator" | "client" | "frontend" | "service" | "database" | "storage" | "queue" | "security" | "external" | "boundary"; export interface PluginDiagramNode { id: string; label: string; type?: PluginDiagramNodeType; parentId?: string; resourceIcon?: string; } export interface PluginDiagramEdge { id?: string; source: string; target: string; label?: string; type?: "dependency" | "request" | "async" | "data"; bidirectional?: boolean; } export interface PluginDiagramGraph { kind: "mind-map" | "flowchart" | "architecture"; theme?: string; structure?: string; nodes: Array; edges: Array; } export type PluginDiagramOperation = { op: "add_node"; node: PluginDiagramNode; } | { op: "update_node"; nodeId: string; changes: Partial> & { parentId?: string | null; resourceIcon?: string | null; }; } | { op: "remove_node"; nodeId: string; cascade?: boolean; } | { op: "add_edge"; edge: PluginDiagramEdge; } | { op: "update_edge"; edgeId: string; changes: Partial> & { label?: string | null; type?: PluginDiagramEdge["type"] | null; bidirectional?: boolean | null; }; } | { op: "remove_edge"; edgeId: string; }; export interface PluginDiagramEditInput extends PluginStructuredEditInput { operations: PluginDiagramOperation[]; reflow?: "preserve" | "all"; } export type PluginTableFieldType = "text" | "number" | "checkbox" | "date" | "select" | "url" | "attachment"; export interface PluginTableField { id: string; name: string; type: PluginTableFieldType; options?: string[]; } export interface PluginTableAttachment { resourceId: string; filename: string; mimeType: string; byteSize: number; } export type PluginTableCell = string | number | boolean | null | PluginTableAttachment[]; /** Attachment writes use resource IDs; the host resolves their metadata and ownership. */ export type PluginTableCellInput = string | number | boolean | null | string[]; export interface PluginTableDocument { schemaVersion: 1; fields: PluginTableField[]; records: Array<{ id: string; cells: Record; }>; view: { filters: Array<{ fieldId: string; operator: "contains" | "eq" | "empty" | "notEmpty"; value?: string; }>; sort: { fieldId: string; direction: "asc" | "desc"; } | null; }; } export type PluginTableOperation = { op: "add_field"; field: Omit; } | { op: "update_field"; fieldId: string; changes: Partial>; } | { op: "remove_field"; fieldId: string; } | { op: "add_record"; recordId?: string; cells?: Record; } | { op: "update_record"; recordId: string; cells: Record; } | { op: "remove_record"; recordId: string; }; export interface PluginTableEditInput extends PluginStructuredEditInput { operations: PluginTableOperation[]; /** Required if a schema change converts or removes populated cells. */ allowDataChanges?: boolean; } export interface PluginPosterGradient { kind: "linear" | "radial"; from: string; to: string; angle: number; } export interface PluginPosterPaintGradient extends PluginPosterGradient { stops?: Array<{ offset: number; color: string; opacity?: number; }>; coords?: { x1: number; y1: number; x2: number; y2: number; r1?: number; r2?: number; }; } export interface PluginPosterShadow { color: string; blur: number; offsetX: number; offsetY: number; } export interface PluginPosterCrop { x: number; y: number; width: number; height: number; } export interface PluginPosterBadge { background: string; padX: number; padY: number; radius: number; } export interface PluginPosterGeometry { id: string; name: string; role?: "title" | "subtitle" | "badge" | "decor"; x: number; y: number; width: number; height: number; rotation: number; opacity: number; visible?: boolean; locked?: boolean; groupId?: string; imagePlaceholder?: boolean; flipX?: boolean; flipY?: boolean; stroke?: string; strokeWidth?: number; shadow?: PluginPosterShadow; gradient?: PluginPosterPaintGradient; } export type PluginPosterElement = PluginPosterGeometry & ({ type: "text"; text: string; sourceText?: string; fill: string; fontSize: number; fontFamily: string; fontStyle?: "normal" | "italic"; underline?: boolean; lineHeight?: number; charSpacing?: number; badge?: PluginPosterBadge; fontWeight: "normal" | "bold"; textAlign: "left" | "center" | "right"; } | { type: "rect" | "ellipse"; fill: string; radius?: number; } | { type: "image"; resourceId: string; crop?: PluginPosterCrop; } | { type: "path"; fill: string; path: string; }); export interface PluginPosterDocument { schemaVersion: 1; width: number; height: number; background: string; backgroundGradient?: PluginPosterGradient; elements: PluginPosterElement[]; copy?: { title: string; subtitle: string; badge: string; }; templateId?: string; platformId?: string; sourceMemoId?: string; previewResourceId?: string; } export type PluginPosterPatch = Partial> & { shadow?: PluginPosterShadow | null; gradient?: PluginPosterPaintGradient | null; crop?: PluginPosterCrop | null; badge?: PluginPosterBadge | null; text?: string; fill?: string; fontSize?: number; fontFamily?: string; fontStyle?: "normal" | "italic"; underline?: boolean; lineHeight?: number; charSpacing?: number; fontWeight?: "normal" | "bold"; textAlign?: "left" | "center" | "right"; radius?: number; resourceId?: string; path?: string; }; export type PluginPosterTemplate = "editorial" | "bold" | "minimal" | "quote"; export type PluginPosterOperation = { op: "add"; element: PluginPosterElement; } | { op: "remove" | "group" | "ungroup"; ids: string[]; } | { op: "duplicate"; ids: string[]; dx?: number; dy?: number; } | { op: "reorder"; ids: string[]; position: "front" | "back" | "forward" | "backward"; } | { op: "align"; ids: string[]; alignment: "left" | "center" | "right" | "top" | "middle" | "bottom"; } | { op: "lock"; ids: string[]; locked: boolean; } | { op: "apply_template"; template: PluginPosterTemplate; heading?: string; subtitle?: string; }; export interface PluginPosterEditInput extends PluginStructuredEditInput { edits?: Array<{ id: string; patch: PluginPosterPatch; }>; operations?: PluginPosterOperation[]; background?: string; backgroundGradient?: PluginPosterGradient | null; canvas?: { width: number; height: number; scaleElements?: boolean; }; platform?: string; } export interface PluginInfographicDocument { schemaVersion: 1; syntax: string; history?: Array<{ id: string; prompt: string; createdAt: string; kind: "generated" | "refined" | "clarified" | "failed"; resultTitle: string; response?: string; decision?: string; template?: string; error?: string; undoneAt?: string; }>; } export type PluginInfographicOperation = { op: "set_data"; path: Array; value: PluginJsonValue; } | { op: "remove_data"; path: Array; } | { op: "insert_data"; path: Array; index: number; value: PluginJsonValue; } | { op: "set_template"; template: string; } | { op: "set_theme"; theme: string; }; export interface PluginInfographicEditInput extends PluginStructuredEditInput { operations: PluginInfographicOperation[]; }