@gentbajko/slopify 3.25.9 → 4.1.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/dist/adapters/account-limits.js +30 -0
- package/dist/adapters/alignment/audio.js +1 -1
- package/dist/adapters/alignment/cache.js +4 -6
- package/dist/adapters/alignment/ctc.js +1 -2
- package/dist/adapters/alignment/lock.js +4 -3
- package/dist/adapters/alignment/multilingual.js +2 -4
- package/dist/adapters/alignment/prefetch.js +2 -1
- package/dist/adapters/alignment/runner.js +1 -1
- package/dist/adapters/alignment/worker.js +3 -2
- package/dist/adapters/explain.js +10 -12
- package/dist/adapters/ffmpeg.js +19 -1
- package/dist/adapters/host-cli/index.js +21 -4
- package/dist/adapters/host-cli/transport.js +2 -1
- package/dist/adapters/http-failure.js +53 -0
- package/dist/adapters/image/bytes.js +2 -1
- package/dist/adapters/image/codex.js +42 -9
- package/dist/adapters/image/fal.js +21 -53
- package/dist/adapters/image/google.js +33 -56
- package/dist/adapters/image/models.js +2 -2
- package/dist/adapters/image/openai.js +22 -48
- package/dist/adapters/image/reference.js +36 -0
- package/dist/adapters/image/replicate.js +21 -49
- package/dist/adapters/image/video.js +2 -1
- package/dist/adapters/interest/search-interest.js +113 -0
- package/dist/adapters/key-probes.js +54 -3
- package/dist/adapters/llm/antigravity-models.js +1 -1
- package/dist/adapters/llm/antigravity.js +11 -6
- package/dist/adapters/llm/assistant-cli.js +388 -0
- package/dist/adapters/llm/child-session.js +83 -0
- package/dist/adapters/llm/claude-code-models.js +52 -99
- package/dist/adapters/llm/claude-code.js +16 -4
- package/dist/adapters/llm/codex-limits.js +27 -68
- package/dist/adapters/llm/codex-models.js +1 -1
- package/dist/adapters/llm/codex-server-models.js +61 -109
- package/dist/adapters/llm/codex.js +12 -1
- package/dist/adapters/llm/document-workspace.js +3 -2
- package/dist/adapters/llm/image-workspace.js +3 -2
- package/dist/adapters/llm/openrouter.js +12 -48
- package/dist/adapters/llm/run-cli.js +9 -24
- package/dist/adapters/llm/sse-lines.js +5 -1
- package/dist/adapters/model-access.js +37 -0
- package/dist/adapters/tts/cartesia.js +15 -46
- package/dist/adapters/tts/elevenlabs.js +20 -52
- package/dist/adapters/tts/gemini.js +21 -41
- package/dist/adapters/tts/inworld-async.js +6 -2
- package/dist/adapters/tts/inworld.js +6 -2
- package/dist/adapters/tts/openai.js +20 -50
- package/dist/adapters/tts/system.js +2 -1
- package/dist/assets/models-lifecycle.yaml +6 -0
- package/dist/assistant-wiring.js +60 -0
- package/dist/autopilot-timers.js +59 -0
- package/dist/catalog/lifecycle.js +52 -0
- package/dist/catalog/propose.js +204 -0
- package/dist/catalog/registry.js +23 -14
- package/dist/catalog/schema.js +4 -1
- package/dist/catalog/store.js +39 -0
- package/dist/catalog/validate.js +5 -2
- package/dist/edge/autostart/native.js +3 -5
- package/dist/edge/autostart/prompt.js +2 -1
- package/dist/edge/autostart/service.js +3 -4
- package/dist/edge/cli-args.js +3 -4
- package/dist/edge/cli.js +2 -1
- package/dist/edge/docker-install/apply.js +11 -11
- package/dist/edge/docker-install/run.js +2 -1
- package/dist/edge/docker-install/state.js +4 -3
- package/dist/edge/docker-install/tree.js +2 -4
- package/dist/edge/docker-install/volume.js +3 -2
- package/dist/edge/docker.js +5 -4
- package/dist/edge/events/hub.js +5 -5
- package/dist/edge/http/actions.js +11 -32
- package/dist/edge/http/actor.js +5 -3
- package/dist/edge/http/app.js +86 -11
- package/dist/edge/http/assistant.js +129 -0
- package/dist/edge/http/audio-preview.js +4 -11
- package/dist/edge/http/auditions.js +1 -1
- package/dist/edge/http/autostart.js +5 -5
- package/dist/edge/http/backups.js +2 -4
- package/dist/edge/http/channel-memory.js +9 -22
- package/dist/edge/http/channels.js +14 -27
- package/dist/edge/http/checkpoints.js +39 -21
- package/dist/edge/http/design-templates.js +167 -0
- package/dist/edge/http/designs.js +178 -0
- package/dist/edge/http/diagnostics.js +5 -1
- package/dist/edge/http/document-themes.js +5 -14
- package/dist/edge/http/draft-files.js +1 -3
- package/dist/edge/http/draft-problem.js +5 -10
- package/dist/edge/http/drafts.js +3 -3
- package/dist/edge/http/entries.js +6 -9
- package/dist/edge/http/extension-auth.js +27 -0
- package/dist/edge/http/external-reviews.js +12 -11
- package/dist/edge/http/files.js +5 -11
- package/dist/edge/http/folder-location.js +1 -4
- package/dist/edge/http/fonts.js +0 -7
- package/dist/edge/http/home.js +47 -14
- package/dist/edge/http/host-cli.js +18 -8
- package/dist/edge/http/ids.js +8 -0
- package/dist/edge/http/keywords.js +35 -0
- package/dist/edge/http/model-checks.js +132 -0
- package/dist/edge/http/narration-peaks.js +5 -13
- package/dist/edge/http/onboarding.js +30 -26
- package/dist/edge/http/open-folder.js +5 -10
- package/dist/edge/http/outputs.js +7 -14
- package/dist/edge/http/patch-notes.js +6 -12
- package/dist/edge/http/planning.js +3 -7
- package/dist/edge/http/problem.js +2 -4
- package/dist/edge/http/project-create.js +2 -1
- package/dist/edge/http/project-templates.js +31 -19
- package/dist/edge/http/projects.js +24 -16
- package/dist/edge/http/prompts.js +9 -16
- package/dist/edge/http/pronunciations.js +1 -2
- package/dist/edge/http/providers.js +48 -34
- package/dist/edge/http/refusal.js +29 -0
- package/dist/edge/http/remote-access.js +40 -0
- package/dist/edge/http/remote-guard.js +71 -0
- package/dist/edge/http/request-guard.js +91 -0
- package/dist/edge/http/reviews.js +12 -25
- package/dist/edge/http/revision-files.js +6 -11
- package/dist/edge/http/revisions.js +14 -19
- package/dist/edge/http/run-cost.js +1 -2
- package/dist/edge/http/same-page.js +80 -0
- package/dist/edge/http/schedules.js +69 -40
- package/dist/edge/http/settings.js +27 -14
- package/dist/edge/http/social.js +283 -0
- package/dist/edge/http/staging.js +3 -5
- package/dist/edge/http/storage-files.js +5 -7
- package/dist/edge/http/storage.js +33 -25
- package/dist/edge/http/studio.js +94 -69
- package/dist/edge/http/style-preview.js +3 -6
- package/dist/edge/http/subtitles.js +3 -17
- package/dist/edge/http/template-studio.js +436 -0
- package/dist/edge/http/trash.js +11 -12
- package/dist/edge/http/tutorial.js +1 -2
- package/dist/edge/http/tutorials.js +5 -11
- package/dist/edge/http/update.js +7 -13
- package/dist/edge/http/waveform.js +3 -6
- package/dist/edge/http/youtube-edits.js +3 -4
- package/dist/edge/mcp/assistant.js +279 -0
- package/dist/edge/mcp/attribution.js +8 -2
- package/dist/edge/mcp/call-route.js +11 -2
- package/dist/edge/mcp/excluded-routes.js +29 -3
- package/dist/edge/mcp/http.js +11 -2
- package/dist/edge/mcp/instructions.js +6 -4
- package/dist/edge/mcp/library-tools.js +9 -5
- package/dist/edge/mcp/remake-tools.js +7 -4
- package/dist/edge/mcp/route-tool.js +35 -15
- package/dist/edge/mcp/server.js +13 -8
- package/dist/edge/mcp/tools-channels.js +11 -9
- package/dist/edge/mcp/tools-designs.js +165 -0
- package/dist/edge/mcp/tools-library.js +19 -7
- package/dist/edge/mcp/tools-planning.js +40 -21
- package/dist/edge/mcp/tools-projects.js +38 -11
- package/dist/edge/mcp/tools-publishing.js +9 -9
- package/dist/edge/mcp/tools-runs.js +23 -10
- package/dist/edge/mcp/tools-schedules.js +32 -8
- package/dist/edge/mcp/tools-setup.js +75 -11
- package/dist/edge/mcp/tools-social.js +47 -0
- package/dist/edge/mcp/tools-storage.js +11 -3
- package/dist/edge/mcp/tools-template-studio.js +166 -0
- package/dist/edge/mcp/tools.js +6 -0
- package/dist/edge/remote-access/cli.js +71 -0
- package/dist/edge/remote-access/model.js +32 -0
- package/dist/edge/remote-access/rules.js +207 -0
- package/dist/edge/remote-access/service.js +203 -0
- package/dist/edge/remote-access/store.js +44 -0
- package/dist/edge/remote-access/views.js +43 -0
- package/dist/extension/slopify-studio-chrome.zip +0 -0
- package/dist/extension/slopify-studio-firefox.zip +0 -0
- package/dist/host-cli/install.js +2 -2
- package/dist/host-cli/open-folder.js +2 -2
- package/dist/host-cli/paths.js +2 -4
- package/dist/host-cli/server.js +4 -4
- package/dist/host-cli/service.js +3 -3
- package/dist/host-cli/status.js +7 -7
- package/dist/kernel/db/migrations/0063-model-checks.sql +20 -0
- package/dist/kernel/db/migrations/0064-template-studio.sql +46 -0
- package/dist/kernel/db/migrations/0065-promise-and-assistant-reviews.sql +58 -0
- package/dist/kernel/db/migrations/0066-assistant.sql +44 -0
- package/dist/kernel/db/migrations/0067-autopilot.sql +6 -0
- package/dist/kernel/db/migrations/0068-topic-scores.sql +17 -0
- package/dist/kernel/db/migrations/0070-designs.sql +53 -0
- package/dist/kernel/db/migrations/0071-design-usage.sql +33 -0
- package/dist/kernel/db/migrations/0072-design-templates.sql +33 -0
- package/dist/kernel/db/migrations/0073-schedule-design-kind.sql +5 -0
- package/dist/kernel/db/migrations/0074-template-bakeoffs.sql +44 -0
- package/dist/kernel/db/migrations/0075-social-posts.sql +25 -0
- package/dist/kernel/db/migrations/0076-channel-social.sql +5 -0
- package/dist/kernel/db/migrations/0077-post-prompts.sql +17 -0
- package/dist/kernel/db/migrations/0078-uploaded-from-links.sql +7 -0
- package/dist/kernel/db/tx.js +2 -4
- package/dist/kernel/errors.js +27 -1
- package/dist/kernel/json-answer.js +15 -0
- package/dist/kernel/lock.js +4 -9
- package/dist/kernel/paths.js +8 -0
- package/dist/kernel/pipeline.js +12 -0
- package/dist/kernel/ports/assistant-cli.js +4 -0
- package/dist/kernel/ports/host-cli.js +3 -0
- package/dist/kernel/ports/interest.js +4 -0
- package/dist/kernel/ports/languages.js +0 -3
- package/dist/kernel/ports/model.js +2 -0
- package/dist/kernel/ports/settings-places.js +31 -0
- package/dist/kernel/ports/system-speech.js +31 -3
- package/dist/kernel/runner/attempt.js +14 -4
- package/dist/kernel/runner/audition.js +3 -1
- package/dist/kernel/runner/checkpoint-authority.js +2 -1
- package/dist/kernel/runner/index.js +8 -10
- package/dist/kernel/runner/model-access.js +40 -0
- package/dist/kernel/runner/model-check.js +153 -0
- package/dist/kernel/runner/providers.js +18 -12
- package/dist/kernel/runner/standalone.js +11 -7
- package/dist/main.js +338 -21
- package/dist/model-catalog.js +20 -0
- package/dist/model-checks.js +166 -0
- package/dist/patch-notes/4.0.0.md +51 -0
- package/dist/patch-notes/4.1.0.md +42 -0
- package/dist/patch-notes/index.json +12 -0
- package/dist/slices/admission/heads.js +2 -1
- package/dist/slices/admission/listing-facts.js +95 -0
- package/dist/slices/admission/repo.js +11 -7
- package/dist/slices/admission/rules.js +50 -15
- package/dist/slices/admission/schema.js +8 -0
- package/dist/slices/admission/stage-writes.js +0 -3
- package/dist/slices/admission/start.js +48 -31
- package/dist/slices/admission/state-words.js +34 -5
- package/dist/slices/admission/substitute.js +7 -4
- package/dist/slices/agents/attention-posts.js +31 -0
- package/dist/slices/agents/attention-templates.js +33 -0
- package/dist/slices/agents/attention.js +10 -1
- package/dist/slices/agents/connection.js +2 -6
- package/dist/slices/agents/model.js +6 -3
- package/dist/slices/agents/repo.js +15 -7
- package/dist/slices/article/continuation.js +0 -63
- package/dist/slices/article/plain.js +3 -2
- package/dist/slices/article/segments.js +2 -62
- package/dist/slices/assistant/access.js +1 -0
- package/dist/slices/assistant/asks.js +80 -0
- package/dist/slices/assistant/cost.js +54 -0
- package/dist/slices/assistant/gate.js +222 -0
- package/dist/slices/assistant/model.js +86 -0
- package/dist/slices/assistant/names.js +23 -0
- package/dist/slices/assistant/prompt.js +74 -0
- package/dist/slices/assistant/repo.js +74 -0
- package/dist/slices/assistant/tokens.js +18 -0
- package/dist/slices/assistant/turn.js +344 -0
- package/dist/slices/autopilot/buffer.js +76 -0
- package/dist/slices/autopilot/model.js +14 -0
- package/dist/slices/autopilot/notify.js +27 -0
- package/dist/slices/autopilot/repo.js +34 -0
- package/dist/slices/autopilot/signals.js +194 -0
- package/dist/slices/autopilot/warnings.js +85 -0
- package/dist/slices/autopilot/weekly.js +100 -0
- package/dist/slices/backups/files.js +2 -6
- package/dist/slices/backups/repo.js +3 -15
- package/dist/slices/backups/service.js +8 -7
- package/dist/slices/channels/cast-images.js +3 -2
- package/dist/slices/channels/model.js +0 -1
- package/dist/slices/channels/rebrand.js +0 -3
- package/dist/slices/channels/repo.js +4 -0
- package/dist/slices/channels/schema.js +7 -1
- package/dist/slices/channels/service.js +10 -0
- package/dist/slices/channels/videos.js +3 -15
- package/dist/slices/checkpoints/index.js +0 -1
- package/dist/slices/control/providers.js +2 -28
- package/dist/slices/designs/artwork.js +66 -0
- package/dist/slices/designs/budget.js +23 -0
- package/dist/slices/designs/calls.js +124 -0
- package/dist/slices/designs/check-context.js +38 -0
- package/dist/slices/designs/check-text.js +43 -0
- package/dist/slices/designs/fields.js +88 -0
- package/dist/slices/designs/frames.js +34 -0
- package/dist/slices/designs/gate.js +130 -0
- package/dist/slices/designs/layout.js +293 -0
- package/dist/slices/designs/model.js +35 -0
- package/dist/slices/designs/pdf-job.js +23 -0
- package/dist/slices/designs/pdf-pages.js +30 -0
- package/dist/slices/designs/pdf-runner.js +68 -0
- package/dist/slices/designs/pdf-worker.js +24 -0
- package/dist/slices/designs/picture-size.js +79 -0
- package/dist/slices/designs/pictures.js +55 -0
- package/dist/slices/designs/quote.js +24 -0
- package/dist/slices/designs/render-args.js +36 -0
- package/dist/slices/designs/render-input.js +59 -0
- package/dist/slices/designs/render.js +215 -0
- package/dist/slices/designs/repo.js +101 -0
- package/dist/slices/designs/requests.js +80 -0
- package/dist/slices/designs/runner.js +239 -0
- package/dist/slices/designs/sample-repo.js +91 -0
- package/dist/slices/designs/sample.js +223 -0
- package/dist/slices/designs/schema.js +87 -0
- package/dist/slices/designs/sections.js +44 -0
- package/dist/slices/designs/service.js +233 -0
- package/dist/slices/designs/steps-repo.js +102 -0
- package/dist/slices/designs/studio-kind.js +39 -0
- package/dist/slices/designs/template-checks.js +44 -0
- package/dist/slices/designs/template-make.js +118 -0
- package/dist/slices/designs/templates.js +218 -0
- package/dist/slices/document/fonts.js +2 -1
- package/dist/slices/document/model.js +7 -4
- package/dist/slices/document/render.js +2 -1
- package/dist/slices/document/theme-schema.js +1 -1
- package/dist/slices/document/theme.js +49 -3
- package/dist/slices/episodes/summarize.js +6 -2
- package/dist/slices/estimate/index.js +72 -28
- package/dist/slices/estimate/requests.js +4 -4
- package/dist/slices/fixes/rules.js +3 -1
- package/dist/slices/fonts/catalog.js +5 -3
- package/dist/slices/fonts/coverage.js +2 -1
- package/dist/slices/fonts/discovery.js +3 -2
- package/dist/slices/fonts/files.js +2 -6
- package/dist/slices/fonts/index.js +0 -1
- package/dist/slices/fonts/sfnt.js +45 -10
- package/dist/slices/images/appearance.js +8 -16
- package/dist/slices/images/scenes.js +102 -28
- package/dist/slices/keywords/digest.js +85 -0
- package/dist/slices/keywords/facts.js +92 -0
- package/dist/slices/keywords/fill.js +80 -0
- package/dist/slices/keywords/model.js +75 -0
- package/dist/slices/keywords/rules.js +187 -0
- package/dist/slices/keywords/schema.js +28 -0
- package/dist/slices/keywords/specs.js +260 -0
- package/dist/slices/keywords/values.js +74 -0
- package/dist/slices/library/lint.js +29 -12
- package/dist/slices/library/model.js +2 -0
- package/dist/slices/library/photorealistic.js +4 -12
- package/dist/slices/library/rename.js +9 -7
- package/dist/slices/library/save.js +14 -10
- package/dist/slices/library/slots.js +37 -11
- package/dist/slices/library/transfer.js +5 -4
- package/dist/slices/library/used-by.js +25 -10
- package/dist/slices/loudness/loudnorm.js +53 -12
- package/dist/slices/loudness/model.js +3 -2
- package/dist/slices/loudness/sentence-level.js +2 -1
- package/dist/slices/model-checks/cost.js +61 -0
- package/dist/slices/model-checks/listing.js +124 -0
- package/dist/slices/model-checks/model.js +20 -0
- package/dist/slices/model-checks/record.js +32 -0
- package/dist/slices/model-checks/repo.js +120 -0
- package/dist/slices/model-checks/rules.js +125 -0
- package/dist/slices/model-checks/run.js +143 -0
- package/dist/slices/model-checks/service.js +198 -0
- package/dist/slices/model-upkeep/model.js +1 -1
- package/dist/slices/model-upkeep/switch.js +72 -27
- package/dist/slices/model-upkeep/usage.js +39 -13
- package/dist/slices/narration/breaths.js +3 -1
- package/dist/slices/narration/clean-pieces.js +3 -1
- package/dist/slices/narration/concat.js +2 -1
- package/dist/slices/narration/pauses-model.js +3 -2
- package/dist/slices/narration/peaks.js +3 -4
- package/dist/slices/narration/pronunciation-chunks.js +4 -3
- package/dist/slices/narration/pronunciation.js +6 -4
- package/dist/slices/narration/steering.js +4 -3
- package/dist/slices/notifications/notifier.js +4 -3
- package/dist/slices/notifications/rules.js +5 -2
- package/dist/slices/notifications/settings.js +4 -12
- package/dist/slices/notifications/subject.js +4 -3
- package/dist/slices/onboarding/copy.js +21 -3
- package/dist/slices/onboarding/first-run.js +16 -40
- package/dist/slices/onboarding/full-video.js +3 -2
- package/dist/slices/onboarding/install.js +6 -4
- package/dist/slices/onboarding/model.js +26 -37
- package/dist/slices/onboarding/packs.js +22 -22
- package/dist/slices/onboarding/preferred-model.js +14 -0
- package/dist/slices/onboarding/quick-short.js +105 -65
- package/dist/slices/onboarding/sample.js +4 -2
- package/dist/slices/onboarding/state.js +9 -11
- package/dist/slices/onboarding/template.js +8 -6
- package/dist/slices/outputs/add.js +3 -2
- package/dist/slices/outputs/service.js +2 -2
- package/dist/slices/patch-notes/library.js +4 -3
- package/dist/slices/play-drafts/convert.js +4 -0
- package/dist/slices/play-drafts/readiness.js +3 -3
- package/dist/slices/play-drafts/review-inputs.js +9 -3
- package/dist/slices/play-drafts/review.js +5 -4
- package/dist/slices/play-drafts/schema.js +4 -0
- package/dist/slices/play-drafts/service.js +17 -7
- package/dist/slices/project-templates/from-project.js +9 -2
- package/dist/slices/project-templates/next-chapter.js +2 -1
- package/dist/slices/project-templates/provider-defaults.js +22 -0
- package/dist/slices/project-templates/repo.js +6 -1
- package/dist/slices/project-templates/setup-sections.js +26 -0
- package/dist/slices/project-templates/setup.js +14 -1
- package/dist/slices/project-templates/stand-ins.js +22 -0
- package/dist/slices/rebuild/activity.js +2 -0
- package/dist/slices/rebuild/admission-repo.js +3 -2
- package/dist/slices/rebuild/narration-history.js +4 -5
- package/dist/slices/rebuild/narration-retry.js +2 -1
- package/dist/slices/rebuild/preview-details.js +32 -14
- package/dist/slices/rebuild/preview-plan.js +3 -8
- package/dist/slices/rebuild/recipe-build.js +8 -3
- package/dist/slices/rebuild/recipe-describe.js +3 -3
- package/dist/slices/rebuild/recipe-digest.js +58 -0
- package/dist/slices/rebuild/recipe-input-schema.js +10 -0
- package/dist/slices/rebuild/recipe-keywords.js +71 -0
- package/dist/slices/rebuild/recipe-legacy.js +5 -1
- package/dist/slices/rebuild/recipe-model.js +4 -0
- package/dist/slices/rebuild/recipe-narration-text.js +2 -1
- package/dist/slices/rebuild/recipe-preparation.js +4 -4
- package/dist/slices/rebuild/recipe-reference.js +8 -4
- package/dist/slices/rebuild/recipe-reviews.js +27 -7
- package/dist/slices/rebuild/recipe-save.js +8 -5
- package/dist/slices/rebuild/recipe-scenes.js +40 -11
- package/dist/slices/rebuild/recipe-shorts.js +8 -8
- package/dist/slices/rebuild/recipe-social.js +46 -0
- package/dist/slices/rebuild/recipe-text.js +64 -20
- package/dist/slices/rebuild/recipe-validation.js +102 -31
- package/dist/slices/rebuild/recipe-visual.js +55 -16
- package/dist/slices/rebuild/recipe-voices.js +3 -2
- package/dist/slices/rebuild/recipe-work.js +19 -7
- package/dist/slices/rebuild/recipe-youtube.js +4 -3
- package/dist/slices/rebuild/recovery-selection.js +3 -1
- package/dist/slices/rebuild/recovery.js +9 -8
- package/dist/slices/rebuild/remake-outdated.js +5 -5
- package/dist/slices/rebuild/repo.js +4 -3
- package/dist/slices/rebuild/review-promise.js +25 -0
- package/dist/slices/rebuild/review-redo.js +3 -2
- package/dist/slices/rebuild/runtime-admission.js +4 -3
- package/dist/slices/rebuild/runtime-agent-review.js +11 -5
- package/dist/slices/rebuild/runtime-animate.js +10 -9
- package/dist/slices/rebuild/runtime-article.js +7 -5
- package/dist/slices/rebuild/runtime-checkpoints.js +5 -4
- package/dist/slices/rebuild/runtime-document.js +11 -13
- package/dist/slices/rebuild/runtime-export-bed.js +8 -12
- package/dist/slices/rebuild/runtime-export-edit.js +8 -16
- package/dist/slices/rebuild/runtime-export-inputs.js +12 -11
- package/dist/slices/rebuild/runtime-export-short.js +9 -5
- package/dist/slices/rebuild/runtime-export.js +38 -15
- package/dist/slices/rebuild/runtime-figure-card.js +2 -1
- package/dist/slices/rebuild/runtime-image.js +8 -12
- package/dist/slices/rebuild/runtime-instructions.js +2 -0
- package/dist/slices/rebuild/runtime-keywords.js +59 -0
- package/dist/slices/rebuild/runtime-lines.js +2 -11
- package/dist/slices/rebuild/runtime-local.js +17 -22
- package/dist/slices/rebuild/runtime-narration-publication.js +2 -5
- package/dist/slices/rebuild/runtime-narration-reuse.js +9 -13
- package/dist/slices/rebuild/runtime-narration-text.js +13 -17
- package/dist/slices/rebuild/runtime-pictures.js +2 -4
- package/dist/slices/rebuild/runtime-piece-label.js +10 -6
- package/dist/slices/rebuild/runtime-plan.js +31 -5
- package/dist/slices/rebuild/runtime-provider.js +67 -25
- package/dist/slices/rebuild/runtime-publication.js +10 -9
- package/dist/slices/rebuild/runtime-review.js +39 -33
- package/dist/slices/rebuild/runtime-run.js +4 -1
- package/dist/slices/rebuild/runtime-shorts.js +31 -50
- package/dist/slices/rebuild/runtime-store.js +20 -10
- package/dist/slices/rebuild/runtime-subtitles.js +28 -25
- package/dist/slices/rebuild/runtime-voices.js +10 -16
- package/dist/slices/rebuild/runtime-youtube.js +14 -31
- package/dist/slices/rebuild/service-readiness.js +11 -3
- package/dist/slices/rebuild/transition-repo.js +6 -5
- package/dist/slices/rebuild/work-records.js +6 -0
- package/dist/slices/reruns/cascade.js +1 -2
- package/dist/slices/reruns/index.js +6 -9
- package/dist/slices/research/synthesis.js +3 -2
- package/dist/slices/reviews/external-model.js +4 -1
- package/dist/slices/reviews/external-repo.js +2 -1
- package/dist/slices/reviews/external-rows.js +2 -3
- package/dist/slices/reviews/holds.js +5 -4
- package/dist/slices/reviews/model.js +32 -11
- package/dist/slices/reviews/repo.js +2 -1
- package/dist/slices/reviews/rules.js +4 -3
- package/dist/slices/reviews/verdict.js +2 -1
- package/dist/slices/reviews/view.js +5 -2
- package/dist/slices/revisions/downloads.js +4 -5
- package/dist/slices/revisions/image-plan.js +1 -1
- package/dist/slices/revisions/mutation-assets.js +9 -5
- package/dist/slices/revisions/mutation-cues.js +2 -5
- package/dist/slices/revisions/mutations.js +3 -3
- package/dist/slices/revisions/repo.js +3 -1
- package/dist/slices/revisions/schema.js +1 -0
- package/dist/slices/revisions/view.js +20 -0
- package/dist/slices/run-cost/limits.js +5 -2
- package/dist/slices/run-cost/meter.js +12 -5
- package/dist/slices/run-cost/panel.js +8 -74
- package/dist/slices/run-cost/plan-readings.js +127 -0
- package/dist/slices/run-cost/plan-use.js +169 -0
- package/dist/slices/run-cost/pricing.js +3 -3
- package/dist/slices/run-cost/week.js +32 -4
- package/dist/slices/schedules/agenda.js +18 -7
- package/dist/slices/schedules/by-date.js +42 -0
- package/dist/slices/schedules/calendar.js +5 -0
- package/dist/slices/schedules/design-agenda.js +36 -0
- package/dist/slices/schedules/design-check.js +41 -0
- package/dist/slices/schedules/design-run.js +126 -0
- package/dist/slices/schedules/next-run.js +62 -0
- package/dist/slices/schedules/prepare.js +18 -2
- package/dist/slices/schedules/repo.js +30 -21
- package/dist/slices/schedules/rescore.js +35 -0
- package/dist/slices/schedules/scheduler.js +13 -3
- package/dist/slices/schedules/schema.js +57 -3
- package/dist/slices/schedules/score.js +107 -0
- package/dist/slices/schedules/service.js +57 -24
- package/dist/slices/schedules/topic-list.js +15 -0
- package/dist/slices/schedules/topic-scores.js +104 -0
- package/dist/slices/schedules/topics.js +53 -41
- package/dist/slices/settings/cli-paths.js +4 -6
- package/dist/slices/settings/first-run.js +8 -43
- package/dist/slices/settings/health.js +30 -15
- package/dist/slices/settings/key-test.js +1 -1
- package/dist/slices/settings/model-reach.js +3 -17
- package/dist/slices/settings/model.js +14 -2
- package/dist/slices/settings/playback.js +34 -23
- package/dist/slices/settings/probe-read.js +16 -0
- package/dist/slices/settings/repo.js +33 -0
- package/dist/slices/settings/tutorial.js +2 -2
- package/dist/slices/settings/voices.js +4 -12
- package/dist/slices/shorts/keep.js +2 -1
- package/dist/slices/shorts/pick.js +6 -18
- package/dist/slices/shorts/prompts.js +4 -14
- package/dist/slices/shorts/render.js +6 -2
- package/dist/slices/social/channel.js +44 -0
- package/dist/slices/social/defaults.js +17 -0
- package/dist/slices/social/due.js +36 -0
- package/dist/slices/social/extension.js +18 -0
- package/dist/slices/social/fit.js +115 -0
- package/dist/slices/social/limits.js +186 -0
- package/dist/slices/social/links.js +21 -0
- package/dist/slices/social/media.js +132 -0
- package/dist/slices/social/model.js +75 -0
- package/dist/slices/social/notice.js +19 -0
- package/dist/slices/social/pack.js +176 -0
- package/dist/slices/social/post-prompt.js +56 -0
- package/dist/slices/social/queue.js +31 -0
- package/dist/slices/social/repo.js +133 -0
- package/dist/slices/social/reshape.js +97 -0
- package/dist/slices/social/rules.js +5 -0
- package/dist/slices/social/schema.js +70 -0
- package/dist/slices/social/serve.js +51 -0
- package/dist/slices/social/service.js +129 -0
- package/dist/slices/social/settings.js +21 -0
- package/dist/slices/social/sources.js +114 -0
- package/dist/slices/social/state.js +110 -0
- package/dist/slices/social/text.js +149 -0
- package/dist/slices/storage/arrange.js +3 -1
- package/dist/slices/storage/assets.js +8 -10
- package/dist/slices/storage/backup-designs.js +74 -0
- package/dist/slices/storage/backup-export.js +8 -3
- package/dist/slices/storage/backup-format.js +10 -0
- package/dist/slices/storage/backup-import.js +22 -4
- package/dist/slices/storage/delete-project.js +6 -5
- package/dist/slices/storage/files-location.js +6 -8
- package/dist/slices/storage/layout.js +13 -2
- package/dist/slices/storage/model.js +3 -0
- package/dist/slices/storage/portable.js +17 -12
- package/dist/slices/storage/schema.js +2 -0
- package/dist/slices/storage/staging-refs.js +2 -1
- package/dist/slices/storage/staging.js +6 -9
- package/dist/slices/storage/trim.js +26 -9
- package/dist/slices/studio/calendar.js +7 -2
- package/dist/slices/studio/disclosure.js +4 -4
- package/dist/slices/studio/model.js +1 -1
- package/dist/slices/studio/pack.js +9 -8
- package/dist/slices/studio/pick.js +2 -11
- package/dist/slices/studio/plan.js +7 -16
- package/dist/slices/studio/queue.js +3 -14
- package/dist/slices/studio/releases.js +26 -0
- package/dist/slices/studio/settings.js +20 -57
- package/dist/slices/studio/videos.js +35 -4
- package/dist/slices/style-preview/render.js +37 -16
- package/dist/slices/style-preview/schema.js +14 -1
- package/dist/slices/style-preview/service.js +2 -1
- package/dist/slices/style-preview/settings.js +33 -5
- package/dist/slices/subtitles/captions.js +1 -1
- package/dist/slices/telemetry/collector-client.js +2 -4
- package/dist/slices/telemetry/flush.js +2 -4
- package/dist/slices/telemetry/model.js +0 -7
- package/dist/slices/telemetry/record.js +10 -3
- package/dist/slices/template-studio/anatomy-view.js +161 -0
- package/dist/slices/template-studio/anatomy.js +73 -0
- package/dist/slices/template-studio/bakeoff-make.js +225 -0
- package/dist/slices/template-studio/bakeoff-repo.js +83 -0
- package/dist/slices/template-studio/bakeoff.js +333 -0
- package/dist/slices/template-studio/budget.js +106 -0
- package/dist/slices/template-studio/cards.js +78 -0
- package/dist/slices/template-studio/checks.js +322 -0
- package/dist/slices/template-studio/document-sample.js +56 -0
- package/dist/slices/template-studio/edit.js +15 -0
- package/dist/slices/template-studio/for-all.js +161 -0
- package/dist/slices/template-studio/free-video.js +31 -0
- package/dist/slices/template-studio/free.js +176 -0
- package/dist/slices/template-studio/gate.js +40 -0
- package/dist/slices/template-studio/hidden.js +20 -0
- package/dist/slices/template-studio/jobs.js +79 -0
- package/dist/slices/template-studio/loudness.js +111 -0
- package/dist/slices/template-studio/make.js +40 -0
- package/dist/slices/template-studio/model.js +58 -0
- package/dist/slices/template-studio/pack-import.js +253 -0
- package/dist/slices/template-studio/pack-samples.js +60 -0
- package/dist/slices/template-studio/pack.js +207 -0
- package/dist/slices/template-studio/paid-view.js +66 -0
- package/dist/slices/template-studio/paid.js +355 -0
- package/dist/slices/template-studio/quote.js +155 -0
- package/dist/slices/template-studio/ready.js +104 -0
- package/dist/slices/template-studio/repo.js +134 -0
- package/dist/slices/template-studio/reviews-path.js +58 -0
- package/dist/slices/template-studio/runner.js +84 -0
- package/dist/slices/template-studio/save.js +236 -0
- package/dist/slices/template-studio/say-it-as.js +248 -0
- package/dist/slices/template-studio/schedule-gate.js +34 -0
- package/dist/slices/template-studio/schedule-price.js +32 -0
- package/dist/slices/template-studio/schedule-sample.js +91 -0
- package/dist/slices/template-studio/schema.js +243 -0
- package/dist/slices/template-studio/scope.js +124 -0
- package/dist/slices/template-studio/sections.js +176 -0
- package/dist/slices/template-studio/service.js +175 -0
- package/dist/slices/template-studio/status.js +191 -0
- package/dist/slices/template-studio/topic.js +223 -0
- package/dist/slices/thumbnail/by-llm.js +1 -1
- package/dist/slices/trash/designs.js +76 -0
- package/dist/slices/trash/model.js +13 -4
- package/dist/slices/trash/service.js +52 -2
- package/dist/slices/tutorials/library.js +3 -2
- package/dist/slices/uploads/repo.js +37 -1
- package/dist/slices/uploads/rules.js +3 -2
- package/dist/slices/video/ass-text.js +17 -0
- package/dist/slices/video/audio-export.js +2 -64
- package/dist/slices/video/edit-list.js +2 -2
- package/dist/slices/video/edit-settings.js +1 -1
- package/dist/slices/video/encoding.js +169 -0
- package/dist/slices/video/ffmpeg.js +23 -21
- package/dist/slices/video/figure-card.js +1 -15
- package/dist/slices/video/plan.js +2 -1
- package/dist/slices/video/slideshow.js +43 -18
- package/dist/slices/voices/attribution.js +3 -2
- package/dist/slices/voices/model.js +9 -8
- package/dist/slices/voices/palette.js +0 -3
- package/dist/slices/voices/script.js +2 -1
- package/dist/slices/youtube/answer.js +4 -16
- package/dist/slices/youtube/edits-repo.js +3 -12
- package/dist/tutorials/AI-CLIs.md +25 -25
- package/dist/tutorials/Agents-MCP.md +34 -33
- package/dist/tutorials/Assistant.md +42 -0
- package/dist/tutorials/Backups.md +7 -7
- package/dist/tutorials/Calendar.md +17 -25
- package/dist/tutorials/Cast-Library.md +19 -19
- package/dist/tutorials/Channels.md +42 -35
- package/dist/tutorials/Costs-and-Run-Cost.md +38 -40
- package/dist/tutorials/Create-Article.md +114 -0
- package/dist/tutorials/Create-Extras.md +112 -0
- package/dist/tutorials/Create-Images.md +165 -0
- package/dist/tutorials/Create-Narration.md +178 -0
- package/dist/tutorials/Create-Overview.md +244 -0
- package/dist/tutorials/Create-Video-and-Style.md +144 -0
- package/dist/tutorials/Docker.md +3 -3
- package/dist/tutorials/Document-Themes.md +32 -32
- package/dist/tutorials/Editing-a-Project.md +94 -94
- package/dist/tutorials/FAQ.md +18 -18
- package/dist/tutorials/First-Launch-and-Welcome.md +50 -64
- package/dist/tutorials/Home-and-Projects.md +115 -71
- package/dist/tutorials/Home.md +33 -33
- package/dist/tutorials/Install.md +14 -13
- package/dist/tutorials/Intros-and-Outros.md +33 -34
- package/dist/tutorials/Keyboard-Shortcuts-and-Command-Palette.md +62 -58
- package/dist/tutorials/Keywords-Slopify-Fills.md +87 -0
- package/dist/tutorials/Models.md +53 -21
- package/dist/tutorials/Multiple-Voices.md +41 -40
- package/dist/tutorials/Narration-Aliases-and-Glossary.md +14 -14
- package/dist/tutorials/Notifications.md +27 -17
- package/dist/tutorials/Other-Languages.md +15 -15
- package/dist/tutorials/PDF-Documents.md +38 -29
- package/dist/tutorials/Posting-to-Social-Sites.md +121 -0
- package/dist/tutorials/Project-Page.md +118 -120
- package/dist/tutorials/Prompts-and-Templates.md +84 -0
- package/dist/tutorials/Prompts.md +48 -44
- package/dist/tutorials/Providers-and-Keys.md +105 -98
- package/dist/tutorials/Publishing-to-YouTube.md +31 -31
- package/dist/tutorials/Recovery-and-Retries.md +31 -31
- package/dist/tutorials/Remote-Access.md +63 -0
- package/dist/tutorials/Reviews-and-Checkpoints.md +98 -90
- package/dist/tutorials/Schedules.md +46 -27
- package/dist/tutorials/Settings-Reference.md +194 -174
- package/dist/tutorials/Shorts.md +34 -33
- package/dist/tutorials/Start-at-Login.md +3 -3
- package/dist/tutorials/Studio-Extension.md +22 -24
- package/dist/tutorials/Template-Studio.md +128 -0
- package/dist/tutorials/Templates.md +51 -77
- package/dist/tutorials/Trash.md +4 -4
- package/dist/tutorials/Troubleshooting.md +44 -44
- package/dist/tutorials/Uninstalling-and-Moving.md +5 -5
- package/dist/tutorials/Updating-and-Patch-Notes.md +18 -18
- package/dist/tutorials/Video-Editing.md +34 -34
- package/dist/tutorials/Where-Your-Files-Live.md +10 -10
- package/dist/tutorials/YouTube-Description.md +26 -26
- package/dist/tutorials/Your-First-Short.md +35 -35
- package/dist/tutorials/_Sidebar.md +19 -14
- package/dist/updater/work-in-progress.js +42 -12
- package/dist/web/assets/index-BNftKQrA.css +1 -0
- package/dist/web/assets/index-Cpa58woP.js +459 -0
- package/dist/web/assets/pdf-BKh8f7R6.js +56 -0
- package/dist/web/assets/pdf.worker.min-BmVo14Nb.mjs +28 -0
- package/dist/web/assets/pdf.worker.min-D7i8o3wR.js +1 -0
- package/dist/web/index.html +2 -2
- package/package.json +6 -2
- package/dist/slices/article/provided-entries.js +0 -66
- package/dist/slices/article/run.js +0 -145
- package/dist/slices/images/run.js +0 -234
- package/dist/slices/narration/legacy-plan.js +0 -58
- package/dist/slices/narration/run.js +0 -270
- package/dist/slices/rebuild/runtime-actions.js +0 -90
- package/dist/slices/research/run.js +0 -224
- package/dist/slices/subtitles/prepare.js +0 -194
- package/dist/slices/subtitles/transcript.js +0 -34
- package/dist/slices/thumbnail/run.js +0 -219
- package/dist/slices/video/audio-inputs.js +0 -33
- package/dist/slices/video/reuse-audio.js +0 -62
- package/dist/slices/video/run.js +0 -78
- package/dist/slices/video/write-export.js +0 -158
- package/dist/slices/video/write-subtitles.js +0 -59
- package/dist/tutorials/Library-Overview.md +0 -76
- package/dist/tutorials/Play-Images.md +0 -161
- package/dist/tutorials/Play-Narration.md +0 -167
- package/dist/tutorials/Play-Outputs.md +0 -109
- package/dist/tutorials/Play-Overview.md +0 -227
- package/dist/tutorials/Play-Title-and-Article.md +0 -136
- package/dist/tutorials/Play-Video-and-Style.md +0 -143
- package/dist/web/assets/index-BadsoORk.css +0 -1
- package/dist/web/assets/index-D8LqNsCl.js +0 -326
- package/dist/web/assets/pdf-T7MCwjIv.js +0 -54
- package/dist/web/assets/pdf.worker.min-Dswkl-cV.mjs +0 -29
- package/dist/web/assets/pdf.worker.min-zC6nfbxG.js +0 -1
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import { detectSlots } from "../admission/substitute.js";
|
|
2
|
+
// What a template's paid sample makes: a short taste of one video about the sample topic, so a
|
|
3
|
+
// Save costs cents, not a whole video. The limits are the document's (fewer pictures, one
|
|
4
|
+
// thumbnail, one short, no checkpoints) and the steps' (`config.sample`: the article's outline
|
|
5
|
+
// and first chapter, the narration's opening).
|
|
6
|
+
// The most pictures a sample draws.
|
|
7
|
+
export const samplePictures = 4;
|
|
8
|
+
// The narration a sample says: about 30 seconds, the length of the video sample.
|
|
9
|
+
export const sampleSpokenWords = 80;
|
|
10
|
+
// The shortest short a sample cuts: its narration is only about 30-45 seconds, so a template's
|
|
11
|
+
// own minimum (45 s or more for the starter packs) would leave nothing to cut.
|
|
12
|
+
export const sampleShortMinSeconds = 15;
|
|
13
|
+
// Put under the article prompt of a sample, unless the person asked for the full script. The
|
|
14
|
+
// prompt anatomy shows it as Slopify's.
|
|
15
|
+
export const sampleArticleInstruction = "This is a short sample of the script: write the outline and only chapter 1, then stop.";
|
|
16
|
+
// The template's setup as its sample runs it. Every keyword the title names and the template
|
|
17
|
+
// leaves empty is the topic; a title without one is the topic itself. A section the user
|
|
18
|
+
// provides at run time has no sample, so it is off here, with no file to attach; text the
|
|
19
|
+
// template holds is kept.
|
|
20
|
+
export function sampleDocument(template, scope) {
|
|
21
|
+
const { form } = template;
|
|
22
|
+
const topic = scope.topic.trim();
|
|
23
|
+
const names = detectSlots(form.title).names;
|
|
24
|
+
const values = Object.create(null);
|
|
25
|
+
for (const [name, value] of Object.entries(form.values))
|
|
26
|
+
values[name] = value;
|
|
27
|
+
for (const name of names)
|
|
28
|
+
if ((values[name] ?? "").trim() === "")
|
|
29
|
+
values[name] = topic;
|
|
30
|
+
const off = (source) => (source === "provide" ? "off" : source);
|
|
31
|
+
// Text the template itself holds (pasted research or article) is the same in every run, so
|
|
32
|
+
// the sample uses it; a file is added to each video in Play, so there is none here.
|
|
33
|
+
const kept = (source, text) => source === "provide" && text.trim() !== "" ? source : off(source);
|
|
34
|
+
const research = kept(form.sources.research, form.provided.research);
|
|
35
|
+
const article = kept(form.sources.article, form.provided.article);
|
|
36
|
+
const sources = {
|
|
37
|
+
research,
|
|
38
|
+
article,
|
|
39
|
+
audio: off(form.sources.audio),
|
|
40
|
+
images: off(form.sources.images),
|
|
41
|
+
thumbnail: off(form.sources.thumbnail),
|
|
42
|
+
video: off(form.sources.video),
|
|
43
|
+
...(form.sources.document === undefined ? {} : { document: off(form.sources.document) }),
|
|
44
|
+
};
|
|
45
|
+
const reviews = form.reviews === undefined
|
|
46
|
+
? undefined
|
|
47
|
+
: form.reviews.reviewer === "agent"
|
|
48
|
+
? // An agent's reviews are answered outside Slopify: the sample never asks it.
|
|
49
|
+
{ ...form.reviews, stages: {} }
|
|
50
|
+
: form.reviews;
|
|
51
|
+
const { imageScale: _scaled, ...unscaled } = form;
|
|
52
|
+
return {
|
|
53
|
+
...template,
|
|
54
|
+
variants: [],
|
|
55
|
+
form: {
|
|
56
|
+
...unscaled,
|
|
57
|
+
title: names.length === 0 ? topic : form.title,
|
|
58
|
+
values,
|
|
59
|
+
sources,
|
|
60
|
+
checkpoints: [],
|
|
61
|
+
thumbnailCount: 1,
|
|
62
|
+
imagePrompts: cappedPrompts(form.imagePrompts, samplePictures),
|
|
63
|
+
...(form.shorts === undefined
|
|
64
|
+
? {}
|
|
65
|
+
: {
|
|
66
|
+
shorts: {
|
|
67
|
+
...form.shorts,
|
|
68
|
+
count: form.shorts.enabled ? "1" : form.shorts.count,
|
|
69
|
+
minSeconds: sampleShortMinimum(form.shorts.minSeconds),
|
|
70
|
+
},
|
|
71
|
+
}),
|
|
72
|
+
...(reviews === undefined ? {} : { reviews }),
|
|
73
|
+
...(form.reference === undefined || form.reference.source !== "provide"
|
|
74
|
+
? {}
|
|
75
|
+
: { reference: { ...form.reference, source: "off" } }),
|
|
76
|
+
...(form.ambientBed === undefined || form.ambientBed.source !== "upload"
|
|
77
|
+
? {}
|
|
78
|
+
: { ambientBed: { ...form.ambientBed, source: "none" } }),
|
|
79
|
+
provided: {
|
|
80
|
+
research: research === "provide" ? form.provided.research : "",
|
|
81
|
+
article: article === "provide" ? form.provided.article : "",
|
|
82
|
+
audio: null,
|
|
83
|
+
thumbnail: null,
|
|
84
|
+
images: [],
|
|
85
|
+
...(form.provided.reference === undefined ? {} : { reference: null }),
|
|
86
|
+
...(form.provided.shortsMusic === undefined ? {} : { shortsMusic: null }),
|
|
87
|
+
...(form.provided.ambientBed === undefined ? {} : { ambientBed: null }),
|
|
88
|
+
},
|
|
89
|
+
},
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
// The image prompts with at most `most` pictures between them, in order: each keeps its own
|
|
93
|
+
// number while they fit, and a prompt past the limit draws none.
|
|
94
|
+
function cappedPrompts(prompts, most) {
|
|
95
|
+
let left = most;
|
|
96
|
+
return prompts.flatMap((prompt) => {
|
|
97
|
+
const wanted = Number.parseInt(prompt.number, 10);
|
|
98
|
+
const count = Math.min(Number.isFinite(wanted) && wanted > 0 ? wanted : 1, left);
|
|
99
|
+
left -= count;
|
|
100
|
+
return count > 0 ? [{ ...prompt, number: String(count) }] : [];
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
// The opening of the narration a sample says: whole sentences up to about `words` words, at
|
|
104
|
+
// least the first sentence.
|
|
105
|
+
export function sampleNarrationText(text, words = sampleSpokenWords) {
|
|
106
|
+
const sentences = text.match(/[^.!?\n]+(?:[.!?]+["')\]]*|\n+|$)/gu) ?? [text];
|
|
107
|
+
let kept = "";
|
|
108
|
+
let count = 0;
|
|
109
|
+
for (const sentence of sentences) {
|
|
110
|
+
const size = sentence.split(/\s+/u).filter((word) => word !== "").length;
|
|
111
|
+
if (kept !== "" && count + size > words)
|
|
112
|
+
break;
|
|
113
|
+
kept += sentence;
|
|
114
|
+
count += size;
|
|
115
|
+
}
|
|
116
|
+
return kept.trim();
|
|
117
|
+
}
|
|
118
|
+
// The template's minimum, or the sample's when the template's is longer (or not a number).
|
|
119
|
+
function sampleShortMinimum(minSeconds) {
|
|
120
|
+
const wanted = Number.parseInt(minSeconds, 10);
|
|
121
|
+
return Number.isFinite(wanted) && wanted <= sampleShortMinSeconds
|
|
122
|
+
? minSeconds
|
|
123
|
+
: String(sampleShortMinSeconds);
|
|
124
|
+
}
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
import { templateSections } from "./model.js";
|
|
2
|
+
export const sourceSections = {
|
|
3
|
+
research: "subject",
|
|
4
|
+
article: "script",
|
|
5
|
+
audio: "voice",
|
|
6
|
+
images: "pictures",
|
|
7
|
+
thumbnail: "thumbnail",
|
|
8
|
+
video: "video",
|
|
9
|
+
document: "document",
|
|
10
|
+
};
|
|
11
|
+
const providedSections = {
|
|
12
|
+
research: "subject",
|
|
13
|
+
article: "script",
|
|
14
|
+
audio: "voice",
|
|
15
|
+
thumbnail: "thumbnail",
|
|
16
|
+
images: "pictures",
|
|
17
|
+
reference: "pictures",
|
|
18
|
+
shortsMusic: "shorts",
|
|
19
|
+
ambientBed: "video",
|
|
20
|
+
};
|
|
21
|
+
export const formSections = {
|
|
22
|
+
title: "subject",
|
|
23
|
+
language: "subject",
|
|
24
|
+
values: "subject",
|
|
25
|
+
checkpoints: "reviews",
|
|
26
|
+
reviews: "reviews",
|
|
27
|
+
format: "video",
|
|
28
|
+
sources: null,
|
|
29
|
+
provided: null,
|
|
30
|
+
llm: "script",
|
|
31
|
+
articlePrompt: "script",
|
|
32
|
+
intro: "script",
|
|
33
|
+
outro: "script",
|
|
34
|
+
audio: "voice",
|
|
35
|
+
narrationPrompt: "voice",
|
|
36
|
+
loudness: "voice",
|
|
37
|
+
sentencePause: "voice",
|
|
38
|
+
paragraphPause: "voice",
|
|
39
|
+
removeBreaths: "voice",
|
|
40
|
+
deEss: "voice",
|
|
41
|
+
levelSentences: "voice",
|
|
42
|
+
chunking: "voice",
|
|
43
|
+
voices: "voice",
|
|
44
|
+
images: "pictures",
|
|
45
|
+
reference: "pictures",
|
|
46
|
+
imagePrompts: "pictures",
|
|
47
|
+
imageScale: "pictures",
|
|
48
|
+
imageScenes: "pictures",
|
|
49
|
+
subtitles: "video",
|
|
50
|
+
imageSeconds: "video",
|
|
51
|
+
edgeSilenceSeconds: "video",
|
|
52
|
+
zoomPercent: "video",
|
|
53
|
+
motionStyle: "video",
|
|
54
|
+
silenceGapSeconds: "video",
|
|
55
|
+
videoEdit: "video",
|
|
56
|
+
ambientBed: "video",
|
|
57
|
+
showFigures: "video",
|
|
58
|
+
useBrandKit: "video",
|
|
59
|
+
thumbnailPrompt: "thumbnail",
|
|
60
|
+
thumbnailCount: "thumbnail",
|
|
61
|
+
shorts: "shorts",
|
|
62
|
+
document: "document",
|
|
63
|
+
youtubeDescription: "upload",
|
|
64
|
+
descriptionPrompt: "upload",
|
|
65
|
+
social: "upload",
|
|
66
|
+
};
|
|
67
|
+
export const documentSections = {
|
|
68
|
+
schemaVersion: null,
|
|
69
|
+
librarySnapshot: null,
|
|
70
|
+
templateSource: null,
|
|
71
|
+
section: null,
|
|
72
|
+
channelId: "subject",
|
|
73
|
+
variants: "subject",
|
|
74
|
+
queue: "schedule",
|
|
75
|
+
expectedWords: "script",
|
|
76
|
+
previewText: "voice",
|
|
77
|
+
fontUpload: "video",
|
|
78
|
+
};
|
|
79
|
+
// The section a setting belongs to, by its path in the template document (`form.audio.voice`).
|
|
80
|
+
// Null for what no section shows (the schema version, Play's open tab).
|
|
81
|
+
export function sectionOfField(path) {
|
|
82
|
+
const [top, field, key] = path;
|
|
83
|
+
if (top !== "form")
|
|
84
|
+
return top === undefined ? null : (lookup(documentSections, top) ?? null);
|
|
85
|
+
if (field === "sources")
|
|
86
|
+
return key === undefined ? null : (lookup(sourceSections, key) ?? null);
|
|
87
|
+
if (field === "provided")
|
|
88
|
+
return key === undefined ? null : (lookup(providedSections, key) ?? null);
|
|
89
|
+
return field === undefined ? null : (lookup(formSections, field) ?? null);
|
|
90
|
+
}
|
|
91
|
+
function lookup(table, key) {
|
|
92
|
+
return Object.hasOwn(table, key) ? table[key] : undefined;
|
|
93
|
+
}
|
|
94
|
+
// The section a piece of rebuild work shows its sample in, by its work key (`article:body`,
|
|
95
|
+
// `image:harbor`, `review:article:body`). Undefined for a key no section shows.
|
|
96
|
+
export function sectionOfWork(key) {
|
|
97
|
+
if (key.startsWith("review:"))
|
|
98
|
+
return "reviews";
|
|
99
|
+
const prefix = key.split(":")[0] ?? "";
|
|
100
|
+
return workPrefixes[prefix];
|
|
101
|
+
}
|
|
102
|
+
const workPrefixes = {
|
|
103
|
+
research: "subject",
|
|
104
|
+
article: "script",
|
|
105
|
+
entry: "script",
|
|
106
|
+
script: "script",
|
|
107
|
+
audio: "voice",
|
|
108
|
+
narration: "voice",
|
|
109
|
+
level: "voice",
|
|
110
|
+
voices: "voice",
|
|
111
|
+
image: "pictures",
|
|
112
|
+
images: "pictures",
|
|
113
|
+
reference: "pictures",
|
|
114
|
+
figure: "pictures",
|
|
115
|
+
thumbnail: "thumbnail",
|
|
116
|
+
export: "video",
|
|
117
|
+
subtitles: "video",
|
|
118
|
+
video: "video",
|
|
119
|
+
animate: "video",
|
|
120
|
+
shorts: "shorts",
|
|
121
|
+
youtube: "upload",
|
|
122
|
+
social: "upload",
|
|
123
|
+
document: "document",
|
|
124
|
+
};
|
|
125
|
+
// What a section's sample is made from: a change in a section outdates the samples after it.
|
|
126
|
+
// Reviews judge the script, voice, pictures and thumbnail, so a change there outdates reviews;
|
|
127
|
+
// the schedule depends on nothing but itself and the subject (titles come from the topics).
|
|
128
|
+
const dependents = {
|
|
129
|
+
subject: ["script", "schedule"],
|
|
130
|
+
script: ["voice", "pictures", "thumbnail", "document", "upload", "reviews"],
|
|
131
|
+
voice: ["video", "reviews"],
|
|
132
|
+
pictures: ["video", "thumbnail", "reviews"],
|
|
133
|
+
video: ["shorts", "upload"],
|
|
134
|
+
thumbnail: ["reviews"],
|
|
135
|
+
shorts: [],
|
|
136
|
+
document: [],
|
|
137
|
+
reviews: [],
|
|
138
|
+
upload: [],
|
|
139
|
+
schedule: [],
|
|
140
|
+
};
|
|
141
|
+
// Every section whose sample a change from `before` to `after` outdates, in pipeline order.
|
|
142
|
+
export function affectedSections(before, after) {
|
|
143
|
+
const changed = new Set();
|
|
144
|
+
for (const path of changedPaths(before, after, [])) {
|
|
145
|
+
const section = sectionOfField(path);
|
|
146
|
+
if (section !== null)
|
|
147
|
+
changed.add(section);
|
|
148
|
+
}
|
|
149
|
+
return withDependents([...changed]);
|
|
150
|
+
}
|
|
151
|
+
// The sections given and every section whose sample is made from them, in pipeline order.
|
|
152
|
+
export function withDependents(sections) {
|
|
153
|
+
const affected = new Set();
|
|
154
|
+
const visit = (section) => {
|
|
155
|
+
if (affected.has(section))
|
|
156
|
+
return;
|
|
157
|
+
affected.add(section);
|
|
158
|
+
for (const next of dependents[section])
|
|
159
|
+
visit(next);
|
|
160
|
+
};
|
|
161
|
+
for (const section of sections)
|
|
162
|
+
visit(section);
|
|
163
|
+
return templateSections.filter((section) => affected.has(section));
|
|
164
|
+
}
|
|
165
|
+
// Paths go down to the third level (`form.sources.audio`), where every section boundary lies.
|
|
166
|
+
function changedPaths(before, after, path) {
|
|
167
|
+
if (JSON.stringify(before) === JSON.stringify(after))
|
|
168
|
+
return [];
|
|
169
|
+
if (path.length >= 3 || !isRecord(before) || !isRecord(after))
|
|
170
|
+
return [path];
|
|
171
|
+
const keys = new Set([...Object.keys(before), ...Object.keys(after)]);
|
|
172
|
+
return [...keys].flatMap((key) => changedPaths(before[key], after[key], [...path, key]));
|
|
173
|
+
}
|
|
174
|
+
function isRecord(value) {
|
|
175
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
176
|
+
}
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { readinessIsUsable } from "../../kernel/ports/model.js";
|
|
3
|
+
import { lastAgentConnection } from "../agents/connection.js";
|
|
4
|
+
import { snapshotEntry, snapshotPrompt } from "../library/snapshot.js";
|
|
5
|
+
import { readNotificationUrl } from "../notifications/settings.js";
|
|
6
|
+
import { templateById } from "../project-templates/repo.js";
|
|
7
|
+
import { scheduleRows } from "../schedules/repo.js";
|
|
8
|
+
import { readProviderDefaults } from "../settings/first-run.js";
|
|
9
|
+
import { listVoices, readJsonSetting } from "../settings/repo.js";
|
|
10
|
+
import { freeChecks } from "./checks.js";
|
|
11
|
+
import { checkedVersion, gateOf, isGated, runnableVersion } from "./gate.js";
|
|
12
|
+
import { queuedJob, runningJob } from "./jobs.js";
|
|
13
|
+
import { fallbackSampleTopic } from "./model.js";
|
|
14
|
+
import { paidView } from "./paid-view.js";
|
|
15
|
+
import { gatesOf, sampleOf } from "./repo.js";
|
|
16
|
+
import { reviewsPath } from "./reviews-path.js";
|
|
17
|
+
import { monthlyCost, upcomingRuns } from "./schedule-sample.js";
|
|
18
|
+
import { baseStatuses, madeStatuses } from "./status.js";
|
|
19
|
+
export function createPriceCache() {
|
|
20
|
+
// ceiling: one entry per schedule and template version seen since boot, a few bytes each.
|
|
21
|
+
const prices = new Map();
|
|
22
|
+
return { get: (key) => prices.get(key), set: (key, price) => void prices.set(key, price) };
|
|
23
|
+
}
|
|
24
|
+
export function priceKey(schedule, template) {
|
|
25
|
+
return `${schedule.id}@${String(schedule.version)}:${template.id}@${String(template.version)}`;
|
|
26
|
+
}
|
|
27
|
+
export const sampleTopicKey = "templateStudio.sampleTopic.default";
|
|
28
|
+
export function defaultSampleTopic(db) {
|
|
29
|
+
const topic = readJsonSetting(db, sampleTopicKey, z.string(), fallbackSampleTopic).trim();
|
|
30
|
+
return topic === "" ? fallbackSampleTopic : topic;
|
|
31
|
+
}
|
|
32
|
+
// The schedules that run a template now: not deleted, not finished.
|
|
33
|
+
export function templateSchedules(db, templateId) {
|
|
34
|
+
return scheduleRows(db).filter((schedule) =>
|
|
35
|
+
// A design schedule names a design template, never a project template.
|
|
36
|
+
schedule.templateKind === "project" &&
|
|
37
|
+
schedule.templateId === templateId &&
|
|
38
|
+
schedule.deletedAt === null &&
|
|
39
|
+
(schedule.status === "active" || schedule.status === "paused"));
|
|
40
|
+
}
|
|
41
|
+
function fitOf(schedule) {
|
|
42
|
+
const { cadence } = schedule;
|
|
43
|
+
return {
|
|
44
|
+
id: schedule.id,
|
|
45
|
+
name: schedule.name,
|
|
46
|
+
topicKeyword: schedule.topicKeyword,
|
|
47
|
+
runDays: cadence.kind === "weekly"
|
|
48
|
+
? cadence.days
|
|
49
|
+
: cadence.kind === "daily"
|
|
50
|
+
? [0, 1, 2, 3, 4, 5, 6]
|
|
51
|
+
: [],
|
|
52
|
+
releases: schedule.releases.map((release) => ({
|
|
53
|
+
day: release.day,
|
|
54
|
+
shorts: release.shorts.length,
|
|
55
|
+
})),
|
|
56
|
+
paused: schedule.status === "paused",
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
function bodiesOf(db, document) {
|
|
60
|
+
const snapshot = document.librarySnapshot;
|
|
61
|
+
if (snapshot === undefined)
|
|
62
|
+
return [];
|
|
63
|
+
return [
|
|
64
|
+
...snapshot.prompts.map((prompt) => snapshotPrompt(db, snapshot, prompt.kind, prompt.name)?.body ?? prompt.body),
|
|
65
|
+
...snapshot.entries.map((entry) => snapshotEntry(db, snapshot, entry.category, entry.name)?.body ?? entry.body),
|
|
66
|
+
];
|
|
67
|
+
}
|
|
68
|
+
// The providers' readiness probes CLIs, which takes seconds: every caller in the window
|
|
69
|
+
// shares one lookup, and a failed one is never kept.
|
|
70
|
+
export function createReadinessCache(load, now = Date.now, ttlMs = 30_000) {
|
|
71
|
+
let held;
|
|
72
|
+
return () => {
|
|
73
|
+
const at = now();
|
|
74
|
+
if (held !== undefined && at - held.at < ttlMs)
|
|
75
|
+
return held.value;
|
|
76
|
+
const value = load();
|
|
77
|
+
const entry = { at, value };
|
|
78
|
+
held = entry;
|
|
79
|
+
value.catch(() => {
|
|
80
|
+
if (held === entry)
|
|
81
|
+
held = undefined;
|
|
82
|
+
});
|
|
83
|
+
return value;
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
const missingTemplate = "This template no longer exists; it may have been deleted. Go to Templates to see your templates.";
|
|
87
|
+
// The studio page's content, answered without waiting for the providers' readiness: the
|
|
88
|
+
// checks that need it are read on their own (`getStudioChecks`).
|
|
89
|
+
export async function getStudio(deps, id) {
|
|
90
|
+
const template = templateById(deps.db, id);
|
|
91
|
+
if (template === undefined)
|
|
92
|
+
return { ok: false, reason: "not-found", message: missingTemplate };
|
|
93
|
+
const gates = gatesOf(deps.db, id);
|
|
94
|
+
const sample = sampleOf(deps.db, id);
|
|
95
|
+
const schedules = templateSchedules(deps.db, id);
|
|
96
|
+
const now = deps.clock.now();
|
|
97
|
+
const cost = monthlyCost(schedules, pricesOf(deps, schedules, template), now);
|
|
98
|
+
const running = runningJob(deps.db);
|
|
99
|
+
const queued = queuedJob(deps.db, id);
|
|
100
|
+
const free = deps.free.view(id, template.document, {
|
|
101
|
+
running: running?.templateId === id && running.templateVersion === template.version,
|
|
102
|
+
queued: queued !== undefined,
|
|
103
|
+
});
|
|
104
|
+
const paid = paidView(deps, id, template);
|
|
105
|
+
return {
|
|
106
|
+
ok: true,
|
|
107
|
+
value: {
|
|
108
|
+
template,
|
|
109
|
+
gate: gateOf(gates, template.version),
|
|
110
|
+
runnableVersion: runnableVersion(gates, template.version) ?? null,
|
|
111
|
+
gated: isGated(gates),
|
|
112
|
+
checkedVersion: checkedVersion(gates, template.version) ?? null,
|
|
113
|
+
sample: {
|
|
114
|
+
topic: sample?.topic ?? defaultSampleTopic(deps.db),
|
|
115
|
+
topicSource: sample?.topicSource ?? "fixed",
|
|
116
|
+
fullScript: sample?.fullScript ?? false,
|
|
117
|
+
},
|
|
118
|
+
sections: carriedSentences(baseStatuses(template.document, {
|
|
119
|
+
...madeStatuses(free, schedules.length, cost),
|
|
120
|
+
...paid.statuses,
|
|
121
|
+
}), gates.find((gate) => gate.version === template.version)),
|
|
122
|
+
paid: paid.view,
|
|
123
|
+
free,
|
|
124
|
+
schedule: { runs: upcomingRuns(schedules, template.document, now), cost },
|
|
125
|
+
reviews: reviewsPath(template.document),
|
|
126
|
+
},
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
// A version Slopify wrote itself keeps its gate, but what it changed has no sample yet: each
|
|
130
|
+
// stale section says who made the change.
|
|
131
|
+
function carriedSentences(sections, gate) {
|
|
132
|
+
if (gate?.state !== "carried" || gate.carriedFrom === null)
|
|
133
|
+
return sections;
|
|
134
|
+
const why = `Slopify made version ${String(gate.version)} from version ${String(gate.carriedFrom)} itself (a retired model switched, or a new name on restore).`;
|
|
135
|
+
return sections.map((section) => section.state === "stale" ? { ...section, sentence: `${why} ${section.sentence}` } : section);
|
|
136
|
+
}
|
|
137
|
+
function pricesOf(deps, schedules, template) {
|
|
138
|
+
return new Map(schedules.flatMap((schedule) => {
|
|
139
|
+
const price = deps.prices.get(priceKey(schedule, template));
|
|
140
|
+
return price === undefined ? [] : [[schedule.id, price]];
|
|
141
|
+
}));
|
|
142
|
+
}
|
|
143
|
+
// The free checks a template passes before Mark ready. The providers' readiness is the slow
|
|
144
|
+
// part, so the page asks for these on their own.
|
|
145
|
+
export async function getStudioChecks(deps, id) {
|
|
146
|
+
const template = templateById(deps.db, id);
|
|
147
|
+
if (template === undefined)
|
|
148
|
+
return { ok: false, reason: "not-found", message: missingTemplate };
|
|
149
|
+
const statuses = await deps.providerStatuses();
|
|
150
|
+
const schedules = templateSchedules(deps.db, id);
|
|
151
|
+
const now = deps.clock.now();
|
|
152
|
+
const cost = monthlyCost(schedules, pricesOf(deps, schedules, template), now);
|
|
153
|
+
return {
|
|
154
|
+
ok: true,
|
|
155
|
+
value: {
|
|
156
|
+
version: template.version,
|
|
157
|
+
checks: freeChecks({
|
|
158
|
+
templateId: id,
|
|
159
|
+
document: template.document,
|
|
160
|
+
bodies: bodiesOf(deps.db, template.document),
|
|
161
|
+
providers: new Map(statuses.map((status) => [
|
|
162
|
+
status.id,
|
|
163
|
+
{ name: status.displayName, ready: readinessIsUsable(status.readiness) },
|
|
164
|
+
])),
|
|
165
|
+
defaults: readProviderDefaults(deps.db),
|
|
166
|
+
schedules: schedules.map(fitOf),
|
|
167
|
+
voices: listVoices(deps.db),
|
|
168
|
+
monthlyCost: cost,
|
|
169
|
+
notificationUrl: readNotificationUrl(deps.db) !== null,
|
|
170
|
+
agentSeenAt: lastAgentConnection(deps.db),
|
|
171
|
+
now,
|
|
172
|
+
}),
|
|
173
|
+
},
|
|
174
|
+
};
|
|
175
|
+
}
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
import { sectionLabel, templateSections, } from "./model.js";
|
|
2
|
+
import { affectedSections } from "./sections.js";
|
|
3
|
+
// What a section's sample is made from, by the step that makes it; null for a section whose
|
|
4
|
+
// sample never depends on a source (the schedule).
|
|
5
|
+
function sourceOf(document, section) {
|
|
6
|
+
const { form } = document;
|
|
7
|
+
switch (section) {
|
|
8
|
+
// Text the template itself holds is in every run, and in its sample (`scope.ts`).
|
|
9
|
+
case "subject":
|
|
10
|
+
return heldText(form.sources.research, form.provided.research);
|
|
11
|
+
case "script":
|
|
12
|
+
return heldText(form.sources.article, form.provided.article);
|
|
13
|
+
case "voice":
|
|
14
|
+
return form.sources.audio;
|
|
15
|
+
case "pictures":
|
|
16
|
+
return form.sources.images;
|
|
17
|
+
case "thumbnail":
|
|
18
|
+
return form.sources.thumbnail;
|
|
19
|
+
case "video":
|
|
20
|
+
return form.sources.video;
|
|
21
|
+
case "document":
|
|
22
|
+
return form.sources.document ?? "off";
|
|
23
|
+
case "shorts":
|
|
24
|
+
return form.shorts?.enabled === true && form.sources.video !== "off" ? "generate" : "off";
|
|
25
|
+
case "upload":
|
|
26
|
+
return form.sources.video;
|
|
27
|
+
case "reviews": {
|
|
28
|
+
const on = (form.checkpoints?.length ?? 0) > 0 ||
|
|
29
|
+
Object.values(form.reviews?.stages ?? {}).some((stage) => stage.mode !== "off");
|
|
30
|
+
return on ? "generate" : "off";
|
|
31
|
+
}
|
|
32
|
+
case "schedule":
|
|
33
|
+
return null;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
function heldText(source, text) {
|
|
37
|
+
return source === "provide" && text.trim() !== "" ? "held" : source;
|
|
38
|
+
}
|
|
39
|
+
// One press of Make sample makes every paid section's sample at once, so its sentence names
|
|
40
|
+
// them: "Make sample makes the samples of Title and keywords, Article and Narration together,
|
|
41
|
+
// about the sample topic."
|
|
42
|
+
export function makeSampleSentence(document) {
|
|
43
|
+
const made = paidSections
|
|
44
|
+
.filter((id) => {
|
|
45
|
+
const source = sourceOf(document, id);
|
|
46
|
+
return source !== "off" && source !== "provide";
|
|
47
|
+
})
|
|
48
|
+
.map((id) => sectionLabel[id]);
|
|
49
|
+
if (made.length <= 1)
|
|
50
|
+
return "Make sample shows what this section makes, about the sample topic.";
|
|
51
|
+
const names = `${made.slice(0, -1).join(", ")} and ${made.at(-1) ?? ""}`;
|
|
52
|
+
return `Make sample makes the samples of ${names} together, about the sample topic.`;
|
|
53
|
+
}
|
|
54
|
+
const offSentence = {
|
|
55
|
+
subject: "Research is off: the script is written from the topic alone.",
|
|
56
|
+
script: "The article is off.",
|
|
57
|
+
voice: "The narration is off.",
|
|
58
|
+
pictures: "Images are off.",
|
|
59
|
+
thumbnail: "The thumbnail is off.",
|
|
60
|
+
video: "The video is off.",
|
|
61
|
+
shorts: "Shorts are off.",
|
|
62
|
+
document: "The PDF is off.",
|
|
63
|
+
reviews: "No pause or AI check is on.",
|
|
64
|
+
upload: "No video, so there is no YouTube description or post.",
|
|
65
|
+
schedule: "",
|
|
66
|
+
};
|
|
67
|
+
// Each section's state before any sample: off, provided at run time (no sample, never blocks
|
|
68
|
+
// Mark ready), or waiting for its first sample. Samples made since replace these (`free` and,
|
|
69
|
+
// later, the paid samples' versions).
|
|
70
|
+
export function baseStatuses(document, made = {}) {
|
|
71
|
+
return templateSections.map((id) => {
|
|
72
|
+
const label = sectionLabel[id];
|
|
73
|
+
const source = sourceOf(document, id);
|
|
74
|
+
if (source === "off")
|
|
75
|
+
return { id, label, state: "off", sentence: offSentence[id] };
|
|
76
|
+
if (source === "provide")
|
|
77
|
+
return {
|
|
78
|
+
id,
|
|
79
|
+
label,
|
|
80
|
+
state: "provided",
|
|
81
|
+
sentence: "Provided at run time: you add the file to each video, so there is no sample.",
|
|
82
|
+
};
|
|
83
|
+
return (made[id] ?? {
|
|
84
|
+
id,
|
|
85
|
+
label,
|
|
86
|
+
state: "stale",
|
|
87
|
+
sentence: paidSections.includes(id)
|
|
88
|
+
? makeSampleSentence(document)
|
|
89
|
+
: "Make sample shows what this section makes, about the sample topic.",
|
|
90
|
+
});
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
// What the free samples say of their sections. The voice's own sample is a paid one; until it
|
|
94
|
+
// is made, Voice shows the loudness before and after.
|
|
95
|
+
export function madeStatuses(free, schedules, cost) {
|
|
96
|
+
const of = (id, sample) => sample.state === "off"
|
|
97
|
+
? undefined
|
|
98
|
+
: { id, label: sectionLabel[id], state: sample.state, sentence: sample.sentence };
|
|
99
|
+
const made = {};
|
|
100
|
+
const video = of("video", free.video);
|
|
101
|
+
if (video !== undefined)
|
|
102
|
+
made.video = video;
|
|
103
|
+
const voice = of("voice", free.loudness);
|
|
104
|
+
if (voice !== undefined)
|
|
105
|
+
made.voice = voice;
|
|
106
|
+
const document = of("document", free.document);
|
|
107
|
+
if (document !== undefined)
|
|
108
|
+
made.document = document;
|
|
109
|
+
made.reviews = {
|
|
110
|
+
id: "reviews",
|
|
111
|
+
label: sectionLabel.reviews,
|
|
112
|
+
state: "current",
|
|
113
|
+
sentence: "Where a run pauses for you, and which AI checks run.",
|
|
114
|
+
};
|
|
115
|
+
made.schedule =
|
|
116
|
+
schedules === 0
|
|
117
|
+
? {
|
|
118
|
+
id: "schedule",
|
|
119
|
+
label: sectionLabel.schedule,
|
|
120
|
+
state: "off",
|
|
121
|
+
sentence: "No schedule runs this template yet.",
|
|
122
|
+
}
|
|
123
|
+
: {
|
|
124
|
+
id: "schedule",
|
|
125
|
+
label: sectionLabel.schedule,
|
|
126
|
+
state: cost?.problem === null || cost === null ? "current" : "stale",
|
|
127
|
+
sentence: cost?.problem ??
|
|
128
|
+
(cost !== null && cost.paused.schedules === schedules
|
|
129
|
+
? `${schedules === 1 ? "1 paused schedule uses" : `${String(schedules)} paused schedules use`} this template: its next runs once resumed, and what they would cost a month.`
|
|
130
|
+
: "The next runs with the titles their topics fill, and the cost a month."),
|
|
131
|
+
};
|
|
132
|
+
return made;
|
|
133
|
+
}
|
|
134
|
+
// The sections a paid sample shows: what the providers make. The video, the PDF and the
|
|
135
|
+
// schedule keep their free samples; the voice shows the loudness until a paid one is made.
|
|
136
|
+
export const paidSections = [
|
|
137
|
+
"subject",
|
|
138
|
+
"script",
|
|
139
|
+
"voice",
|
|
140
|
+
"pictures",
|
|
141
|
+
"thumbnail",
|
|
142
|
+
"shorts",
|
|
143
|
+
"upload",
|
|
144
|
+
];
|
|
145
|
+
// What each paid section's sample is for the current version: made for it, being made,
|
|
146
|
+
// waiting (with why and what to press), failed (with the step's own sentence), or made for an
|
|
147
|
+
// older version and outdated by a change since. A section the change since the last made
|
|
148
|
+
// sample never touched keeps that sample, current.
|
|
149
|
+
export function paidStatuses(input) {
|
|
150
|
+
const row = input.versions.find((one) => one.templateVersion === input.headVersion);
|
|
151
|
+
const done = input.versions.find((one) => one.state === "done" && one.templateVersion <= input.headVersion);
|
|
152
|
+
const madeFrom = done === undefined ? undefined : input.documentOf(done.templateVersion);
|
|
153
|
+
const changed = new Set(madeFrom === undefined || done === undefined
|
|
154
|
+
? paidSections
|
|
155
|
+
: affectedSections(madeFrom, input.headDocument));
|
|
156
|
+
const status = (id, state, sentence) => ({
|
|
157
|
+
id,
|
|
158
|
+
label: sectionLabel[id],
|
|
159
|
+
state,
|
|
160
|
+
sentence,
|
|
161
|
+
});
|
|
162
|
+
const made = {};
|
|
163
|
+
if (row === undefined && done === undefined)
|
|
164
|
+
return made;
|
|
165
|
+
for (const id of paidSections) {
|
|
166
|
+
if (row?.state === "done") {
|
|
167
|
+
made[id] = status(id, "current", `Made for version ${String(input.headVersion)}.`);
|
|
168
|
+
continue;
|
|
169
|
+
}
|
|
170
|
+
if (!changed.has(id) && done !== undefined) {
|
|
171
|
+
made[id] = status(id, "current", `Made for version ${String(done.templateVersion)}; nothing it shows changed since.`);
|
|
172
|
+
continue;
|
|
173
|
+
}
|
|
174
|
+
const pending = row?.state === "queued" || row?.state === "making";
|
|
175
|
+
if (pending && (input.running || row?.state === "making"))
|
|
176
|
+
made[id] = status(id, "making", `Making the sample of version ${String(input.headVersion)}.`);
|
|
177
|
+
else if (pending)
|
|
178
|
+
made[id] = status(id, "waiting", input.busyElsewhere
|
|
179
|
+
? "Waits for another template's sample to finish."
|
|
180
|
+
: "Queued: it starts in a moment.");
|
|
181
|
+
else if (row?.state === "held")
|
|
182
|
+
made[id] = status(id, "waiting", row.heldReason ?? "Waiting. Press Make sample to make it.");
|
|
183
|
+
else if (row?.state === "failed")
|
|
184
|
+
made[id] = status(id, "needs-fix", row.heldReason ?? "The sample failed. Press Make sample to try again.");
|
|
185
|
+
else
|
|
186
|
+
made[id] = status(id, "stale", done === undefined
|
|
187
|
+
? makeSampleSentence(input.headDocument)
|
|
188
|
+
: `Changed since the sample of version ${String(done.templateVersion)}. Press Make sample to see it again.`);
|
|
189
|
+
}
|
|
190
|
+
return made;
|
|
191
|
+
}
|