StillMade AIDeveloper docs
Browse documentation · SDK 0.1.0

Execution API

Import, validate, run, and inspect the SDK using its actual public exports.

Import the SDK

The downloaded pack contains a local ES module. There is no global npm installation required.

js
import {readFile} from 'node:fs/promises';
import {validatePackage, testPackage, runPackageAsync}
  from './packages/block-sdk/index.js';

const pkg = JSON.parse(await readFile('./examples/word-count.stillmade.json', 'utf8'));
validatePackage(pkg);
const report = await testPackage(pkg);
if (!report.passed) throw new Error('Fix the fixtures before continuing');
const result = await runPackageAsync(pkg, pkg.tests[0].input);
console.log(result.outputs);

Main functions

FunctionResult and behavior
sdkCompatibility(declared, runtimeVersion?)supported, unsupported or invalid; defaults to the actual host SDK version
validateManifest(manifest)valid plus field-level errors
validatePackage(package)true, or throws BlockError
testPackage(package, options)Promise of digest-bound fixture report
runPackage(package, input, options)Synchronous recipe-only outputs
runPackageAsync(package, input, options)Promise of RunPackageResult; recipe progress is optional, and hosted runtimes require an explicit trusted executor
capabilityOperation(manifest)Validated hosted generation, analysis, or timeline proposal operation
prepareCapabilityInvocation(package, input)Bounded request for the declared hosted operation
capabilityOutputs(package, generatedValue)Declared typed output, including strict timeline proposals and canonical media references
defaultCapabilityExpectations(manifest)Operation-specific bounded output checks
validateCapabilityResult(manifest, result)Detached typed result; optional generated-media receipts are shape-checked and bound to outputs, not authenticated
scanPackage(package)Schema, dependency, permission, and static checks
admitPackage(package, options)Scan, fixtures, and optional supplied sample runner
resolveContextInputs(manifest, values, snapshot)Copied, permission-checked context bindings
compatible(outputPort, inputPort)Compatibility, adapter, or failure reason
connectionCompatibility(outputPort, inputPort)Direct match or a possible versioned host conversion; actual values still require checking
validateConnectionAdapter(outputPort, inputPort, options)Checks the saved adapter pin and receiving project-read permissions
adaptConnectionValue(outputPort, inputPort, value, options)Host-only copied data projection using authorized context; no I/O or provider execution
digest(value)Promise of canonical JSON SHA-256 digest

Async result and progress contract

Packages declaring native desktop tools require a trusted options.desktop executor and an explicit package-level desktop mapping (editable src/desktop.json). Their local JavaScript/recipe must never count as native execution. The conservative guard also covers legacy packages without changing their pinned bytes. Offline native admission is source-only with zero executed fixtures; connected execution and saved-result reuse require a bound native receipt. See Native desktop execution for the complete contract and current Natron-only action support.

runPackage is synchronous and recipe-only. runPackageAsync dispatches the supported runtime and resolves RunPackageResult, containing final outputs and runtime-appropriate optional metadata/media receipts or JavaScript state. External hosts must validate and accept Step state atomically with outputs; the SDK does not persist it. A capability executor returns CapabilityResult, which cannot contain Step state: validateCapabilityResult rejects that field. Stateful JavaScript output is a different runtime result, not a provider response.

Both recipe entrypoints accept onProgress({stepId, complete, total}); asynchronous dispatch forwards this callback when executing a recipe. It is not a provider percentage or a new queued-job protocol. An AbortSignal requests cancellation through the existing runtime/host adapter. Provider job polling, progress UI, retries, costs and retained-result adoption remain host responsibilities. Do not return an invented {pending: ...} envelope as declared Block outputs or assume a canceled network wait undoes provider work.

Host integration

Node creates a disposable worker for JavaScript execution. Browsers run recipe/JavaScript in disposable workers. ComfyUI uses a host-controlled account connection with explicit confirmation; it never gives the worker or iframe network credentials. Pass an AbortSignal for cancellation. A returned output object does not mutate a project or authorize storage writes.

Connected Project Type rehearsal can carry pixel images through asset ports using a bounded, preview-only PNG data URL and exact-reference in-memory bridge. It works in the CLI and browser without a media service; it never downloads unknown references or creates project assets. See media previews.

TypeScript declarations

ts
/** Exact stable SemVer, ^version, ~version, or space-separated comparator intersection. */
export type SdkVersionRange = string;
export * from './semantic-contracts.js';
export * from './workflow-events.js';
export * from './workflow-approvals.js';
export * from './package-semantics.js';
export * from './define-block.js';
export * from './adapter-registry.js';
export * from './block-storage.js';
export type {BlockViewDocumentTools,DocumentDraftOperation,DocumentEntry,DocumentPath} from './document-drafts.js';
export type {BlockViewDocumentOptions,BlockViewDocumentConnection} from './document-store-binding.js';
export interface BlockViewBridge { connectDocument(options:import('./document-store-binding.js').BlockViewDocumentOptions):Readonly<import('./document-store-binding.js').BlockViewDocumentConnection>; }
export interface SdkCompatibility { status:'supported'|'unsupported'|'invalid'; declared:unknown; runtimeVersion:string; message:string; }
export function sdkCompatibility(declared:unknown,runtimeVersion?:string):SdkCompatibility;
export type Port = { type: string; imageMode?: 'pixels'|'reference'; role?: string; context?: keyof typeof CONTEXT_FIELDS; primary?: boolean; required?: boolean; default?: unknown; min?: number; max?: number; description?: string } & Partial<import('./semantic-contracts.js').SemanticContract>;
export interface Manifest { schemaVersion: 1; id: string; name: string; version: string; sdkVersion: SdkVersionRange; description: string; kind: 'task'|'workspace'|'editor-extension'|'composite'; inputs: Record<string, Port>; outputs: Record<string, Port>; runtime: 'recipe'|'javascript'|'module'|'comfyui'|'capability'; jobs?: {kind:'cooperative';version:1}; state?: {scope:'step';version:number;initial:Record<string,unknown>;migrations?:StateMigration[]}; entry?: string; permissions: { project: string[]; desktop?: DesktopPermission[]; capabilities?: ['comfyui.execute']|['text.generate']|['audio.speech']|['audio.transcribe']|['image.generate']|['video.generate']|['image.describe']|['timeline.propose']|['workspace.propose']|['connection.execute']; network?: never[]; filesystem?: never[]; secrets?: never[] }; desktopTools?:DesktopToolDeclaration[]; uiLayout?: {kind:'tabs'|'sections';groups:{id:string;label:string;inputs:string[];outputs:string[];collapsed?:boolean}[]}; ui?: ({ control: 'text'|'number'|'slider'|'checkbox'|'asset'; port: string; label?: string; when?: {port:string;equals:string|boolean} } | {control:'select'|'multiselect';port:string;options:string[];label?:string;when?:{port:string;equals:string|boolean}} | {control:'gallery';port:string;label?:string} | {control:'before-after';port:string;before:string;label?:string})[]; }
export interface BlockView { html: string; css?: string; themedCss?: string; javascript?: string; appearance?: 'host'|'original'; }
/** A frame view: any interface code (frameworks, SVG, canvas, drag) with assets named by SHA-256. */
export interface FrameView { runtime: 'frame'; html: string; css?: string; themedCss?: string; javascript?: string; appearance?: 'host'|'original'; files?: {schemaVersion: 1; files: Record<string, {sha256: string; bytes: number; mediaType: string}>}; }
export interface BlockPackage { portable?: PortableMetadata; manifest: Manifest; view?: BlockView|FrameView; code?: string; module?: ModuleDescriptor; comfyui?: ComfyWorkflow; capability?: ConnectedCapability|TextGenerationCapability|SpeechCapability|TranscriptionCapability|ImageGenerationCapability|VideoGenerationCapability|ImageDescriptionCapability|TimelineProposalCapability; recipe?: { schemaVersion: 1; steps: { id: string; op: string; args: Record<string, unknown> }[]; outputs: Record<string, unknown> }; tests: { name: string; input: Record<string, unknown>; expected?: Record<string, unknown>; state?: BlockState; expectedState?: BlockState; expectations?: Record<string, ConnectedResultExpectation|ComfyImageExpectation|CapabilityTextExpectation|CapabilityAudioExpectation|CapabilityTranscriptExpectation|CapabilityImageExpectation|CapabilityVideoExpectation|CapabilityTimelineExpectation> }[]; }
/** Named sandbox action with fixed declared input settings and produced ports. */
export interface BlockOperation {id:string;label:string;description:string;inputs:Record<string,string|number|boolean>;outputs:string[]}
export interface Manifest {
  operations?: BlockOperation[];
  storage?: import('./block-storage.js').BlockStorageDeclaration;
  /** Events the Block can run on by itself, once the project owner turns them on. */
  triggers?: import('./triggers.js').BlockTrigger[];
  semantics?: import('./semantic-contracts.js').SemanticDefinition[];
  provenance?: { remixSource?: BlockPackage; remixPolicy?: {allowRemixing: boolean; sourceInspection?: "yes"|"no"|"license-controlled"}; remixAncestors?: {id: string; version: string; digest: string}[]; remixedFrom?: { id: string; version: string; digest: string }; [key: string]: unknown };
  summary?: Record<string, unknown>;
  license?: string;
  category?: string;
  /** Listing compatibility only; this does not grant native device permissions. */
  platforms?: Record<'phone'|'browser'|'desktop', { supported: boolean; reason?: string }>;
}
export interface TestReport { digest: string; sdkVersion: string; passed: boolean; execution?: 'host-executor'|'desktop-host-executor'|'unavailable'; liveVerified?: false; reviewRequired?: true; results: { name: string; passed: boolean; code?: string; message?: string }[]; }
export function validatePackage(pkg: unknown): true;
export function testPackage(pkg: BlockPackage, options?: { timeoutMs?: number; comfyui?: ComfyExecutor; capability?: CapabilityExecutor; desktop?:DesktopExecutor }): Promise<TestReport>;
export const SDK_VERSION: '0.1.0';
export const ROOT_CHAT_ID: 'stillmade.starting-chat';
export function stableStringify(value: unknown): string;
export function validateManifest(value: unknown): { valid: boolean; errors: { path: string; message: string }[] };
export function validateRecipe(recipe: BlockPackage['recipe']): true;
export interface RecipeProgress {stepId:string;complete:number;total:number}
export type JavaScriptRequirementResult = {resolved:false;requirement:Port & {key:string}}|{resolved:true;requirement:Port & {key:string};value:unknown};
export interface JavaScriptUserRequest {$stillmadeUserRequest:1;key:string}
export interface JavaScriptChatRequest {$stillmadeChatRequest:1;key:string}
export interface JavaScriptBlockSDK {requestFromChat(key:string):JavaScriptChatRequest|JavaScriptRequirementResult}
export interface JavaScriptBlockSDK {requestFromUser(key:string):JavaScriptUserRequest|JavaScriptRequirementResult}
export interface RunPackageOptions {requestFromUser?:(request:{requirement:Port & {key:string};signal?:AbortSignal})=>{value:unknown}|Promise<{value:unknown}>}
export interface RunPackageResult {userAnswers?:Record<string,unknown>}
export interface RunPackageOptions {requestFromChat?:(request:{requirement:Port & {key:string};signal?:AbortSignal})=>{value:unknown}|Promise<{value:unknown}>}
export interface RunPackageResult {chatValues?:Record<string,unknown>}
export interface JavaScriptBlockSDK {emit(key:string,value:unknown):void;resolveRequirement(key:string):JavaScriptRequirementResult;getProjectContext():Record<string,unknown>;getProjectContext(field:string):unknown;validate(value:unknown,schema:import('./semantic-contracts.js').SemanticContract['schema']):boolean}
/** Recipe Step progress only; provider/native job progress belongs to the host. */
export interface RecipeRunOptions {signal?:AbortSignal;onProgress?:(progress:RecipeProgress)=>void}
export function runPackage(pkg: BlockPackage, values: Record<string, unknown>, options?: RecipeRunOptions): { outputs: Record<string, unknown> };
export function compatible(output: string|Port, input: string|Port, options?: {semantics?: import('./semantic-contracts.js').SemanticRegistry}): { compatible: boolean; adapter?: string|null; reason?: string };
/** Host-owned deterministic conversion, pinned on a workflow connection. */
export interface ConnectionAdapterPin { id: string; version: 1; }
export interface ConnectionCompatibility { compatible: boolean; adapter?: ConnectionAdapterPin|null; requiresValue?: boolean; contextFields?: string[]; reason?: string; }
export interface ConnectionAdapterOptions { semantics?: import('./semantic-contracts.js').SemanticRegistry; permissions?: string[]; adapter?: ConnectionAdapterPin|null; context?: Record<string, unknown>; }
export const ADAPTERS: readonly Readonly<ConnectionAdapterPin & {output:string;input:string;contextFields:readonly string[];requiresValue:true}>[];
export function connectionCompatibility(output: string|Port, input: string|Port, options?: Pick<ConnectionAdapterOptions,'semantics'>): ConnectionCompatibility;
export function validateConnectionAdapter(output: string|Port, input: string|Port, options?: Omit<ConnectionAdapterOptions,'context'>): ConnectionCompatibility;
export function adaptConnectionValue(output: string|Port, input: string|Port, value: unknown, options?: ConnectionAdapterOptions): unknown;
export function digest(value: unknown): Promise<string>;
export class BlockError extends Error { code: string; details: unknown[]; }

