@gentbajko/slopify 2.4.0 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +201 -21
- package/NOTICE +12 -0
- package/README.md +21 -40
- package/SUBTITLES.md +1 -1
- package/dist/adapter-registry.js +11 -1
- package/dist/adapters/alignment/cache.js +4 -1
- package/dist/adapters/alignment/ctc.js +25 -23
- package/dist/adapters/alignment/index.js +37 -6
- package/dist/adapters/alignment/multilingual.js +267 -0
- package/dist/adapters/alignment/protocol.js +11 -0
- package/dist/adapters/alignment/quality.js +4 -3
- package/dist/adapters/alignment/sentences.js +95 -0
- package/dist/adapters/alignment/spec.js +24 -0
- package/dist/adapters/alignment/spell.js +769 -0
- package/dist/adapters/alignment/text.js +56 -9
- package/dist/adapters/alignment/window.js +34 -30
- package/dist/adapters/alignment/worker.js +23 -21
- package/dist/adapters/explain.js +11 -11
- package/dist/adapters/host-cli/index.js +55 -5
- package/dist/adapters/host-cli/transport.js +13 -6
- package/dist/adapters/image/bytes.js +2 -2
- package/dist/adapters/image/codex-output.js +60 -18
- package/dist/adapters/image/codex.js +166 -25
- package/dist/adapters/image/fal.js +31 -3
- package/dist/adapters/image/google.js +17 -2
- package/dist/adapters/image/openai.js +45 -16
- package/dist/adapters/image/reference.js +41 -0
- package/dist/adapters/image/replicate.js +14 -2
- package/dist/adapters/image/video.js +2 -2
- package/dist/adapters/key-probes.js +36 -0
- package/dist/adapters/llm/claude-code.js +168 -32
- package/dist/adapters/llm/cli-login-error.js +1 -1
- package/dist/adapters/llm/codex-limits.js +157 -0
- package/dist/adapters/llm/codex-models.js +2 -1
- package/dist/adapters/llm/codex-server-models.js +2 -1
- package/dist/adapters/llm/codex.js +99 -12
- package/dist/adapters/llm/document-workspace.js +2 -2
- package/dist/adapters/llm/gemini-workspace.js +1 -1
- package/dist/adapters/llm/gemini.js +16 -3
- package/dist/adapters/llm/image-workspace.js +58 -0
- package/dist/adapters/llm/openrouter.js +11 -3
- package/dist/adapters/llm/run-cli.js +26 -9
- package/dist/adapters/tts/cartesia.js +10 -0
- package/dist/adapters/tts/elevenlabs.js +31 -9
- package/dist/adapters/tts/inworld-async.js +9 -5
- package/dist/adapters/tts/inworld.js +17 -3
- package/dist/adapters/tts/openai.js +3 -0
- package/dist/adapters/tts/voice-languages.js +80 -0
- package/dist/assets/fonts/noto/NotoSans-Regular.ttf +0 -0
- package/dist/assets/fonts/noto/NotoSansArabic-Regular.ttf +0 -0
- package/dist/assets/fonts/noto/NotoSansDevanagari-Regular.ttf +0 -0
- package/dist/assets/fonts/noto/NotoSansHebrew-Regular.ttf +0 -0
- package/dist/assets/fonts/noto/NotoSansThai-Regular.ttf +0 -0
- package/dist/assets/fonts/noto/OFL.txt +93 -0
- package/dist/assets/fonts/noto/SOURCE.txt +18 -0
- package/dist/assets/models.yaml +7 -0
- package/dist/assets/sample/sample-audiobook.tar +0 -0
- package/dist/assets/sample/sample-podcast.tar +0 -0
- package/dist/assets/sample/sample-project.tar +0 -0
- package/dist/catalog/merge.js +132 -0
- package/dist/catalog/registry.js +33 -12
- package/dist/catalog/runtime-models.js +1 -1
- package/dist/catalog/schema.js +12 -1
- package/dist/catalog/store.js +147 -8
- package/dist/catalog/validate.js +17 -2
- package/dist/compose.yaml +71 -0
- package/dist/edge/autostart/docker-record.js +32 -0
- package/dist/edge/autostart/docker.js +50 -0
- package/dist/edge/autostart/index.js +78 -0
- package/dist/edge/autostart/launcher.js +176 -0
- package/dist/edge/autostart/model.js +3 -0
- package/dist/edge/autostart/native.js +210 -0
- package/dist/edge/autostart/prompt.js +66 -0
- package/dist/edge/autostart/service.js +81 -0
- package/dist/edge/cli.js +57 -51
- package/dist/edge/docker-install/activation.js +56 -0
- package/dist/edge/docker-install/apply.js +458 -0
- package/dist/edge/docker-install/engine.js +362 -0
- package/dist/edge/docker-install/run.js +154 -0
- package/dist/edge/docker-install/state.js +146 -0
- package/dist/edge/{docker-projects → docker-install}/volume.js +1 -5
- package/dist/edge/docker.js +14 -22
- package/dist/edge/events/hub.js +11 -0
- package/dist/edge/host-cli.js +1 -1
- package/dist/edge/http/actions.js +32 -10
- package/dist/edge/http/app.js +60 -2
- package/dist/edge/http/auditions.js +70 -0
- package/dist/edge/http/autostart.js +37 -0
- package/dist/edge/http/backups.js +40 -0
- package/dist/edge/http/channel-memory.js +92 -0
- package/dist/edge/http/channels.js +128 -0
- package/dist/edge/http/entries.js +22 -3
- package/dist/edge/http/files.js +1 -1
- package/dist/edge/http/folder-location.js +1 -1
- package/dist/edge/http/home.js +39 -0
- package/dist/edge/http/host-cli.js +45 -6
- package/dist/edge/http/narration-peaks.js +76 -0
- package/dist/edge/http/onboarding.js +152 -0
- package/dist/edge/http/open-folder.js +1 -1
- package/dist/edge/http/patch-notes.js +45 -0
- package/dist/edge/http/planning.js +4 -2
- package/dist/edge/http/problem.js +1 -0
- package/dist/edge/http/project-create.js +87 -0
- package/dist/edge/http/projects.js +31 -99
- package/dist/edge/http/prompts.js +40 -3
- package/dist/edge/http/pronunciations.js +23 -4
- package/dist/edge/http/providers.js +86 -0
- package/dist/edge/http/reviews.js +121 -0
- package/dist/edge/http/revision-files.js +1 -1
- package/dist/edge/http/revisions.js +1 -1
- package/dist/edge/http/run-cost.js +25 -0
- package/dist/edge/http/schedules.js +111 -6
- package/dist/edge/http/settings.js +128 -6
- package/dist/edge/http/storage-files.js +50 -0
- package/dist/edge/http/storage.js +29 -2
- package/dist/edge/http/studio.js +207 -0
- package/dist/edge/http/style-preview.js +100 -0
- package/dist/edge/http/subtitles.js +1 -1
- package/dist/edge/http/trash.js +69 -0
- package/dist/edge/http/update.js +24 -3
- package/dist/edge/http/whats-new.js +15 -0
- package/dist/edge/http/youtube-edits.js +83 -0
- package/dist/edge/native-update.js +62 -0
- package/dist/host-cli/open-folder.js +10 -10
- package/dist/host-cli/runtime.js +12 -3
- package/dist/kernel/db/migrations/0022-drop-duplicate-held-work.sql +56 -0
- package/dist/kernel/db/migrations/0024-reference-attachments.sql +18 -0
- package/dist/kernel/db/migrations/0025-automatic-reviews.sql +40 -0
- package/dist/kernel/db/migrations/0026-schedule-topic-generation.sql +23 -0
- package/dist/kernel/db/migrations/0027-run-cost.sql +58 -0
- package/dist/kernel/db/migrations/0030-automatic-retries.sql +18 -0
- package/dist/kernel/db/migrations/0031-prompt-history-and-description-edits.sql +33 -0
- package/dist/kernel/db/migrations/0032-channels.sql +65 -0
- package/dist/kernel/db/migrations/0034-script-prompts.sql +23 -0
- package/dist/kernel/db/migrations/0035-narration-aliases.sql +13 -0
- package/dist/kernel/db/migrations/0037-project-uploads.sql +8 -0
- package/dist/kernel/db/migrations/0038-voice-languages.sql +7 -0
- package/dist/kernel/db/migrations/0039-channel-essentials.sql +64 -0
- package/dist/kernel/db/migrations/0040-standalone-usage.sql +35 -0
- package/dist/kernel/paths.js +27 -6
- package/dist/kernel/pipeline.js +4 -1
- package/dist/kernel/ports/host-cli.js +139 -16
- package/dist/kernel/ports/image.js +3 -1
- package/dist/kernel/ports/key-probe.js +1 -0
- package/dist/kernel/ports/languages.js +157 -0
- package/dist/kernel/ports/llm.js +3 -1
- package/dist/kernel/ports/model.js +5 -2
- package/dist/kernel/ports/narration-aliases.js +60 -0
- package/dist/kernel/ports/plan-limits.js +36 -0
- package/dist/kernel/runner/attempt.js +18 -9
- package/dist/kernel/runner/audition.js +36 -0
- package/dist/kernel/runner/graph.js +24 -5
- package/dist/kernel/runner/index.js +35 -5
- package/dist/kernel/runner/meter.js +1 -0
- package/dist/kernel/runner/providers.js +164 -9
- package/dist/kernel/runner/retry-policy.js +43 -0
- package/dist/kernel/runner/standalone.js +134 -0
- package/dist/kernel/runner/work-authority.js +28 -2
- package/dist/main.js +321 -20
- package/dist/patch-notes/0.4.2-to-1.0.md +93 -0
- package/dist/patch-notes/1.0-to-2.0.md +74 -0
- package/dist/patch-notes/2.0-to-3.0.md +257 -0
- package/dist/patch-notes/3.0.0.md +70 -0
- package/dist/patch-notes/index.json +26 -0
- package/dist/slices/admission/model.js +35 -0
- package/dist/slices/admission/repo.js +24 -4
- package/dist/slices/admission/rules.js +126 -1
- package/dist/slices/admission/schema.js +68 -1
- package/dist/slices/admission/short-mode.js +47 -0
- package/dist/slices/admission/start.js +90 -16
- package/dist/slices/article/continuation.js +2 -2
- package/dist/slices/article/provided-entries.js +2 -2
- package/dist/slices/article/run.js +6 -2
- package/dist/slices/article/segments.js +3 -3
- package/dist/slices/backups/files.js +135 -0
- package/dist/slices/backups/folder.js +43 -0
- package/dist/slices/backups/model.js +65 -0
- package/dist/slices/backups/repo.js +28 -0
- package/dist/slices/backups/schedule.js +60 -0
- package/dist/slices/backups/service.js +311 -0
- package/dist/slices/batch/index.js +9 -2
- package/dist/slices/cancel/index.js +1 -1
- package/dist/slices/channels/cast-images.js +110 -0
- package/dist/slices/channels/cast-match.js +32 -0
- package/dist/slices/channels/images.js +19 -0
- package/dist/slices/channels/model.js +5 -0
- package/dist/slices/channels/rebrand.js +100 -0
- package/dist/slices/channels/repo.js +218 -0
- package/dist/slices/channels/runs.js +129 -0
- package/dist/slices/channels/schema.js +129 -0
- package/dist/slices/channels/service.js +180 -0
- package/dist/slices/channels/studio-csv.js +110 -0
- package/dist/slices/channels/videos.js +120 -0
- package/dist/slices/checkpoints/recovery.js +10 -0
- package/dist/slices/control/index.js +2 -1
- package/dist/slices/document/fonts.js +1 -1
- package/dist/slices/document/render.js +1 -1
- package/dist/slices/episodes/related.js +90 -0
- package/dist/slices/episodes/repo.js +60 -0
- package/dist/slices/episodes/service.js +58 -0
- package/dist/slices/episodes/summarize.js +170 -0
- package/dist/slices/estimate/index.js +113 -24
- package/dist/slices/estimate/requests.js +60 -2
- package/dist/slices/fixes/rules.js +73 -0
- package/dist/slices/fonts/coverage.js +82 -0
- package/dist/slices/fonts/sfnt.js +74 -0
- package/dist/slices/images/run.js +8 -5
- package/dist/slices/images/scale.js +84 -0
- package/dist/slices/library/diff.js +122 -0
- package/dist/slices/library/history.js +100 -0
- package/dist/slices/library/model.js +3 -0
- package/dist/slices/library/photorealistic.js +49 -0
- package/dist/slices/library/repo.js +19 -14
- package/dist/slices/library/save.js +62 -12
- package/dist/slices/library/slots.js +15 -3
- package/dist/slices/library/snapshot.js +8 -2
- package/dist/slices/library/used-by.js +153 -0
- package/dist/slices/loudness/level-pieces.js +41 -0
- package/dist/slices/loudness/loudnorm.js +164 -0
- package/dist/slices/loudness/model.js +153 -0
- package/dist/slices/model-upkeep/model.js +10 -0
- package/dist/slices/model-upkeep/switch.js +217 -0
- package/dist/slices/model-upkeep/usage.js +183 -0
- package/dist/slices/narration/aliases-library.js +31 -0
- package/dist/slices/narration/aliases-schema.js +53 -0
- package/dist/slices/narration/aliases.js +49 -0
- package/dist/slices/narration/blocks.js +352 -0
- package/dist/slices/narration/chunk.js +19 -7
- package/dist/slices/narration/concat.js +2 -2
- package/dist/slices/narration/describe.js +45 -0
- package/dist/slices/narration/pauses-model.js +63 -0
- package/dist/slices/narration/pauses.js +269 -0
- package/dist/slices/narration/peaks-model.js +1 -0
- package/dist/slices/narration/peaks.js +94 -0
- package/dist/slices/narration/preparation.js +21 -3
- package/dist/slices/narration/pronunciation-chunks.js +3 -3
- package/dist/slices/narration/pronunciation.js +72 -25
- package/dist/slices/narration/run.js +6 -6
- package/dist/slices/narration/shared-glossary.js +1 -1
- package/dist/slices/narration/steering.js +15 -4
- package/dist/slices/notifications/notifier.js +94 -0
- package/dist/slices/notifications/rules.js +102 -0
- package/dist/slices/notifications/send.js +40 -0
- package/dist/slices/notifications/settings.js +34 -0
- package/dist/slices/onboarding/copy.js +143 -0
- package/dist/slices/onboarding/first-run.js +46 -0
- package/dist/slices/onboarding/install.js +119 -0
- package/dist/slices/onboarding/model.js +64 -0
- package/dist/slices/onboarding/packs.js +491 -0
- package/dist/slices/onboarding/quick-short.js +129 -0
- package/dist/slices/onboarding/sample.js +132 -0
- package/dist/slices/onboarding/state.js +68 -0
- package/dist/slices/onboarding/template.js +73 -0
- package/dist/slices/patch-notes/library.js +73 -0
- package/dist/slices/patch-notes/seen.js +77 -0
- package/dist/slices/play-drafts/convert.js +160 -9
- package/dist/slices/play-drafts/readiness.js +3 -0
- package/dist/slices/play-drafts/repo.js +9 -1
- package/dist/slices/play-drafts/review-inputs.js +22 -3
- package/dist/slices/play-drafts/schema.js +109 -2
- package/dist/slices/play-drafts/service.js +10 -1
- package/dist/slices/play-drafts/start.js +43 -18
- package/dist/slices/play-drafts/uploads.js +2 -1
- package/dist/slices/project-templates/from-project.js +70 -4
- package/dist/slices/project-templates/one-off.js +26 -0
- package/dist/slices/project-templates/repo.js +2 -1
- package/dist/slices/project-templates/service.js +15 -4
- package/dist/slices/project-templates/setup.js +29 -2
- package/dist/slices/rebuild/admission-repo.js +1 -1
- package/dist/slices/rebuild/model.js +6 -0
- package/dist/slices/rebuild/preview-details.js +67 -2
- package/dist/slices/rebuild/preview-plan.js +13 -6
- package/dist/slices/rebuild/recipe-audio-parts.js +40 -7
- package/dist/slices/rebuild/recipe-audio.js +66 -12
- package/dist/slices/rebuild/recipe-build.js +15 -5
- package/dist/slices/rebuild/recipe-cast.js +18 -0
- package/dist/slices/rebuild/recipe-checkpoints.js +11 -9
- package/dist/slices/rebuild/recipe-describe.js +93 -0
- package/dist/slices/rebuild/recipe-edit.js +13 -1
- package/dist/slices/rebuild/recipe-exports.js +62 -8
- package/dist/slices/rebuild/recipe-input-schema.js +43 -1
- package/dist/slices/rebuild/recipe-legacy.js +12 -0
- package/dist/slices/rebuild/recipe-loudness.js +45 -0
- package/dist/slices/rebuild/recipe-model.js +25 -6
- package/dist/slices/rebuild/recipe-pauses.js +7 -0
- package/dist/slices/rebuild/recipe-preparation.js +3 -3
- package/dist/slices/rebuild/recipe-provider-choice.js +11 -1
- package/dist/slices/rebuild/recipe-reference.js +58 -0
- package/dist/slices/rebuild/recipe-reviews.js +117 -0
- package/dist/slices/rebuild/recipe-save.js +4 -1
- package/dist/slices/rebuild/recipe-shorts.js +32 -5
- package/dist/slices/rebuild/recipe-text.js +114 -19
- package/dist/slices/rebuild/recipe-validation.js +29 -3
- package/dist/slices/rebuild/recipe-visual.js +104 -29
- package/dist/slices/rebuild/recipe-voices.js +286 -0
- package/dist/slices/rebuild/recipe-work.js +77 -6
- package/dist/slices/rebuild/recipe-youtube.js +2 -0
- package/dist/slices/rebuild/recovery-conflict.js +7 -3
- package/dist/slices/rebuild/recovery-model.js +3 -0
- package/dist/slices/rebuild/recovery-selection.js +28 -2
- package/dist/slices/rebuild/recovery.js +35 -17
- package/dist/slices/rebuild/repo.js +3 -3
- package/dist/slices/rebuild/retry.js +18 -0
- package/dist/slices/rebuild/review-redo.js +110 -0
- package/dist/slices/rebuild/runtime-actions.js +14 -2
- package/dist/slices/rebuild/runtime-admission.js +4 -1
- package/dist/slices/rebuild/runtime-animate.js +4 -4
- package/dist/slices/rebuild/runtime-article.js +5 -5
- package/dist/slices/rebuild/runtime-document.js +4 -4
- package/dist/slices/rebuild/runtime-export-bed.js +43 -0
- package/dist/slices/rebuild/runtime-export-edit.js +70 -11
- package/dist/slices/rebuild/runtime-export-inputs.js +52 -10
- package/dist/slices/rebuild/runtime-export-short.js +85 -0
- package/dist/slices/rebuild/runtime-export.js +84 -19
- package/dist/slices/rebuild/runtime-figure-card.js +87 -0
- package/dist/slices/rebuild/runtime-image.js +69 -0
- package/dist/slices/rebuild/runtime-local.js +154 -27
- package/dist/slices/rebuild/runtime-materialize.js +8 -0
- package/dist/slices/rebuild/runtime-narration-reuse.js +2 -1
- package/dist/slices/rebuild/runtime-narration-text.js +7 -7
- package/dist/slices/rebuild/runtime-pictures.js +28 -0
- package/dist/slices/rebuild/runtime-piece-label.js +29 -0
- package/dist/slices/rebuild/runtime-provider.js +134 -19
- package/dist/slices/rebuild/runtime-publication.js +21 -5
- package/dist/slices/rebuild/runtime-review.js +237 -0
- package/dist/slices/rebuild/runtime-run.js +17 -11
- package/dist/slices/rebuild/runtime-shorts.js +48 -23
- package/dist/slices/rebuild/runtime-store.js +39 -10
- package/dist/slices/rebuild/runtime-subtitles.js +72 -19
- package/dist/slices/rebuild/runtime-voices.js +103 -0
- package/dist/slices/rebuild/runtime-youtube.js +7 -6
- package/dist/slices/rebuild/service-readiness.js +15 -1
- package/dist/slices/rebuild/soften.js +49 -0
- package/dist/slices/rebuild/transition-repo.js +10 -3
- package/dist/slices/research/run.js +4 -4
- package/dist/slices/research/synthesis.js +2 -2
- package/dist/slices/reviews/model.js +105 -0
- package/dist/slices/reviews/outcome.js +22 -0
- package/dist/slices/reviews/repo.js +106 -0
- package/dist/slices/reviews/rules.js +63 -0
- package/dist/slices/reviews/verdict.js +71 -0
- package/dist/slices/reviews/view.js +30 -0
- package/dist/slices/revisions/adopt-content.js +12 -2
- package/dist/slices/revisions/adopt.js +9 -2
- package/dist/slices/revisions/downloads.js +7 -1
- package/dist/slices/revisions/image-plan.js +183 -0
- package/dist/slices/revisions/mutation-assets.js +43 -9
- package/dist/slices/revisions/mutation-cues.js +71 -0
- package/dist/slices/revisions/mutation-prepare.js +8 -10
- package/dist/slices/revisions/mutation-request.js +2 -1
- package/dist/slices/revisions/mutations.js +97 -3
- package/dist/slices/revisions/schema.js +16 -2
- package/dist/slices/run-cost/limits.js +128 -0
- package/dist/slices/run-cost/meter.js +47 -0
- package/dist/slices/run-cost/panel.js +234 -0
- package/dist/slices/run-cost/pricing.js +92 -0
- package/dist/slices/run-cost/week.js +108 -0
- package/dist/slices/schedules/agenda.js +158 -0
- package/dist/slices/schedules/repo.js +58 -18
- package/dist/slices/schedules/scheduler.js +67 -16
- package/dist/slices/schedules/schema.js +138 -1
- package/dist/slices/schedules/service.js +48 -4
- package/dist/slices/schedules/similar.js +90 -0
- package/dist/slices/schedules/topic-list.js +163 -0
- package/dist/slices/schedules/topics.js +422 -0
- package/dist/slices/settings/first-run.js +102 -0
- package/dist/slices/settings/health.js +190 -0
- package/dist/slices/settings/key-guides.js +128 -0
- package/dist/slices/settings/key-test.js +85 -0
- package/dist/slices/settings/model.js +11 -1
- package/dist/slices/settings/playback.js +15 -0
- package/dist/slices/settings/repo.js +17 -3
- package/dist/slices/settings/voices.js +64 -4
- package/dist/slices/settings/whats-new.js +64 -0
- package/dist/slices/shorts/captions.js +9 -0
- package/dist/slices/shorts/pick.js +3 -3
- package/dist/slices/shorts/prompts.js +1 -1
- package/dist/slices/shorts/render.js +54 -5
- package/dist/slices/storage/asset-name.js +3 -0
- package/dist/slices/storage/backup-export.js +48 -9
- package/dist/slices/storage/backup-format.js +38 -1
- package/dist/slices/storage/backup-import.js +191 -19
- package/dist/slices/storage/delete-project.js +7 -4
- package/dist/slices/storage/documents.js +79 -0
- package/dist/slices/storage/files-location.js +531 -0
- package/dist/slices/storage/layout.js +20 -0
- package/dist/slices/storage/model.js +14 -0
- package/dist/slices/storage/portable.js +95 -12
- package/dist/slices/storage/reconcile.js +19 -2
- package/dist/slices/storage/repo.js +4 -1
- package/dist/slices/storage/schema.js +11 -0
- package/dist/slices/storage/trim.js +146 -0
- package/dist/slices/studio/disclosure.js +74 -0
- package/dist/slices/studio/model.js +28 -0
- package/dist/slices/studio/pack.js +209 -0
- package/dist/slices/studio/settings.js +133 -0
- package/dist/slices/style-preview/images.js +61 -0
- package/dist/slices/style-preview/render.js +161 -0
- package/dist/slices/style-preview/schema.js +45 -0
- package/dist/slices/style-preview/service.js +93 -0
- package/dist/slices/style-preview/settings.js +89 -0
- package/dist/slices/subtitles/captions.js +42 -9
- package/dist/slices/subtitles/model.js +22 -0
- package/dist/slices/subtitles/prepare.js +27 -16
- package/dist/slices/subtitles/transcript.js +1 -1
- package/dist/slices/thumbnail/run.js +7 -7
- package/dist/slices/trash/model.js +25 -0
- package/dist/slices/trash/service.js +273 -0
- package/dist/slices/uploads/repo.js +20 -0
- package/dist/slices/video/ambient-bed-schema.js +15 -0
- package/dist/slices/video/ambient-bed.js +95 -0
- package/dist/slices/video/ambient-mix.js +72 -0
- package/dist/slices/video/audio-inputs.js +2 -2
- package/dist/slices/video/cards.js +5 -2
- package/dist/slices/video/edit-list.js +23 -2
- package/dist/slices/video/edit-settings.js +13 -3
- package/dist/slices/video/ffmpeg.js +63 -9
- package/dist/slices/video/figure-card.js +492 -0
- package/dist/slices/video/figure-spans.js +51 -0
- package/dist/slices/video/plan.js +125 -13
- package/dist/slices/video/run.js +14 -12
- package/dist/slices/video/slideshow.js +39 -4
- package/dist/slices/voices/attribution.js +69 -0
- package/dist/slices/voices/audio-files.js +82 -0
- package/dist/slices/voices/audition.js +25 -0
- package/dist/slices/voices/cast.js +56 -0
- package/dist/slices/voices/grouping.js +49 -0
- package/dist/slices/voices/join.js +35 -0
- package/dist/slices/voices/languages.js +25 -0
- package/dist/slices/voices/model.js +179 -0
- package/dist/slices/voices/palette.js +26 -0
- package/dist/slices/voices/panel.js +91 -0
- package/dist/slices/voices/portraits.js +55 -0
- package/dist/slices/voices/script.js +136 -0
- package/dist/slices/voices/timing.js +58 -0
- package/dist/slices/youtube/answer.js +1 -1
- package/dist/slices/youtube/chapters.js +126 -0
- package/dist/slices/youtube/edits-repo.js +69 -0
- package/dist/slices/youtube/edits.js +89 -0
- package/dist/slices/youtube/placeholders.js +98 -0
- package/dist/slices/youtube/transcript.js +11 -4
- package/dist/updater/service.js +66 -21
- package/dist/web/assets/index-CUA2sUxU.css +1 -0
- package/dist/web/assets/index-CX590kE-.js +303 -0
- package/dist/web/assets/jetbrains-mono-cyrillic-400-normal-BEIGL1Tu.woff2 +0 -0
- package/dist/web/assets/jetbrains-mono-cyrillic-400-normal-ugxPyKxw.woff +0 -0
- package/dist/web/assets/jetbrains-mono-greek-400-normal-B9oWc5Lo.woff +0 -0
- package/dist/web/assets/jetbrains-mono-greek-400-normal-C190GLew.woff2 +0 -0
- package/dist/web/assets/jetbrains-mono-latin-400-normal-6-qcROiO.woff +0 -0
- package/dist/web/assets/jetbrains-mono-latin-400-normal-V6pRDFza.woff2 +0 -0
- package/dist/web/assets/jetbrains-mono-latin-ext-400-normal-Bc8Ftmh3.woff2 +0 -0
- package/dist/web/assets/jetbrains-mono-latin-ext-400-normal-fXTG6kC5.woff +0 -0
- package/dist/web/assets/jetbrains-mono-vietnamese-400-normal-CqNFfHCs.woff +0 -0
- package/dist/web/assets/{pdf-CAJNT254.js → pdf-BG8n_uc5.js} +1 -1
- package/dist/web/index.html +2 -2
- package/package.json +4 -4
- package/dist/edge/docker-launch.js +0 -81
- package/dist/edge/docker-projects/activation.js +0 -35
- package/dist/edge/docker-projects/claims.js +0 -85
- package/dist/edge/docker-projects/committed.js +0 -40
- package/dist/edge/docker-projects/engine.js +0 -461
- package/dist/edge/docker-projects/install.js +0 -254
- package/dist/edge/docker-projects/prune.js +0 -66
- package/dist/edge/docker-projects/recover.js +0 -100
- package/dist/edge/docker-projects/state.js +0 -225
- package/dist/web/assets/index-BGgYMm2u.css +0 -1
- package/dist/web/assets/index-BVVgtntL.js +0 -171
- package/scripts/docker-run.sh +0 -3
- /package/dist/edge/{docker-projects → docker-install}/tree.js +0 -0
package/LICENSE
CHANGED
|
@@ -1,21 +1,201 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
1
|
+
Apache License
|
|
2
|
+
Version 2.0, January 2004
|
|
3
|
+
http://www.apache.org/licenses/
|
|
4
|
+
|
|
5
|
+
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
|
6
|
+
|
|
7
|
+
1. Definitions.
|
|
8
|
+
|
|
9
|
+
"License" shall mean the terms and conditions for use, reproduction,
|
|
10
|
+
and distribution as defined by Sections 1 through 9 of this document.
|
|
11
|
+
|
|
12
|
+
"Licensor" shall mean the copyright owner or entity authorized by
|
|
13
|
+
the copyright owner that is granting the License.
|
|
14
|
+
|
|
15
|
+
"Legal Entity" shall mean the union of the acting entity and all
|
|
16
|
+
other entities that control, are controlled by, or are under common
|
|
17
|
+
control with that entity. For the purposes of this definition,
|
|
18
|
+
"control" means (i) the power, direct or indirect, to cause the
|
|
19
|
+
direction or management of such entity, whether by contract or
|
|
20
|
+
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
|
21
|
+
outstanding shares, or (iii) beneficial ownership of such entity.
|
|
22
|
+
|
|
23
|
+
"You" (or "Your") shall mean an individual or Legal Entity
|
|
24
|
+
exercising permissions granted by this License.
|
|
25
|
+
|
|
26
|
+
"Source" form shall mean the preferred form for making modifications,
|
|
27
|
+
including but not limited to software source code, documentation
|
|
28
|
+
source, and configuration files.
|
|
29
|
+
|
|
30
|
+
"Object" form shall mean any form resulting from mechanical
|
|
31
|
+
transformation or translation of a Source form, including but
|
|
32
|
+
not limited to compiled object code, generated documentation,
|
|
33
|
+
and conversions to other media types.
|
|
34
|
+
|
|
35
|
+
"Work" shall mean the work of authorship, whether in Source or
|
|
36
|
+
Object form, made available under the License, as indicated by a
|
|
37
|
+
copyright notice that is included in or attached to the work
|
|
38
|
+
(an example is provided in the Appendix below).
|
|
39
|
+
|
|
40
|
+
"Derivative Works" shall mean any work, whether in Source or Object
|
|
41
|
+
form, that is based on (or derived from) the Work and for which the
|
|
42
|
+
editorial revisions, annotations, elaborations, or other modifications
|
|
43
|
+
represent, as a whole, an original work of authorship. For the purposes
|
|
44
|
+
of this License, Derivative Works shall not include works that remain
|
|
45
|
+
separable from, or merely link (or bind by name) to the interfaces of,
|
|
46
|
+
the Work and Derivative Works thereof.
|
|
47
|
+
|
|
48
|
+
"Contribution" shall mean any work of authorship, including
|
|
49
|
+
the original version of the Work and any modifications or additions
|
|
50
|
+
to that Work or Derivative Works thereof, that is intentionally
|
|
51
|
+
submitted to Licensor for inclusion in the Work by the copyright owner
|
|
52
|
+
or by an individual or Legal Entity authorized to submit on behalf of
|
|
53
|
+
the copyright owner. For the purposes of this definition, "submitted"
|
|
54
|
+
means any form of electronic, verbal, or written communication sent
|
|
55
|
+
to the Licensor or its representatives, including but not limited to
|
|
56
|
+
communication on electronic mailing lists, source code control systems,
|
|
57
|
+
and issue tracking systems that are managed by, or on behalf of, the
|
|
58
|
+
Licensor for the purpose of discussing and improving the Work, but
|
|
59
|
+
excluding communication that is conspicuously marked or otherwise
|
|
60
|
+
designated in writing by the copyright owner as "Not a Contribution."
|
|
61
|
+
|
|
62
|
+
"Contributor" shall mean Licensor and any individual or Legal Entity
|
|
63
|
+
on behalf of whom a Contribution has been received by Licensor and
|
|
64
|
+
subsequently incorporated within the Work.
|
|
65
|
+
|
|
66
|
+
2. Grant of Copyright License. Subject to the terms and conditions of
|
|
67
|
+
this License, each Contributor hereby grants to You a perpetual,
|
|
68
|
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
69
|
+
copyright license to reproduce, prepare Derivative Works of,
|
|
70
|
+
publicly display, publicly perform, sublicense, and distribute the
|
|
71
|
+
Work and such Derivative Works in Source or Object form.
|
|
72
|
+
|
|
73
|
+
3. Grant of Patent License. Subject to the terms and conditions of
|
|
74
|
+
this License, each Contributor hereby grants to You a perpetual,
|
|
75
|
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
76
|
+
(except as stated in this section) patent license to make, have made,
|
|
77
|
+
use, offer to sell, sell, import, and otherwise transfer the Work,
|
|
78
|
+
where such license applies only to those patent claims licensable
|
|
79
|
+
by such Contributor that are necessarily infringed by their
|
|
80
|
+
Contribution(s) alone or by combination of their Contribution(s)
|
|
81
|
+
with the Work to which such Contribution(s) was submitted. If You
|
|
82
|
+
institute patent litigation against any entity (including a
|
|
83
|
+
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
|
84
|
+
or a Contribution incorporated within the Work constitutes direct
|
|
85
|
+
or contributory patent infringement, then any patent licenses
|
|
86
|
+
granted to You under this License for that Work shall terminate
|
|
87
|
+
as of the date such litigation is filed.
|
|
88
|
+
|
|
89
|
+
4. Redistribution. You may reproduce and distribute copies of the
|
|
90
|
+
Work or Derivative Works thereof in any medium, with or without
|
|
91
|
+
modifications, and in Source or Object form, provided that You
|
|
92
|
+
meet the following conditions:
|
|
93
|
+
|
|
94
|
+
(a) You must give any other recipients of the Work or
|
|
95
|
+
Derivative Works a copy of this License; and
|
|
96
|
+
|
|
97
|
+
(b) You must cause any modified files to carry prominent notices
|
|
98
|
+
stating that You changed the files; and
|
|
99
|
+
|
|
100
|
+
(c) You must retain, in the Source form of any Derivative Works
|
|
101
|
+
that You distribute, all copyright, patent, trademark, and
|
|
102
|
+
attribution notices from the Source form of the Work,
|
|
103
|
+
excluding those notices that do not pertain to any part of
|
|
104
|
+
the Derivative Works; and
|
|
105
|
+
|
|
106
|
+
(d) If the Work includes a "NOTICE" text file as part of its
|
|
107
|
+
distribution, then any Derivative Works that You distribute must
|
|
108
|
+
include a readable copy of the attribution notices contained
|
|
109
|
+
within such NOTICE file, excluding those notices that do not
|
|
110
|
+
pertain to any part of the Derivative Works, in at least one
|
|
111
|
+
of the following places: within a NOTICE text file distributed
|
|
112
|
+
as part of the Derivative Works; within the Source form or
|
|
113
|
+
documentation, if provided along with the Derivative Works; or,
|
|
114
|
+
within a display generated by the Derivative Works, if and
|
|
115
|
+
wherever such third-party notices normally appear. The contents
|
|
116
|
+
of the NOTICE file are for informational purposes only and
|
|
117
|
+
do not modify the License. You may add Your own attribution
|
|
118
|
+
notices within Derivative Works that You distribute, alongside
|
|
119
|
+
or as an addendum to the NOTICE text from the Work, provided
|
|
120
|
+
that such additional attribution notices cannot be construed
|
|
121
|
+
as modifying the License.
|
|
122
|
+
|
|
123
|
+
You may add Your own copyright statement to Your modifications and
|
|
124
|
+
may provide additional or different license terms and conditions
|
|
125
|
+
for use, reproduction, or distribution of Your modifications, or
|
|
126
|
+
for any such Derivative Works as a whole, provided Your use,
|
|
127
|
+
reproduction, and distribution of the Work otherwise complies with
|
|
128
|
+
the conditions stated in this License.
|
|
129
|
+
|
|
130
|
+
5. Submission of Contributions. Unless You explicitly state otherwise,
|
|
131
|
+
any Contribution intentionally submitted for inclusion in the Work
|
|
132
|
+
by You to the Licensor shall be under the terms and conditions of
|
|
133
|
+
this License, without any additional terms or conditions.
|
|
134
|
+
Notwithstanding the above, nothing herein shall supersede or modify
|
|
135
|
+
the terms of any separate license agreement you may have executed
|
|
136
|
+
with Licensor regarding such Contributions.
|
|
137
|
+
|
|
138
|
+
6. Trademarks. This License does not grant permission to use the trade
|
|
139
|
+
names, trademarks, service marks, or product names of the Licensor,
|
|
140
|
+
except as required for reasonable and customary use in describing the
|
|
141
|
+
origin of the Work and reproducing the content of the NOTICE file.
|
|
142
|
+
|
|
143
|
+
7. Disclaimer of Warranty. Unless required by applicable law or
|
|
144
|
+
agreed to in writing, Licensor provides the Work (and each
|
|
145
|
+
Contributor provides its Contributions) on an "AS IS" BASIS,
|
|
146
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
|
147
|
+
implied, including, without limitation, any warranties or conditions
|
|
148
|
+
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
|
149
|
+
PARTICULAR PURPOSE. You are solely responsible for determining the
|
|
150
|
+
appropriateness of using or redistributing the Work and assume any
|
|
151
|
+
risks associated with Your exercise of permissions under this License.
|
|
152
|
+
|
|
153
|
+
8. Limitation of Liability. In no event and under no legal theory,
|
|
154
|
+
whether in tort (including negligence), contract, or otherwise,
|
|
155
|
+
unless required by applicable law (such as deliberate and grossly
|
|
156
|
+
negligent acts) or agreed to in writing, shall any Contributor be
|
|
157
|
+
liable to You for damages, including any direct, indirect, special,
|
|
158
|
+
incidental, or consequential damages of any character arising as a
|
|
159
|
+
result of this License or out of the use or inability to use the
|
|
160
|
+
Work (including but not limited to damages for loss of goodwill,
|
|
161
|
+
work stoppage, computer failure or malfunction, or any and all
|
|
162
|
+
other commercial damages or losses), even if such Contributor
|
|
163
|
+
has been advised of the possibility of such damages.
|
|
164
|
+
|
|
165
|
+
9. Accepting Warranty or Additional Liability. While redistributing
|
|
166
|
+
the Work or Derivative Works thereof, You may choose to offer,
|
|
167
|
+
and charge a fee for, acceptance of support, warranty, indemnity,
|
|
168
|
+
or other liability obligations and/or rights consistent with this
|
|
169
|
+
License. However, in accepting such obligations, You may act only
|
|
170
|
+
on Your own behalf and on Your sole responsibility, not on behalf
|
|
171
|
+
of any other Contributor, and only if You agree to indemnify,
|
|
172
|
+
defend, and hold each Contributor harmless for any liability
|
|
173
|
+
incurred by, or claims asserted against, such Contributor by reason
|
|
174
|
+
of your accepting any such warranty or additional liability.
|
|
175
|
+
|
|
176
|
+
END OF TERMS AND CONDITIONS
|
|
177
|
+
|
|
178
|
+
APPENDIX: How to apply the Apache License to your work.
|
|
179
|
+
|
|
180
|
+
To apply the Apache License to your work, attach the following
|
|
181
|
+
boilerplate notice, with the fields enclosed by brackets "[]"
|
|
182
|
+
replaced with your own identifying information. (Don't include
|
|
183
|
+
the brackets!) The text should be enclosed in the appropriate
|
|
184
|
+
comment syntax for the file format. We also recommend that a
|
|
185
|
+
file or class name and description of purpose be included on the
|
|
186
|
+
same "printed page" as the copyright notice for easier
|
|
187
|
+
identification within third-party archives.
|
|
188
|
+
|
|
189
|
+
Copyright 2026 Gent Bajko
|
|
190
|
+
|
|
191
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
192
|
+
you may not use this file except in compliance with the License.
|
|
193
|
+
You may obtain a copy of the License at
|
|
194
|
+
|
|
195
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
196
|
+
|
|
197
|
+
Unless required by applicable law or agreed to in writing, software
|
|
198
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
199
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
200
|
+
See the License for the specific language governing permissions and
|
|
201
|
+
limitations under the License.
|
package/NOTICE
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
Slopify
|
|
2
|
+
Copyright 2026 Gent Bajko
|
|
3
|
+
https://github.com/GentBajko/slopify
|
|
4
|
+
|
|
5
|
+
This product includes software developed by Gent Bajko as Slopify.
|
|
6
|
+
|
|
7
|
+
Under section 4(d) of the Apache License 2.0, any distribution of this software or a
|
|
8
|
+
derivative of it must include a readable copy of this NOTICE, for example in its
|
|
9
|
+
documentation or an "About" or credits screen.
|
|
10
|
+
|
|
11
|
+
The Slopify name and logo are not licensed under the Apache License (section 6):
|
|
12
|
+
a fork or derivative must use a name of its own and not present itself as Slopify.
|
package/README.md
CHANGED
|
@@ -30,42 +30,22 @@ slopify
|
|
|
30
30
|
|
|
31
31
|
Both commands launch the same local app.
|
|
32
32
|
|
|
33
|
-
For Docker on Linux with Node 26
|
|
34
|
-
`npx @gentbajko/slopify@latest --docker`.
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
is omitted. `--port 7070` changes the localhost port. Custom installations sharing
|
|
50
|
-
a machine need distinct `SLOPIFY_DOCKER_NAME` and `SLOPIFY_DOCKER_VOLUME` values.
|
|
51
|
-
Do not store unrelated documents in the managed Projects tree: storage
|
|
52
|
-
reconciliation owns it. Moving to another folder performs a verified copy;
|
|
53
|
-
existing unrelated contents are never merged or overwritten.
|
|
54
|
-
|
|
55
|
-
Existing installations are stopped, copied and verified before the new folder
|
|
56
|
-
is activated. Current and historical output actions show the real host folder
|
|
57
|
-
on the machine running Slopify; downloads remain available. This also works with
|
|
58
|
-
`--host-cli=off`, without installing a host helper. Docker does not open a desktop
|
|
59
|
-
window on your browser's machine.
|
|
60
|
-
|
|
61
|
-
Rerun the launcher after changing host CLI installations or search paths.
|
|
62
|
-
Plain `docker run` is API-only unless connected to an already configured helper.
|
|
63
|
-
It does not set up a host project folder or install host services; its files stay
|
|
64
|
-
in the private named volume. Use the managed launcher for automatic migration
|
|
65
|
-
and host-folder access. Use `--host-cli=off` for API-only launcher setup, or
|
|
66
|
-
`--accept-host-cli` to approve non-interactive setup.
|
|
67
|
-
See the [Docker setup guide](https://github.com/GentBajko/slopify#docker) for
|
|
68
|
-
updates and the dedicated helper's status/disable commands.
|
|
33
|
+
For Docker on Linux with Node 26+, Docker Engine and the Docker Compose plugin, use
|
|
34
|
+
`slopify --docker` or `npx @gentbajko/slopify@latest --docker`. It writes one
|
|
35
|
+
`compose.yaml` and its `.env` under `~/.local/share/slopify/docker/slopify/` and starts
|
|
36
|
+
Slopify at `http://127.0.0.1:6969`, restarting with Docker. Project files go to
|
|
37
|
+
`~/Slopify/Projects` (`--projects-dir` to choose another, `--port` for the port); the
|
|
38
|
+
database, keys and logs stay private in the `slopify-data` volume.
|
|
39
|
+
|
|
40
|
+
If Claude Code, Codex or Gemini is installed, it asks once before setting up the host CLI
|
|
41
|
+
bridge, a private helper that runs those CLIs on your machine with their existing logins.
|
|
42
|
+
Use `--host-cli=off` for API keys only, or `--accept-host-cli` to approve without a prompt.
|
|
43
|
+
|
|
44
|
+
Update with `npx @gentbajko/slopify@latest update`, Docker or not. It waits for running
|
|
45
|
+
work, keeps a copy to go back to (the database, or a recovery volume in Docker), and puts
|
|
46
|
+
the previous version back if the new one doesn't start. Installations made by 2.5.0 or
|
|
47
|
+
earlier are taken over as they are: same volume, same project folder. See the
|
|
48
|
+
[Docker guide](https://github.com/GentBajko/slopify/blob/main/docs/docker.md) for details.
|
|
69
49
|
|
|
70
50
|
## How to use it
|
|
71
51
|
|
|
@@ -110,14 +90,15 @@ for account limits. Both model IDs are bundled; Inworld's LLM catalogue does not
|
|
|
110
90
|
| `--data-dir` | `SLOPIFY_DATA_DIR` | `~/.slopify` |
|
|
111
91
|
| `--projects-dir` (Docker only) | `SLOPIFY_DOCKER_PROJECTS_DIR` | remembered path; otherwise `~/Slopify/Projects` (custom names: `~/Slopify/<container>/Projects`) |
|
|
112
92
|
| `--no-open` | `SLOPIFY_NO_OPEN` | the browser opens |
|
|
113
|
-
| `--docker` | — | run locally; with the flag,
|
|
93
|
+
| `--docker` | — | run locally; with the flag, install or update the Docker version |
|
|
94
|
+
| `update` | — | update the running app, or the Docker installation if you have one |
|
|
114
95
|
| — | `SLOPIFY_FFMPEG` | the bundled binary |
|
|
115
96
|
|
|
116
97
|
There is no login. Binding to anything but `127.0.0.1` hands the app and every key in
|
|
117
98
|
it to whoever reaches the port, and the CLI says so on startup.
|
|
118
99
|
|
|
119
100
|
Native installations keep `slopify.db`, `projects/`, `staging/` and `logs/` under
|
|
120
|
-
their configured data directory.
|
|
101
|
+
their configured data directory. Docker places only projects in its
|
|
121
102
|
remembered host folder; keep both that folder and the named private volume when
|
|
122
103
|
backing up an installation. The portable settings archive is not a project/history backup.
|
|
123
104
|
|
|
@@ -136,7 +117,7 @@ That binary is a separate program, run as a child process with an argument array
|
|
|
136
117
|
is licensed under the **GPL-3.0-or-later**. Slopify does not link against it, does not
|
|
137
118
|
embed it, and does not distribute it inside this package; its licence text and the
|
|
138
119
|
location of its corresponding source ship beside it in `ffmpeg-static`. Slopify's own
|
|
139
|
-
code is
|
|
120
|
+
code is Apache-2.0 and stays Apache-2.0. Anyone redistributing the downloaded binary takes on the
|
|
140
121
|
GPL's obligations for it, including offering that corresponding source.
|
|
141
122
|
|
|
142
123
|
Point `SLOPIFY_FFMPEG` at your own build to use that instead.
|
|
@@ -168,7 +149,7 @@ in [SUPPORTERS.md](https://github.com/GentBajko/slopify/blob/main/SUPPORTERS.md)
|
|
|
168
149
|
|
|
169
150
|
## Licence
|
|
170
151
|
|
|
171
|
-
|
|
152
|
+
Apache-2.0 (see LICENSE and NOTICE; keep the NOTICE when redistributing). The ffmpeg binary fetched at install time is a separate GPL-3.0-or-later program,
|
|
172
153
|
as described above.
|
|
173
154
|
|
|
174
155
|
Source, issues and the full guide: <https://github.com/GentBajko/slopify>
|
package/SUBTITLES.md
CHANGED
|
@@ -10,7 +10,7 @@ For a completed project, open its final Video or Audio export section, set subti
|
|
|
10
10
|
|
|
11
11
|
If narration omits a short phrase, alignment can skip that transcript span when the surrounding speech is a strong match, including omissions inside an alignment window. The export records the omitted text and audio position for review. Recovery stays bounded and never recreates missing speech.
|
|
12
12
|
|
|
13
|
-
Audio Off disables subtitles. Video Off produces WAV audio with separate subtitle files. Uploaded audio must match the article; substantial mismatches fail with a message to correct the transcript. Review timing and spelling before publishing. English
|
|
13
|
+
Audio Off disables subtitles. Video Off produces WAV audio with separate subtitle files. Uploaded audio must match the article; substantial mismatches fail with a message to correct the transcript. Review timing and spelling before publishing. English, Spanish, German, French, Italian, Portuguese, Dutch, Catalan, Polish and Czech are timed word by word (the other nine with a separate 248 MB multilingual model, downloaded on first use into `<data-dir>/models/multilingual-subtitles/`, about 1.1 GB of memory while aligning); other project languages are timed sentence by sentence. See docs/multilingual-timing.md. Unusual pronunciations and passages in another language than the project's can fail alignment.
|
|
14
14
|
|
|
15
15
|
Fonts are copied into the completed project's caption assets, so an existing export can reuse its chosen font even after the original system font is removed. Installed fonts and uploaded fonts stay local. SRT/VTT are portable text/timing files and do not embed a font; the chosen font is used in burned video captions.
|
|
16
16
|
|
package/dist/adapter-registry.js
CHANGED
|
@@ -6,6 +6,7 @@ import { replicateImage } from "./adapters/image/replicate.js";
|
|
|
6
6
|
import { claudeCodeLlm } from "./adapters/llm/claude-code.js";
|
|
7
7
|
import { nodeClaudeCodeModels } from "./adapters/llm/claude-code-models.js";
|
|
8
8
|
import { codexLlm } from "./adapters/llm/codex.js";
|
|
9
|
+
import { nodeCodexLimits } from "./adapters/llm/codex-limits.js";
|
|
9
10
|
import { nodeCodexModels } from "./adapters/llm/codex-models.js";
|
|
10
11
|
import { geminiLlm } from "./adapters/llm/gemini.js";
|
|
11
12
|
import { nodeGeminiModels } from "./adapters/llm/gemini-models.js";
|
|
@@ -43,6 +44,7 @@ export function buildRegistry(deps) {
|
|
|
43
44
|
codexLlm({
|
|
44
45
|
run: cliFor("codex"),
|
|
45
46
|
readModels: () => nodeCodexModels(process.env, cliBinary(deps.db, "codex")),
|
|
47
|
+
readLimits: () => nodeCodexLimits(cliBinary(deps.db, "codex"), process.env),
|
|
46
48
|
}),
|
|
47
49
|
],
|
|
48
50
|
[
|
|
@@ -73,7 +75,15 @@ export function buildRegistry(deps) {
|
|
|
73
75
|
],
|
|
74
76
|
["openai-image", openAiImage({ fetch: deps.fetch, key: keyOf("openai-image") })],
|
|
75
77
|
["google-image", googleImage({ fetch: deps.fetch, key: keyOf("google-image") })],
|
|
76
|
-
[
|
|
78
|
+
[
|
|
79
|
+
"codex-image",
|
|
80
|
+
codexImage({
|
|
81
|
+
run: cliFor("codex"),
|
|
82
|
+
// The same list, and so the same models and efforts, as the Codex text provider.
|
|
83
|
+
readModels: () => nodeCodexModels(process.env, cliBinary(deps.db, "codex")),
|
|
84
|
+
readLimits: () => nodeCodexLimits(cliBinary(deps.db, "codex"), process.env),
|
|
85
|
+
}),
|
|
86
|
+
],
|
|
77
87
|
]);
|
|
78
88
|
if (deps.hostCli) {
|
|
79
89
|
for (const id of hostLlmIds)
|
|
@@ -48,7 +48,10 @@ async function downloadModel(input, deps, target) {
|
|
|
48
48
|
let response;
|
|
49
49
|
try {
|
|
50
50
|
response = await deps.fetch(deps.model.url, {
|
|
51
|
-
signal: AbortSignal.any([
|
|
51
|
+
signal: AbortSignal.any([
|
|
52
|
+
input.signal,
|
|
53
|
+
AbortSignal.timeout(deps.model.timeoutMs ?? 300_000),
|
|
54
|
+
]),
|
|
52
55
|
});
|
|
53
56
|
}
|
|
54
57
|
catch (error) {
|
|
@@ -1,16 +1,17 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { englishMismatch, englishSpec } from "./spec.js";
|
|
2
2
|
export const frameSeconds = 0.02;
|
|
3
|
-
export const mismatch =
|
|
4
|
-
export function alignWindow(logits, frames, words, complete) {
|
|
5
|
-
|
|
3
|
+
export const mismatch = englishMismatch;
|
|
4
|
+
export function alignWindow(logits, frames, words, complete, spec = englishSpec) {
|
|
5
|
+
const labels = spec.labels;
|
|
6
|
+
if (frames < 1 || frames > 1100 || logits.length !== frames * labels)
|
|
6
7
|
throw new Error("The subtitle alignment window exceeds its safe size.");
|
|
7
|
-
const tokens = tokenize(words);
|
|
8
|
+
const tokens = tokenize(words, spec);
|
|
8
9
|
if (tokens.ids.length === 0 || tokens.ids.length > 1500)
|
|
9
10
|
throw new Error("The subtitle transcript window exceeds its safe size.");
|
|
10
11
|
const states = [0];
|
|
11
12
|
for (const id of tokens.ids)
|
|
12
13
|
states.push(id, 0);
|
|
13
|
-
const probabilities = logSoftmax(logits, frames);
|
|
14
|
+
const probabilities = logSoftmax(logits, frames, labels);
|
|
14
15
|
const width = states.length;
|
|
15
16
|
const back = new Uint8Array(frames * width);
|
|
16
17
|
let previous = new Float32Array(width).fill(-Infinity);
|
|
@@ -31,32 +32,33 @@ export function alignWindow(logits, frames, words, complete) {
|
|
|
31
32
|
score = previous[state - 2] ?? -Infinity;
|
|
32
33
|
step = 2;
|
|
33
34
|
}
|
|
34
|
-
current[state] = score + (probabilities[frame *
|
|
35
|
+
current[state] = score + (probabilities[frame * labels + (states[state] ?? 0)] ?? -Infinity);
|
|
35
36
|
back[frame * width + state] = step;
|
|
36
37
|
}
|
|
37
38
|
previous = current;
|
|
38
39
|
}
|
|
39
40
|
const state = endState(previous, tokens, complete);
|
|
40
41
|
if (!Number.isFinite(previous[state]))
|
|
41
|
-
throw new Error(mismatch);
|
|
42
|
-
const traced = trace(back, states, tokens, words, probabilities, frames, state);
|
|
42
|
+
throw new Error(spec.mismatch);
|
|
43
|
+
const traced = trace(back, states, tokens, words, probabilities, frames, state, labels);
|
|
43
44
|
if (traced.length === 0)
|
|
44
|
-
throw new Error(mismatch);
|
|
45
|
+
throw new Error(spec.mismatch);
|
|
45
46
|
const confidence = traced.reduce((sum, word) => sum + (word.confidence ?? 0), 0) / traced.length;
|
|
46
|
-
const
|
|
47
|
-
|
|
48
|
-
|
|
47
|
+
const { gates } = spec;
|
|
48
|
+
const poor = traced.filter((word) => (word.confidence ?? 0) < gates.poorScore).length / traced.length;
|
|
49
|
+
if (confidence < gates.meanPosterior || poor > gates.poorShare)
|
|
50
|
+
throw new Error(spec.mismatch);
|
|
49
51
|
return { words: traced, confidence };
|
|
50
52
|
}
|
|
51
|
-
function tokenize(words) {
|
|
53
|
+
function tokenize(words, spec) {
|
|
52
54
|
const ids = [], owners = [], ends = [];
|
|
53
55
|
for (const [index, word] of words.entries()) {
|
|
54
56
|
if (index > 0) {
|
|
55
|
-
ids.push(
|
|
57
|
+
ids.push(spec.delimiter);
|
|
56
58
|
owners.push(-1);
|
|
57
59
|
}
|
|
58
60
|
for (const letter of word.spoken.replaceAll(" ", "|")) {
|
|
59
|
-
const id =
|
|
61
|
+
const id = spec.ids[letter];
|
|
60
62
|
if (id !== undefined) {
|
|
61
63
|
ids.push(id);
|
|
62
64
|
owners.push(index);
|
|
@@ -80,7 +82,7 @@ function endState(scores, tokens, complete) {
|
|
|
80
82
|
}
|
|
81
83
|
return best;
|
|
82
84
|
}
|
|
83
|
-
function trace(back, states, tokens, words, probabilities, frames, finalState) {
|
|
85
|
+
function trace(back, states, tokens, words, probabilities, frames, finalState, labels) {
|
|
84
86
|
const found = words.map((word) => ({
|
|
85
87
|
text: word.text,
|
|
86
88
|
start: Infinity,
|
|
@@ -96,7 +98,7 @@ function trace(back, states, tokens, words, probabilities, frames, finalState) {
|
|
|
96
98
|
if (word !== undefined) {
|
|
97
99
|
word.start = Math.min(word.start, frame * frameSeconds);
|
|
98
100
|
word.end = Math.max(word.end, (frame + 1) * frameSeconds);
|
|
99
|
-
word.score += Math.exp(probabilities[frame *
|
|
101
|
+
word.score += Math.exp(probabilities[frame * labels + (states[state] ?? 0)] ?? -Infinity);
|
|
100
102
|
word.count += 1;
|
|
101
103
|
}
|
|
102
104
|
}
|
|
@@ -110,18 +112,18 @@ function trace(back, states, tokens, words, probabilities, frames, finalState) {
|
|
|
110
112
|
];
|
|
111
113
|
});
|
|
112
114
|
}
|
|
113
|
-
function logSoftmax(logits, frames) {
|
|
115
|
+
function logSoftmax(logits, frames, labels) {
|
|
114
116
|
const result = new Float32Array(logits.length);
|
|
115
117
|
for (let frame = 0; frame < frames; frame += 1) {
|
|
116
|
-
const offset = frame *
|
|
118
|
+
const offset = frame * labels;
|
|
117
119
|
let max = -Infinity;
|
|
118
|
-
for (let label = 0; label <
|
|
120
|
+
for (let label = 0; label < labels; label += 1)
|
|
119
121
|
max = Math.max(max, logits[offset + label] ?? -Infinity);
|
|
120
122
|
let sum = 0;
|
|
121
|
-
for (let label = 0; label <
|
|
123
|
+
for (let label = 0; label < labels; label += 1)
|
|
122
124
|
sum += Math.exp((logits[offset + label] ?? -Infinity) - max);
|
|
123
125
|
const divisor = max + Math.log(sum);
|
|
124
|
-
for (let label = 0; label <
|
|
126
|
+
for (let label = 0; label < labels; label += 1)
|
|
125
127
|
result[offset + label] = (logits[offset + label] ?? -Infinity) - divisor;
|
|
126
128
|
}
|
|
127
129
|
return result;
|
|
@@ -1,13 +1,18 @@
|
|
|
1
|
-
import { mkdir, mkdtemp, rm } from "node:fs/promises";
|
|
1
|
+
import { mkdir, mkdtemp, readFile, rm } from "node:fs/promises";
|
|
2
2
|
import { join } from "node:path";
|
|
3
|
+
import { languageInfo } from "../../kernel/ports/languages.js";
|
|
3
4
|
import { decodeAudio } from "./audio.js";
|
|
4
|
-
import { prepareModel } from "./cache.js";
|
|
5
|
+
import { alignmentModel, prepareModel } from "./cache.js";
|
|
5
6
|
import { claimWorker } from "./lock.js";
|
|
7
|
+
import { alignmentSpecFor, multilingualModel } from "./multilingual.js";
|
|
6
8
|
import { runAlignmentWorker } from "./runner.js";
|
|
7
|
-
import {
|
|
9
|
+
import { sentenceTiming, speechShape } from "./sentences.js";
|
|
8
10
|
export const alignSubtitles = async (request) => {
|
|
9
11
|
request.signal.throwIfAborted();
|
|
10
|
-
|
|
12
|
+
if (languageInfo(request.language).timing === "sentences")
|
|
13
|
+
return timeSentences(request);
|
|
14
|
+
const english = request.language === undefined || request.language === "en";
|
|
15
|
+
alignmentSpecFor(request.language).words(request.text, "", request.aliases ?? []);
|
|
11
16
|
await mkdir(request.cacheDir, { recursive: true, mode: 0o700 });
|
|
12
17
|
const release = await claimWorker(request.cacheDir, request.signal);
|
|
13
18
|
try {
|
|
@@ -15,14 +20,20 @@ export const alignSubtitles = async (request) => {
|
|
|
15
20
|
cacheDir: request.cacheDir,
|
|
16
21
|
signal: request.signal,
|
|
17
22
|
onProgress: (current, total) => request.onProgress?.(Math.round((current / total) * 20), 100),
|
|
18
|
-
});
|
|
23
|
+
}, { model: english ? alignmentModel : multilingualModel, fetch: globalThis.fetch });
|
|
19
24
|
request.onProgress?.(20, 100);
|
|
20
25
|
const working = await mkdtemp(join(request.cacheDir, ".alignment-audio-"));
|
|
21
26
|
try {
|
|
22
27
|
const pcmPath = join(working, "audio.f32");
|
|
23
28
|
await decodeAudio(request.ffmpeg, request.audioPath, pcmPath, request.signal);
|
|
24
29
|
request.onProgress?.(25, 100);
|
|
25
|
-
return await runAlignmentWorker({
|
|
30
|
+
return await runAlignmentWorker({
|
|
31
|
+
modelPath,
|
|
32
|
+
pcmPath,
|
|
33
|
+
text: request.text,
|
|
34
|
+
...(english ? {} : { language: request.language }),
|
|
35
|
+
...(request.aliases?.length ? { aliases: [...request.aliases] } : {}),
|
|
36
|
+
}, request.signal, (current, total) => request.onProgress?.(25 + Math.round((current / total) * 75), 100), undefined, request.onOmission);
|
|
26
37
|
}
|
|
27
38
|
finally {
|
|
28
39
|
await rm(working, { recursive: true, force: true });
|
|
@@ -32,3 +43,23 @@ export const alignSubtitles = async (request) => {
|
|
|
32
43
|
await release();
|
|
33
44
|
}
|
|
34
45
|
};
|
|
46
|
+
// No model and no download: the narration's loudness says where it pauses, and the sentences
|
|
47
|
+
// are laid over it (`sentences.ts`).
|
|
48
|
+
async function timeSentences(request) {
|
|
49
|
+
await mkdir(request.cacheDir, { recursive: true, mode: 0o700 });
|
|
50
|
+
const working = await mkdtemp(join(request.cacheDir, ".sentence-audio-"));
|
|
51
|
+
try {
|
|
52
|
+
const pcmPath = join(working, "audio.f32");
|
|
53
|
+
await decodeAudio(request.ffmpeg, request.audioPath, pcmPath, request.signal);
|
|
54
|
+
request.onProgress?.(50, 100);
|
|
55
|
+
const bytes = await readFile(pcmPath);
|
|
56
|
+
const length = Math.floor(bytes.length / 4) * 4;
|
|
57
|
+
const samples = new Float32Array(bytes.buffer.slice(bytes.byteOffset, bytes.byteOffset + length));
|
|
58
|
+
const words = sentenceTiming(request.text, request.language ?? "en", speechShape(samples));
|
|
59
|
+
request.onProgress?.(100, 100);
|
|
60
|
+
return words;
|
|
61
|
+
}
|
|
62
|
+
finally {
|
|
63
|
+
await rm(working, { recursive: true, force: true });
|
|
64
|
+
}
|
|
65
|
+
}
|