Technical referenceAPI signatures
Project and artwork API
Create documents, address stable IDs, and edit individual layers or elements. Read project concepts for ownership and the quickstart for a minimal executable operation.
Use the signatures below to check arguments and return types. A value after = is the default; ? marks an optional input. Named data shapes are listed in API types.
StoryboardProject
create
static create(options: ProjectOptions): StoryboardProject;fromJSON
static fromJSON(input: unknown, options: {
actor?: string;
} = {}): StoryboardProject;open
static async open(path: string, options: {
actor?: string;
} = {}): Promise<StoryboardProject>;id
get id(): string;title
get title(): string;canUndo
get canUndo(): boolean;canRedo
get canRedo(): boolean;version
get version(): number;toJSON
toJSON(): StoryboardDocument;previewComponentUpgrade
previewComponentUpgrade(instanceId: string, options: ComponentUpgradeOptions = {}): {
conflicts: ValueMergeConflict[];
incomingChanges: string[];
retainedLocalChanges: string[];
version: number;
instanceId: string;
sourceVersion: number;
owner: { kind: "panel" | "animation"; id: string; };
inputHash: string;
conflictsResolved: boolean;
};componentOriginData
componentOriginData(instanceId: string, options: PageOptions = {}): {
version: number;
instanceId: string;
componentId: string;
baselineVersion: number;
sha256: string;
instanceState: "missing" | "detached" | "matching" | "stale";
instanceSource: { id: Id; version: number; } | null;
libraryVersion: number | null;
offset: number;
limit: number;
total: number;
nextOffset: number | null;
items: { location: "missing" | "instance" | "elsewhere"; sourceId: string; copyId: string; }[];
};shotDependencyData
shotDependencyData(animationId: string, options: PageOptions = {}): {
version: number;
animationId: string;
dependencyHash: string;
total: number;
offset: number;
limit: number;
nextOffset: number | null;
items: ShotDependency[];
};studio
get studio(): import("../model/types/studio.js").StudioContent;boardPanels
boardPanels(options: PageOptions = {}): { id: string; shotId: string; startFrame: number; durationFrames: number; transition: Transition; width: number; height: number; revision: number; }[];shotAnimation
shotAnimation(id: string): ShotAnimation;editorialSequence
editorialSequence(id: string): EditorialSequence;shotCoordinates
shotCoordinates(animationId: string, targetId: string, options: CoordinateOptions = {}): ShotCoordinateSpace;shotControllerData
shotControllerData(animationId: string, controllerId: string, query: ShotControllerQuery = { collection: "keyframes" }): { collection: "targets" | "keyframes"; total: number; nextOffset: number | null; items: { frame: number; weight: number; easing: Easing; index: number; }[]; animationId: string; controllerId: string; name: string; mode: "replace" | "additive"; stackIndex: number; staticWeight: number; activeRange: { startFrame: number; endFrame: number; } | null; frame: number | null; evaluatedWeight: number | null; counts: { targets: number; keyframes: number; }; offset: number; limit: number; } | { collection: "targets" | "keyframes"; total: number; nextOffset: number | null; items: { evaluatedState: EvaluatedLayerState | null; layerId: string; values: Partial<Record<LayerChannel, number>>; index: number; }[]; animationId: string; controllerId: string; name: string; mode: "replace" | "additive"; stackIndex: number; staticWeight: number; activeRange: { startFrame: number; endFrame: number; } | null; frame: number | null; evaluatedWeight: number | null; counts: { targets: number; keyframes: number; }; offset: number; limit: number; };shotMeshData
shotMeshData(animationId: string, layerId: string, query: ShotMeshQuery = { collection: "keyframes" }): { animationId: string; layerId: string; bindingKind: "skin" | "mesh" | "curve" | "envelope"; curveRest: CurveMeshPose | null; curveSegments: number | null; envelopeRest: EnvelopeMeshPose | null; envelopeGrid: { columns: number; rows: number; } | null; collection: "joints"; offset: number; limit: number; total: number; nextOffset: number | null; counts: { joints: number; weights: number; vertices: number; triangles: number; keyframes: number; }; items: { layerId: string; id: string; bind: Readonly<AffineMatrix>; index: number; }[]; } | { animationId: string; layerId: string; bindingKind: "skin" | "mesh" | "curve" | "envelope"; curveRest: CurveMeshPose | null; curveSegments: number | null; envelopeRest: EnvelopeMeshPose | null; envelopeGrid: { columns: number; rows: number; } | null; collection: "weights"; offset: number; limit: number; total: number; nextOffset: number | null; counts: { joints: number; weights: number; vertices: number; triangles: number; keyframes: number; }; items: { index: number; influences: readonly { jointId: string; weight: number; }[]; }[]; } | { animationId: string; layerId: string; bindingKind: "skin" | "mesh" | "curve" | "envelope"; curveRest: CurveMeshPose | null; curveSegments: number | null; envelopeRest: EnvelopeMeshPose | null; envelopeGrid: { columns: number; rows: number; } | null; collection: "triangles"; offset: number; limit: number; total: number; nextOffset: number | null; counts: { joints: number; weights: number; vertices: number; triangles: number; keyframes: number; }; items: { index: number; vertices: number[]; }[]; } | { animationId: string; layerId: string; bindingKind: "skin" | "mesh" | "curve" | "envelope"; curveRest: CurveMeshPose | null; curveSegments: number | null; envelopeRest: EnvelopeMeshPose | null; envelopeGrid: { columns: number; rows: number; } | null; collection: "keyframes"; offset: number; limit: number; total: number; nextOffset: number | null; counts: { joints: number; weights: number; vertices: number; triangles: number; keyframes: number; }; items: { index: number; frame: number; easing: Easing; }[]; } | { frame: number | null; animationId: string; layerId: string; bindingKind: "skin" | "mesh" | "curve" | "envelope"; curveRest: CurveMeshPose | null; curveSegments: number | null; envelopeRest: EnvelopeMeshPose | null; envelopeGrid: { columns: number; rows: number; } | null; collection: "vertices"; offset: number; limit: number; total: number; nextOffset: number | null; counts: { joints: number; weights: number; vertices: number; triangles: number; keyframes: number; }; items: { x: number; y: number; index: number; }[]; };shotPointCoordinates
shotPointCoordinates(animationId: string, targetId: string, point: {
x: number;
y: number;
}, options: ShotPointOptions): {
animationId: string;
targetId: string;
frame: number;
direction: "localToFrame" | "frameToLocal";
candidates: ShotPointCandidate[];
};editorialClips
editorialClips(sequenceId: string, options: PageOptions = {}): EditorialClip[];scriptSummary
scriptSummary(): { id: string; title: string; revision: number; entryCount: number; } | null;palettes
palettes(options: PageOptions = {}): { id: string; name: string; swatchCount: number; }[];paletteSwatches
paletteSwatches(id: string, options: PageOptions = {}): PaletteSwatch[];paletteBindings
paletteBindings(swatchId: string, options: PageOptions = {}): PaletteBindingUsage[];putPalette
putPalette(palette: Palette): this;removePalette
removePalette(id: string): this;setColorBinding
setColorBinding(elementId: string, channel: ColorChannel, binding: ColorBinding | null): this;scriptEntries
scriptEntries(options: PageOptions = {}): ScriptEntry[];replaceScript
replaceScript(input: ScriptInput, expectedRevision: number): ScriptChangeReport;shotBoardPanels
shotBoardPanels(animationId: string, options: PageOptions = {}): { id: Id; shotId: Id; number: string; title: string; width: number; height: number; durationFrames: number; startFrame: number; transition: Transition; status: "working" | "review" | "approved"; action: string; dialogue: string; camera: string; notes: string; revision: number; }[];studioAudioTracks
studioAudioTracks(ownerId: string, options: PageOptions = {}): { clipCount: number; id: string; name: string; muted: boolean; }[];studioAudioClips
studioAudioClips(ownerId: string, trackId: string, options: PageOptions = {}): StudioAudioClip[];addShotElement
addShotElement(animationId: string, layerId: string, element: DrawingElement): this;removeShotElements
removeShotElements(animationId: string, layerId: string, ids: readonly string[]): this;reviseShotElement
reviseShotElement(animationId: string, layerId: string, id: string, element: DrawingElement): this;patchShotPixels
patchShotPixels(animationId: string, layerId: string, id: string, x: number, y: number, patch: import("../model/types.js").PixelBuffer): this;setStudio
setStudio(content: import("../model/types/studio.js").StudioContent): this;capturePanelAnimation
capturePanelAnimation(panelId: string, options: PanelCaptureOptions): PanelCaptureResult;duplicateShotAnimation
duplicateShotAnimation(sourceAnimationId: string, options: ShotDuplicateOptions): ShotDuplicateResult;instantiateShotCharacter
instantiateShotCharacter(sourceAnimationId: string, options: CharacterInstanceOptions): CharacterInstanceResult;editShotAnimation
editShotAnimation(id: string, edits: readonly import("../model/types/shot.js").ShotAnimationEdit[]): this;putShotAnimation
putShotAnimation(animation: ShotAnimation): this;putEditorialSequence
putEditorialSequence(sequence: EditorialSequence): this;editStudioAudio
editStudioAudio(ownerId: string, edits: readonly import("../model/types/studio-audio.js").StudioAudioEdit[]): this;setStudioAudio
setStudioAudio(ownerId: string, tracks: readonly import("../model/types/studio-audio.js").StudioAudioTrack[]): this;editEditorial
editEditorial(id: string, edits: readonly EditorialEdit[]): this;removeShotAnimation
removeShotAnimation(id: string): this;removeEditorialSequence
removeEditorialSequence(id: string): this;plan
/** Validate serializable changes on an isolated draft, without changing this session. */
plan(label: string, commands: EditCommand[]): EditPlan;commit
/** Atomically save a plan and its receipt to this session's existing .cboard. */
async commit(input: EditPlan, options: {
requestId: string;
}): Promise<CommitResult>;readAsset
readAsset(id: string): Buffer;captureAssetReader
/** Capture the saved media source independently of later session saves or Save As. */
captureAssetReader(): (id: string) => Buffer;save
async save(path: string, options: {
overwrite?: boolean;
expectedVersion?: number;
assetRoot?: string;
} = {}): Promise<void>;transaction
transaction<T>(label: string, work: () => T): T;undo
undo(): boolean;redo
redo(): boolean;setMetadata
setMetadata(key: string, value: string): this;configure
configure(changes: ProjectChanges): this;addScene
addScene(name: string, id?: Id): SceneHandle;addSequence
addSequence(name: string, id?: Id): SequenceHandle;scene
scene(id: Id): SceneHandle;panel
panel(id: Id): PanelHandle;panelCaptions
panelCaptions(id: Id): {
id: string;
title: string;
action: string;
dialogue: string;
camera: string;
notes: string;
};select
select(query: {
panelId: Id;
layerId?: Id;
elementIds?: Id[];
}): Selection;migrateProject
/** Copy the current saved document; never replaces a source or existing destination. */
export async function migrateProject(sourcePath: string, targetPath: string, options: {
expectedVersion?: number;
} = {}): Promise<ProjectMigrationReport>;SequenceHandle
addScene
addScene(name: string, id?: Id): SceneHandle;SceneHandle
addShot
addShot(name: string, id?: Id): ShotHandle;ShotHandle
addPanel
addPanel(options: PanelOptions = {}): PanelHandle;PanelHandle
addRasterLayer
addRasterLayer(name: string, options: LayerOptions = {}, parentGroupId?: Id): LayerHandle;addVectorLayer
addVectorLayer(name: string, options: LayerOptions = {}, parentGroupId?: Id): LayerHandle;addGroup
addGroup(name: string, options: LayerOptions = {}, parentGroupId?: Id): LayerHandle;addMotion
addMotion(label: string, from: Point, to: Point, color = "#d14a32", id?: Id): Id;revise
revise(changes: Partial<Pick<Panel, "title" | "durationFrames" | "action" | "dialogue" | "camera" | "notes">>): this;layer
layer(id: Id): LayerHandle;LayerHandle
scene3D
scene3D(scene: Scene3D, options: Partial<Pick<Scene3DElement, "id" | "name" | "matrix" | "opacity" | "visible">> = {}): Id;rasterSurface
rasterSurface(image: PixelBuffer, options: Partial<Pick<RasterSurface, "id" | "name" | "matrix" | "opacity" | "visible">> = {}): Id;readPixels
readPixels(elementId: Id, region?: PixelRegion): PixelBuffer;editPixels
editPixels(elementId: Id, region: PixelRegion, edit: (patch: PixelBuffer) => void): this;rasterStroke
rasterStroke(points: Point[], brush: BrushPreset, options: StrokeOptions = {}): Id;erase
erase(points: Point[], brush: BrushPreset, options: Omit<StrokeOptions, "erase"> = {}): Id;vectorStroke
vectorStroke(points: Point[], options: VectorStrokeOptions = {}): Id;path
path(commands: PathCommand[], options: {
id?: Id;
name?: string;
fill?: VectorFill;
stroke?: string;
strokeWidth?: number;
opacity?: number;
} = {}): Id;text
text(text: string, x: number, y: number, options: {
id?: Id;
name?: string;
color?: string;
font?: string;
align?: "left" | "center" | "right";
opacity?: number;
} = {}): Id;set
set(changes: LayerChanges): this;edit
edit(elementId: Id, updater: (element: DrawingElement) => DrawingElement): this;outlineStroke
outlineStroke(elementId: Id): this;booleanPath
booleanPath(elementId: Id, tool: readonly PathCommand[], operation: PathBooleanOperation): this;Selection
transform
transform(transform: Partial<Transform>, options: {
pivot?: Pivot;
} = {}): this;opacity
opacity(value: number): this;remove
remove(): void;CodeboardError
toJSON
toJSON(): {
code: ErrorCode;
message: string;
retryable: boolean;
details: Readonly<Record<string, unknown>>;
};capabilities
/** Implementation inventory, not a production qualification or codec guarantee. */
export async function capabilities(options: {
probeDependencies?: boolean;
ffmpegPath?: string;
ffprobePath?: string;
} = {}): Promise<CapabilityReport>;planDrawingElement
function planDrawingElement(element: DrawingElement): PlanDrawingElement;planShotElement
function planShotElement(element: DrawingElement): PlanDrawingElement;planShotAnimation
function planShotAnimation(input: ShotAnimation): PlanShotAnimation;planComponentSource
function planComponentSource(input: readonly Layer[]): PlanStudioLayer[];planCaptionImport
/** Prepare an atomic caption-only plan; the caller persists it and commits with a request ID. */
export function planCaptionImport(project: StoryboardProject, input: readonly CaptionImportRow[]): CaptionImportReport;importScriptCSV
/** Import explicit stable entry IDs and panel links; does not mutate a project. */
export function importScriptCSV(csv: string, options: ScriptCSVOptions): ScriptInput;exportScriptCSV
/** Export editable script fields; callers retain project/script revision separately. */
export function exportScriptCSV(input: ScriptInput | ProductionScript): string;inspectScriptFDX
/** Inspect the supported screenplay subset and every omitted element/attribute before binding IDs. */
export function inspectScriptFDX(xml: string): FDXInspection;importScriptFDX
/** Import hash-bound, explicitly identified records; project revision and panel checks apply later. */
export function importScriptFDX(xml: string, input: FDXImportOptions): {
script: ScriptInput;
sourceSha256: string;
losses: FDXLoss[];
};planScriptBoard
/** Create explicitly staged panels and append their script links in the same recoverable commit. */
export function planScriptBoard(project: StoryboardProject, input: readonly ScriptBoardPanel[]): ScriptBoardReport;planBoardCapture
/** Capture every board panel and conform its frozen incoming transitions in one version-pinned plan. */
export function planBoardCapture(project: StoryboardProject, input: BoardCaptureOptions): {
plan: EditPlan;
source: { projectId: string; version: number; durationFrames: number; };
sequenceId: string;
panels: { startFrame: number; durationFrames: number; revision: number; panelId: string; animationId: string; clipId: string; }[];
audio: { mode: "omit" | "convert"; omittedTracks: number; mappings: { sourceId: string; targetId: string; }[]; quantizedPositions: number; };
};planShotLipSync
/** Replace only the selected local-frame window of an existing shot mouth drawing track. */
export function planShotLipSync(project: StoryboardProject, animationId: string, layerId: string, options: LipSyncOptions): EditPlan;parseCaptionCSV
/** Strict CSV: commas, escaped quotes and multiline quoted fields; no inferred panel matching. */
export function parseCaptionCSV(input: string): CaptionImportRow[];Codeboard by Nonom Friedman
Explore Nonom Library