export interface ContinuationProgress {kind:'continuation';turn:number;complete:number|null;total:number|null}
export interface CooperativeJobContext {readonly continuation:unknown;pending(continuation:unknown,progress?:{complete:number;total:number}):{$stillmadeJob:1;continuation:unknown;progress:{complete:number;total:number}|null}}
export const COOPERATIVE_JOB_LIMITS:Readonly<{turns:32}>;
export function continuationProgressValid(value:unknown,previous?:ContinuationProgress|null):value is ContinuationProgress;
export interface RunPackageOptions extends Omit<RecipeRunOptions,'onProgress'> {onProgress?:(progress:RecipeProgress|ContinuationProgress)=>void;state?:BlockState;comfyui?:ComfyExecutor;capability?:CapabilityExecutor}
/** Final runtime result; only JavaScript Blocks can return Step state. */
export interface RunPackageResult extends CapabilityResult {state?:BlockState}
export function runPackageAsync(pkg: BlockPackage, values: Record<string, unknown>, options?: RunPackageOptions): Promise<RunPackageResult>;

export interface AdmissionCheck { name: string; passed: boolean; message?: string; }
export type ModelBackendKind='managed-api'|'huggingface-endpoint'|'comfyui'|'local-worker';
export interface ModelPortabilityCheck extends AdmissionCheck {runtimeVerified:false;contract:'generation-backend/1';mode:'host-capability'|'reviewed-comfyui'|'host-action'|'not-applicable';operations:string[];compatibleBackends:ModelBackendKind[];code?:'MODEL_PORTABILITY'}
export const MODEL_PORTABILITY_CONTRACT:'generation-backend/1';
export const PORTABLE_GENERATION_OPERATIONS:readonly ['text.generate','audio.speech','audio.transcribe','image.generate','video.generate','image.describe','timeline.propose','workspace.propose'];
export type HostedCapabilityOperation='text.generate'|'audio.speech'|'audio.transcribe'|'image.generate'|'video.generate'|'image.describe'|'timeline.propose'|'workspace.propose'|'connection.execute';
export interface HostedCapabilityOperationInfo{readonly executor:'capability-run'|'connection';readonly mode:'sync'|'async';readonly byok:boolean;readonly summary:string}
/** The single source of host-mediated operations; every route, filter and doc derives from it. */
export const HOSTED_CAPABILITY_OPERATIONS:Readonly<Record<HostedCapabilityOperation,HostedCapabilityOperationInfo>>;
export const HOSTED_OPERATION_NAMES:readonly HostedCapabilityOperation[];
export const CAPABILITY_RUN_OPERATIONS:readonly HostedCapabilityOperation[];
export const SYNC_CAPABILITY_RUN_OPERATIONS:readonly HostedCapabilityOperation[];
export const BYOK_CAPABILITY_OPERATIONS:readonly HostedCapabilityOperation[];
export const UI_INPUT_CONTROLS:readonly ['text','number','slider','checkbox','asset','select','multiselect'];
export const UI_OUTPUT_PRESENTATIONS:readonly ['gallery','before-after'];
/** Every field an input or output port may declare; admission rejects any other. See /docs/reference/ports. */
export const PORT_FIELDS:readonly ['type','required','default','min','max','description','role','primary','context','imageMode','key','semantic','accepts','schema','sources','sensitivity','freshnessPolicy','cardinality','batchable'];
/** Offline source constraint only; it never contacts, approves, or verifies a live model backend. */
export function reviewModelPortability(pkg:BlockPackage):ModelPortabilityCheck;
export interface AdmissionReport { execution?:'not-run'|'desktop-host-executor'; tests?:number; fixtureContracts?:number; platformChecks?: PlatformCheckReport; passed: boolean; liveVerified?: false; reviewRequired?: true; results: AdmissionCheck[]; digest: string; preview?: { outputs: Record<string, unknown> }; }
export function scanPackage(pkg: BlockPackage): { passed: boolean; results: AdmissionCheck[]; execution?: 'not-run'; liveVerified?: false; reviewRequired?: true };
/** Execution safety only; not a completion or installation certificate. */
export function scanPackageSource(pkg: BlockPackage): { passed: boolean; results: AdmissionCheck[]; execution?: 'not-run'; liveVerified?: false; reviewRequired?: true };
/** New creation/import admission, including model portability and integration constraints. */
export function scanAdmissionPackage(pkg:BlockPackage):{passed:boolean;results:AdmissionCheck[];execution?:'not-run';liveVerified?:false;reviewRequired?:true};
export function admitPackage(pkg: BlockPackage, options?: { test?: (pkg: BlockPackage) => Promise<TestReport>; run?: (pkg: BlockPackage, input: Record<string, unknown>) => Promise<{ outputs: Record<string, unknown> }>; sampleInput?: Record<string, unknown>; platformProbe?:PlatformProbe; desktop?:DesktopExecutor }): Promise<AdmissionReport>;

/** Read-only media identity supplied by the host. URLs do not grant guest network access. */
export interface ContextMediaReference { assetId: string; versionId: string; kind: 'image'|'video'|'audio'; url: string; role?: string; sceneId?: string; shotId?: string; label?: string; source: string; }
export interface ContextMediaVersion { schemaVersion: 1; id: string; assetId: string; versionId: string; asset: ContextMediaReference; source: string; active: boolean; sceneId?: string; shotId?: string; timestamp?: number; createdAt?: number|string; model?: string; provider?: string; duration?: number; }
export interface ContextDocumentVersion { schemaVersion: 1; id: string; versionId: string; documentType: 'shot-plan'|'timeline'|'bible'; source: string; active: boolean; label?: string; name?: string; createdAt?: number|string; }
export type ContextGeneration = ContextMediaVersion & { status: 'completed' };
export type ContextSelection = {kind:'project'} | {kind:'scene';sceneId:string} | {kind:'selected-shots';shotIds:string[]} | {kind:'selected-assets';assetIds:string[]};
export const CONTEXT_FIELDS: { script: 'script'; transcript: 'transcript'; shots: 'shot[]'; shotPlan: 'shot-plan'; scenes: 'scene[]'; characters: 'character[]'; locations: 'location[]'; styles: 'style[]'; assets: 'asset[]'; generations: 'metadata[]'; versions: 'metadata[]'; timeline: 'timeline'; editor: 'timeline'; canvas: 'pipeline'; blueprint: 'bible'; panels: 'panel-document'; board: 'board-document'; animation: 'scene-document'; metadata: 'metadata' };
export function resolveContextInputs(manifest: Manifest, values: Record<string, unknown>, context?: Record<string, unknown>): Record<string, unknown>;
/** What `stillmade.project.read(fields)` returns: metadata plus the declared context fields. Requires `project.read`. */
export function projectReadSnapshot(manifest: Manifest, context?: Record<string, unknown>, fields?: string[]): Record<string, unknown>;

export function validateView(view: unknown): true;
export const FRAME_VIEW_LIMITS: Readonly<{htmlBytes:262144;cssBytes:262144;javascriptBytes:4194304;assetFiles:32;assetBytes:8388608;taskMs:250;longTaskMs:1000}>;
export const FRAME_VIEW_ASSET_TYPES: readonly string[];
export function isFrameView(view: unknown): view is FrameView;
export function validateFrameView(view: FrameView): true;
/** Frame view JavaScript is one classic script (an IIFE bundle). */
export function parseFrameViewJavaScript(source: string): {ast: unknown};
/** Platform compilation: every function and loop body calls the task guard. */
export function instrumentFrameViewJavaScript(source: string, guard: string): string;
export function describeViewFiles(files: Record<string, Uint8Array|ArrayBuffer|string>): Promise<NonNullable<FrameView['files']>>;
/** In a frame view, the StillMade object also offers its asset files. */
export interface FrameViewAssets { asset(path: string): string; assetBytes(path: string): ArrayBuffer; }
export const VIEW_LIMITS: Readonly<{htmlBytes:65536;cssBytes:32768;javascriptBytes:65536;messageBytes:4194304;runsPerMinute:30;imagePreviewsPerMinute:60;imagePreviewMs:15000;imagePreviewEdge:512}>;

