gitextract_4hr0t8jh/ ├── .dockerignore ├── .eslintrc.json ├── .gitignore ├── .husky/ │ ├── pre-commit │ └── pre-push ├── .nvmrc ├── .tmp_check_task.ts ├── CHANGELOG.md ├── Dockerfile ├── README.md ├── README_en.md ├── caddyfile ├── debug-request.json ├── docker-compose.test.yml ├── docker-compose.yml ├── eslint.config.mjs ├── extract_chinese.py ├── lib/ │ └── prompts/ │ ├── character-reference/ │ │ ├── character_image_to_description.en.txt │ │ ├── character_image_to_description.zh.txt │ │ ├── character_reference_to_sheet.en.txt │ │ └── character_reference_to_sheet.zh.txt │ ├── novel-promotion/ │ │ ├── agent_acting_direction.en.txt │ │ ├── agent_acting_direction.zh.txt │ │ ├── agent_character_profile.en.txt │ │ ├── agent_character_profile.zh.txt │ │ ├── agent_character_visual.en.txt │ │ ├── agent_character_visual.zh.txt │ │ ├── agent_cinematographer.en.txt │ │ ├── agent_cinematographer.zh.txt │ │ ├── agent_clip.en.txt │ │ ├── agent_clip.zh.txt │ │ ├── agent_shot_variant_analysis.en.txt │ │ ├── agent_shot_variant_analysis.zh.txt │ │ ├── agent_shot_variant_generate.en.txt │ │ ├── agent_shot_variant_generate.zh.txt │ │ ├── agent_storyboard_detail.en.txt │ │ ├── agent_storyboard_detail.zh.txt │ │ ├── agent_storyboard_insert.en.txt │ │ ├── agent_storyboard_insert.zh.txt │ │ ├── agent_storyboard_plan.en.txt │ │ ├── agent_storyboard_plan.zh.txt │ │ ├── character_create.en.txt │ │ ├── character_create.zh.txt │ │ ├── character_description_update.en.txt │ │ ├── character_description_update.zh.txt │ │ ├── character_modify.en.txt │ │ ├── character_modify.zh.txt │ │ ├── character_regenerate.en.txt │ │ ├── character_regenerate.zh.txt │ │ ├── episode_split.en.txt │ │ ├── episode_split.zh.txt │ │ ├── image_prompt_modify.en.txt │ │ ├── image_prompt_modify.zh.txt │ │ ├── location_create.en.txt │ │ ├── location_create.zh.txt │ │ ├── location_description_update.en.txt │ │ ├── location_description_update.zh.txt │ │ ├── location_modify.en.txt │ │ ├── location_modify.zh.txt │ │ ├── location_regenerate.en.txt │ │ ├── location_regenerate.zh.txt │ │ ├── screenplay_conversion.en.txt │ │ ├── screenplay_conversion.zh.txt │ │ ├── select_location.en.txt │ │ ├── select_location.zh.txt │ │ ├── single_panel_image.en.txt │ │ ├── single_panel_image.zh.txt │ │ ├── storyboard_edit.en.txt │ │ ├── storyboard_edit.zh.txt │ │ ├── voice_analysis.en.txt │ │ └── voice_analysis.zh.txt │ ├── proxy.ts │ └── skills/ │ ├── api-config-template.system.txt │ └── tutorial.system.txt ├── messages/ │ ├── en/ │ │ ├── actions.json │ │ ├── apiConfig.json │ │ ├── apiTypes.json │ │ ├── assetHub.json │ │ ├── assetLibrary.json │ │ ├── assetModal.json │ │ ├── assetPicker.json │ │ ├── assets.json │ │ ├── auth.json │ │ ├── billing.json │ │ ├── common.json │ │ ├── configModal.json │ │ ├── errors.json │ │ ├── landing.json │ │ ├── layout.json │ │ ├── modelSection.json │ │ ├── nav.json │ │ ├── novel-promotion.json │ │ ├── profile.json │ │ ├── progress.json │ │ ├── providerSection.json │ │ ├── scriptView.json │ │ ├── smartImport.json │ │ ├── stages.json │ │ ├── storyboard.json │ │ ├── video.json │ │ ├── voice.json │ │ ├── workspace.json │ │ ├── workspaceDetail.json │ │ └── worldContextModal.json │ └── zh/ │ ├── actions.json │ ├── apiConfig.json │ ├── apiTypes.json │ ├── assetHub.json │ ├── assetLibrary.json │ ├── assetModal.json │ ├── assetPicker.json │ ├── assets.json │ ├── auth.json │ ├── billing.json │ ├── common.json │ ├── configModal.json │ ├── errors.json │ ├── landing.json │ ├── layout.json │ ├── modelSection.json │ ├── nav.json │ ├── novel-promotion.json │ ├── profile.json │ ├── progress.json │ ├── providerSection.json │ ├── scriptView.json │ ├── smartImport.json │ ├── stages.json │ ├── storyboard.json │ ├── video.json │ ├── voice.json │ ├── workspace.json │ ├── workspaceDetail.json │ └── worldContextModal.json ├── middleware.ts ├── next.config.ts ├── package.json ├── postcss.config.mjs ├── prisma/ │ ├── schema.prisma │ └── schema.sqlit.prisma ├── scripts/ │ ├── billing-cleanup-pending-freezes.ts │ ├── billing-reconcile-ledger.ts │ ├── bull-board.ts │ ├── check-api-handler.ts │ ├── check-capability-catalog.mjs │ ├── check-image-urls-contract.ts │ ├── check-log-semantic.ts │ ├── check-media-normalization.ts │ ├── check-model-config-contract.mjs │ ├── check-no-console.ts │ ├── check-outbound-image-runtime-sample.ts │ ├── check-outbound-image-success-rate.ts │ ├── check-outbound-image-unification.ts │ ├── check-pricing-catalog.mjs │ ├── cleanup-remove-legacy-voice-data.ts │ ├── diagnose-project.ts │ ├── guards/ │ │ ├── api-route-contract-guard.mjs │ │ ├── changed-file-test-impact-guard.mjs │ │ ├── file-line-count-guard.mjs │ │ ├── image-reference-normalization-guard.mjs │ │ ├── locale-navigation-guard.mjs │ │ ├── no-api-direct-llm-call.mjs │ │ ├── no-duplicate-endpoint-entry.mjs │ │ ├── no-hardcoded-model-capabilities.mjs │ │ ├── no-internal-task-sync-fallback.mjs │ │ ├── no-media-provider-bypass.mjs │ │ ├── no-model-key-downgrade.mjs │ │ ├── no-multiple-sources-of-truth.mjs │ │ ├── no-provider-guessing.mjs │ │ ├── no-server-mirror-state.mjs │ │ ├── prompt-ab-regression.mjs │ │ ├── prompt-i18n-guard.mjs │ │ ├── prompt-json-canary-guard.mjs │ │ ├── prompt-semantic-regression.mjs │ │ ├── task-loading-baseline.json │ │ ├── task-loading-guard.mjs │ │ ├── task-state-unification-guard.sh │ │ ├── task-status-cutover-audit.sh │ │ ├── task-submit-compensation-guard.mjs │ │ ├── task-target-states-no-polling-guard.mjs │ │ ├── test-behavior-quality-guard.mjs │ │ ├── test-behavior-route-coverage-guard.mjs │ │ ├── test-behavior-tasktype-coverage-guard.mjs │ │ ├── test-route-coverage-guard.mjs │ │ └── test-tasktype-coverage-guard.mjs │ ├── media-archive-legacy-refs.ts │ ├── media-backfill-refs.ts │ ├── media-build-unreferenced-index.ts │ ├── media-mapping.ts │ ├── media-restore-dry-run.ts │ ├── media-safety-backup.ts │ ├── migrate-cancelled-to-failed.ts │ ├── migrate-image-urls-contract.ts │ ├── migrate-local-to-minio.ts │ ├── migrate-to-minio.sh │ ├── migrate-to-minio.ts │ ├── migrations/ │ │ ├── migrate-capability-selections.ts │ │ ├── migrate-custom-pricing-v2.ts │ │ ├── migrate-gateway-route-openai-compat.ts │ │ ├── migrate-graph-artifacts-unique-index.ts │ │ ├── migrate-model-config-contract.ts │ │ ├── migrate-qwen-to-bailian.ts │ │ ├── migrate-release-blockers.ts │ │ └── reports/ │ │ ├── model-config-migration-report.apply.json │ │ ├── model-config-migration-report.post-alias-apply.json │ │ ├── model-config-migration-report.post-alias-dryrun.json │ │ └── model-config-migration-report.pre-apply.json │ ├── task-error-stats.ts │ ├── test-full-image-flow.ts │ ├── test-image-url-flow.ts │ ├── test-minio.ts │ ├── test-regression-runner.sh │ ├── test-sign-api.ts │ ├── tmp-cleanup-project-models.mjs │ ├── tmp-find-old-model.mjs │ └── watchdog.ts ├── src/ │ ├── app/ │ │ ├── [locale]/ │ │ │ ├── auth/ │ │ │ │ ├── signin/ │ │ │ │ │ └── page.tsx │ │ │ │ └── signup/ │ │ │ │ └── page.tsx │ │ │ ├── layout.tsx │ │ │ ├── page.tsx │ │ │ ├── profile/ │ │ │ │ ├── components/ │ │ │ │ │ ├── ApiConfigTab.tsx │ │ │ │ │ ├── api-config/ │ │ │ │ │ │ ├── DefaultModelSection.tsx │ │ │ │ │ │ ├── ProviderCard.tsx │ │ │ │ │ │ ├── ProviderSection.tsx │ │ │ │ │ │ ├── hooks.ts │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ ├── provider-card/ │ │ │ │ │ │ │ ├── ModelTemplateAssistantModal.tsx │ │ │ │ │ │ │ ├── ProviderAdvancedFields.tsx │ │ │ │ │ │ │ ├── ProviderBaseFields.tsx │ │ │ │ │ │ │ ├── ProviderCardShell.tsx │ │ │ │ │ │ │ ├── hooks/ │ │ │ │ │ │ │ │ └── useProviderCardState.ts │ │ │ │ │ │ │ └── types.ts │ │ │ │ │ │ └── types.ts │ │ │ │ │ └── api-config-tab/ │ │ │ │ │ ├── ApiConfigProviderList.tsx │ │ │ │ │ ├── ApiConfigTabContainer.tsx │ │ │ │ │ ├── ApiConfigToolbar.tsx │ │ │ │ │ ├── DefaultModelCards.tsx │ │ │ │ │ └── hooks/ │ │ │ │ │ └── useApiConfigFilters.ts │ │ │ │ └── page.tsx │ │ │ ├── providers.tsx │ │ │ └── workspace/ │ │ │ ├── [projectId]/ │ │ │ │ ├── components/ │ │ │ │ │ └── Sidebar.tsx │ │ │ │ ├── episode-selection.ts │ │ │ │ ├── hooks/ │ │ │ │ │ └── useProject.ts │ │ │ │ ├── modes/ │ │ │ │ │ └── novel-promotion/ │ │ │ │ │ ├── NovelPromotionWorkspace.tsx │ │ │ │ │ ├── StageNavigation.tsx │ │ │ │ │ ├── WorkspaceProvider.tsx │ │ │ │ │ ├── WorkspaceStageRuntimeContext.tsx │ │ │ │ │ ├── components/ │ │ │ │ │ │ ├── AssetLibrary.tsx │ │ │ │ │ │ ├── AssetsStage.tsx │ │ │ │ │ │ ├── ConfigStage.tsx │ │ │ │ │ │ ├── NovelInputStage.tsx │ │ │ │ │ │ ├── PanelEditForm.tsx │ │ │ │ │ │ ├── PromptsStage.tsx │ │ │ │ │ │ ├── ScriptStage.tsx │ │ │ │ │ │ ├── ScriptView.tsx │ │ │ │ │ │ ├── SmartImportWizard.tsx │ │ │ │ │ │ ├── StoryboardStage.tsx │ │ │ │ │ │ ├── VideoStage.tsx │ │ │ │ │ │ ├── VideoStageRoute.tsx │ │ │ │ │ │ ├── VoiceStage.tsx │ │ │ │ │ │ ├── VoiceStageRoute.tsx │ │ │ │ │ │ ├── WorkspaceAssetLibraryModal.tsx │ │ │ │ │ │ ├── WorkspaceHeaderShell.tsx │ │ │ │ │ │ ├── WorkspaceRunStreamConsoles.tsx │ │ │ │ │ │ ├── WorkspaceStageContent.tsx │ │ │ │ │ │ ├── WorkspaceTopActions.tsx │ │ │ │ │ │ ├── assets/ │ │ │ │ │ │ │ ├── AddLocationModal.tsx │ │ │ │ │ │ │ ├── AssetToolbar.tsx │ │ │ │ │ │ │ ├── AssetsStageModals.tsx │ │ │ │ │ │ │ ├── AssetsStageStatusOverlays.tsx │ │ │ │ │ │ │ ├── CharacterCard.tsx │ │ │ │ │ │ │ ├── CharacterEditModal.tsx │ │ │ │ │ │ │ ├── CharacterProfileCard.tsx │ │ │ │ │ │ │ ├── CharacterProfileDialog.tsx │ │ │ │ │ │ │ ├── CharacterSection.tsx │ │ │ │ │ │ │ ├── ImageEditModal.tsx │ │ │ │ │ │ │ ├── LocationCard.tsx │ │ │ │ │ │ │ ├── LocationEditModal.tsx │ │ │ │ │ │ │ ├── LocationSection.tsx │ │ │ │ │ │ │ ├── UnconfirmedProfilesSection.tsx │ │ │ │ │ │ │ ├── VoiceSettings.tsx │ │ │ │ │ │ │ ├── character-card/ │ │ │ │ │ │ │ │ ├── CharacterCardActions.tsx │ │ │ │ │ │ │ │ ├── CharacterCardGallery.tsx │ │ │ │ │ │ │ │ └── CharacterCardHeader.tsx │ │ │ │ │ │ │ ├── hooks/ │ │ │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ │ │ ├── useAssetModals.ts │ │ │ │ │ │ │ │ ├── useAssetsCopyFromHub.ts │ │ │ │ │ │ │ │ ├── useAssetsGlobalActions.ts │ │ │ │ │ │ │ │ ├── useAssetsImageEdit.ts │ │ │ │ │ │ │ │ ├── useBatchGeneration.helpers.ts │ │ │ │ │ │ │ │ ├── useBatchGeneration.ts │ │ │ │ │ │ │ │ ├── useCharacterActions.ts │ │ │ │ │ │ │ │ ├── useLocationActions.ts │ │ │ │ │ │ │ │ ├── useProfileManagement.ts │ │ │ │ │ │ │ │ └── useTTSGeneration.ts │ │ │ │ │ │ │ └── location-card/ │ │ │ │ │ │ │ ├── LocationCardActions.tsx │ │ │ │ │ │ │ ├── LocationCardHeader.tsx │ │ │ │ │ │ │ └── LocationImageList.tsx │ │ │ │ │ │ ├── prompts-stage/ │ │ │ │ │ │ │ ├── PromptEditorPanel.tsx │ │ │ │ │ │ │ ├── PromptListCardView.tsx │ │ │ │ │ │ │ ├── PromptListPanel.tsx │ │ │ │ │ │ │ ├── PromptListTableView.tsx │ │ │ │ │ │ │ ├── PromptsStageLayout.tsx │ │ │ │ │ │ │ ├── PromptsStageShell.tsx │ │ │ │ │ │ │ ├── hooks/ │ │ │ │ │ │ │ │ └── usePromptStageActions.tsx │ │ │ │ │ │ │ └── runtime/ │ │ │ │ │ │ │ ├── hooks/ │ │ │ │ │ │ │ │ ├── usePromptAiModifyFlow.ts │ │ │ │ │ │ │ │ ├── usePromptAppendFlow.ts │ │ │ │ │ │ │ │ ├── usePromptAssetMention.ts │ │ │ │ │ │ │ │ ├── usePromptDraftByShot.ts │ │ │ │ │ │ │ │ └── usePromptEditorRuntime.ts │ │ │ │ │ │ │ ├── promptStageRuntime.types.ts │ │ │ │ │ │ │ ├── promptStageRuntime.utils.ts │ │ │ │ │ │ │ └── promptStageRuntimeCore.tsx │ │ │ │ │ │ ├── script-view/ │ │ │ │ │ │ │ ├── ScriptViewAssetsPanel.tsx │ │ │ │ │ │ │ ├── ScriptViewContainer.tsx │ │ │ │ │ │ │ ├── ScriptViewCore.tsx │ │ │ │ │ │ │ ├── ScriptViewRuntime.tsx │ │ │ │ │ │ │ ├── ScriptViewScriptPanel.tsx │ │ │ │ │ │ │ ├── SpotlightCards.tsx │ │ │ │ │ │ │ ├── asset-state-utils.ts │ │ │ │ │ │ │ └── clip-asset-utils.ts │ │ │ │ │ │ ├── smart-import/ │ │ │ │ │ │ │ ├── hooks/ │ │ │ │ │ │ │ │ └── useWizardState.ts │ │ │ │ │ │ │ ├── steps/ │ │ │ │ │ │ │ │ ├── StepConfirm.tsx │ │ │ │ │ │ │ │ ├── StepMapping.tsx │ │ │ │ │ │ │ │ ├── StepParse.tsx │ │ │ │ │ │ │ │ └── StepSource.tsx │ │ │ │ │ │ │ └── types.ts │ │ │ │ │ │ ├── storyboard/ │ │ │ │ │ │ │ ├── AIDataModal.tsx │ │ │ │ │ │ │ ├── AIDataModal.types.ts │ │ │ │ │ │ │ ├── AIDataModalFormPane.tsx │ │ │ │ │ │ │ ├── AIDataModalPreviewPane.tsx │ │ │ │ │ │ │ ├── CandidateSelector.tsx │ │ │ │ │ │ │ ├── ImageEditModal.tsx │ │ │ │ │ │ │ ├── ImageEditModalAssetPicker.tsx │ │ │ │ │ │ │ ├── ImageEditModalSelectedAssets.tsx │ │ │ │ │ │ │ ├── ImageSection.css │ │ │ │ │ │ │ ├── ImageSection.tsx │ │ │ │ │ │ │ ├── ImageSectionActionButtons.tsx │ │ │ │ │ │ │ ├── ImageSectionCandidateMode.tsx │ │ │ │ │ │ │ ├── InsertPanelButton.tsx │ │ │ │ │ │ │ ├── InsertPanelModal.tsx │ │ │ │ │ │ │ ├── PanelActionButtons.tsx │ │ │ │ │ │ │ ├── PanelCard.tsx │ │ │ │ │ │ │ ├── PanelVariantModal.tsx │ │ │ │ │ │ │ ├── PanelVariantModal.types.ts │ │ │ │ │ │ │ ├── PanelVariantModalCustomOptions.tsx │ │ │ │ │ │ │ ├── PanelVariantModalSuggestionList.tsx │ │ │ │ │ │ │ ├── ScreenplayDisplay.tsx │ │ │ │ │ │ │ ├── StoryboardCanvas.tsx │ │ │ │ │ │ │ ├── StoryboardGroup.tsx │ │ │ │ │ │ │ ├── StoryboardGroup.types.ts │ │ │ │ │ │ │ ├── StoryboardGroupActions.tsx │ │ │ │ │ │ │ ├── StoryboardGroupDialogs.tsx │ │ │ │ │ │ │ ├── StoryboardGroupFailedAlert.tsx │ │ │ │ │ │ │ ├── StoryboardGroupHeader.tsx │ │ │ │ │ │ │ ├── StoryboardHeader.tsx │ │ │ │ │ │ │ ├── StoryboardPanelList.tsx │ │ │ │ │ │ │ ├── StoryboardStageShell.tsx │ │ │ │ │ │ │ ├── StoryboardToolbar.tsx │ │ │ │ │ │ │ ├── hooks/ │ │ │ │ │ │ │ │ ├── contracts.ts │ │ │ │ │ │ │ │ ├── image-generation-runtime.ts │ │ │ │ │ │ │ │ ├── panel-candidate-runtime.ts │ │ │ │ │ │ │ │ ├── panel-operations-shared.ts │ │ │ │ │ │ │ │ ├── panel-save-coordinator.ts │ │ │ │ │ │ │ │ ├── storyboard-panel-asset-utils.ts │ │ │ │ │ │ │ │ ├── storyboard-state-utils.ts │ │ │ │ │ │ │ │ ├── useAIDataModalState.ts │ │ │ │ │ │ │ │ ├── useImageGeneration.ts │ │ │ │ │ │ │ │ ├── usePanelCandidates.ts │ │ │ │ │ │ │ │ ├── usePanelCrudActions.ts │ │ │ │ │ │ │ │ ├── usePanelEpisodeCachePatch.ts │ │ │ │ │ │ │ │ ├── usePanelImageDownload.ts │ │ │ │ │ │ │ │ ├── usePanelImageModification.ts │ │ │ │ │ │ │ │ ├── usePanelImageRegeneration.ts │ │ │ │ │ │ │ │ ├── usePanelInsertActions.ts │ │ │ │ │ │ │ │ ├── usePanelOperations.ts │ │ │ │ │ │ │ │ ├── usePanelVariant.ts │ │ │ │ │ │ │ │ ├── useStoryboardAiDataRuntime.ts │ │ │ │ │ │ │ │ ├── useStoryboardBatchPanelGeneration.ts │ │ │ │ │ │ │ │ ├── useStoryboardGroupActions.ts │ │ │ │ │ │ │ │ ├── useStoryboardGroupTaskErrors.ts │ │ │ │ │ │ │ │ ├── useStoryboardInsertVariantRuntime.ts │ │ │ │ │ │ │ │ ├── useStoryboardModalRuntime.ts │ │ │ │ │ │ │ │ ├── useStoryboardPanelAssetActions.ts │ │ │ │ │ │ │ │ ├── useStoryboardStageController.ts │ │ │ │ │ │ │ │ ├── useStoryboardStageStatus.ts │ │ │ │ │ │ │ │ ├── useStoryboardStageUiState.ts │ │ │ │ │ │ │ │ ├── useStoryboardState.ts │ │ │ │ │ │ │ │ └── useStoryboardTaskAwareStoryboards.ts │ │ │ │ │ │ │ └── index.tsx │ │ │ │ │ │ ├── video/ │ │ │ │ │ │ │ ├── FirstLastFramePanel.tsx │ │ │ │ │ │ │ ├── VideoPanelCard.tsx │ │ │ │ │ │ │ ├── VideoPromptModal.tsx │ │ │ │ │ │ │ ├── VideoToolbar.tsx │ │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ │ ├── panel-card/ │ │ │ │ │ │ │ │ ├── VideoPanelCardBody.tsx │ │ │ │ │ │ │ │ ├── VideoPanelCardFooter.tsx │ │ │ │ │ │ │ │ ├── VideoPanelCardHeader.tsx │ │ │ │ │ │ │ │ ├── VideoPanelCardLayout.tsx │ │ │ │ │ │ │ │ ├── VideoPanelCardShell.tsx │ │ │ │ │ │ │ │ ├── hooks/ │ │ │ │ │ │ │ │ │ └── useVideoPanelActions.tsx │ │ │ │ │ │ │ │ ├── runtime/ │ │ │ │ │ │ │ │ │ ├── hooks/ │ │ │ │ │ │ │ │ │ │ ├── usePanelLipSync.ts │ │ │ │ │ │ │ │ │ │ ├── usePanelPlayer.ts │ │ │ │ │ │ │ │ │ │ ├── usePanelPromptEditor.ts │ │ │ │ │ │ │ │ │ │ ├── usePanelTaskStatus.ts │ │ │ │ │ │ │ │ │ │ ├── usePanelVideoModel.ts │ │ │ │ │ │ │ │ │ │ └── usePanelVoiceManager.ts │ │ │ │ │ │ │ │ │ ├── shared.ts │ │ │ │ │ │ │ │ │ └── videoPanelRuntimeCore.tsx │ │ │ │ │ │ │ │ └── types.ts │ │ │ │ │ │ │ └── types.ts │ │ │ │ │ │ ├── video-stage/ │ │ │ │ │ │ │ ├── VideoRenderPanel.tsx │ │ │ │ │ │ │ ├── VideoStageLayout.tsx │ │ │ │ │ │ │ ├── VideoStageShell.tsx │ │ │ │ │ │ │ ├── VideoTimelinePanel.tsx │ │ │ │ │ │ │ └── hooks/ │ │ │ │ │ │ │ └── useVideoStageRuntime.tsx │ │ │ │ │ │ ├── voice/ │ │ │ │ │ │ │ ├── EmbeddedVoiceToolbar.tsx │ │ │ │ │ │ │ ├── EmotionSettingsPanel.tsx │ │ │ │ │ │ │ ├── EmptyVoiceState.tsx │ │ │ │ │ │ │ ├── SpeakerVoiceBindingDialog.tsx │ │ │ │ │ │ │ ├── SpeakerVoiceStatus.tsx │ │ │ │ │ │ │ ├── VoiceDesignDialog.tsx │ │ │ │ │ │ │ ├── VoiceLineCard.tsx │ │ │ │ │ │ │ └── VoiceToolbar.tsx │ │ │ │ │ │ └── voice-stage/ │ │ │ │ │ │ ├── VoiceControlPanel.tsx │ │ │ │ │ │ ├── VoiceLineList.tsx │ │ │ │ │ │ ├── VoiceStageLayout.tsx │ │ │ │ │ │ ├── VoiceStageShell.tsx │ │ │ │ │ │ └── hooks/ │ │ │ │ │ │ └── useVoiceStageRuntime.tsx │ │ │ │ │ ├── hooks/ │ │ │ │ │ │ ├── useNovelPromotionWorkspaceController.ts │ │ │ │ │ │ ├── useRebuildConfirm.ts │ │ │ │ │ │ ├── useWorkspaceAssetLibraryShell.ts │ │ │ │ │ │ ├── useWorkspaceConfigActions.ts │ │ │ │ │ │ ├── useWorkspaceEpisodeStageData.ts │ │ │ │ │ │ ├── useWorkspaceExecution.ts │ │ │ │ │ │ ├── useWorkspaceModalEscape.ts │ │ │ │ │ │ ├── useWorkspaceProjectSnapshot.ts │ │ │ │ │ │ ├── useWorkspaceStageNavigation.ts │ │ │ │ │ │ ├── useWorkspaceStageRuntime.ts │ │ │ │ │ │ ├── useWorkspaceUserModels.ts │ │ │ │ │ │ ├── useWorkspaceVideoActions.ts │ │ │ │ │ │ └── workspace-controller-view-model.ts │ │ │ │ │ └── types.ts │ │ │ │ └── page.tsx │ │ │ ├── asset-hub/ │ │ │ │ ├── components/ │ │ │ │ │ ├── AddLocationModal.tsx │ │ │ │ │ ├── AssetGrid.tsx │ │ │ │ │ ├── CharacterCard.tsx │ │ │ │ │ ├── CharacterEditModal.tsx │ │ │ │ │ ├── FolderModal.tsx │ │ │ │ │ ├── FolderSidebar.tsx │ │ │ │ │ ├── LocationCard.tsx │ │ │ │ │ ├── LocationEditModal.tsx │ │ │ │ │ ├── VoiceCard.tsx │ │ │ │ │ ├── VoiceCreationModal.tsx │ │ │ │ │ ├── VoiceDesignDialog.tsx │ │ │ │ │ ├── VoicePickerDialog.tsx │ │ │ │ │ ├── VoiceSettings.tsx │ │ │ │ │ └── voice-creation/ │ │ │ │ │ ├── VoiceCreationForm.tsx │ │ │ │ │ ├── VoiceCreationModalLayout.tsx │ │ │ │ │ ├── VoiceCreationModalShell.tsx │ │ │ │ │ ├── VoicePreviewSection.tsx │ │ │ │ │ └── hooks/ │ │ │ │ │ └── useVoiceCreation.tsx │ │ │ │ └── page.tsx │ │ │ └── page.tsx │ │ ├── api/ │ │ │ ├── admin/ │ │ │ │ └── download-logs/ │ │ │ │ └── route.ts │ │ │ ├── asset-hub/ │ │ │ │ ├── ai-design-character/ │ │ │ │ │ └── route.ts │ │ │ │ ├── ai-design-location/ │ │ │ │ │ └── route.ts │ │ │ │ ├── ai-modify-character/ │ │ │ │ │ └── route.ts │ │ │ │ ├── ai-modify-location/ │ │ │ │ │ └── route.ts │ │ │ │ ├── appearances/ │ │ │ │ │ └── route.ts │ │ │ │ ├── character-voice/ │ │ │ │ │ └── route.ts │ │ │ │ ├── characters/ │ │ │ │ │ ├── [characterId]/ │ │ │ │ │ │ ├── appearances/ │ │ │ │ │ │ │ └── [appearanceIndex]/ │ │ │ │ │ │ │ └── route.ts │ │ │ │ │ │ └── route.ts │ │ │ │ │ └── route.ts │ │ │ │ ├── folders/ │ │ │ │ │ ├── [folderId]/ │ │ │ │ │ │ └── route.ts │ │ │ │ │ └── route.ts │ │ │ │ ├── generate-image/ │ │ │ │ │ └── route.ts │ │ │ │ ├── locations/ │ │ │ │ │ ├── [locationId]/ │ │ │ │ │ │ └── route.ts │ │ │ │ │ └── route.ts │ │ │ │ ├── modify-image/ │ │ │ │ │ └── route.ts │ │ │ │ ├── picker/ │ │ │ │ │ └── route.ts │ │ │ │ ├── reference-to-character/ │ │ │ │ │ └── route.ts │ │ │ │ ├── select-image/ │ │ │ │ │ └── route.ts │ │ │ │ ├── undo-image/ │ │ │ │ │ └── route.ts │ │ │ │ ├── update-asset-label/ │ │ │ │ │ └── route.ts │ │ │ │ ├── upload-image/ │ │ │ │ │ └── route.ts │ │ │ │ ├── upload-temp/ │ │ │ │ │ └── route.ts │ │ │ │ ├── voice-design/ │ │ │ │ │ └── route.ts │ │ │ │ └── voices/ │ │ │ │ ├── [id]/ │ │ │ │ │ └── route.ts │ │ │ │ ├── route.ts │ │ │ │ └── upload/ │ │ │ │ └── route.ts │ │ │ ├── auth/ │ │ │ │ ├── [...nextauth]/ │ │ │ │ │ └── route.ts │ │ │ │ └── register/ │ │ │ │ └── route.ts │ │ │ ├── cos/ │ │ │ │ └── image/ │ │ │ │ └── route.ts │ │ │ ├── files/ │ │ │ │ └── [...path]/ │ │ │ │ └── route.ts │ │ │ ├── novel-promotion/ │ │ │ │ └── [projectId]/ │ │ │ │ ├── ai-create-character/ │ │ │ │ │ └── route.ts │ │ │ │ ├── ai-create-location/ │ │ │ │ │ └── route.ts │ │ │ │ ├── ai-modify-appearance/ │ │ │ │ │ └── route.ts │ │ │ │ ├── ai-modify-location/ │ │ │ │ │ └── route.ts │ │ │ │ ├── ai-modify-shot-prompt/ │ │ │ │ │ └── route.ts │ │ │ │ ├── analyze/ │ │ │ │ │ └── route.ts │ │ │ │ ├── analyze-global/ │ │ │ │ │ └── route.ts │ │ │ │ ├── analyze-shot-variants/ │ │ │ │ │ └── route.ts │ │ │ │ ├── assets/ │ │ │ │ │ └── route.ts │ │ │ │ ├── character/ │ │ │ │ │ ├── appearance/ │ │ │ │ │ │ └── route.ts │ │ │ │ │ ├── confirm-selection/ │ │ │ │ │ │ └── route.ts │ │ │ │ │ └── route.ts │ │ │ │ ├── character-profile/ │ │ │ │ │ ├── batch-confirm/ │ │ │ │ │ │ └── route.ts │ │ │ │ │ └── confirm/ │ │ │ │ │ └── route.ts │ │ │ │ ├── character-voice/ │ │ │ │ │ └── route.ts │ │ │ │ ├── cleanup-unselected-images/ │ │ │ │ │ └── route.ts │ │ │ │ ├── clips/ │ │ │ │ │ ├── [clipId]/ │ │ │ │ │ │ └── route.ts │ │ │ │ │ └── route.ts │ │ │ │ ├── copy-from-global/ │ │ │ │ │ └── route.ts │ │ │ │ ├── download-images/ │ │ │ │ │ └── route.ts │ │ │ │ ├── download-videos/ │ │ │ │ │ └── route.ts │ │ │ │ ├── download-voices/ │ │ │ │ │ └── route.ts │ │ │ │ ├── editor/ │ │ │ │ │ └── route.ts │ │ │ │ ├── episodes/ │ │ │ │ │ ├── [episodeId]/ │ │ │ │ │ │ └── route.ts │ │ │ │ │ ├── batch/ │ │ │ │ │ │ └── route.ts │ │ │ │ │ ├── route.ts │ │ │ │ │ ├── split/ │ │ │ │ │ │ └── route.ts │ │ │ │ │ └── split-by-markers/ │ │ │ │ │ └── route.ts │ │ │ │ ├── generate-character-image/ │ │ │ │ │ └── route.ts │ │ │ │ ├── generate-image/ │ │ │ │ │ └── route.ts │ │ │ │ ├── generate-video/ │ │ │ │ │ └── route.ts │ │ │ │ ├── insert-panel/ │ │ │ │ │ └── route.ts │ │ │ │ ├── lip-sync/ │ │ │ │ │ └── route.ts │ │ │ │ ├── location/ │ │ │ │ │ ├── confirm-selection/ │ │ │ │ │ │ └── route.ts │ │ │ │ │ └── route.ts │ │ │ │ ├── modify-asset-image/ │ │ │ │ │ └── route.ts │ │ │ │ ├── modify-storyboard-image/ │ │ │ │ │ └── route.ts │ │ │ │ ├── panel/ │ │ │ │ │ ├── route.ts │ │ │ │ │ └── select-candidate/ │ │ │ │ │ └── route.ts │ │ │ │ ├── panel-link/ │ │ │ │ │ └── route.ts │ │ │ │ ├── panel-variant/ │ │ │ │ │ └── route.ts │ │ │ │ ├── photography-plan/ │ │ │ │ │ └── route.ts │ │ │ │ ├── reference-to-character/ │ │ │ │ │ └── route.ts │ │ │ │ ├── regenerate-group/ │ │ │ │ │ └── route.ts │ │ │ │ ├── regenerate-panel-image/ │ │ │ │ │ └── route.ts │ │ │ │ ├── regenerate-single-image/ │ │ │ │ │ └── route.ts │ │ │ │ ├── regenerate-storyboard-text/ │ │ │ │ │ └── route.ts │ │ │ │ ├── route.ts │ │ │ │ ├── screenplay-conversion/ │ │ │ │ │ └── route.ts │ │ │ │ ├── script-to-storyboard-stream/ │ │ │ │ │ └── route.ts │ │ │ │ ├── select-character-image/ │ │ │ │ │ └── route.ts │ │ │ │ ├── select-location-image/ │ │ │ │ │ └── route.ts │ │ │ │ ├── speaker-voice/ │ │ │ │ │ └── route.ts │ │ │ │ ├── story-to-script-stream/ │ │ │ │ │ └── route.ts │ │ │ │ ├── storyboard-group/ │ │ │ │ │ └── route.ts │ │ │ │ ├── storyboards/ │ │ │ │ │ └── route.ts │ │ │ │ ├── undo-regenerate/ │ │ │ │ │ └── route.ts │ │ │ │ ├── update-appearance/ │ │ │ │ │ └── route.ts │ │ │ │ ├── update-asset-label/ │ │ │ │ │ └── route.ts │ │ │ │ ├── update-location/ │ │ │ │ │ └── route.ts │ │ │ │ ├── update-prompt/ │ │ │ │ │ └── route.ts │ │ │ │ ├── upload-asset-image/ │ │ │ │ │ └── route.ts │ │ │ │ ├── video-proxy/ │ │ │ │ │ └── route.ts │ │ │ │ ├── video-urls/ │ │ │ │ │ └── route.ts │ │ │ │ ├── voice-analyze/ │ │ │ │ │ └── route.ts │ │ │ │ ├── voice-design/ │ │ │ │ │ └── route.ts │ │ │ │ ├── voice-generate/ │ │ │ │ │ └── route.ts │ │ │ │ └── voice-lines/ │ │ │ │ └── route.ts │ │ │ ├── projects/ │ │ │ │ ├── [projectId]/ │ │ │ │ │ ├── assets/ │ │ │ │ │ │ └── route.ts │ │ │ │ │ ├── costs/ │ │ │ │ │ │ └── route.ts │ │ │ │ │ ├── data/ │ │ │ │ │ │ └── route.ts │ │ │ │ │ └── route.ts │ │ │ │ └── route.ts │ │ │ ├── runs/ │ │ │ │ ├── [runId]/ │ │ │ │ │ ├── cancel/ │ │ │ │ │ │ └── route.ts │ │ │ │ │ ├── events/ │ │ │ │ │ │ └── route.ts │ │ │ │ │ ├── route.ts │ │ │ │ │ └── steps/ │ │ │ │ │ └── [stepKey]/ │ │ │ │ │ └── retry/ │ │ │ │ │ └── route.ts │ │ │ │ └── route.ts │ │ │ ├── sse/ │ │ │ │ └── route.ts │ │ │ ├── storage/ │ │ │ │ └── sign/ │ │ │ │ └── route.ts │ │ │ ├── system/ │ │ │ │ └── boot-id/ │ │ │ │ └── route.ts │ │ │ ├── task-target-states/ │ │ │ │ └── route.ts │ │ │ ├── tasks/ │ │ │ │ ├── [taskId]/ │ │ │ │ │ └── route.ts │ │ │ │ ├── dismiss/ │ │ │ │ │ └── route.ts │ │ │ │ └── route.ts │ │ │ ├── user/ │ │ │ │ ├── api-config/ │ │ │ │ │ ├── assistant/ │ │ │ │ │ │ ├── probe-media-template/ │ │ │ │ │ │ │ └── route.ts │ │ │ │ │ │ └── validate-media-template/ │ │ │ │ │ │ └── route.ts │ │ │ │ │ ├── probe-model-llm-protocol/ │ │ │ │ │ │ └── route.ts │ │ │ │ │ ├── route.ts │ │ │ │ │ ├── test-connection/ │ │ │ │ │ │ └── route.ts │ │ │ │ │ └── test-provider/ │ │ │ │ │ └── route.ts │ │ │ │ ├── assistant/ │ │ │ │ │ └── chat/ │ │ │ │ │ └── route.ts │ │ │ │ ├── balance/ │ │ │ │ │ └── route.ts │ │ │ │ ├── costs/ │ │ │ │ │ ├── details/ │ │ │ │ │ │ └── route.ts │ │ │ │ │ └── route.ts │ │ │ │ ├── models/ │ │ │ │ │ └── route.ts │ │ │ │ └── transactions/ │ │ │ │ └── route.ts │ │ │ └── user-preference/ │ │ │ └── route.ts │ │ ├── globals.css │ │ └── m/ │ │ └── [publicId]/ │ │ └── route.ts │ ├── components/ │ │ ├── ConfirmDialog.tsx │ │ ├── LanguageSwitcher.tsx │ │ ├── Navbar.tsx │ │ ├── ProgressToast.tsx │ │ ├── UpdateNoticeModal.tsx │ │ ├── ai-elements/ │ │ │ ├── conversation.tsx │ │ │ ├── message.tsx │ │ │ ├── reasoning.tsx │ │ │ └── tool.tsx │ │ ├── assistant/ │ │ │ ├── AssistantChatModal.tsx │ │ │ └── useAssistantChat.ts │ │ ├── auth/ │ │ │ └── PasswordStrengthIndicator.tsx │ │ ├── image-generation/ │ │ │ ├── ImageGenerationInlineCountButton.tsx │ │ │ └── ImageGenerationSlotOverlay.tsx │ │ ├── llm-console/ │ │ │ ├── LLMStageStreamCard.tsx │ │ │ └── index.ts │ │ ├── media/ │ │ │ ├── MediaImage.tsx │ │ │ └── MediaImageWithLoading.tsx │ │ ├── providers/ │ │ │ └── QueryProvider.tsx │ │ ├── shared/ │ │ │ └── assets/ │ │ │ ├── CharacterCreationModal.tsx │ │ │ ├── CharacterEditModal.tsx │ │ │ ├── GlobalAssetPicker.tsx │ │ │ ├── LocationCreationModal.tsx │ │ │ ├── LocationEditModal.tsx │ │ │ ├── character-creation/ │ │ │ │ ├── CharacterCreationForm.tsx │ │ │ │ ├── CharacterCreationPreview.tsx │ │ │ │ └── hooks/ │ │ │ │ └── useCharacterCreationSubmit.ts │ │ │ └── index.ts │ │ ├── task/ │ │ │ ├── TaskStatusInline.tsx │ │ │ └── TaskStatusOverlay.tsx │ │ ├── ui/ │ │ │ ├── CapsuleNav.tsx │ │ │ ├── ConfigModals.tsx │ │ │ ├── ImagePreviewModal.tsx │ │ │ ├── SegmentedControl.tsx │ │ │ ├── SharedComponents.tsx │ │ │ ├── ai-edit-style.ts │ │ │ ├── config-modals/ │ │ │ │ ├── ConfigConfirmModal.tsx │ │ │ │ ├── ConfigDeleteModal.tsx │ │ │ │ ├── ConfigEditModal.tsx │ │ │ │ ├── ModelCapabilityDropdown.tsx │ │ │ │ ├── WorldContextModal.tsx │ │ │ │ └── config-modal-selectors.tsx │ │ │ ├── icons/ │ │ │ │ ├── AISparklesIcon.tsx │ │ │ │ ├── AppIcon.tsx │ │ │ │ ├── RatioPreviewIcon.tsx │ │ │ │ ├── custom.tsx │ │ │ │ ├── index.ts │ │ │ │ └── registry.ts │ │ │ ├── model-dropdown-innovative.tsx │ │ │ ├── model-dropdown-ios.tsx │ │ │ ├── model-dropdown-variants.tsx │ │ │ ├── patterns/ │ │ │ │ ├── PanelCardV2.tsx │ │ │ │ ├── PanelEditFormV2.tsx │ │ │ │ ├── StoryboardHeaderV2.tsx │ │ │ │ ├── index.ts │ │ │ │ └── types.ts │ │ │ ├── primitives/ │ │ │ │ ├── GlassButton.tsx │ │ │ │ ├── GlassChip.tsx │ │ │ │ ├── GlassField.tsx │ │ │ │ ├── GlassInput.tsx │ │ │ │ ├── GlassModalShell.tsx │ │ │ │ ├── GlassSurface.tsx │ │ │ │ ├── GlassTextarea.tsx │ │ │ │ └── index.ts │ │ │ └── select-variants.tsx │ │ └── voice/ │ │ ├── VoiceDesignDialogBase.tsx │ │ ├── VoiceDesignGeneratorSection.tsx │ │ └── voice-design-shared.ts │ ├── contexts/ │ │ └── ToastContext.tsx │ ├── features/ │ │ └── video-editor/ │ │ ├── components/ │ │ │ ├── Preview/ │ │ │ │ ├── RemotionPreview.tsx │ │ │ │ └── index.ts │ │ │ ├── Timeline/ │ │ │ │ ├── Timeline.tsx │ │ │ │ └── index.ts │ │ │ ├── TransitionPicker.tsx │ │ │ └── VideoEditorStage.tsx │ │ ├── hooks/ │ │ │ ├── useEditorActions.ts │ │ │ └── useEditorState.ts │ │ ├── index.ts │ │ ├── remotion/ │ │ │ ├── VideoComposition.tsx │ │ │ └── transitions/ │ │ │ └── index.tsx │ │ ├── types/ │ │ │ └── editor.types.ts │ │ └── utils/ │ │ ├── migration.ts │ │ └── time-utils.ts │ ├── hooks/ │ │ └── common/ │ │ ├── useCandidateSystem.ts │ │ └── useGithubReleaseUpdate.ts │ ├── i18n/ │ │ ├── navigation.ts │ │ └── routing.ts │ ├── i18n.ts │ ├── instrumentation.ts │ ├── lib/ │ │ ├── ai-runtime/ │ │ │ ├── client.ts │ │ │ ├── errors.ts │ │ │ ├── index.ts │ │ │ └── types.ts │ │ ├── api-auth.ts │ │ ├── api-config.ts │ │ ├── api-errors.ts │ │ ├── api-fetch.ts │ │ ├── app-meta.ts │ │ ├── ark-api.ts │ │ ├── ark-llm.ts │ │ ├── asset-utils/ │ │ │ ├── ai-design.ts │ │ │ └── index.ts │ │ ├── assets/ │ │ │ └── description-fields.ts │ │ ├── assistant-platform/ │ │ │ ├── errors.ts │ │ │ ├── index.ts │ │ │ ├── registry.ts │ │ │ ├── runtime.ts │ │ │ ├── skills/ │ │ │ │ ├── api-config-template.ts │ │ │ │ └── tutorial.ts │ │ │ ├── system-prompts.ts │ │ │ └── types.ts │ │ ├── async/ │ │ │ └── map-with-concurrency.ts │ │ ├── async-poll.ts │ │ ├── async-submit.ts │ │ ├── async-task-utils.ts │ │ ├── auth.ts │ │ ├── billing/ │ │ │ ├── cost.ts │ │ │ ├── currency.ts │ │ │ ├── errors.ts │ │ │ ├── index.ts │ │ │ ├── ledger.ts │ │ │ ├── mode.ts │ │ │ ├── money.ts │ │ │ ├── reporting.ts │ │ │ ├── runtime-usage.ts │ │ │ ├── service.ts │ │ │ ├── task-policy.ts │ │ │ └── types.ts │ │ ├── config-service.ts │ │ ├── constants.ts │ │ ├── contracts/ │ │ │ ├── image-urls-contract.test.ts │ │ │ └── image-urls-contract.ts │ │ ├── crypto-utils.ts │ │ ├── env.ts │ │ ├── episode-marker-detector.ts │ │ ├── error-handler.ts │ │ ├── error-utils.ts │ │ ├── errors/ │ │ │ ├── codes.ts │ │ │ ├── display.ts │ │ │ ├── extract.ts │ │ │ ├── normalize.ts │ │ │ ├── types.ts │ │ │ └── user-messages.ts │ │ ├── fonts.ts │ │ ├── gemini-batch-utils.ts │ │ ├── generator-api.ts │ │ ├── generators/ │ │ │ ├── ark.ts │ │ │ ├── audio/ │ │ │ │ ├── bailian.ts │ │ │ │ └── index.ts │ │ │ ├── base.ts │ │ │ ├── factory.ts │ │ │ ├── fal.ts │ │ │ ├── image/ │ │ │ │ ├── gemini-compatible.ts │ │ │ │ ├── google.ts │ │ │ │ ├── index.ts │ │ │ │ └── openai-compatible.ts │ │ │ ├── minimax.ts │ │ │ ├── official.ts │ │ │ ├── resolution-adapter.ts │ │ │ ├── video/ │ │ │ │ ├── google.ts │ │ │ │ ├── index.ts │ │ │ │ └── openai-compatible.ts │ │ │ └── vidu.ts │ │ ├── image-cache.ts │ │ ├── image-generation/ │ │ │ ├── count-preference.ts │ │ │ ├── count.ts │ │ │ ├── location-slots.ts │ │ │ ├── slot-state.ts │ │ │ └── use-image-generation-count.ts │ │ ├── image-label.ts │ │ ├── json-repair.ts │ │ ├── lipsync/ │ │ │ ├── index.ts │ │ │ ├── preprocess.ts │ │ │ ├── providers/ │ │ │ │ ├── bailian.ts │ │ │ │ ├── fal.ts │ │ │ │ └── vidu.ts │ │ │ └── types.ts │ │ ├── llm/ │ │ │ ├── chat-completion.ts │ │ │ ├── chat-stream.ts │ │ │ ├── completion-parts.ts │ │ │ ├── index.ts │ │ │ ├── providers/ │ │ │ │ ├── ark.ts │ │ │ │ ├── google.ts │ │ │ │ └── openai-compat.ts │ │ │ ├── reasoning-capability.ts │ │ │ ├── runtime-shared.ts │ │ │ ├── runtime.ts │ │ │ ├── stream-helpers.ts │ │ │ ├── stream-timeout.ts │ │ │ ├── types.ts │ │ │ ├── utils.ts │ │ │ └── vision.ts │ │ ├── llm-client.ts │ │ ├── llm-observe/ │ │ │ ├── config.ts │ │ │ ├── internal-stream-context.ts │ │ │ ├── internal-task.ts │ │ │ ├── route-task.ts │ │ │ ├── stage-pipeline.ts │ │ │ ├── task-policy.ts │ │ │ └── types.ts │ │ ├── logging/ │ │ │ ├── config.ts │ │ │ ├── context.ts │ │ │ ├── core.ts │ │ │ ├── file-writer.ts │ │ │ ├── redact.ts │ │ │ ├── semantic.ts │ │ │ └── types.ts │ │ ├── media/ │ │ │ ├── attach.ts │ │ │ ├── hash.ts │ │ │ ├── image-url.test.ts │ │ │ ├── image-url.ts │ │ │ ├── outbound-image.test.ts │ │ │ ├── outbound-image.ts │ │ │ ├── service.ts │ │ │ └── types.ts │ │ ├── media-process.ts │ │ ├── migrations/ │ │ │ └── gateway-route-openai-compat.ts │ │ ├── model-capabilities/ │ │ │ ├── catalog.ts │ │ │ ├── lookup.ts │ │ │ ├── video-effective.ts │ │ │ └── video-model-options.ts │ │ ├── model-config-contract.ts │ │ ├── model-gateway/ │ │ │ ├── index.ts │ │ │ ├── llm.ts │ │ │ ├── openai-compat/ │ │ │ │ ├── chat.ts │ │ │ │ ├── common.ts │ │ │ │ ├── image.ts │ │ │ │ ├── index.ts │ │ │ │ ├── responses.ts │ │ │ │ ├── template-image.ts │ │ │ │ ├── template-video.ts │ │ │ │ └── video.ts │ │ │ ├── router.ts │ │ │ └── types.ts │ │ ├── model-pricing/ │ │ │ ├── catalog.ts │ │ │ ├── lookup.ts │ │ │ ├── version.ts │ │ │ └── video-tier.ts │ │ ├── modes.ts │ │ ├── novel-promotion/ │ │ │ ├── insert-panel.ts │ │ │ ├── panel-ai-data-sync.ts │ │ │ ├── run-stream/ │ │ │ │ └── types.ts │ │ │ ├── script-to-storyboard/ │ │ │ │ └── orchestrator.ts │ │ │ ├── stages/ │ │ │ │ ├── contracts/ │ │ │ │ │ ├── video-stage-contract.ts │ │ │ │ │ └── voice-stage-contract.ts │ │ │ │ ├── video-stage-runtime/ │ │ │ │ │ ├── immediate-video-submission.ts │ │ │ │ │ ├── task-targets.ts │ │ │ │ │ ├── types.ts │ │ │ │ │ ├── useVideoDownloadAll.ts │ │ │ │ │ ├── useVideoFirstLastFrameFlow.ts │ │ │ │ │ ├── useVideoPanelLinking.ts │ │ │ │ │ ├── useVideoPanelViewport.ts │ │ │ │ │ ├── useVideoPanelsProjection.ts │ │ │ │ │ ├── useVideoPromptState.ts │ │ │ │ │ ├── useVideoStageUiState.ts │ │ │ │ │ ├── useVideoTaskStates.ts │ │ │ │ │ ├── useVideoVoiceLines.ts │ │ │ │ │ └── utils.ts │ │ │ │ ├── video-stage-runtime-core.tsx │ │ │ │ ├── voice-stage-runtime/ │ │ │ │ │ ├── types.ts │ │ │ │ │ ├── useBindablePanelOptions.ts │ │ │ │ │ ├── useSpeakerAssetNavigation.ts │ │ │ │ │ ├── useVoiceGenerationActions.ts │ │ │ │ │ ├── useVoiceLineBindings.ts │ │ │ │ │ ├── useVoiceLineCrudActions.ts │ │ │ │ │ ├── useVoiceLineEditorState.ts │ │ │ │ │ ├── useVoicePlayback.ts │ │ │ │ │ ├── useVoiceRuntimeSync.ts │ │ │ │ │ ├── useVoiceSpeakerState.ts │ │ │ │ │ ├── useVoiceStageDataLoader.ts │ │ │ │ │ ├── useVoiceTaskState.ts │ │ │ │ │ └── utils.ts │ │ │ │ └── voice-stage-runtime-core.tsx │ │ │ └── story-to-script/ │ │ │ ├── clip-matching.ts │ │ │ ├── orchestrator.ts │ │ │ └── types.ts │ │ ├── openai-compat-media-template.ts │ │ ├── openai-compat-template-runtime.ts │ │ ├── prisma-error.ts │ │ ├── prisma-retry.ts │ │ ├── prisma.ts │ │ ├── prompt-i18n/ │ │ │ ├── build-prompt.ts │ │ │ ├── catalog.ts │ │ │ ├── errors.ts │ │ │ ├── index.ts │ │ │ ├── prompt-ids.ts │ │ │ ├── template-store.ts │ │ │ └── types.ts │ │ ├── providers/ │ │ │ ├── bailian/ │ │ │ │ ├── audio.ts │ │ │ │ ├── catalog.ts │ │ │ │ ├── image.ts │ │ │ │ ├── index.ts │ │ │ │ ├── llm.ts │ │ │ │ ├── probe.ts │ │ │ │ ├── tts.ts │ │ │ │ ├── types.ts │ │ │ │ ├── video.ts │ │ │ │ ├── voice-cleanup.ts │ │ │ │ ├── voice-design.ts │ │ │ │ └── voice-manage.ts │ │ │ ├── fal/ │ │ │ │ └── base-url.ts │ │ │ ├── official/ │ │ │ │ └── model-registry.ts │ │ │ └── siliconflow/ │ │ │ ├── audio.ts │ │ │ ├── catalog.ts │ │ │ ├── image.ts │ │ │ ├── index.ts │ │ │ ├── llm.ts │ │ │ ├── probe.ts │ │ │ ├── types.ts │ │ │ └── video.ts │ │ ├── query/ │ │ │ ├── client.ts │ │ │ ├── hooks/ │ │ │ │ ├── index.ts │ │ │ │ ├── run-stream/ │ │ │ │ │ ├── event-parser.ts │ │ │ │ │ ├── recovered-run-subscription.ts │ │ │ │ │ ├── run-event-adapter.ts │ │ │ │ │ ├── run-request-executor.ts │ │ │ │ │ ├── run-stream-sse-body.ts │ │ │ │ │ ├── run-stream-state-runtime.ts │ │ │ │ │ ├── run-stream-view.ts │ │ │ │ │ ├── snapshot.ts │ │ │ │ │ ├── state-machine.ts │ │ │ │ │ └── types.ts │ │ │ │ ├── useGlobalAssets.ts │ │ │ │ ├── useProjectAssets.ts │ │ │ │ ├── useProjectData.ts │ │ │ │ ├── useRunStreamState.ts │ │ │ │ ├── useSSE.ts │ │ │ │ ├── useScriptToStoryboardRunStream.ts │ │ │ │ ├── useStoryToScriptRunStream.ts │ │ │ │ ├── useStoryboards.ts │ │ │ │ ├── useTaskPresentation.ts │ │ │ │ ├── useTaskStatus.ts │ │ │ │ ├── useTaskTargetStateMap.ts │ │ │ │ ├── useUserModels.ts │ │ │ │ └── useVoiceLines.ts │ │ │ ├── keys.ts │ │ │ ├── mutations/ │ │ │ │ ├── asset-hub-character-mutations.ts │ │ │ │ ├── asset-hub-creation-mutations.ts │ │ │ │ ├── asset-hub-location-mutations.ts │ │ │ │ ├── asset-hub-mutations-runtime.ts │ │ │ │ ├── asset-hub-mutations-shared.ts │ │ │ │ ├── asset-hub-update-mutations.ts │ │ │ │ ├── asset-hub-voice-mutations.ts │ │ │ │ ├── character-base-mutations.ts │ │ │ │ ├── character-image-ops-mutations.ts │ │ │ │ ├── character-profile-mutations.ts │ │ │ │ ├── character-voice-mutations.ts │ │ │ │ ├── index.ts │ │ │ │ ├── location-image-mutations.ts │ │ │ │ ├── location-management-mutations.ts │ │ │ │ ├── mutation-shared.ts │ │ │ │ ├── storyboard-panel-mutations.ts │ │ │ │ ├── storyboard-prompt-mutations.ts │ │ │ │ ├── task-mutations.ts │ │ │ │ ├── useAssetHubMutations.ts │ │ │ │ ├── useCharacterMutations.core.ts │ │ │ │ ├── useCharacterMutations.ts │ │ │ │ ├── useEpisodeMutations.ts │ │ │ │ ├── useLocationMutations.core.ts │ │ │ │ ├── useLocationMutations.ts │ │ │ │ ├── useProjectConfigMutations.ts │ │ │ │ ├── useProjectMutations.ts │ │ │ │ ├── useStoryboardMutations.core.ts │ │ │ │ ├── useStoryboardMutations.ts │ │ │ │ ├── useVideoMutations.ts │ │ │ │ └── useVoiceMutations.ts │ │ │ └── task-target-overlay.ts │ │ ├── rate-limit.ts │ │ ├── redis.ts │ │ ├── run-runtime/ │ │ │ ├── publisher.ts │ │ │ ├── service.ts │ │ │ ├── task-bridge.ts │ │ │ ├── types.ts │ │ │ ├── workflow-lease.ts │ │ │ └── workflow.ts │ │ ├── server-boot.ts │ │ ├── srt.ts │ │ ├── sse/ │ │ │ └── shared-subscriber.ts │ │ ├── storage/ │ │ │ ├── bootstrap.ts │ │ │ ├── errors.ts │ │ │ ├── factory.ts │ │ │ ├── index.ts │ │ │ ├── init.ts │ │ │ ├── providers/ │ │ │ │ ├── cos.ts │ │ │ │ ├── local.ts │ │ │ │ └── minio.ts │ │ │ ├── signed-urls.ts │ │ │ ├── types.ts │ │ │ └── utils.ts │ │ ├── storyboard-phases.ts │ │ ├── task/ │ │ │ ├── client.ts │ │ │ ├── error-message.ts │ │ │ ├── errors.ts │ │ │ ├── has-output.ts │ │ │ ├── intent.ts │ │ │ ├── presentation.ts │ │ │ ├── progress-message.ts │ │ │ ├── publisher.ts │ │ │ ├── queues.ts │ │ │ ├── reconcile.ts │ │ │ ├── resolve-locale.ts │ │ │ ├── service.ts │ │ │ ├── state-service.ts │ │ │ ├── submitter.ts │ │ │ ├── types.ts │ │ │ └── ui-payload.ts │ │ ├── update-check.ts │ │ ├── user-api/ │ │ │ ├── llm-test-connection.ts │ │ │ ├── model-llm-protocol-probe.ts │ │ │ ├── model-template/ │ │ │ │ ├── index.ts │ │ │ │ ├── probe.ts │ │ │ │ ├── save.ts │ │ │ │ ├── schema.ts │ │ │ │ └── validator.ts │ │ │ └── provider-test.ts │ │ ├── voice/ │ │ │ ├── generate-voice-line.ts │ │ │ └── provider-voice-binding.ts │ │ ├── word-count.ts │ │ ├── workers/ │ │ │ ├── handlers/ │ │ │ │ ├── analyze-global-parse.ts │ │ │ │ ├── analyze-global-persist.ts │ │ │ │ ├── analyze-global-prompt.ts │ │ │ │ ├── analyze-global.ts │ │ │ │ ├── analyze-novel.ts │ │ │ │ ├── asset-hub-ai-design.ts │ │ │ │ ├── asset-hub-ai-modify.ts │ │ │ │ ├── asset-hub-image-task-handler.ts │ │ │ │ ├── asset-hub-modify-task-handler.ts │ │ │ │ ├── character-image-task-handler.ts │ │ │ │ ├── character-profile-helpers.ts │ │ │ │ ├── character-profile.ts │ │ │ │ ├── clips-build.ts │ │ │ │ ├── episode-split.ts │ │ │ │ ├── image-task-handler-shared.ts │ │ │ │ ├── image-task-handlers-core.ts │ │ │ │ ├── image-task-handlers.ts │ │ │ │ ├── llm-proxy.ts │ │ │ │ ├── llm-stream.ts │ │ │ │ ├── location-image-task-handler.ts │ │ │ │ ├── modify-asset-image-task-handler.ts │ │ │ │ ├── modify-description-sync.ts │ │ │ │ ├── panel-image-task-handler.ts │ │ │ │ ├── panel-variant-task-handler.ts │ │ │ │ ├── reference-to-character-helpers.ts │ │ │ │ ├── reference-to-character.ts │ │ │ │ ├── resolve-analysis-model.ts │ │ │ │ ├── screenplay-convert-helpers.ts │ │ │ │ ├── screenplay-convert.ts │ │ │ │ ├── script-to-storyboard-atomic-retry.ts │ │ │ │ ├── script-to-storyboard-helpers.ts │ │ │ │ ├── script-to-storyboard.ts │ │ │ │ ├── shot-ai-persist.ts │ │ │ │ ├── shot-ai-prompt-appearance.ts │ │ │ │ ├── shot-ai-prompt-location.ts │ │ │ │ ├── shot-ai-prompt-runtime.ts │ │ │ │ ├── shot-ai-prompt-shot.ts │ │ │ │ ├── shot-ai-prompt-utils.ts │ │ │ │ ├── shot-ai-prompt.ts │ │ │ │ ├── shot-ai-tasks.ts │ │ │ │ ├── shot-ai-variants.ts │ │ │ │ ├── story-to-script-helpers.ts │ │ │ │ ├── story-to-script.ts │ │ │ │ ├── voice-analyze-helpers.ts │ │ │ │ ├── voice-analyze.ts │ │ │ │ └── voice-design.ts │ │ │ ├── image.worker.ts │ │ │ ├── index.ts │ │ │ ├── shared.ts │ │ │ ├── text.worker.ts │ │ │ ├── user-concurrency-gate.ts │ │ │ ├── utils.ts │ │ │ ├── video.worker.ts │ │ │ └── voice.worker.ts │ │ ├── workflow-concurrency.ts │ │ ├── workflow-engine/ │ │ │ └── dependencies.ts │ │ └── workspace/ │ │ └── model-setup.ts │ ├── middleware.ts │ ├── pages/ │ │ └── _document.tsx │ ├── styles/ │ │ ├── animations.css │ │ ├── ui-semantic-glass.css │ │ └── ui-tokens-glass.css │ └── types/ │ ├── character-profile.ts │ ├── next-auth.d.ts │ ├── project.ts │ └── storyboard-types.ts ├── standards/ │ ├── capabilities/ │ │ ├── catalog.example.json │ │ └── image-video.catalog.json │ ├── pricing/ │ │ └── image-video.pricing.json │ └── prompt-canary/ │ ├── screenplay_conversion.canary.json │ ├── story_to_script_clips.canary.json │ ├── storyboard_panels.canary.json │ └── voice_analysis.canary.json ├── tests/ │ ├── concurrency/ │ │ └── billing/ │ │ └── ledger.concurrency.test.ts │ ├── contracts/ │ │ ├── behavior-test-standard.md │ │ ├── requirements-matrix.test.ts │ │ ├── requirements-matrix.ts │ │ ├── route-behavior-matrix.ts │ │ ├── route-catalog.ts │ │ ├── task-type-catalog.ts │ │ └── tasktype-behavior-matrix.ts │ ├── fixtures/ │ │ └── billing/ │ │ └── cases.json │ ├── helpers/ │ │ ├── assertions.ts │ │ ├── auth.ts │ │ ├── billing-fixtures.ts │ │ ├── db-reset.ts │ │ ├── fakes/ │ │ │ ├── llm.ts │ │ │ ├── media.ts │ │ │ ├── providers.ts │ │ │ └── scenario-server.ts │ │ ├── fixtures.ts │ │ ├── mock-query-client.ts │ │ ├── prisma.ts │ │ └── request.ts │ ├── hidden/ │ │ └── README.md │ ├── integration/ │ │ ├── api/ │ │ │ ├── contract/ │ │ │ │ ├── crud-routes.test.ts │ │ │ │ ├── direct-submit-routes.test.ts │ │ │ │ ├── infra-routes.test.ts │ │ │ │ ├── llm-observe-routes.test.ts │ │ │ │ ├── run-cancel.route.test.ts │ │ │ │ ├── run-step-retry.route.test.ts │ │ │ │ └── task-infra-routes.test.ts │ │ │ ├── helpers/ │ │ │ │ └── call-route.ts │ │ │ └── specific/ │ │ │ ├── asset-hub-appearances-route.test.ts │ │ │ ├── asset-hub-generate-image-art-style.test.ts │ │ │ ├── asset-hub-location-create-no-auto-generate.test.ts │ │ │ ├── characters-post-reference-forwarding.test.ts │ │ │ ├── characters-post.test.ts │ │ │ ├── novel-promotion-character-style-forwarding.test.ts │ │ │ ├── novel-promotion-generate-image-art-style.test.ts │ │ │ ├── novel-promotion-location-style-forwarding.test.ts │ │ │ ├── novel-promotion-project-art-style-validation.test.ts │ │ │ ├── panel-variant-route.test.ts │ │ │ ├── project-create-default-audio-model.test.ts │ │ │ ├── reference-to-character-api.test.ts │ │ │ ├── speaker-voice-provider-contract.test.ts │ │ │ ├── user-api-config-probe-model-llm-protocol.test.ts │ │ │ ├── user-api-config-put.test.ts │ │ │ ├── user-assistant-chat-api-config.test.ts │ │ │ ├── user-models-audio-filter.test.ts │ │ │ ├── user-preference-art-style-validation.test.ts │ │ │ └── voice-generate-default-audio-model.test.ts │ │ ├── billing/ │ │ │ ├── api-contract.integration.test.ts │ │ │ ├── ledger.integration.test.ts │ │ │ ├── service.integration.test.ts │ │ │ ├── submitter.integration.test.ts │ │ │ └── worker-lifecycle.integration.test.ts │ │ ├── chain/ │ │ │ ├── image.chain.test.ts │ │ │ ├── text.chain.test.ts │ │ │ ├── video.chain.test.ts │ │ │ └── voice.chain.test.ts │ │ ├── provider/ │ │ │ ├── fal-provider.contract.test.ts │ │ │ └── openai-compat-provider.contract.test.ts │ │ ├── run-runtime/ │ │ │ └── retry-failed-step.integration.test.ts │ │ └── task/ │ │ └── create-task-dedupe.integration.test.ts │ ├── regression/ │ │ ├── panel-variant-cross-storyboard.test.ts │ │ ├── task-dedupe-recovery.test.ts │ │ └── task-enqueue-billing-rollback.test.ts │ ├── setup/ │ │ ├── env.ts │ │ ├── global-setup.ts │ │ └── global-teardown.ts │ ├── system/ │ │ ├── generate-image.system.test.ts │ │ ├── generate-video.system.test.ts │ │ ├── helpers/ │ │ │ ├── seed.ts │ │ │ ├── tasks.ts │ │ │ └── workers.ts │ │ ├── text-workflow.system.test.ts │ │ └── voice-generate.system.test.ts │ └── unit/ │ ├── ai-runtime/ │ │ └── errors.test.ts │ ├── api-config/ │ │ ├── assistant-chat-modal-content.test.ts │ │ ├── minimax-preset.test.ts │ │ ├── preset-coming-soon.test.ts │ │ ├── provider-card-assistant-saved-label.test.ts │ │ ├── provider-card-pricing-form.test.ts │ │ ├── provider-card-protocol-probe.test.ts │ │ ├── provider-card-shell.test.ts │ │ ├── provider-card-tutorial-modal.test.ts │ │ ├── use-api-config-filters.test.ts │ │ ├── use-assistant-chat-saved-events.test.ts │ │ └── use-providers-order.test.ts │ ├── assistant-platform/ │ │ ├── registry.test.ts │ │ ├── runtime.test.ts │ │ ├── skills-api-config-template.test.ts │ │ └── system-prompts.test.ts │ ├── async-poll-ocompat.test.ts │ ├── billing/ │ │ ├── cost-error-branches.test.ts │ │ ├── cost.test.ts │ │ ├── ledger-extra.test.ts │ │ ├── mode.test.ts │ │ ├── runtime-usage.test.ts │ │ ├── service.test.ts │ │ └── task-policy.test.ts │ ├── components/ │ │ ├── character-creation-modal.test.ts │ │ ├── image-generation-inline-count-button.test.ts │ │ ├── llm-stage-stream-card-error.test.ts │ │ ├── location-creation-modal.test.ts │ │ ├── navbar-download-logs.test.ts │ │ └── voice-design-shared.test.ts │ ├── generator-api-openai-template-required.test.ts │ ├── generator-api.test.ts │ ├── generators/ │ │ ├── factory.test.ts │ │ ├── fal-video-kling-presets.test.ts │ │ ├── image-provider-smoke.test.ts │ │ ├── openai-compatible-image.test.ts │ │ └── openai-compatible-video.test.ts │ ├── guards/ │ │ ├── api-route-contract-guard.test.ts │ │ ├── changed-file-test-impact-guard.test.ts │ │ ├── image-reference-normalization-guard.test.ts │ │ └── task-submit-compensation-guard.test.ts │ ├── helpers/ │ │ ├── api-fetch.test.ts │ │ ├── json-repair.test.ts │ │ ├── llm-stage-stream-card-output.test.ts │ │ ├── logging-core.test.ts │ │ ├── migrate-gateway-route-openai-compat.test.ts │ │ ├── prompt-suffix-regression.test.ts │ │ ├── recovered-run-subscription.test.ts │ │ ├── reference-to-character-helpers.test.ts │ │ ├── route-task-helpers.test.ts │ │ ├── run-request-executor.run-events.test.ts │ │ ├── run-stream-state-machine.test.ts │ │ ├── run-stream-view.test.ts │ │ ├── task-state-service.test.ts │ │ ├── task-submitter-helpers.test.ts │ │ ├── update-check.test.ts │ │ └── workspace-model-setup.test.ts │ ├── image-generation/ │ │ ├── count.test.ts │ │ └── slot-state.test.ts │ ├── lipsync-bailian.test.ts │ ├── lipsync-preprocess.test.ts │ ├── llm/ │ │ ├── ark-llm-thinking.test.ts │ │ ├── chat-completion-official-provider.test.ts │ │ ├── chat-completion-openai-compatible-protocol.test.ts │ │ ├── chat-stream-official-provider.test.ts │ │ ├── chat-stream-openai-compatible-protocol.test.ts │ │ ├── completion-parts-think-tag.test.ts │ │ └── reasoning-capability.test.ts │ ├── model-capabilities/ │ │ ├── bailian-video-capabilities.test.ts │ │ ├── image-resolution-default.test.ts │ │ └── video-effective.test.ts │ ├── model-gateway/ │ │ ├── llm.test.ts │ │ ├── openai-compat-responses.test.ts │ │ ├── openai-compat-template-image-output-urls.test.ts │ │ ├── openai-compat-template-renderer.test.ts │ │ ├── openai-compat-template-video-external-id.test.ts │ │ └── router.test.ts │ ├── novel-promotion/ │ │ ├── character-voice-mutations.test.ts │ │ ├── immediate-video-submission.test.ts │ │ ├── insert-panel-user-input.test.ts │ │ ├── panel-task-status-error-code.test.ts │ │ ├── use-tts-generation.test.ts │ │ ├── video-model-options.test.ts │ │ ├── video-panel-card-body.test.ts │ │ ├── video-panels-projection-error-code.test.ts │ │ ├── voice-generation-actions.test.ts │ │ ├── voice-runtime-sync.test.ts │ │ ├── voice-stage-data-loader.test.ts │ │ └── workspace-video-actions.test.ts │ ├── optimistic/ │ │ ├── ai-data-modal-state.test.ts │ │ ├── asset-hub-mutations.test.ts │ │ ├── panel-ai-data-sync.test.ts │ │ ├── panel-save-coordinator.test.ts │ │ ├── project-asset-mutations.test.ts │ │ ├── sse-invalidation.test.ts │ │ ├── task-target-overlay.test.ts │ │ └── task-target-state-map.test.ts │ ├── providers/ │ │ ├── bailian-llm.test.ts │ │ ├── bailian-tts.test.ts │ │ ├── bailian-video.test.ts │ │ ├── bailian-voice-cleanup.test.ts │ │ ├── bailian-voice-design.test.ts │ │ └── model-registry.test.ts │ ├── query/ │ │ └── project-location-generate-body.test.ts │ ├── run-runtime/ │ │ └── task-bridge.test.ts │ ├── storage/ │ │ ├── bootstrap.test.ts │ │ └── factory.test.ts │ ├── task/ │ │ ├── async-poll-bailian.test.ts │ │ ├── async-poll-external-id.test.ts │ │ ├── async-poll-openai.test.ts │ │ ├── error-catalog.contract.test.ts │ │ ├── error-message.test.ts │ │ ├── intent.test.ts │ │ ├── llm-observe-contract.test.ts │ │ ├── normalize-error.test.ts │ │ ├── presentation.test.ts │ │ ├── publisher.direct-run-events.test.ts │ │ └── publisher.replay.test.ts │ ├── user-api/ │ │ ├── llm-test-connection.test.ts │ │ ├── model-llm-protocol-probe.test.ts │ │ ├── model-template-save.test.ts │ │ ├── model-template-schema.test.ts │ │ ├── provider-test-compatible.test.ts │ │ └── provider-test.test.ts │ ├── voice/ │ │ ├── generate-voice-line.test.ts │ │ └── provider-voice-binding.test.ts │ ├── worker/ │ │ ├── analyze-global.test.ts │ │ ├── analyze-novel.test.ts │ │ ├── asset-hub-ai-design.test.ts │ │ ├── asset-hub-ai-modify.test.ts │ │ ├── asset-hub-image-suffix.test.ts │ │ ├── character-image-task-handler.test.ts │ │ ├── character-profile.test.ts │ │ ├── clips-build.test.ts │ │ ├── episode-split.test.ts │ │ ├── image-task-handlers-core.test.ts │ │ ├── image-worker.test.ts │ │ ├── llm-proxy.test.ts │ │ ├── llm-stream.test.ts │ │ ├── location-image-task-handler.test.ts │ │ ├── modify-image-reference-description.test.ts │ │ ├── panel-image-task-handler.test.ts │ │ ├── panel-variant-task-handler.test.ts │ │ ├── reference-to-character.test.ts │ │ ├── resolve-analysis-model.test.ts │ │ ├── screenplay-convert.test.ts │ │ ├── script-to-storyboard-atomic-retry.test.ts │ │ ├── script-to-storyboard-orchestrator.retry.test.ts │ │ ├── script-to-storyboard.test.ts │ │ ├── shared.direct-run-events.test.ts │ │ ├── shot-ai-prompt-appearance.test.ts │ │ ├── shot-ai-prompt-location.test.ts │ │ ├── shot-ai-prompt-shot.test.ts │ │ ├── shot-ai-tasks.test.ts │ │ ├── shot-ai-variants.test.ts │ │ ├── story-to-script-orchestrator.retry.test.ts │ │ ├── story-to-script.test.ts │ │ ├── user-concurrency-gate.test.ts │ │ ├── video-generation-resume.test.ts │ │ ├── video-worker.test.ts │ │ ├── voice-analyze.test.ts │ │ ├── voice-design.test.ts │ │ ├── voice-line-parse-helpers.test.ts │ │ └── voice-worker.test.ts │ └── workspace/ │ ├── episode-selection.test.ts │ └── rebuild-confirm.test.ts ├── tsconfig.json ├── vitest.config.ts └── vitest.core-coverage.config.ts