export type PublishPlatformId = 'youtube-shorts' | 'tiktok' | 'instagram-reels'; export type PublishPlatform = PublishPlatformId; export type PublishVisibilityIntent = 'private' | 'unlisted' | 'public'; export interface PublishProfileSource { url: string; title: string; retrievedAt: string; fields: string[]; } export interface PublishPlatformProfile { platform: PublishPlatformId; displayName: string; profileVersion: string; retrievedAt: string; sources: PublishProfileSource[]; media: { containers: string[]; videoCodecs: string[]; audioCodecs?: string[]; audioRequired: boolean; progressiveRequired?: boolean; minDurationSeconds?: number; maxDurationSeconds?: number; maxSizeBytes?: number; minWidth?: number; maxWidth?: number; minHeight?: number; maxHeight?: number; minFrameRate?: number; maxFrameRate?: number; aspectRatios?: Array<{ label: string; ratio: number; tolerance?: number; }>; minAspectRatio?: number; maxAspectRatio?: number; maxVideoBitrateMbps?: number; maxAudioSampleRateHz?: number; maxAudioChannels?: number; recommendedAspectRatio?: string; }; metadata: { maxTitleCharacters: number; maxDescriptionCharacters?: number; maxHashtags?: number; syntheticDisclosureRequired: boolean; supportedVisibility: PublishVisibilityIntent[]; captionsOptional: boolean; captionFormats: string[]; thumbnailOptional: boolean; thumbnailFormats: string[]; }; } export interface PublishSyntheticMediaDisclosure { containsSyntheticMedia: boolean; disclosureText?: string; } export interface PublishMetadataArtifact { projectSlug: string; title: string; description?: string; tags?: string[]; visibility: PublishVisibilityIntent; syntheticMedia?: PublishSyntheticMediaDisclosure; captionsPath?: string; thumbnailPath?: string; createdAt: string; updatedAt?: string; } export interface PublishMediaInfo { path: string; container: string; videoCodec?: string; audioCodec?: string; audioPresent: boolean; durationSeconds?: number; width?: number; height?: number; sizeBytes?: number; frameRate?: number; progressive?: boolean; videoBitrateMbps?: number; audioSampleRate?: number; audioChannels?: number; } export interface PublishValidationIssue { code: | 'container_unsupported' | 'video_codec_unsupported' | 'audio_codec_unsupported' | 'audio_missing' | 'progressive_required' | 'duration_too_short' | 'duration_too_long' | 'file_too_large' | 'width_too_small' | 'width_too_large' | 'height_too_small' | 'height_too_large' | 'frame_rate_too_low' | 'frame_rate_too_high' | 'aspect_ratio_unsupported' | 'bitrate_too_high' | 'audio_sample_rate_too_high' | 'audio_channels_too_high' | 'title_missing' | 'title_too_long' | 'description_too_long' | 'hashtags_too_many' | 'visibility_unsupported' | 'synthetic_disclosure_missing' | 'caption_format_unsupported' | 'thumbnail_format_unsupported' | 'media_probe_incomplete'; severity: 'blocker' | 'warning'; message: string; observed?: unknown; limit?: unknown; } export interface PublishValidationResult { ok: boolean; blockers: PublishValidationIssue[]; warnings: PublishValidationIssue[]; } export interface PublishPackageManifest { projectSlug: string; platform: PublishPlatformId; packageVersion: string; profileVersion: string; createdAt: string; inputs: { finalVideo: string; metadata: string; captions?: string; thumbnail?: string; }; files: Array<{ role: 'final-video' | 'metadata' | 'captions' | 'thumbnail'; path: string; sha256: string; sizeBytes: number; }>; validation: PublishValidationResult; sources: PublishProfileSource[]; }