/** A display-only copy. Never substitute this URL for the original run input. */
export interface BlockImagePreview { url: `data:image/png;base64,${string}`; width: number; height: number; }
export interface BlockImagePixels { width: number; height: number; data: number[]; role?: string; }
export interface BlockImageReference { kind: 'image'; assetId: string; versionId: string; url: string; role?: string; }
export type DesktopPermission = "screen.capture"|"cursor.track"|"camera.capture"|"microphone.capture"|"clipboard.read"|"clipboard.write"|"media.pick"|"notifications.show"|"power.keep-awake"|"native.tools";
export type DesktopToolDeclaration = {id:'org.natron.Natron';adapterVersion:1;actions:('launch'|'project.import'|'project.open'|'project.render')[]} | {id:'org.stillmade.PythonAdapter';adapterVersion:1;actions:('adapter.import'|'adapter.inspect'|'adapter.execute'|'adapter.describe'|'adapter.call')[]};
export type DesktopExecution = {schemaVersion:1;tool:'org.natron.Natron';action:'project.render';arguments:Record<'projectId'|'input'|'reader'|'writer'|'firstFrame'|'lastFrame',{input:string}>;outputs:Record<string,'asset'>} | {schemaVersion:1;tool:'org.stillmade.PythonAdapter';action:'adapter.execute';arguments:Record<'adapterId'|'sourceDigest'|'functionId'|'input',{input:string}>;outputs:Record<string,'result'>} | {schemaVersion:2;tool:'org.stillmade.PythonAdapter';action:'adapter.call';source:{code:string;digest:string;license:string};functionId:string;arguments:Record<string,{input:string}>;outputs:{result:'result'}};
export interface DesktopExecutionRequest {schemaVersion:1;requestId:string;packageDigest:string;inputDigest:string;tools:DesktopToolDeclaration[]}
export interface DesktopExecutionReceipt {schemaVersion:1;requestId:string;packageDigest:string;inputDigest:string;outputDigest:string;tool:'org.natron.Natron'|'org.stillmade.PythonAdapter';adapterVersion:1;action:'project.render'|'adapter.execute'|'adapter.call';executionId:string}
export interface DesktopExecutionResult {outputs:Record<string,unknown>;desktopReceipt:DesktopExecutionReceipt}
/** Trusted host only; issue evidence after the approved native action and output registration. */
export type DesktopExecutor=(pkg:BlockPackage,input:Record<string,unknown>,options:{signal?:AbortSignal;request:DesktopExecutionRequest})=>Promise<DesktopExecutionResult>;
export interface BlockPackage {desktop?:DesktopExecution}
export interface RunPackageOptions {desktop?:DesktopExecutor}
export interface RunPackageResult {desktopReceipt?:DesktopExecutionReceipt}
export function requiresDesktopExecution(pkg:unknown):boolean;
export function assertLocalDesktopExecutionUnavailable(pkg:unknown):void;
export function validateDesktopExecution(pkg:BlockPackage,options?:{required?:boolean}):true;
export function validateDesktopExecutionRecord(pkg:BlockPackage,input:Record<string,unknown>,result:DesktopExecutionResult):Promise<DesktopExecutionResult>;
export function desktopInvocation(pkg:BlockPackage,input:Record<string,unknown>):{tool:'org.natron.Natron';operation:'tool.project.render';args:Record<string,unknown>;outputs:Record<string,'asset'>};
export function desktopOutputs(pkg:BlockPackage,result:Record<string,unknown>):Record<string,unknown>;
export function prepareDesktopExecution(pkg:BlockPackage,input:Record<string,unknown>):Promise<{package:BlockPackage;input:Record<string,unknown>;request:DesktopExecutionRequest}>;
export function validateDesktopExecutionResult(pkg:BlockPackage,request:DesktopExecutionRequest,result:unknown):Promise<DesktopExecutionResult>;
export type DesktopToolOperation='tool.status'|'tool.launch'|'tool.project.import'|'tool.project.open'|'tool.project.render'|'tool.adapter.import'|'tool.adapter.inspect'|'tool.adapter.execute'|'tool.adapter.describe'|'tool.adapter.call';
export type BlockViewTag = 'div'|'section'|'article'|'header'|'footer'|'p'|'span'|'strong'|'em'|'small'|'h1'|'h2'|'h3'|'h4'|'label'|'button'|'input'|'textarea'|'select'|'option'|'ul'|'ol'|'li'|'table'|'thead'|'tbody'|'tr'|'th'|'td'|'details'|'summary'|'output'|'progress'|'img';
export interface BlockViewNode { tag: BlockViewTag; text?: string; children?: BlockViewNode[]; id?: string; className?: string; action?: string; value?: string|number; type?: 'text'|'number'|'range'|'checkbox'|'radio'|'color'; checked?: boolean; disabled?: boolean; placeholder?: string; min?: string|number; max?: string|number; step?: string|number; label?: string; }
export interface BlockViewAction { action: string; value: string; checked: boolean; event: 'click'|'input'|'change'; }
export interface BlockMediaReference { kind: 'video'|'audio'; assetId: string; versionId: string; url: string; role?: string; }
export interface BlockMediaPreview { kind: 'video'|'audio'; url: string; mimeType: string; bytes: number; }
export interface BlockViewBridge { useOutput(outputs: Record<string, BlockMediaReference|BlockMediaReference[]>): Promise<Record<string, unknown>>; previewMedia(value: BlockMediaReference): Promise<BlockMediaPreview>; releaseMedia(url: string): void; render(targetId: string, tree: BlockViewNode[]): void; onAction(callback: (event: BlockViewAction) => void|Promise<void>): () => void; desktop(operation: DesktopPermission|DesktopToolOperation|import('./block-storage.js').BlockStorageOperation|"record.start"|"record.stop"|"record.cancel"|"session.close", args?: Record<string,unknown>): Promise<Record<string,unknown>>; readonly input: Record<string, unknown>; onInput(callback: (input: Record<string, unknown>) => void): () => void; run(input: Record<string, unknown>): Promise<Record<string, unknown>>; previewImage(value: BlockImageReference|BlockImagePixels): Promise<BlockImagePreview>; }

/** Validate hosted UI colors independently of the preserved original stylesheet. */
export function validateViewAppearance(view?: BlockView, options?: {appearance?:'host'|'original'}): true;
export const APPEARANCE_TOKENS: readonly string[];

/** Inert API prompt for reviewed core image nodes. Endpoints and credentials belong to the host. */
export interface ComfyWorkflow { schemaVersion: 1; prompt: Record<string, {class_type: 'LoadImage'|'ImageInvert'|'ImageScale'|'PreviewImage'|'CheckpointLoaderSimple'|'CLIPTextEncode'|'EmptyLatentImage'|'KSampler'|'VAEEncode'|'VAEDecode'; inputs: Record<string, unknown>}>; inputs: Record<string, {node: string; input: string; encoding: 'uploaded-image'|'scalar'}>; outputs: Record<string, {node: string; collection: 'images'; index: 0}>; }
export interface ComfyImageExpectation { kind: 'image'; count: 1; width?: number; height?: number; maxBytes?: number; sha256?: string; }
export interface ComfyImageMetadata { width: number; height: number; bytes: number; mimeType: 'image/png'; frames: 1; sha256?: string; }
export type ComfyExecutor = (pkg: BlockPackage, input: Record<string, unknown>, options: {signal?: AbortSignal}) => Promise<{outputs: Record<string, unknown>; metadata: Record<string, ComfyImageMetadata>}>;
export function validateComfyWorkflow(workflow: ComfyWorkflow, manifest: Manifest): {order: string[]; classes: string[]};
export function validateComfyExpectations(manifest: Manifest, expectations: Record<string, ComfyImageExpectation>): true;
export function testComfyOutputs(manifest: Manifest, outputs: Record<string, unknown>, expectations: Record<string, ComfyImageExpectation>, options: {metadata: Record<string, ComfyImageMetadata>}): {passed: true; checks: unknown[]};

export function validateComfyInput(workflow: ComfyWorkflow, manifest: Manifest, input: Record<string, unknown>): Record<string, unknown>;
export function digestComfyInput(manifest: Manifest, input: Record<string, unknown>): Promise<string>;
export function prepareComfyPrompt(workflow: ComfyWorkflow, manifest: Manifest, input: Record<string, unknown>, uploads: Record<string, ComfyImageMetadata & {filename: string; type?: 'input'; subfolder?: ''}>): ComfyWorkflow['prompt'];
export function validateComfyBackend(workflow: ComfyWorkflow, manifest: Manifest, objectInfo: unknown): {compatible: true; classes: string[]; contracts: Record<string, unknown>};
export function extractComfyOutputs(workflow: ComfyWorkflow, manifest: Manifest, history: unknown, options: {promptId: string}): Record<string, {filename: string; subfolder: ''; type: 'temp'}>;


export interface PlatformCapture { frames?: { interface?: 'host'|'guest'; width?: number; height?: number; touch?: boolean; controls: number; issues: { code: string; message: string; severity?: 'warning'|'error' }[] }[]; interactionPassed?: boolean|null; embedded?:boolean; continuityPassed?:boolean; states?:Record<'empty'|'populated'|'loading'|'error'|'success'|'long-labels'|'enlarged-text',boolean>; error?: string; unavailable?: string; }
export interface PlatformProbeOptions { content: BlockPackage; platform: 'phone'|'browser'|'desktop'; viewport: {width:number;height:number;touch:boolean;label?:'compact'|'phone'|'tablet'|'phone-landscape'|'desktop'}; theme:'light'|'dark'|'white'; }
export type PlatformProbe = (options: PlatformProbeOptions) => PlatformCapture|Promise<PlatformCapture>;
export interface PlatformTargetCheck { supported:boolean|null; reason:string; checks:{viewport:{width:number;height:number;touch:boolean};theme:string;passed:boolean|null;message:string;findings?:{code:string;message:string}[]}[]; }
export interface PlatformCheckReport {schemaVersion:2;policy:'mobile-ui-1';subject:{id:string;version:string;runtime:string};digest:string;checkedAt:string;versions:{sdk:string;renderer:number;checks:number};targets:Record<'phone'|'browser'|'desktop',PlatformTargetCheck>;}
export function testPlatforms(content:BlockPackage,options?:{probe?:PlatformProbe;runtimePassed?:boolean;runtimeMessage?:string;sourceDigest?:string;targets?:('phone'|'browser'|'desktop')[]}):Promise<PlatformCheckReport>;
export function measurePlatformLayout(options?:{touch?:boolean;nativeWorkspace?:boolean}):NonNullable<PlatformCapture['frames']>[number];
export function assessPlatformCapture(capture:PlatformCapture):{passed:boolean|null;message:string};
export function checkedPlatformTargets(report:PlatformCheckReport,expectedDigest:string):PlatformCheckReport['targets']|null;
export function mobileActivationStatus(report:PlatformCheckReport|undefined,expectedDigest:string,manifest?:Manifest):{ready:boolean;reason:string};
export const PLATFORM_CHECK_POLICY:'mobile-ui-1';
export const PLATFORM_CHECK_VERSION:2;
export const PLATFORM_RENDERER_VERSION:2;
export const PLATFORM_CHECK_TARGETS:Readonly<Record<'phone'|'browser'|'desktop',readonly {width:number;height:number;touch:boolean;label?:string}[]>>;
export const PLATFORM_CHECK_THEMES:readonly ['light','dark','white'];
/** Static import inspection only. It never connects a backend or runs a test. */
export interface ComfyImportInspection {
  format: 'api'|'api-wrapper'; source: Record<string, unknown>; prompt: ComfyWorkflow['prompt'];
  nodes: {id: string; classType: string; title?: string; label: string}[];
  inputCandidates: {node: string; input: string; label: string; type: 'image'|'integer'|'text'; encoding: 'uploaded-image'|'scalar'; required: boolean; default?: unknown; options?: string[]}[];
  outputCandidates: {node: string; label: string; type: 'image'; collection: 'images'; index: 0; required: true}[];
  warnings: string[]; execution: 'not-run';
}
export function inspectComfyImport(raw: string|Record<string, unknown>): ComfyImportInspection;
/** Requires explicit typed mappings and fixtures; returned source still needs host review and Confirm Import. */
export function buildComfyImportPackage(raw: string|Record<string, unknown>, options: {
  manifest: Manifest; inputs: ComfyWorkflow['inputs']; outputs: ComfyWorkflow['outputs']; tests: BlockPackage['tests'];
}): BlockPackage;

/** Declarative requests. Model, provider, voice, speed, image size/quality, keys, payment and approval belong to the host. */
export interface TextGenerationCapability { schemaVersion: 1; operation: 'text.generate'; prompt: {$input: string}; system: string; maxTokens: number; output: string; /** Other declared inputs to send as read-only project context. */ context?: string[]; /** With a json output port: the JSON schema the reply must match. */ schema?: JsonSchema; /** One json input of earlier {role, content} turns sent before the prompt. */ history?: {$input: string}; }
export interface SpeechCapability { schemaVersion: 1; operation: 'audio.speech'; text: {$input: string}; output: string; }
export interface TranscriptionCapability { schemaVersion: 1; operation: 'audio.transcribe'; audio: {$input: string}; language: {$input: string}; output: string; }
export interface ImageGenerationCapability { schemaVersion: 1; operation: 'image.generate'; prompt: {$input: string}; output: string; }
export interface TextGenerationInvocation { operation: 'text.generate'; system: string; prompt: string; maxTokens: number; history?: {role:'user'|'assistant';content:string}[]; }
/** text.generate history bounds: turns, characters per turn and in total. */
export const TEXT_HISTORY_LIMITS: Readonly<{turns:20;turn:8000;total:24000}>;
export interface SpeechInvocation { operation: 'audio.speech'; text: string; }
export interface TranscriptionInvocation { operation: 'audio.transcribe'; audio: {kind:'audio';assetId:string;versionId:string;url:string;mimeType?:string}; language: string; }
export interface ImageGenerationInvocation { operation: 'image.generate'; prompt: string; }
export type CapabilityInvocation = TextGenerationInvocation|SpeechInvocation|TranscriptionInvocation|ImageGenerationInvocation|VideoGenerationInvocation|ImageDescriptionInvocation|TimelineProposalInvocation;
export interface CapabilityTextExpectation { kind: 'text'|'script'; minLength: number; maxLength: number; includes?: string[]; }
export interface CapabilityAudioExpectation { kind: 'audio'; format: 'wav'; minDuration: number; maxDuration: number; minBytes: number; maxBytes: number; }
export interface CapabilityTranscriptExpectation {kind:'transcript';minWords:number;maxWords:number;}
export interface CapabilityImageExpectation { kind: 'image'; format: 'png'; width: 1024; height: 1024; minBytes: number; maxBytes: number; }
export interface CapabilityTimelineExpectation {kind:'timeline-edit';minCommands:number;maxCommands:number;}
/** Measured by the host from canonical bytes; these fields alone do not prove the bytes or ownership. */
export interface SpeechAudioReference { kind: 'audio'; assetId: string; versionId: string; url: string; mimeType: 'audio/wav'; duration: number; bytes: number; sampleRate: 24000; channels: 1; }
/** Measured MP3 or WAV from catalog voices, music or sound effects. */
export interface GeneratedAudioReference { kind: 'audio'; assetId: string; versionId: string; url: string; mimeType: 'audio/mpeg'|'audio/wav'; duration: number; bytes: number; sampleRate: number; channels: 1|2; }
export interface GeneratedImageReference { kind: 'image'; assetId: string; versionId: string; url: string; mimeType: 'image/png'; width: number; height: number; bytes: number; }
/** Bounded and bound to an output; authenticated owner/run verification belongs to the host client. */
export interface SpeechMediaReceipt extends SpeechAudioReference { schemaVersion: 1|2; ownerId: string; runId: string; index: number; storageKey: string; sha256: string; }
export interface GeneratedAudioMediaReceipt extends GeneratedAudioReference { schemaVersion: 3; ownerId: string; runId: string; index: number; storageKey: string; sha256: string; }
export interface GeneratedImageMediaReceipt extends GeneratedImageReference { schemaVersion: 1|2|3; ownerId: string; runId: string; index: number; storageKey: string; sha256: string; }
export interface CapabilityResult { outputs: Record<string, unknown>; metadata?: Record<string, unknown>; mediaReceipts?: Record<string, SpeechMediaReceipt|GeneratedAudioMediaReceipt|GeneratedImageMediaReceipt|GeneratedVideoMediaReceipt>; }
/** Inject only from a trusted host or an explicit test harness; guest code cannot supply this callback. */
export type CapabilityExecutor = (pkg: BlockPackage, input: Record<string, unknown>, options: {signal?: AbortSignal}) => Promise<CapabilityResult>;
export const CAPABILITY_LIMITS: Readonly<{prompt:32000;system:8000;output:32768;maxTokens:4096;fixtures:3;includes:8;includeLength:256;packageBytes:262144;metadataBytes:8192}>;
/** media.analyze bounds: images per run, question length and the closer-inspected video range in seconds. */
export const MEDIA_ANALYZE_LIMITS: Readonly<{images:4;question:2000;range:12}>;
/** web.fetch and web.research bounds: URL, instruction and topic lengths, sources kept and answer size. */
export const WEB_CAPABILITY_LIMITS: Readonly<{url:2048;instruction:4000;topic:500;sources:12;answer:32768}>;
/** image.describe with an image[] input sends one to four images together. */
export const IMAGE_DESCRIBE_LIMITS: Readonly<{images:4}>;
export const SPEECH_CAPABILITY_LIMITS: Readonly<{text:3800;duration:1400;bytes:67108864;sampleRate:24000;channels:1}>;
/** Measured catalog audio (voices, music, sound effects): MP3 or WAV as generated. Music lengths are whole seconds; sound effects are tenths of a second. */
export const AUDIO_CAPABILITY_LIMITS: Readonly<{bytes:134217728;duration:1800;music:Readonly<{min:5;max:240;default:30}>;sfx:Readonly<{min:0.5;max:22;default:4}>}>;
export const IMAGE_CAPABILITY_LIMITS: Readonly<{prompt:32000;bytes:12000000;width:1024;height:1024;maxSide:8192;maxPixels:40000000;maxBytes:67108864}>;
export interface ImageGenerationModel {label:string;aspectRatios:readonly string[];resolutions:readonly string[];qualities:readonly string[];references:number;seed:boolean}
export interface VideoGenerationModel {label:string;aspectRatios:readonly string[];resolutions:readonly string[];durations:readonly number[];firstFrame:boolean;lastFrame:boolean;requiresFirstFrame:boolean;seed:boolean;nativeAudio:boolean}
export interface ImageSettings {model:string;aspectRatio:string;resolution:string;quality:string}
export interface VideoSettings {model:string;duration:number;resolution:string;aspectRatio:string;generateAudio:boolean}
/** Every image model a Block can use; the same catalog as the app's own Blocks. */
export const IMAGE_GENERATION_MODELS: Readonly<Record<string,ImageGenerationModel>>;
/** Every video model a Block can use; the same catalog as the app's own Blocks. */
export const VIDEO_GENERATION_MODELS: Readonly<Record<string,VideoGenerationModel>>;
export const DEFAULT_IMAGE_MODEL: string;
export const DEFAULT_VIDEO_MODEL: string;
/** The value of a setting a model has no knob for. */
export const DEFAULT_SETTING: 'default';
export const GENERATION_LIMITS: Readonly<{references:8;negativePrompt:2000;seed:2147483647}>;
/** Fill and check image settings; `strict` rejects values the model does not accept. */
export function imageSettings(value?:Partial<ImageSettings>,options?:{strict?:boolean}):ImageSettings;
/** Fill and check video settings, including Veo's 1080p-is-8-seconds rule. */
export function videoSettings(value?:Partial<VideoSettings>,options?:{strict?:boolean;firstFrame?:boolean}):VideoSettings;
export function validateSeed(seed:number):number;
export const MEDIA_GENERATE_LIMITS: Readonly<{items:50;prompt:4000}>;
export const MEDIA_GENERATE_OPERATIONS: readonly ['image','video','speech','music','sfx'];
/** Voices, music and sound effects on the app's own generators. */
export const AUDIO_GENERATION: Readonly<{speech:Readonly<{text:3800;defaultVoice:'asteria';speed:Readonly<{min:0.25;max:4;default:1}>}>;music:Readonly<{min:5;max:240;default:30}>;sfx:Readonly<{min:0.5;max:22;default:4}>}>;
export function audioSettings(operation:'speech',value?:{voice?:string;speed?:number},options?:{strict?:boolean}):{voice:string;speed:number};
export function audioSettings(operation:'music'|'sfx',value?:{durationSec?:number},options?:{strict?:boolean}):{durationSec:number};
export function mediaGenerateRequest(request:unknown):unknown;
export function capabilityOperation(manifest: Manifest): 'text.generate'|'audio.speech'|'audio.transcribe'|'image.generate'|'video.generate'|'image.describe'|'timeline.propose'|'workspace.propose';
export function validateCapability(capability: TextGenerationCapability|SpeechCapability|TranscriptionCapability|ImageGenerationCapability|VideoGenerationCapability|ImageDescriptionCapability|TimelineProposalCapability, manifest: Manifest): true;
export function prepareCapabilityInvocation(pkg: BlockPackage, input: Record<string, unknown>): CapabilityInvocation;
export function capabilityOutputs(pkg: BlockPackage, text: string): Record<string, string|{schemaVersion:1;text:string}>;
export function capabilityOutputs(pkg: BlockPackage, audio: SpeechAudioReference): Record<string, SpeechAudioReference>;
export function capabilityOutputs(pkg: BlockPackage, transcript: {schemaVersion:1;text:string;words:{text:string;start:number;end:number}[]}): Record<string, {schemaVersion:1;text:string;words:{text:string;start:number;end:number}[]}>;
export function capabilityOutputs(pkg: BlockPackage, image: GeneratedImageReference): Record<string, GeneratedImageReference>;
export function capabilityOutputs(pkg: BlockPackage, text: string): Record<string, TimelineEdit>;
export function validateSpeechAudioReference(value: SpeechAudioReference|GeneratedAudioReference): true;
/** Measured MP3 or WAV reference returned by audio.music, audio.sfx and catalog voices. */
export function validateGeneratedAudioReference(value: GeneratedAudioReference): true;
export function validateGeneratedImageReference(value: GeneratedImageReference): true;
export function defaultCapabilityExpectations(manifest: Manifest): Record<string, CapabilityTextExpectation|CapabilityAudioExpectation|CapabilityTranscriptExpectation|CapabilityImageExpectation|CapabilityVideoExpectation|CapabilityTimelineExpectation>;
export function validateCapabilityExpectations(manifest: Manifest, expectations: Record<string, CapabilityTextExpectation|CapabilityAudioExpectation|CapabilityTranscriptExpectation|CapabilityImageExpectation|CapabilityVideoExpectation|CapabilityTimelineExpectation>): true;
export function testCapabilityOutputs(manifest: Manifest, outputs: Record<string, unknown>, expectations: Record<string, CapabilityTextExpectation|CapabilityAudioExpectation|CapabilityTranscriptExpectation|CapabilityImageExpectation|CapabilityVideoExpectation|CapabilityTimelineExpectation>): {passed:true;checks:({output:string;kind:'text'|'script';length:number;includesMatched:number}|{output:string;kind:'audio';format:'wav';duration:number;bytes:number;sampleRate:24000;channels:1}|{output:string;kind:'transcript';words:number}|{output:string;kind:'image';format:'png';width:1024;height:1024;bytes:number}|{output:string;kind:'timeline-edit';commands:number})[]};
/** Bounded output validation only; metadata does not establish a verified live provider receipt. */
export function validateCapabilityResult(manifest: Manifest, result: CapabilityResult): CapabilityResult;

/** Host storage is scoped to the account, project, and Step instance. */
export interface BlockState {version:number;value:Record<string,unknown>}
export const STATE_LIMIT_BYTES: 65536;
export function initialBlockState(manifest:Manifest):BlockState;
export function validateBlockState(manifest:Manifest,state:unknown):BlockState;

export interface TimelineEditCommand {
 collection: 'clips'|'audioItems'|'captions';
 operation: 'move'|'trim'|'split'|'volume'|'mute'|'remove'|'caption.add'|'caption.update'|'grade'|'transition';
 before: {id:string; [key:string]:unknown}|null;
 values: {type?:string;duration?:number;soundOn?:boolean;soundId?:string;lut?:'None'|'Cold'|'Warm'|'Desaturated'|'High Contrast'|'Filmic'|'Teal and Orange';font?:'Hanken Grotesk';size?:number;highlightColor?:string;background?:string;backgroundOpacity?:number;backgroundPadding?:number;backgroundRadius?:number;position?:'top left'|'top center'|'top right'|'middle left'|'middle center'|'middle right'|'bottom left'|'bottom center'|'bottom right';animation?:'none'|'fade';words?:Array<{text:string;start:number;end:number}>;color?:string|{brightness:number;contrast:number;saturation:number;temperature:number;sharpness:number;vignette:number};id?:string;trackId?:string;text?:string;end?:number;at?:number;newId?:string;start?:number;trimStart?:number;duration?:number;volume?:number;muted?:boolean};
}
export interface TimelineEdit {schemaVersion:1;title:string;timelineId:string;commands:TimelineEditCommand[];}
export function isTimelineEdit(value:unknown):value is TimelineEdit;

export interface WorkspaceEdit {schemaVersion:1;title:string;field:'blueprint'|'panels'|'board'|'canvas'|'animation';before:Record<string,unknown>&{schemaVersion:1};after:Record<string,unknown>&{schemaVersion:1};}
export function isWorkspaceEdit(value:unknown):value is WorkspaceEdit;
export const WORKSPACE_EDIT_FIELDS:readonly WorkspaceEdit['field'][];

export function validateBlockOutputs(manifest: Manifest, values: Record<string, unknown>): Record<string, unknown>;

/** Optional schema-1 Project Type setup, consumed by the StillMade host. */
export interface ProjectTypeOnboardingQuestion {id:string;label:string;type:'text'|'textarea'|'select';required?:boolean;options?:string[];default?:string;}
export interface ProjectTypeDefaults {aspectRatio?:'16:9'|'9:16'|'1:1';brief?:string;}

/** Optional Project Type production rule. Only trusted host receipts can satisfy it. */
export interface ProjectTypeOutcome {type:"export"|"delivery"|"project_outcome";dedupe?:"material_project_state";minimumDurationSec?:number;}

export interface VideoGenerationCapability {schemaVersion:1;operation:'video.generate';prompt:{$input:string};output:string;}
export interface VideoGenerationInvocation {operation:'video.generate';prompt:string;}
export interface GeneratedVideoReference {kind:'video';assetId:string;versionId:string;url:string;mimeType:'video/mp4';width:number;height:number;duration:number;bytes:number;}
export interface GeneratedVideoMediaReceipt extends GeneratedVideoReference {schemaVersion:1;ownerId:string;runId:string;index:number;storageKey:string;sha256:string;}
export interface CapabilityVideoExpectation {kind:'video';format:'mp4';minDuration:number;maxDuration:number;minBytes:number;maxBytes:number;minWidth:number;maxWidth:number;minHeight:number;maxHeight:number;}
export const VIDEO_CAPABILITY_LIMITS:Readonly<{prompt:32000;bytes:67108864;duration:60;width:3840;height:3840;pixels:8294400}>;
export function validateGeneratedVideoReference(value:GeneratedVideoReference):true;
export function capabilityOutputs(pkg:BlockPackage,video:GeneratedVideoReference):Record<string,GeneratedVideoReference>;

export interface ImageDescriptionCapability {schemaVersion:1;operation:'image.describe';image:{$input:string};instruction:string;maxTokens:number;output:string;}
export interface ImageDescriptionInvocation {operation:'image.describe';image:GeneratedImageReference|{width:number;height:number;data:number[]};instruction:string;maxTokens:number;}
export interface TimelineProposalCapability {schemaVersion:1;operation:'timeline.propose';context:Record<string,{$input:string}>;instruction:string;maxTokens:number;output:string;}
export interface TimelineProposalInvocation {operation:'timeline.propose';context:Record<string,unknown>;instruction:string;maxTokens:number;}

export const COMFY_MODEL_LIMITS: Readonly<{steps:number;prompt:number;dimension:number;seed:number}>;
export function comfyModelRequirements(workflow: ComfyWorkflow): string[];

export type StateMigrationOperation={op:'rename';from:string;to:string}|{op:'default';key:string;value:unknown}|{op:'remove';key:string};
export interface StateMigration {fromVersion:number;operations:StateMigrationOperation[]}
export function validateStateMigrations(state:Manifest['state']):true;
export function stateMigrationRoute(manifest:Manifest,fromVersion:number):StateMigration|null;
export function migrateBlockState(previousManifest:Manifest,nextManifest:Manifest,state:BlockState):{state:BlockState;operations:StateMigrationOperation[];fromVersion:number;toVersion:number};
export const STATE_MIGRATION_LIMITS:Readonly<{routes:16;operations:64;keyLength:80;declarationBytes:65536}>;

/** In-session host job. This handle is never a guest output or durable receipt. */
export type PackageJobStatus = 'queued'|'loading'|'running'|'completed'|'failed'|'cancelled';
export interface PackageJobSnapshot {readonly id:string;readonly status:PackageJobStatus;readonly progress:Readonly<RecipeProgress|ContinuationProgress>|null;readonly error?:Readonly<{code:string;message:string}>}
export interface PackageJob {readonly id:string;readonly result:Promise<RunPackageResult>;getSnapshot():Readonly<PackageJobSnapshot>;subscribe(listener:()=>void):()=>void;cancel():boolean}
export interface PackageJobOptions extends RunPackageOptions {timeoutMs?:number;execute?:(pkg:BlockPackage,input:Record<string,unknown>,options:RunPackageOptions)=>Promise<RunPackageResult>|RunPackageResult}
export function createPackageJob(pkg:BlockPackage,input:Record<string,unknown>,options?:PackageJobOptions):PackageJob;

export {TimelineRange,ApprovalDecision,TIMELINE_RANGE_MAX_MS,isTimelineRange,isApprovalDecision} from './interaction-values.js';

/** Trusted native Script Writer services; does not grant guest permissions. */
export const SCRIPT_HOST_SERVICE_VERSION: 1;
export const SCRIPT_HOST_OPERATIONS: readonly string[];
/** Checks the service version and all required callable operations. */
export function requireScriptHostServices<T>(services:T):T;

export * from './native-workspace-contract.js';

export * from './script-project-browser.js';

export * from './script-collaboration.js';

export * from './script-server-services.js';

export * from './voiceover-host-services.js';

export * from './shot-planning-host-services.js';

export * from './blueprint-host-services.js';

export * from './shot-planning-sandbox-host.js';

export * from './board-editor-host.js';

/** Canonical immediate-use portable profile; legacy packages remain readable. */
export type PortableSource = {license:'MIT'|'BSD-2-Clause'|'BSD-3-Clause'|'ISC'|'Apache-2.0';paths:string[];evidence:string[];changes:string} & ({repository:string;commit:string;kind?:never}|{kind:'original';repository?:never;commit?:never});
export interface PortableMetadata {format:'stillmade-block/1';dependencies:[];sources:PortableSource[];files:Record<string,string>;lineage:{parents:{id:string;version:string;digest:string}[];changes:string}}
export const PORTABLE_FORMAT:'stillmade-block/1';
export const PORTABLE_LIMITS:Readonly<{archive:number;expanded:number;files:number}>;
export function recognizedLicense(text:string):PortableSource['license']|null;
export function validatePortableMetadata(pkg:BlockPackage):void;
export function withPortableAttribution(pkg:BlockPackage):BlockPackage;
export function withOriginalSource(pkg:BlockPackage):BlockPackage;
export function portableFiles(pkg:BlockPackage):Record<string,string>;
export function packageFromPortableFiles(files:Record<string,string>):BlockPackage;
export function readPortableArchive(bytes:Uint8Array,codec:{unzipSync:(bytes:Uint8Array)=>Record<string,Uint8Array>}):BlockPackage;
export function writePortableArchive(pkg:BlockPackage,codec:{zipSync:Function}):Uint8Array;
export function verifyPortableSources(pkg:BlockPackage,options?:{fetcher?:typeof fetch;signal?:AbortSignal}):Promise<{passed:boolean;legacy?:boolean;results?:{name:string;passed:boolean;message:string}[]}>;

export * from './workspace-application.js';

export * from './workspace-navigation.js';

export * from './canvas-workspace-host.js';
export * from './native-host-providers.js';

export {blockRemixPolicy,assertRemixReady,REMIX_AUTHORING_REQUIREMENT} from './remix-policy.js';
export interface SdkCompatibility {status:'supported'|'unsupported'|'invalid';declared:unknown;runtimeVersion:string;message:string}
export interface Manifest { schemaVersion: 1; id: string; name: string; version: string; sdkVersion: SdkVersionRange; description: string; kind: 'task'|'workspace'|'editor-extension'|'composite'; inputs: Record<string, Port>; outputs: Record<string, Port>; runtime: 'recipe'|'javascript'|'module'|'comfyui'|'capability'; jobs?: {kind:'cooperative';version:1}; state?: {scope:'step';version:number;initial:Record<string,unknown>;migrations?:StateMigration[]}; entry?: string; permissions: { project: string[]; desktop?: DesktopPermission[]; capabilities?: ['comfyui.execute']|['text.generate']|['audio.speech']|['audio.transcribe']|['image.generate']|['video.generate']|['image.describe']|['timeline.propose']|['workspace.propose']|['connection.execute']; network?: never[]; filesystem?: never[]; secrets?: never[] }; uiLayout?: {kind:'tabs'|'sections';groups:{id:string;label:string;inputs:string[];outputs:string[];collapsed?:boolean}[]}; ui?: ({ control: 'text'|'number'|'slider'|'checkbox'|'asset'; port: string; label?: string; when?: {port:string;equals:string|boolean} } | {control:'select'|'multiselect';port:string;options:string[];label?:string;when?:{port:string;equals:string|boolean}} | {control:'gallery';port:string;label?:string} | {control:'before-after';port:string;before:string;label?:string})[]; }
export interface BlockPackage { portable?: PortableMetadata; manifest: Manifest; view?: BlockView|FrameView; code?: string; module?: ModuleDescriptor; comfyui?: ComfyWorkflow; capability?: ConnectedCapability|TextGenerationCapability|SpeechCapability|TranscriptionCapability|ImageGenerationCapability|VideoGenerationCapability|ImageDescriptionCapability|TimelineProposalCapability; recipe?: { schemaVersion: 1; steps: { id: string; op: string; args: Record<string, unknown> }[]; outputs: Record<string, unknown> }; tests: { name: string; input: Record<string, unknown>; expected?: Record<string, unknown>; state?: BlockState; expectedState?: BlockState; expectations?: Record<string, ConnectedResultExpectation|ComfyImageExpectation|CapabilityTextExpectation|CapabilityAudioExpectation|CapabilityTranscriptExpectation|CapabilityImageExpectation|CapabilityVideoExpectation|CapabilityTimelineExpectation> }[]; }
export type CapabilityInvocation = TextGenerationInvocation|SpeechInvocation|TranscriptionInvocation|ImageGenerationInvocation|VideoGenerationInvocation|ImageDescriptionInvocation|TimelineProposalInvocation;
export interface CapabilityResult { outputs: Record<string, unknown>; metadata?: Record<string, unknown>; mediaReceipts?: Record<string, SpeechMediaReceipt|GeneratedAudioMediaReceipt|GeneratedImageMediaReceipt|GeneratedVideoMediaReceipt>; }
export function capabilityOperation(manifest: Manifest): 'text.generate'|'audio.speech'|'audio.transcribe'|'image.generate'|'video.generate'|'image.describe'|'timeline.propose'|'workspace.propose';
export function validateCapability(capability: TextGenerationCapability|SpeechCapability|TranscriptionCapability|ImageGenerationCapability|VideoGenerationCapability|ImageDescriptionCapability|TimelineProposalCapability, manifest: Manifest): true;
export function defaultCapabilityExpectations(manifest: Manifest): Record<string, CapabilityTextExpectation|CapabilityAudioExpectation|CapabilityTranscriptExpectation|CapabilityImageExpectation|CapabilityVideoExpectation|CapabilityTimelineExpectation>;
export function validateCapabilityExpectations(manifest: Manifest, expectations: Record<string, CapabilityTextExpectation|CapabilityAudioExpectation|CapabilityTranscriptExpectation|CapabilityImageExpectation|CapabilityVideoExpectation|CapabilityTimelineExpectation>): true;
export function testCapabilityOutputs(manifest: Manifest, outputs: Record<string, unknown>, expectations: Record<string, CapabilityTextExpectation|CapabilityAudioExpectation|CapabilityTranscriptExpectation|CapabilityImageExpectation|CapabilityVideoExpectation|CapabilityTimelineExpectation>): {passed:true;checks:({output:string;kind:'text'|'script';length:number;includesMatched:number}|{output:string;kind:'audio';format:'wav';duration:number;bytes:number;sampleRate:24000;channels:1}|{output:string;kind:'transcript';words:number}|{output:string;kind:'image';format:'png';width:1024;height:1024;bytes:number}|{output:string;kind:'timeline-edit';commands:number})[]};
export * from './voiceover-workspace-host.js';
export * from './blueprint-workspace-host.js';
export * from './canvas-chat-host.js';
export * from './canvas-timing.js';
export * from './canvas-chat-edit-broker.js';
export * from './canvas-chat-build-broker.js';
export * from './canvas-chat-descriptor-broker.js';
export * from './presenter-host.js';
export * from './presenter-placement-broker.js';
export * from './presenter-insertion-broker.js';
export * from './presenter-build-broker.js';
export * from './presenter-gap-broker.js';
export * from './presenter-provision-broker.js';
export * from './native-preview-contract.js';
export * from './animated-assets-host.js';
export * from './pipeline-execution-host.js';
export * from './pipeline-node-generation-host.js';
export * from './pipeline-runtime-host.js';

export * from './canvas-generation-host.js';

export * from './media-description-host.js';
export * from './audio-score-host.js';
export * from './video-assets-host.js';
export * from './editor-execution-host.js';
export * from './canvas-node-host.js';
export * from './media-upload-host.js';
export * from './youtube-connection-host.js';
export * from './youtube-host.js';

export interface TransitionSettings {type:string;duration:number;soundOn:boolean;soundId:string;}
export const TRANSITION_SETTINGS: readonly {readonly type:string;readonly sounds:readonly string[]}[];
export function isTransitionSettings(value:unknown):value is TransitionSettings;

/** Host-installed media export dependency; unavailable to sandbox guest code. */
export interface MediaExportSession {read(url:string):Promise<Uint8Array>;close():void}
export interface MediaExportHost {version:1;open(urls:string[],options?:{signal?:AbortSignal;checkCurrent?:()=>void}):MediaExportSession}
export const MEDIA_EXPORT_LIMITS:Readonly<{files:256;fileBytes:268435456;totalBytes:536870912;concurrency:6;attempts:3}>;
export function requireMediaExportHost(host:unknown):MediaExportHost;

/** Inert, user-requested file download result; not a Block package archive. */
export interface FileBundleSource {[key:string]:unknown;kind:'image'|'video'|'audio';assetId:string;versionId:string;url:string;role?:string}
export interface FileBundle {schemaVersion:1;format:'file'|'zip';name:string;files:({path:string;text:string}|{path:string;source:FileBundleSource})[]}
export const FILE_BUNDLE_LIMITS:Readonly<{files:256;textBytes:3000000;pathLength:180}>;
export function isFileBundle(value:unknown):value is FileBundle;

/** Host admission for user-selected originals; no guest upload permission. */
export const MEDIA_IMPORT_MAX_BYTES: number;
export const MEDIA_IMPORT_FORMATS: Readonly<Record<string, Readonly<{kind:'image'|'video'|'audio';mimeType:string}>>>;
/** Every upload the host stores: media plus general files (kind 'file'). */
export const IMPORT_FORMATS: Readonly<Record<string, Readonly<{kind:'image'|'video'|'audio'|'file';mimeType:string}>>>;
/** Checks a chosen file; `kinds` defaults to media, pass ['file'] for general files. */
export function inspectMediaImportFile(file:{name:string;size:number;type?:string},options?:{kinds?:Array<'image'|'video'|'audio'|'file'>}):{kind:'image'|'video'|'audio'|'file';extension:string;mimeType?:string};
export * from './data-values.js';
export * from './cloud-storage.js';
export * from './triggers.js';
export * from './mock-host.js';
export * from './view-bridge.js';
export * from './port-types.js';
export * from './trigger-examples.js';

/** Metadata only; filled values do not imply media access or execution approval. */
export interface AgentValuePresence {status:'missing'|'empty'|'invalid'|'filled';filled:boolean;characters?:number;items?:number;fields?:number;availability?:'verified'|'unknown'}
export interface AgentInputPresence extends AgentValuePresence {id:string;type:string;required:boolean;source:'project'|'provided'|'default'|'unset';locked:boolean}
export function inspectAgentValue(value:unknown,port?:{type:string;[key:string]:unknown},options?:{mediaVerified?:boolean}):AgentValuePresence;
export function inspectAgentPorts(ports?:Record<string,{type:string;[key:string]:unknown}>,values?:Record<string,unknown>,options?:{offset?:number;limit?:number;locked?:string[]}):{fields:AgentInputPresence[];total:number;nextOffset:number|null};
export function inspectAgentBlock(content:unknown,values?:Record<string,unknown>,options?:{offset?:number;limit?:number;outputOffset?:number;outputs?:Record<string,unknown>;locked?:string[]}):{schemaVersion:1;block:Record<string,unknown>;inputs:ReturnType<typeof inspectAgentPorts>;outputs:ReturnType<typeof inspectAgentPorts>;prerequisites:{inputs:Array<{inputKey:string;type:string;source:string;locked:boolean}>;partial:boolean};permissions:Record<string,string[]>;platforms:Record<string,{supported:boolean}>;stateContract:{scope:string|null;version:number|null}|null;execution:{runtime:string|null;cooperativeJobs:boolean};readiness:'partial'|'needs-input'|'inputs-present';admission:'not-checked';mediaAccess:'not-checked';executionApproval:'not-granted'};
export interface AgentDocumentField {path:string[];type:string;status:'missing'|'empty'|'filled';filled:boolean;characters?:number;items?:number;fields?:number;childrenInspected?:number;childrenOmitted?:boolean}
export function inspectAgentDocument(document:unknown,options?:{limit?:number;maxDepth?:number}):{fields:AgentDocumentField[];partial:boolean;inspection:'presence-only';validation:'not-checked';mediaAccess:'not-checked'};
export interface AgentEditableInput {id:string;type:string;description?:string;min?:number;max?:number;options?:unknown[];selection?:string;optionsPartial?:boolean}
export function agentInputChoices(manifest:{inputs?:Record<string,{type:string;description?:string;context?:unknown;min?:number;max?:number}>;ui?:any[]},locked?:string[],options?:{offset?:number}):AgentEditableInput[];
export function parseAgentInput(manifest:Parameters<typeof agentInputChoices>[0],args:unknown,options?:{locked?:string[];busy?:boolean;disabled?:boolean}):{field:string;value:unknown};
export {defineNativeAgentAdapter,bindNativeAgentActions,bindNativeWorkspaceActions,NATIVE_WORKSPACE_ACTION_LIMIT} from './native-agent-contract.js';
export type {NativeAgentAction,NativeAgentAdapter,NativeWorkspaceAction} from './native-agent-contract.js';

export * from './export-policy.js';
export {createUniversalResolver} from './universal-resolver.js';
export type {ResolutionSource,ResolutionDependency,ResolutionValue,ResolutionOptions,ResolutionCandidate,ResolutionDecision,ResolutionAnswer,ResolutionResult,UniversalResolver,UniversalResolverServices} from './universal-resolver.js';

export function inspectAgentDocumentPage(document:unknown,options?:{path?:string[];offset?:number;limit?:number}):{focus:AgentDocumentField;fields:AgentDocumentField[];total:number;offset:number;nextOffset:number|null;inspection:'presence-only';validation:'not-checked';mediaAccess:'not-checked'};

export * from './asset-generation-host.js';

export * from './pipeline-asset-host.js';

export * from './byok-payment-host.js';

export * from './repository-application.js';

export * from './portable-media-actions.js';

export type ProjectFlowFailureCode='EXECUTION_FAILED'|'RESULT_DELIVERY_FAILED'|'RESULT_SAVE_FAILED';
export const PROJECT_FLOW_FAILURE_CODES:readonly ProjectFlowFailureCode[];
export type ProjectFlowPerspective='planned'|'active_run'|'historical_run';
export interface ProjectFlowTarget {projectId:string;placementId?:string;inputKey?:string;outputKey?:string;runId?:string;attemptId?:string;itemId?:string;perspective?:ProjectFlowPerspective}
export type ProjectFlowValuePath=Array<{kind:'field';key:string}|{kind:'item';index:number}>;
export interface ProjectFlowLocalMediaReference {assetId:string;versionId:string;kind:'image'|'video'|'audio'}
export interface ProjectFlowLocalMediaInspection extends ProjectFlowLocalMediaReference {availability:'present'|'not-on-this-device'|'version-mismatch'|'unavailable';scope:'this-device';cloudAvailable:false;playbackVerified:false;execution:'none'}
export interface ProjectFlowTextPreview {kind:'text';excerpt:string;characters?:number;revision?:string;path?:ProjectFlowValuePath;identity?:string;offset?:number;limit?:number;nextOffset?:number|null;truncated?:boolean;pageable?:boolean;redacted?:boolean}
export interface ProjectFlowTextPageRequest {placementId:string;portKind:'input'|'output';portKey:string;path:ProjectFlowValuePath;identity:string;offset:number;limit:number}
export interface ProjectFlowCandidate {id:string;label:string;reason?:string|null;sourcePlacementId?:string|null;outputKey?:string|null;preview?:unknown;adapter?:{id:string;version:number}|null;adapterDetail?:ProjectFlowAdapterDetail|null}
export interface ProjectFlowAdapterDetail {id?:string;version?:number|string;available:boolean;inputType?:string;outputType?:string;effect?:string;status?:string;steps?:Array<{id:string;version:number|string}>;contextFields?:string[]}
export interface ProjectFlowInput {key:string;label:string;required:boolean;state:string;reason?:string|null;source?:string|null;sourceKind?:string|null;sourcePlacementId?:string|null;sourceOutputKey?:string|null;explicit?:boolean;selectionReason?:string|null;valuePolicy?:string|null;materialized?:boolean;preview?:unknown;candidates:ProjectFlowCandidate[];candidatesOmitted?:number;candidateCount?:number;candidateRevision?:string;candidateOffset?:number;candidateLimit?:number;candidateNextOffset?:number|null;[key:string]:unknown}
export interface ProjectFlowNativeObservation {kind:'native-canvas-output';nodeId:string;blockId:string;blockVersion:string;outputKey:string;handle:string;runReceiptAvailable:false;revision:string}
export interface ProjectFlowOutput {key:string;label:string;state:string;runId?:string|null;preview?:unknown;observation?:ProjectFlowNativeObservation|null;availabilityReason?:string|null}
export type ProjectFlowConditionOperator='present'|'equals'|'not-equals'|'greater-than'|'at-least'|'less-than'|'at-most';
export interface ProjectFlowCondition {inputKey:string;inputLabel:string;path:string[];operator:ProjectFlowConditionOperator;outcome:'unknown'|'ran'|'skipped'}
export interface ProjectFlowExecution {kind:'StillMade hosted capability'|'Connected ComfyUI service'|'Block runtime'|'Condition bypass';delivery:'captured'|'not-produced';mediaReceiptCount:number}
export interface ProjectFlowInputEvidence {key:string;label:string;kind:string|null;assetId?:string|null;versionId?:string|null;count?:number|null;sourceId?:string|null;sourceRevision?:string|null;sourceReference?:{id:string;version:string;path:Array<string|number>}|null;sourceKind?:string|null;sourceStepId?:string|null;sourcePort?:string|null;sourceRunId?:string|null;sourceAdapterId?:string|null;sourceAdapterVersion?:string|null;items?:Array<{kind:string|null;assetId:string|null;versionId:string|null;count:number|null}>;truncated?:boolean}
export interface ProjectFlowActiveRun {scope:'this-tab'|'shared-tab';kind:'single'|'connected'|'batch'|'loop';startedAt:string;runId:string|null;progress:string|null;actorLabel?:string;attempt?:number|null;batchIndex?:number;batchCount?:number;iteration?:number;additionalRuns?:number;initialInputs:ProjectFlowInputEvidence[]|null;inputsComplete:boolean}
export interface ProjectFlowFailureDiagnostic {code:ProjectFlowFailureCode;durationMs:number|null}
export interface ProjectFlowFailedAttempt extends ProjectFlowFailureDiagnostic {runId:string;at:string;attempt?:number;batchIndex?:number;batchCount?:number}
export interface ProjectFlowHistoryEntry {receiptId?:string;inputs?:ProjectFlowInputEvidence[]|null;inputsRevision?:string;inputsCount?:number|null;inputsOffset?:number;inputsLimit?:number;inputsNextOffset?:number|null;inputsRetainedComplete?:boolean;inputsTruncated?:boolean;execution?:ProjectFlowExecution;diagnostic?:ProjectFlowFailureDiagnostic;recovered?:boolean;[key:string]:unknown}
export interface ProjectFlowSelection {kind:'existing-media'|'host-action';selectionId:string;at?:string}
export interface ProjectFlowActivity {selection?:ProjectFlowSelection;failedAttempt?:ProjectFlowFailedAttempt;execution?:ProjectFlowExecution;active?:ProjectFlowActiveRun;applied?:boolean;at?:string|null;runId?:string|null;skipped?:boolean;[key:string]:unknown}
export interface ProjectFlowRetainedCandidate {candidateId:string;kind:'unused'|'connected'|'batch'|'loop';loopRunId?:string;loopReceiptDigest?:string;loopStartPlacementId?:string;historical?:true;selection?:ProjectFlowSelection;verification?:'verified-original'|'requires-inspection';runId:string|null;at:string|null;outputDigest:string;packageDigest:string|null;inputDigest:string|null;attempt?:number|null;batchIndex?:number|null;batchCount?:number|null;iteration?:number|null;reason:string;applied:false;previewRestricted:boolean;inputs:ProjectFlowInputEvidence[]|null;inputsCount:number|null;inputsOffset:number;inputsNextOffset:number|null;inputsRetainedComplete:boolean;outputs:ProjectFlowOutput[];outputsCount:number;outputsOffset:number;outputsNextOffset:number|null}
export interface ProjectFlowRetainedListRequest {placementId:string;revision:string;offset:number;limit:number}
export interface ProjectFlowRetainedInspectRequest extends ProjectFlowRetainedListRequest {candidateId:string;section:'inputs'|'outputs'|'text'|'collection';outputKey?:string;path?:Array<{kind:'field';key:string}|{kind:'item';index:number}>;identity?:string}
export interface ProjectFlowPlacement {id:string;state:string;localMediaInputs?:string[];condition?:ProjectFlowCondition;activity?:ProjectFlowActivity|null;history?:ProjectFlowHistoryEntry[];retainedLoopRuns?:{runId:string;planDigest:string;receiptDigest:string;loopDigest:string;iterations:number;selected:boolean;location:"shared-project";validation:"requires-review"}[];unusedResults?:ProjectFlowRetainedCandidate[];unusedResultsRevision?:string;unusedResultsCount?:number;unusedResultsOffset?:number;unusedResultsNextOffset?:number|null;inputs:ProjectFlowInput[];outputs:ProjectFlowOutput[];[key:string]:unknown}
export interface ProjectFlowEdge {from:string;to:string;inputKey:string;outputKey?:string|null;sourceRunId?:string|null;state?:string;materialized?:boolean;adapter?:unknown}
export interface ProjectFlowIssue {message:string;placementId?:string|null;inputKey?:string|null}
export interface ProjectFlowSnapshot {contractVersion:1;projectId:string|null;snapshotCursor?:string;revision?:string;scope?:'project'|'placement';definition:{id:string;version:string}|null;placements:ProjectFlowPlacement[];edges:ProjectFlowEdge[];issues:ProjectFlowIssue[];partial:boolean;projectFlowPartial?:boolean;total?:number;nextOffset?:number|null;pageComplete?:boolean;candidatePage?:{placementId:string;inputKey:string;total:number;candidateRevision:string;offset:number;limit:number;nextOffset:number|null}}
export const PROJECT_FLOW_CONTRACT_VERSION:1;
export const PROJECT_FLOW_PERSPECTIVES:readonly ProjectFlowPerspective[];
export interface ProjectTaskControlRequest { projectId:string; taskId:string; action:'pause'|'resume'|'takeover'|'cancel'; requestId:string; requesterId:string; taskRevision:string; instructionRevision:number; controlEpoch:number; reason?:string; }
export interface ProjectTaskControlReceipt { requestId:string; taskId:string; action:'pause'|'resume'|'takeover'|'cancel'; status:string; instructionRevision:number; controlEpoch:number; }
export interface ProjectCapabilityRequestRead { projectId:string; requestId:string; expectedRevision?:string; }
export interface ProjectCapabilityRequestDelivery { projectId:string; requestId:string; runId:string; revision:string; state:string; recoveryState:'retrieved'|'pending'|'unavailable'; packageDigest:string; inputDigest:string; quoteDigest:string; outputs:Record<string,unknown>|null; execution:'none'; applied:false; selectionChanged:false; providerPolled:false; validatedFor:'delivery-only'; }
export const PROJECT_FLOW_OPERATIONS:Readonly<Record<'inspectTasks'|'controlTask'|'inspectFlow'|'diagnoseHandoff'|'listPlacements'|'readText'|'listPorts'|'listRunInputs'|'listHistory'|'listRetainedResults'|'inspectRetainedResult'|'listCandidates'|'reviewSourceUndo'|'updateAffected'|'previewCompletedResults'|'useCompletedResults'|'recoverSubmittedResult'|'recoverCapabilityRequest'|'recoverMedia'|'inspectLocalMedia'|'previewSourceChange'|'changeSource'|'previewConverterRoute'|'applyConverterRoute'|'listConverterContracts'|'previewResultPin'|'pinResult'|'clearResultPin'|'revealTarget',Readonly<{id:string;nativeAction:string|null;externalTool:string|null;effect:'read'|'project_edit'|'navigate'|'run'|'task_control'}>>>;
export const PROJECT_FLOW_LIMITS:Readonly<{placements:1000;edges:4000;issues:1000;bytes:12000000}>;
export function projectFlowTarget(value:unknown):Readonly<ProjectFlowTarget>;
export function projectFlowSnapshot<T extends ProjectFlowSnapshot>(value:T):T;
export function redactProjectFlowMediaAddresses<T>(value:T):T;

// Pure future application contracts; Manifest/BlockPackage remain unchanged.
export * from './browser-application.js';
export * from './browser-application-execution.js';
export * from './browser-application-guest.js';

export * from './browser-application-artifacts.js';

export type ConnectionBackend='pipedream'|'composio'|'nango'|'generated';
export interface ConnectionPin {backend:ConnectionBackend;id:string;version:string;schemaHash:string;integrationId?:string}
export interface ConnectedCapability {schemaVersion:1;operation:'connection.execute';appId:string;capabilityId:string;pin:ConnectionPin;bindings:Record<string,string>;output:string;inputSchema:Record<string,unknown>;outputSchema:Record<string,unknown>}
export interface ConnectedResultExpectation {kind:'connected-result';maximumBytes:number}
export interface ConnectedAppMetadata {id:string;blockId?:string;name:string}
export interface ConnectedTaskMetadata extends ConnectionPin {capabilityId:string;definitionHash:string;name:string;description?:string;inputSchema:Record<string,unknown>;outputSchema:Record<string,unknown>;kind?:'action'|'trigger'|'sync';semantics?:string}
export function connectedAppBlock(app:ConnectedAppMetadata,route:ConnectedTaskMetadata):BlockPackage;
export interface ConnectionConfigurationRequest {operation:'reload'|'options'|'configure';propName?:string;query?:string;page?:number;previousContext?:Record<string,unknown>}
export interface ConnectionConfigurationResult {schemaVersion:1;operation:'reload'|'options'|'configure';inputSchema:Record<string,unknown>;schemaDigest:string;dynamicPropsId?:string;propName?:string;options?:Array<{label:string;value:unknown}>;previousContext?:Record<string,unknown>}
/** Pure package construction; the authenticated host separately validates the current exact-account configuration receipt. Trigger metadata is not ordinary action admission. */
export function configuredConnectionBlock(app:ConnectedAppMetadata,route:ConnectedTaskMetadata,basePackage:BlockPackage,configuration:ConnectionConfigurationResult):Promise<BlockPackage>;
export function validateConnectedCapability(capability:ConnectedCapability,manifest:Manifest):true;
export function prepareConnectedInvocation(pkg:BlockPackage,raw:Record<string,unknown>):{operation:'connection.execute';appId:string;capabilityId:string;pin:ConnectionPin;input:Record<string,unknown>};
export interface SchemaFields {currencyDigits(currency:string):number;minorUnits(decimal:string,currency:string):number;formatMoney(minor:number,currency:string):string;preview(value:unknown,options?:{maximumFields?:number}):BlockViewNode[];read(root:unknown,path:Array<string|number>):unknown;set(root:unknown,path:Array<string|number>,value:unknown):Record<string,unknown>;controls(schema:Record<string,unknown>,bindings:Record<string,string>,values:Record<string,unknown>,options?:{canEdit?:boolean;busy?:boolean}):{tree:unknown[];actions:unknown[]};change(values:Record<string,unknown>,actions:unknown[],event:unknown):Record<string,unknown>;fromState(input:Record<string,unknown>,state:Record<string,unknown>,bindings:Record<string,string>):Record<string,unknown>;edits(values:Record<string,unknown>,state:Record<string,unknown>,bindings:Record<string,string>):{patch:Record<string,unknown>;before:Record<string,unknown>;changed:boolean}}
export function createSchemaFields(lockedInputKeys?:string[]):Readonly<SchemaFields>;
export interface BlockViewBridge {schemaFields:Readonly<SchemaFields>}

export interface ConnectionReferencePointer {id:string;version:string}
export interface ConnectionReferenceField {path:Array<string|number>;value:string|number|boolean|null}
export interface ConnectionReferenceSnapshot {schemaVersion:1;source:{kind:'connection-result'|'desktop-result';appId?:string;accountLabel?:string;runId:string;sourceDigest:string;inputDigest:string;pin?:ConnectionPin;capabilityId:string;outputDigest?:string;evidence?:'desktop-host-receipt-envelope';cloudVerified?:false};fetchedAt:string;fields:ConnectionReferenceField[]}
export function referenceFields(value:unknown,options?:{maximum?:number}):{fields:ConnectionReferenceField[];partial:boolean};
export function selectReferenceFields(value:unknown,paths:Array<Array<string|number>>):ConnectionReferenceField[];

/** Exact selected fields; require explicit resolver selection. The host rechecks source permission. */
export function snapshotSemanticValues(reference: ConnectionReferencePointer & {label:string;visibility:'private'|'project';status:string;snapshot?:ConnectionReferenceSnapshot|null}): Array<Record<string, unknown>>;

export interface SharedWorkContract {schemaVersion:1;kind:string;version:number;schema:Record<string,unknown>}
export interface Manifest {sharedWork?:SharedWorkContract}
export type SharedWorkOperation='list'|'accounts'|'grants'|'create'|'bind'|'read'|'update'|'creatives'|'contribute'|'grant'|'revoke'|'unlink';
export interface BlockViewBridge {connectedApp(operation:'tasks'|'preview-task'|'apply-task',args?:Record<string,unknown>):Promise<Record<string,unknown>>;onSharedWorkRefresh(callback:()=>void):()=>void;sharedWork(operation:SharedWorkOperation,args?:Record<string,unknown>):Promise<Record<string,unknown>>}
export const SHARED_WORK_OPERATIONS:readonly SharedWorkOperation[];
export function sharedWorkRequest(operation:SharedWorkOperation,args?:Record<string,unknown>):{operation:SharedWorkOperation;args:Record<string,unknown>};
export function validateSharedWorkContract(value:unknown):true;

export function connectedAppViewRequest(operation: 'tasks'|'preview-task'|'apply-task', args?: Record<string, unknown>): {operation:string; args:Record<string,unknown>};
export function installConnectedAppViewBridge(channel:string,session:string,enabled:boolean,send:(value:unknown,target:string)=>void): {connectedApp(operation:'tasks'|'preview-task'|'apply-task',args?:Record<string,unknown>):Promise<unknown>};

export interface BlockViewBridge {previewSharedWorkMedia(contributionId:string):Promise<{url:string;kind:'image'|'video'|'audio'}>;releaseSharedWorkMedia(url:string):void;}

export interface PythonCallableOperation {id:string;name:string;description?:string;parameters:{name:string;type:'str'|'int'|'float'|'bool'}[];returnType:'str'|'int'|'float'|'bool';inputSchema:Record<string,unknown>;outputSchema:Record<string,unknown>}
export function pythonConnectionBlock(options:{name:string;source:string;sourceDigest:string;license:string;operation:PythonCallableOperation;input?:Record<string,unknown>}):Promise<BlockPackage>;
export const CONNECTION_API_OPERATIONS:Readonly<Record<string,{method:'GET'|'POST';path:string;query?:string[]}>>;
export function createConnectionClient(options:{request:(path:string,options:{method:'GET'|'POST';body?:Record<string,unknown>;signal?:AbortSignal})=>Promise<unknown>}):{readonly schemaVersion:1;call(operation:keyof typeof CONNECTION_API_OPERATIONS,args?:Record<string,unknown>,options?:{signal?:AbortSignal}):Promise<unknown>};
/** A JSON Schema subset for structured text.generate replies: type, description, title, enum, properties, required, additionalProperties, items, minItems, maxItems, minLength, maxLength, pattern, format, minimum, maximum. */
export type JsonSchema = {type:JsonSchemaType|JsonSchemaType[];description?:string;title?:string;enum?:(string|number|boolean|null)[];properties?:Record<string,JsonSchema>;required?:string[];additionalProperties?:boolean;items?:JsonSchema;minItems?:number;maxItems?:number;minLength?:number;maxLength?:number;pattern?:string;format?:'date'|'date-time'|'email'|'uri';minimum?:number;maximum?:number};
export type JsonSchemaType = 'object'|'array'|'string'|'number'|'integer'|'boolean'|'null';
export const JSON_SCHEMA_LIMITS: Readonly<{bytes:8192;depth:8;properties:64;enum:64;stringLength:4000}>;
export function validateJsonSchema(schema: JsonSchema): true;
/** The first place a value breaks the schema, as "$.path: reason", or null when it matches. */
export function jsonSchemaMismatch(value: unknown, schema: JsonSchema, path?: string): string|null;
export function jsonSchemaInstruction(schema: JsonSchema): string;
export function parseJsonReply(text: string): unknown;

/** Runtime `module`: an ES module (with optional WebAssembly and data files) named by SHA-256. */
export interface ModuleFile { sha256: string; bytes: number; mediaType: 'text/javascript'|'application/wasm'|'application/json'|'text/plain'|'image/png'|'image/jpeg'|'image/webp'|'font/woff2'|'application/octet-stream'; }
export interface ModuleDescriptor { schemaVersion: 1; entry: string; files: Record<string, ModuleFile>; }
export const MODULE_RUNTIME_VERSION: 1;
export const MODULE_LIMITS: Readonly<{files:64;fileBytes:67108864;totalBytes:134217728;path:160;wallClockMs:120000;maxWallClockMs:1800000;progressGraceMs:60000;messageBytes:16777216;logEntries:500}>;
export const MODULE_MEDIA_TYPES: readonly ModuleFile['mediaType'][];
export const MODULE_HOST_API: readonly string[];
export function validateModuleDescriptor(module: ModuleDescriptor): true;
export function moduleFileDigest(bytes: ArrayBuffer|Uint8Array): Promise<string>;
export function describeModuleFiles(entry: string, files: Record<string, Uint8Array|ArrayBuffer|string>, options?: {mediaTypes?: Record<string, ModuleFile['mediaType']>}): Promise<ModuleDescriptor>;
export function moduleMediaType(path: string): ModuleFile['mediaType'];
export function verifyModuleFile(module: ModuleDescriptor, path: string, bytes: ArrayBuffer|Uint8Array): Promise<Uint8Array>;
export function moduleDeadline(startedAt: number, lastProgressAt: number): number;
/** The run-limit clock: host-call time is not counted toward the 2-minute limit; the 30-minute hard limit counts real time. */
export function moduleRunClock(now?: () => number): Readonly<{progress(): void; hostStarted(): void; hostFinished(): void; expired(): boolean}>;
/** The `stillmade` object a module entry receives: `export default async function run(input, stillmade)`. */
export interface ModuleHost {
  input: Record<string, unknown>;
  signal: AbortSignal;
  progress(value: number, label?: string): void;
  log(...values: unknown[]): void;
  /** A copy of one of the module's own files, such as a .wasm build. */
  asset(path: string): ArrayBuffer;
  files: { read(ref: {kind:string;assetId:string;versionId:string;url:string}): Promise<ArrayBuffer>; write(data: ArrayBuffer|ArrayBufferView|Blob|string, options: {mediaType: string; name?: string}): Promise<{kind:'image'|'video'|'audio';assetId:string;versionId:string;url:string;mimeType:string;bytes:number}>; };
  /** On-device media work by StillMade: decode, extract, normalise, cut, join, resize, thumbnail. */
  media: { transform(request: MediaTransformRequest): Promise<SavedMediaRef|DecodedAudio>; };
  actions: { run(action: Record<string, unknown>): Promise<unknown>; };
  hosted: { run(operation: string, request: Record<string, unknown>): Promise<unknown>; };
  /** Declared-origin network calls; StillMade adds the person's own key. */
  net: { fetch(url: string|URL, init?: {method?: string; headers?: Record<string,string>|[string,string][]; body?: ArrayBuffer|ArrayBufferView|Blob|string}): Promise<Response>; };
  /** Published adapter operations, with the person's own account. */
  connections: { call(appId: string, operation: string, input?: Record<string, unknown>): Promise<unknown>; };
  /** The Block's cloud storage in this project (manifest `storage`). */
  storage: import('./cloud-storage.js').ModuleStorageApi;
  /** The current project, limited to declared fields (`project.read`). */
  project: { read(fields?: string[]): Promise<Record<string, unknown>>; };
  /** Project media assets (`asset.create`, `asset.version.append`). */
  assets: { create(file: {kind:'image'|'video'|'audio';assetId:string;versionId:string;url:string}, options?: {name?: string}): Promise<{kind:string;assetId:string;versionId:string;url:string;label?:string}>; appendVersion(asset: string|{assetId:string}, file: {kind:string;assetId:string;versionId:string;url:string}): Promise<{kind:string;assetId:string;versionId:string;url:string}>; };
}
export const MODULE_HOSTED_OPERATIONS: readonly string[];
export function moduleHostedPackage(source: Record<string, unknown>, operation: string, request: Record<string, unknown>): {package: BlockPackage; input: Record<string, unknown>};

/** `stillmade.media.transform` requests and the `@stillmade/block-sdk/media` helpers. */
export type SavedMediaRef = {kind:'image'|'video'|'audio'|'asset'; assetId:string; versionId:string; url:string; mimeType?:string; bytes?:number; name?:string};
export type RenderSettings = {fps?:24|30|60; resolution?:720|1080|2160; quality?:'low'|'medium'|'high'};
export type TimeRange = {start:number; end:number};
export type MediaTransformRequest =
  | {operation:'audio.decode'; source:SavedMediaRef; sampleRate?:8000|16000|22050|24000|32000|44100|48000}
  | {operation:'audio.extract'; source:SavedMediaRef; format?:'wav'|'mp3'}
  | {operation:'audio.normalize'; source:SavedMediaRef; targetLufs?:number; format?:'wav'|'mp3'}
  | {operation:'video.cut'; source:SavedMediaRef; keep:TimeRange[]; settings?:RenderSettings}
  | {operation:'video.concat'; sources:SavedMediaRef[]; settings?:RenderSettings}
  | {operation:'video.resize'; source:SavedMediaRef; settings:RenderSettings}
  | {operation:'image.thumbnail'; source:SavedMediaRef; at?:number; width?:number};
export type DecodedAudio = {sampleRate:number; duration:number; samples:Float32Array};
export const MEDIA_TRANSFORM_LIMITS: Readonly<{ranges:500;sources:50;durationSeconds:21600;decodeSamples:201326592;sampleRates:readonly number[];thumbnailWidth:4096}>;
export const MEDIA_TRANSFORM_OPERATIONS: readonly MediaTransformRequest['operation'][];
export function mediaTransformRequest(value: MediaTransformRequest): Required<MediaTransformRequest>;
export function mediaTransformSources(request: MediaTransformRequest): SavedMediaRef[];
export function silentRanges(samples: Float32Array|number[], sampleRate: number, options?: {thresholdDb?:number; minSilence?:number; window?:number}): TimeRange[];
export function keepRanges(silent: TimeRange[], duration: number, options?: {padding?:number}): TimeRange[];
export function integratedLoudness(channels: Float32Array[], sampleRate: number): number;
export function loudnessGain(channels: Float32Array[], sampleRate: number, targetLufs?: number): number;
export function loudnessMeter(sampleRate: number, channelCount?: number): Readonly<{push(channels: Float32Array[]): void; loudness(): number; peak(): number}>;
export function gainFor(measuredLufs: number, peak: number, targetLufs?: number): number;
export function wavWriter(channelCount: number, sampleRate: number, frames: number): Readonly<{buffer: ArrayBuffer; write(channels: Float32Array[], from?: number, to?: number, gain?: number): void}>;
export function encodeWav(channels: Float32Array[], sampleRate: number): ArrayBuffer;
export function decodeWav(buffer: ArrayBuffer): {channels: Float32Array[]; sampleRate: number};

Connected failure recovery

The shared Step failure control supports last-valid recovery for eligible stateless sandbox Blocks and bounded hosted text, speech or image generation with immutable receipts for media. Recovery applies only to interactive connected runs. It is not automatic retry or an SDK pending-result envelope. A successful run must first be retained with this policy, bound to the same account, project, workflow, source and inputs.

Sandbox image recovery requires exact immutable PNG receipts and ordered pixel input evidence, with up to 16 images and 32 MiB of saved PNGs. Hosted text recovery requires only the text.generate capability permission, no other scopes or state, and text/structured ports. After a definite eligible output, expectation or provider-response failure, the host offers an explicit reuse action. It verifies both the failed request and the original successful project receipt, requires the same provider/model/payment selection, and repeats current source, context and access checks before adoption. Pending, uncertain, canceled and unclassified requests are not eligible.

Reused results preserve the original output/receipt identity and are marked skipped; they do not create another generation, reservation or qualifying production execution. Recovery does not change billing for the failed attempt. The original retained successful record must remain available. External hosts must supply equivalent authoritative verification and attribution handling; copying a saved output or setting skipped is not proof. Legacy speech/image receipts, video, ComfyUI, background and standalone recovery remain unsupported; eligible hosted speech/image recovery requires immutable version-2 receipts and the same explicit original-run verification.

Failures

Execution rejects invalid input, unknown outputs, timeouts, and unsupported operations. Preserve the original media and show the failure. See errors and testing.