@gentbajko/slopify 3.25.9 → 4.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/dist/adapters/account-limits.js +30 -0
- package/dist/adapters/alignment/cache.js +3 -5
- package/dist/adapters/alignment/ctc.js +1 -2
- package/dist/adapters/alignment/lock.js +4 -3
- package/dist/adapters/alignment/multilingual.js +0 -3
- package/dist/adapters/alignment/prefetch.js +2 -1
- package/dist/adapters/alignment/worker.js +2 -1
- package/dist/adapters/explain.js +0 -3
- package/dist/adapters/ffmpeg.js +19 -1
- package/dist/adapters/host-cli/index.js +19 -3
- package/dist/adapters/http-failure.js +53 -0
- package/dist/adapters/image/codex.js +36 -4
- package/dist/adapters/image/fal.js +17 -50
- package/dist/adapters/image/google.js +31 -55
- package/dist/adapters/image/openai.js +20 -47
- package/dist/adapters/image/reference.js +36 -0
- package/dist/adapters/image/replicate.js +18 -47
- package/dist/adapters/interest/search-interest.js +113 -0
- package/dist/adapters/key-probes.js +53 -2
- package/dist/adapters/llm/antigravity.js +4 -0
- 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 +51 -98
- package/dist/adapters/llm/claude-code.js +13 -2
- package/dist/adapters/llm/codex-limits.js +27 -68
- package/dist/adapters/llm/codex-server-models.js +61 -109
- package/dist/adapters/llm/codex.js +12 -1
- package/dist/adapters/llm/openrouter.js +10 -47
- package/dist/adapters/llm/run-cli.js +6 -22
- 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 +19 -40
- package/dist/adapters/tts/inworld-async.js +4 -1
- package/dist/adapters/tts/inworld.js +3 -0
- package/dist/adapters/tts/openai.js +20 -50
- 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 +3 -1
- package/dist/catalog/schema.js +2 -0
- package/dist/catalog/store.js +39 -0
- 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 +4 -25
- package/dist/edge/http/actor.js +5 -3
- package/dist/edge/http/app.js +85 -10
- package/dist/edge/http/assistant.js +127 -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 +1 -3
- package/dist/edge/http/channel-memory.js +7 -20
- package/dist/edge/http/channels.js +13 -26
- package/dist/edge/http/checkpoints.js +33 -17
- 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 +2 -11
- package/dist/edge/http/draft-files.js +1 -3
- package/dist/edge/http/draft-problem.js +4 -9
- 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 +38 -13
- 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 +1 -14
- package/dist/edge/http/open-folder.js +5 -10
- package/dist/edge/http/outputs.js +4 -12
- package/dist/edge/http/patch-notes.js +4 -10
- package/dist/edge/http/planning.js +2 -6
- package/dist/edge/http/problem.js +2 -4
- package/dist/edge/http/project-create.js +1 -0
- package/dist/edge/http/project-templates.js +29 -17
- package/dist/edge/http/projects.js +2 -12
- package/dist/edge/http/prompts.js +7 -14
- package/dist/edge/http/pronunciations.js +1 -2
- package/dist/edge/http/providers.js +39 -24
- 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 +11 -24
- package/dist/edge/http/revision-files.js +5 -10
- package/dist/edge/http/revisions.js +10 -15
- package/dist/edge/http/run-cost.js +1 -2
- package/dist/edge/http/same-page.js +80 -0
- package/dist/edge/http/schedules.js +59 -32
- package/dist/edge/http/settings.js +22 -13
- package/dist/edge/http/social.js +282 -0
- package/dist/edge/http/staging.js +2 -4
- package/dist/edge/http/storage-files.js +5 -7
- package/dist/edge/http/storage.js +23 -23
- package/dist/edge/http/studio.js +23 -50
- package/dist/edge/http/style-preview.js +1 -4
- package/dist/edge/http/subtitles.js +3 -17
- package/dist/edge/http/template-studio.js +433 -0
- package/dist/edge/http/trash.js +10 -11
- 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 +2 -3
- 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 +25 -0
- package/dist/edge/mcp/http.js +11 -2
- package/dist/edge/mcp/instructions.js +5 -3
- package/dist/edge/mcp/library-tools.js +1 -0
- package/dist/edge/mcp/route-tool.js +35 -15
- package/dist/edge/mcp/server.js +13 -8
- package/dist/edge/mcp/tools-channels.js +2 -0
- package/dist/edge/mcp/tools-designs.js +165 -0
- package/dist/edge/mcp/tools-library.js +14 -2
- package/dist/edge/mcp/tools-planning.js +23 -4
- package/dist/edge/mcp/tools-projects.js +28 -1
- package/dist/edge/mcp/tools-runs.js +14 -1
- package/dist/edge/mcp/tools-schedules.js +28 -4
- package/dist/edge/mcp/tools-setup.js +61 -3
- package/dist/edge/mcp/tools-social.js +46 -0
- package/dist/edge/mcp/tools-storage.js +8 -0
- 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/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/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/runner/attempt.js +3 -1
- 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 +15 -10
- package/dist/kernel/runner/standalone.js +9 -5
- package/dist/main.js +334 -19
- package/dist/model-checks.js +166 -0
- package/dist/patch-notes/4.0.0.md +51 -0
- package/dist/patch-notes/index.json +6 -0
- package/dist/slices/admission/heads.js +2 -1
- package/dist/slices/admission/repo.js +2 -1
- package/dist/slices/admission/rules.js +43 -8
- 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/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 +79 -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 +342 -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 +4 -3
- package/dist/slices/channels/cast-images.js +2 -1
- 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 +6 -0
- package/dist/slices/channels/service.js +10 -0
- package/dist/slices/channels/videos.js +2 -14
- package/dist/slices/checkpoints/index.js +0 -1
- package/dist/slices/control/providers.js +0 -26
- 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 +128 -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 +222 -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/episodes/summarize.js +5 -1
- package/dist/slices/estimate/index.js +45 -7
- package/dist/slices/fonts/catalog.js +3 -2
- 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 +6 -15
- package/dist/slices/images/scenes.js +100 -27
- package/dist/slices/keywords/digest.js +84 -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 +2 -1
- package/dist/slices/library/used-by.js +25 -10
- package/dist/slices/loudness/loudnorm.js +51 -11
- 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 +112 -0
- package/dist/slices/model-checks/run.js +143 -0
- package/dist/slices/model-checks/service.js +198 -0
- package/dist/slices/model-upkeep/switch.js +70 -25
- package/dist/slices/model-upkeep/usage.js +26 -11
- package/dist/slices/narration/breaths.js +2 -1
- package/dist/slices/narration/clean-pieces.js +2 -1
- package/dist/slices/narration/concat.js +2 -1
- package/dist/slices/narration/peaks.js +3 -4
- package/dist/slices/narration/pronunciation-chunks.js +4 -3
- package/dist/slices/narration/pronunciation.js +3 -2
- 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 +2 -1
- package/dist/slices/onboarding/copy.js +2 -1
- package/dist/slices/onboarding/first-run.js +3 -2
- package/dist/slices/onboarding/full-video.js +3 -2
- package/dist/slices/onboarding/install.js +4 -3
- package/dist/slices/onboarding/model.js +0 -16
- package/dist/slices/onboarding/packs.js +22 -22
- package/dist/slices/onboarding/quick-short.js +2 -1
- package/dist/slices/onboarding/sample.js +0 -1
- package/dist/slices/onboarding/state.js +2 -11
- package/dist/slices/onboarding/template.js +2 -1
- package/dist/slices/patch-notes/library.js +3 -2
- package/dist/slices/play-drafts/convert.js +4 -0
- package/dist/slices/play-drafts/review-inputs.js +8 -2
- package/dist/slices/play-drafts/review.js +5 -4
- package/dist/slices/play-drafts/schema.js +4 -0
- package/dist/slices/project-templates/from-project.js +9 -2
- package/dist/slices/project-templates/repo.js +6 -1
- package/dist/slices/project-templates/setup.js +8 -0
- 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 +27 -9
- 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 +3 -3
- 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 +6 -3
- 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 +98 -28
- package/dist/slices/rebuild/recipe-visual.js +55 -16
- package/dist/slices/rebuild/recipe-work.js +15 -3
- package/dist/slices/rebuild/recipe-youtube.js +4 -3
- package/dist/slices/rebuild/recovery-selection.js +3 -1
- package/dist/slices/rebuild/recovery.js +3 -2
- package/dist/slices/rebuild/repo.js +4 -3
- package/dist/slices/rebuild/review-promise.js +25 -0
- package/dist/slices/rebuild/review-redo.js +2 -1
- 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 +9 -8
- package/dist/slices/rebuild/runtime-article.js +3 -2
- package/dist/slices/rebuild/runtime-checkpoints.js +5 -4
- package/dist/slices/rebuild/runtime-document.js +8 -11
- package/dist/slices/rebuild/runtime-export-bed.js +6 -11
- package/dist/slices/rebuild/runtime-export-edit.js +6 -15
- package/dist/slices/rebuild/runtime-export-inputs.js +7 -7
- package/dist/slices/rebuild/runtime-export-short.js +8 -4
- package/dist/slices/rebuild/runtime-export.js +34 -12
- package/dist/slices/rebuild/runtime-figure-card.js +2 -1
- package/dist/slices/rebuild/runtime-image.js +4 -9
- 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 +14 -20
- 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 +10 -15
- 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 +60 -19
- package/dist/slices/rebuild/runtime-publication.js +10 -9
- package/dist/slices/rebuild/runtime-review.js +33 -28
- package/dist/slices/rebuild/runtime-run.js +4 -1
- package/dist/slices/rebuild/runtime-shorts.js +25 -45
- package/dist/slices/rebuild/runtime-store.js +3 -8
- package/dist/slices/rebuild/runtime-subtitles.js +16 -14
- package/dist/slices/rebuild/runtime-voices.js +8 -15
- package/dist/slices/rebuild/runtime-youtube.js +11 -29
- 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/reviews/external-model.js +3 -0
- package/dist/slices/reviews/external-repo.js +2 -1
- package/dist/slices/reviews/external-rows.js +2 -3
- package/dist/slices/reviews/model.js +26 -8
- package/dist/slices/reviews/repo.js +2 -1
- package/dist/slices/reviews/rules.js +1 -0
- package/dist/slices/reviews/view.js +5 -2
- package/dist/slices/revisions/downloads.js +4 -5
- package/dist/slices/revisions/mutation-assets.js +7 -4
- package/dist/slices/revisions/mutation-cues.js +2 -5
- package/dist/slices/revisions/mutations.js +0 -1
- 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 +11 -2
- 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 +24 -16
- package/dist/slices/schedules/rescore.js +35 -0
- package/dist/slices/schedules/scheduler.js +13 -3
- package/dist/slices/schedules/schema.js +54 -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 +48 -36
- package/dist/slices/settings/cli-paths.js +4 -6
- package/dist/slices/settings/first-run.js +2 -11
- package/dist/slices/settings/model-reach.js +3 -17
- package/dist/slices/settings/model.js +10 -0
- package/dist/slices/settings/playback.js +33 -22
- 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/pick.js +2 -15
- package/dist/slices/shorts/prompts.js +2 -13
- package/dist/slices/shorts/render.js +3 -0
- 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 +131 -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 +55 -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 +128 -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 +20 -2
- 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 +16 -11
- 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 +10 -3
- package/dist/slices/studio/calendar.js +4 -1
- package/dist/slices/studio/pick.js +2 -11
- package/dist/slices/studio/plan.js +6 -15
- package/dist/slices/studio/queue.js +3 -14
- package/dist/slices/studio/releases.js +26 -0
- package/dist/slices/studio/settings.js +14 -51
- package/dist/slices/studio/videos.js +12 -0
- package/dist/slices/style-preview/render.js +34 -13
- package/dist/slices/style-preview/schema.js +13 -0
- package/dist/slices/style-preview/service.js +2 -1
- package/dist/slices/style-preview/settings.js +33 -5
- 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 +118 -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 +103 -0
- package/dist/slices/template-studio/checks.js +273 -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 +54 -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 +205 -0
- package/dist/slices/template-studio/paid-view.js +66 -0
- package/dist/slices/template-studio/paid.js +348 -0
- package/dist/slices/template-studio/quote.js +148 -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 +30 -0
- package/dist/slices/template-studio/schedule-sample.js +87 -0
- package/dist/slices/template-studio/schema.js +218 -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 +173 -0
- package/dist/slices/template-studio/status.js +174 -0
- package/dist/slices/template-studio/topic.js +223 -0
- 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/video/ass-text.js +17 -0
- package/dist/slices/video/audio-export.js +2 -64
- package/dist/slices/video/encoding.js +160 -0
- package/dist/slices/video/ffmpeg.js +23 -21
- package/dist/slices/video/figure-card.js +1 -15
- package/dist/slices/video/slideshow.js +43 -18
- package/dist/slices/voices/palette.js +0 -3
- package/dist/slices/youtube/answer.js +2 -15
- package/dist/slices/youtube/edits-repo.js +2 -11
- package/dist/tutorials/Agents-MCP.md +2 -1
- package/dist/tutorials/Assistant.md +42 -0
- package/dist/tutorials/Channels.md +2 -0
- package/dist/tutorials/Home-and-Projects.md +19 -0
- package/dist/tutorials/Install.md +1 -0
- package/dist/tutorials/Keywords-Slopify-Fills.md +87 -0
- package/dist/tutorials/Models.md +33 -1
- package/dist/tutorials/Notifications.md +6 -0
- package/dist/tutorials/Play-Images.md +4 -0
- package/dist/tutorials/Posting-to-Social-Sites.md +121 -0
- package/dist/tutorials/Prompts.md +10 -6
- package/dist/tutorials/Remote-Access.md +63 -0
- package/dist/tutorials/Reviews-and-Checkpoints.md +13 -2
- package/dist/tutorials/Schedules.md +21 -1
- package/dist/tutorials/Settings-Reference.md +50 -8
- package/dist/tutorials/Template-Studio.md +125 -0
- package/dist/tutorials/Templates.md +3 -0
- package/dist/tutorials/_Sidebar.md +5 -0
- package/dist/updater/work-in-progress.js +42 -12
- package/dist/web/assets/index-CkAI_2E7.css +1 -0
- package/dist/web/assets/index-DcD0cdfo.js +334 -0
- package/dist/web/assets/{pdf-T7MCwjIv.js → pdf-TODRwF31.js} +1 -1
- package/dist/web/index.html +2 -2
- package/package.json +5 -1
- 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/web/assets/index-BadsoORk.css +0 -1
- package/dist/web/assets/index-D8LqNsCl.js +0 -326
|
@@ -58,7 +58,7 @@ export const starterPacks = [
|
|
|
58
58
|
kind: "article",
|
|
59
59
|
name: "Sleep lore · Story",
|
|
60
60
|
body: [
|
|
61
|
-
"Write a long, calm bedtime telling of {{
|
|
61
|
+
"Write a long, calm bedtime telling of {{Topic}} for listeners who want to drift off to sleep.",
|
|
62
62
|
"",
|
|
63
63
|
"Length: 2800-3200 words.",
|
|
64
64
|
"",
|
|
@@ -83,7 +83,7 @@ export const starterPacks = [
|
|
|
83
83
|
kind: "article",
|
|
84
84
|
name: "Sleep lore · 60-second short",
|
|
85
85
|
body: [
|
|
86
|
-
`Subject: {{
|
|
86
|
+
`Subject: {{Topic}}, as a quiet moment from myth or legend.`,
|
|
87
87
|
"",
|
|
88
88
|
scriptRules,
|
|
89
89
|
"- Keep the calm, hushed tone of a bedtime story even in the hook.",
|
|
@@ -94,7 +94,7 @@ export const starterPacks = [
|
|
|
94
94
|
kind: "image",
|
|
95
95
|
name: "Sleep lore · Scene",
|
|
96
96
|
body: [
|
|
97
|
-
"A dreamlike painted scene from the legend of {{
|
|
97
|
+
"A dreamlike painted scene from the legend of {{Topic}}.",
|
|
98
98
|
"Soft oil-painting style with visible brushwork, muted twilight palette of deep blues, dusky violets and warm lantern gold.",
|
|
99
99
|
"Gentle haze, low contrast, wide calm composition with plenty of quiet space; distant figures rather than close faces.",
|
|
100
100
|
"Peaceful and still, nothing threatening in the frame.",
|
|
@@ -106,7 +106,7 @@ export const starterPacks = [
|
|
|
106
106
|
kind: "thumbnail",
|
|
107
107
|
name: "Sleep lore · Thumbnail",
|
|
108
108
|
body: [
|
|
109
|
-
"A serene, luminous painting that sums up the legend of {{
|
|
109
|
+
"A serene, luminous painting that sums up the legend of {{Topic}} in one image.",
|
|
110
110
|
"One clear subject in the centre, soft moonlight or candlelight, deep blue and gold palette, gentle mist.",
|
|
111
111
|
"Readable at a small size: simple shapes, strong silhouette, calm mood.",
|
|
112
112
|
noText,
|
|
@@ -117,7 +117,7 @@ export const starterPacks = [
|
|
|
117
117
|
kind: "description",
|
|
118
118
|
name: "Sleep lore · Description",
|
|
119
119
|
body: [
|
|
120
|
-
"Write a YouTube description for a sleep story about {{
|
|
120
|
+
"Write a YouTube description for a sleep story about {{Topic}}.",
|
|
121
121
|
"",
|
|
122
122
|
"- Summary: 2-3 soothing sentences that invite the viewer to settle in. Mention that the story is calm and has no sudden sounds.",
|
|
123
123
|
"- Chapters: one per part of the story, 3-6 gentle words each.",
|
|
@@ -164,7 +164,7 @@ export const starterPacks = [
|
|
|
164
164
|
kind: "article",
|
|
165
165
|
name: "True crime · Case",
|
|
166
166
|
body: [
|
|
167
|
-
"Write a documentary narration about the case of {{
|
|
167
|
+
"Write a documentary narration about the case of {{Topic}}.",
|
|
168
168
|
"",
|
|
169
169
|
"Length: 2200-2600 words.",
|
|
170
170
|
"",
|
|
@@ -190,7 +190,7 @@ export const starterPacks = [
|
|
|
190
190
|
kind: "article",
|
|
191
191
|
name: "True crime · 60-second short",
|
|
192
192
|
body: [
|
|
193
|
-
"Subject: one striking, well-documented moment from the case of {{
|
|
193
|
+
"Subject: one striking, well-documented moment from the case of {{Topic}}.",
|
|
194
194
|
"",
|
|
195
195
|
scriptRules,
|
|
196
196
|
"- Respectful and factual: no gore, no speculation about guilt, no invented detail.",
|
|
@@ -201,7 +201,7 @@ export const starterPacks = [
|
|
|
201
201
|
kind: "image",
|
|
202
202
|
name: "True crime · Scene",
|
|
203
203
|
body: [
|
|
204
|
-
"A moody documentary-style photograph evoking the setting of {{
|
|
204
|
+
"A moody documentary-style photograph evoking the setting of {{Topic}}: the place, the era, the objects, the weather.",
|
|
205
205
|
"Cinematic 35mm look, overcast or night light, desaturated cool palette with deep shadows and a single practical light source.",
|
|
206
206
|
"Empty streets, closed doors, rain on glass, paperwork on a desk; no recognisable real people, no bodies, no blood, no weapons pointed at anyone.",
|
|
207
207
|
noText,
|
|
@@ -212,7 +212,7 @@ export const starterPacks = [
|
|
|
212
212
|
kind: "thumbnail",
|
|
213
213
|
name: "True crime · Thumbnail",
|
|
214
214
|
body: [
|
|
215
|
-
"A tense cinematic image that sums up the case of {{
|
|
215
|
+
"A tense cinematic image that sums up the case of {{Topic}}: one strong object or place in sharp focus against a dark, blurred background.",
|
|
216
216
|
"High contrast, cold blue and amber light, heavy vignette, readable at phone size.",
|
|
217
217
|
"No real people's faces, no gore.",
|
|
218
218
|
noText,
|
|
@@ -223,7 +223,7 @@ export const starterPacks = [
|
|
|
223
223
|
kind: "description",
|
|
224
224
|
name: "True crime · Description",
|
|
225
225
|
body: [
|
|
226
|
-
"Write a YouTube description for a documentary about the case of {{
|
|
226
|
+
"Write a YouTube description for a documentary about the case of {{Topic}}.",
|
|
227
227
|
"",
|
|
228
228
|
"- Summary: 2-3 factual sentences on what happened and what the video covers. No sensational words.",
|
|
229
229
|
"- Chapters: split where the story moves from events to investigation to outcome; 3-6 plain words each.",
|
|
@@ -273,7 +273,7 @@ export const starterPacks = [
|
|
|
273
273
|
kind: "article",
|
|
274
274
|
name: "History · Documentary",
|
|
275
275
|
body: [
|
|
276
|
-
"Write a documentary narration about {{
|
|
276
|
+
"Write a documentary narration about {{Topic}}.",
|
|
277
277
|
"",
|
|
278
278
|
"Length: 2000-2400 words.",
|
|
279
279
|
"",
|
|
@@ -297,7 +297,7 @@ export const starterPacks = [
|
|
|
297
297
|
kind: "article",
|
|
298
298
|
name: "History · 60-second short",
|
|
299
299
|
body: [
|
|
300
|
-
"Subject: one surprising, true story or detail about {{
|
|
300
|
+
"Subject: one surprising, true story or detail about {{Topic}}.",
|
|
301
301
|
"",
|
|
302
302
|
scriptRules,
|
|
303
303
|
"- Put the year and the place in the first two sentences.",
|
|
@@ -308,7 +308,7 @@ export const starterPacks = [
|
|
|
308
308
|
kind: "image",
|
|
309
309
|
name: "History · Scene",
|
|
310
310
|
body: [
|
|
311
|
-
"A historically grounded illustration of {{
|
|
311
|
+
"A historically grounded illustration of {{Topic}}: period-accurate clothing, architecture, tools and landscape.",
|
|
312
312
|
"Rich painterly realism in the manner of a museum reconstruction, warm golden light, earthy ochre, umber and faded blue palette.",
|
|
313
313
|
"Wide establishing views and mid shots of daily life; figures shown at a distance or from behind rather than as portraits of real people.",
|
|
314
314
|
noText,
|
|
@@ -319,7 +319,7 @@ export const starterPacks = [
|
|
|
319
319
|
kind: "thumbnail",
|
|
320
320
|
name: "History · Thumbnail",
|
|
321
321
|
body: [
|
|
322
|
-
"A dramatic, detailed painting that sums up {{
|
|
322
|
+
"A dramatic, detailed painting that sums up {{Topic}} in one moment: one clear focal subject, strong light from one side, dust or smoke in the air.",
|
|
323
323
|
"Warm ochre and deep blue palette, high contrast, simple composition that reads at phone size.",
|
|
324
324
|
noText,
|
|
325
325
|
].join(" "),
|
|
@@ -329,7 +329,7 @@ export const starterPacks = [
|
|
|
329
329
|
kind: "description",
|
|
330
330
|
name: "History · Description",
|
|
331
331
|
body: [
|
|
332
|
-
"Write a YouTube description for a history documentary about {{
|
|
332
|
+
"Write a YouTube description for a history documentary about {{Topic}}.",
|
|
333
333
|
"",
|
|
334
334
|
"- Summary: 2-3 sentences that name the period and place and say what the viewer will understand by the end.",
|
|
335
335
|
"- Chapters: one per section of the narration, 2-6 words each, in title case.",
|
|
@@ -371,7 +371,7 @@ export const starterPacks = [
|
|
|
371
371
|
kind: "article",
|
|
372
372
|
name: "Science · Explainer",
|
|
373
373
|
body: [
|
|
374
|
-
"Write an explainer video narration about {{
|
|
374
|
+
"Write an explainer video narration about {{Topic}} for curious viewers with no science background.",
|
|
375
375
|
"",
|
|
376
376
|
"Length: 1400-1800 words.",
|
|
377
377
|
"",
|
|
@@ -396,7 +396,7 @@ export const starterPacks = [
|
|
|
396
396
|
kind: "article",
|
|
397
397
|
name: "Science · 60-second short",
|
|
398
398
|
body: [
|
|
399
|
-
"Subject: one mind-bending but true fact about {{
|
|
399
|
+
"Subject: one mind-bending but true fact about {{Topic}}, and why it is so.",
|
|
400
400
|
"",
|
|
401
401
|
scriptRules,
|
|
402
402
|
"- Give one real number with its unit and a comparison that makes it graspable.",
|
|
@@ -407,7 +407,7 @@ export const starterPacks = [
|
|
|
407
407
|
kind: "image",
|
|
408
408
|
name: "Science · Visual",
|
|
409
409
|
body: [
|
|
410
|
-
"A clean, striking visual that explains an aspect of {{
|
|
410
|
+
"A clean, striking visual that explains an aspect of {{Topic}}.",
|
|
411
411
|
"Modern 3D-rendered or macro-photography look, crisp detail, dark background with vivid cyan, magenta and amber accents, soft rim light.",
|
|
412
412
|
"One clear subject, scientifically plausible shapes and scales, generous negative space.",
|
|
413
413
|
noText,
|
|
@@ -418,7 +418,7 @@ export const starterPacks = [
|
|
|
418
418
|
kind: "thumbnail",
|
|
419
419
|
name: "Science · Thumbnail",
|
|
420
420
|
body: [
|
|
421
|
-
"A bold, eye-catching image about {{
|
|
421
|
+
"A bold, eye-catching image about {{Topic}}: one surprising subject, glowing against a deep dark background.",
|
|
422
422
|
"Saturated cyan and amber, strong contrast, simple composition that reads at phone size.",
|
|
423
423
|
noText,
|
|
424
424
|
].join(" "),
|
|
@@ -428,7 +428,7 @@ export const starterPacks = [
|
|
|
428
428
|
kind: "description",
|
|
429
429
|
name: "Science · Description",
|
|
430
430
|
body: [
|
|
431
|
-
"Write a YouTube description for a science explainer about {{
|
|
431
|
+
"Write a YouTube description for a science explainer about {{Topic}}.",
|
|
432
432
|
"",
|
|
433
433
|
"- Summary: 2-3 sentences that pose the question and promise a clear answer, without exaggeration.",
|
|
434
434
|
"- Chapters: one per step of the explanation, 2-6 words each.",
|
|
@@ -471,14 +471,14 @@ export const starterSet = {
|
|
|
471
471
|
key: "shortScript",
|
|
472
472
|
kind: "article",
|
|
473
473
|
name: "Starter · 60-second short",
|
|
474
|
-
body: ["Subject: {{
|
|
474
|
+
body: ["Subject: {{Topic}}.", "", scriptRules].join("\n"),
|
|
475
475
|
},
|
|
476
476
|
{
|
|
477
477
|
key: "image",
|
|
478
478
|
kind: "image",
|
|
479
479
|
name: "Starter · Vertical scene",
|
|
480
480
|
body: [
|
|
481
|
-
"A cinematic vertical image about {{
|
|
481
|
+
"A cinematic vertical image about {{Topic}}.",
|
|
482
482
|
"Rich colour, dramatic light, one clear subject large in the frame so it reads on a phone.",
|
|
483
483
|
"Keep the lower half calm: captions are drawn over it.",
|
|
484
484
|
noText,
|
|
@@ -121,7 +121,8 @@ export function shortDraft(input) {
|
|
|
121
121
|
images: input.providers.images,
|
|
122
122
|
articlePrompt: input.names.shortScript ?? "",
|
|
123
123
|
imagePrompts: [{ name: input.names.image ?? "", number: shortImages }],
|
|
124
|
-
|
|
124
|
+
// {{Topic}} since 4.0; a pack installed before asks for {{topic}}, so both are filled.
|
|
125
|
+
values: { Topic: topic, topic },
|
|
125
126
|
provided: {},
|
|
126
127
|
silenceGapSeconds: 0.5,
|
|
127
128
|
imageSeconds: shortImageSeconds,
|
|
@@ -19,7 +19,6 @@ export const sampleArchives = {
|
|
|
19
19
|
audiobook: bundled("sample-audiobook.tar"),
|
|
20
20
|
podcast: bundled("sample-podcast.tar"),
|
|
21
21
|
};
|
|
22
|
-
export const sampleArchive = sampleArchives.library;
|
|
23
22
|
const archiveOf = (deps, id) => deps.archives?.[id] ?? sampleArchives[id];
|
|
24
23
|
function recordedProject(db, id) {
|
|
25
24
|
const record = readSampleRecord(db, id);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
-
import { readSetting, writeSetting } from "../settings/repo.js";
|
|
2
|
+
import { readJsonSetting, readSetting, writeSetting } from "../settings/repo.js";
|
|
3
3
|
// What the first five minutes remember, in the settings table: whether the first-run screen
|
|
4
4
|
// was dismissed, which project is the bundled sample, and which library rows each installed
|
|
5
5
|
// starter pack became. None of these keys is in a portable backup's settings, so another
|
|
@@ -25,16 +25,7 @@ const shortRequests = z.record(z.string(), z.string());
|
|
|
25
25
|
// ceiling: only a retry of a recent click needs its answer.
|
|
26
26
|
const shortRequestsKept = 20;
|
|
27
27
|
function readJson(db, key, schema) {
|
|
28
|
-
|
|
29
|
-
if (raw === undefined)
|
|
30
|
-
return undefined;
|
|
31
|
-
try {
|
|
32
|
-
const parsed = schema.safeParse(JSON.parse(raw));
|
|
33
|
-
return parsed.success ? parsed.data : undefined;
|
|
34
|
-
}
|
|
35
|
-
catch {
|
|
36
|
-
return undefined;
|
|
37
|
-
}
|
|
28
|
+
return readJsonSetting(db, key, schema, undefined);
|
|
38
29
|
}
|
|
39
30
|
export function firstRunDismissed(db) {
|
|
40
31
|
return readSetting(db, dismissedKey) !== undefined;
|
|
@@ -9,7 +9,8 @@ export function packTemplate(pack, names, voiceId) {
|
|
|
9
9
|
return playDraftDocumentSchema.parse({
|
|
10
10
|
schemaVersion: 1,
|
|
11
11
|
form: {
|
|
12
|
-
|
|
12
|
+
// The topic typed in Play, or the one a schedule fills each run, names the video.
|
|
13
|
+
title: "{{Topic}}",
|
|
13
14
|
format: "16:9",
|
|
14
15
|
sources: {
|
|
15
16
|
research: style.research ? "generate" : "off",
|
|
@@ -3,6 +3,7 @@ import { readFile } from "node:fs/promises";
|
|
|
3
3
|
import { join } from "node:path";
|
|
4
4
|
import { fileURLToPath } from "node:url";
|
|
5
5
|
import { z } from "zod";
|
|
6
|
+
import { hasErrnoCode } from "../../kernel/errors.js";
|
|
6
7
|
// The patch notes the app shows in Settings → Patch notes: Markdown files kept in the
|
|
7
8
|
// repository's docs/patch-notes/ and copied into the build beside the compiled code
|
|
8
9
|
// (scripts/copy-assets.mjs). index.json lists them with a title and a date; each note is
|
|
@@ -34,7 +35,7 @@ export async function listPatchNotes(dir) {
|
|
|
34
35
|
raw = await readFile(join(dir, "index.json"), "utf8");
|
|
35
36
|
}
|
|
36
37
|
catch (error) {
|
|
37
|
-
if (error
|
|
38
|
+
if (hasErrnoCode(error, "ENOENT"))
|
|
38
39
|
throw new PatchNotesMissing("This copy of Slopify has no patch notes: its docs/patch-notes/index.json is missing. Reinstall Slopify (or run npm run build) and reload the page.");
|
|
39
40
|
throw error;
|
|
40
41
|
}
|
|
@@ -66,7 +67,7 @@ export async function readPatchNote(dir, id) {
|
|
|
66
67
|
return await readFile(join(dir, `${id}.md`), "utf8");
|
|
67
68
|
}
|
|
68
69
|
catch (error) {
|
|
69
|
-
if (error
|
|
70
|
+
if (hasErrnoCode(error, "ENOENT"))
|
|
70
71
|
return undefined;
|
|
71
72
|
throw error;
|
|
72
73
|
}
|
|
@@ -9,6 +9,7 @@ import { pausesOfForm } from "../narration/pauses-model.js";
|
|
|
9
9
|
import { reviewSettingsFromForm } from "../reviews/model.js";
|
|
10
10
|
import { stageMakesItems } from "../reviews/rules.js";
|
|
11
11
|
import { defaultShorts, shortsExtrasOf, shortsSettingsProblems, } from "../shorts/model.js";
|
|
12
|
+
import { socialOfForm } from "../social/settings.js";
|
|
12
13
|
import { defaultSubtitles } from "../subtitles/model.js";
|
|
13
14
|
import { ambientBedOfForm, ambientBedProblems } from "../video/ambient-bed.js";
|
|
14
15
|
// Said where the control is, since the music sits in a closed disclosure on the Export rail.
|
|
@@ -206,6 +207,9 @@ export function toAdmissionDraft(input) {
|
|
|
206
207
|
...(form.descriptionPrompt?.trim() ? { descriptionPrompt: form.descriptionPrompt } : {}),
|
|
207
208
|
}
|
|
208
209
|
: {}),
|
|
210
|
+
// Posting is free unless a site's words come from a post prompt; none turned on is left out,
|
|
211
|
+
// which is what every draft saved before posting was.
|
|
212
|
+
...((social) => (social === undefined ? {} : { social }))(socialOfForm(form.social)),
|
|
209
213
|
// Cut from the narration too, so the same rule: a switch left on with narration Off asks
|
|
210
214
|
// for nothing.
|
|
211
215
|
...(shortsOn && form.shorts !== undefined ? { shorts: shortsOf(form.shorts) } : {}),
|
|
@@ -25,8 +25,13 @@ export function reviewBinding(value) {
|
|
|
25
25
|
attachmentIdentity: value.attachmentIdentity,
|
|
26
26
|
});
|
|
27
27
|
}
|
|
28
|
-
export function resolveReviewInputs(deps, view, font
|
|
29
|
-
|
|
28
|
+
export function resolveReviewInputs(deps, view, font,
|
|
29
|
+
// A view no draft row holds (the template studio prices a schedule's run on one): it is its
|
|
30
|
+
// own latest version and has no uploads.
|
|
31
|
+
unsaved = false) {
|
|
32
|
+
const fresh = unsaved
|
|
33
|
+
? { ok: true, value: view }
|
|
34
|
+
: readDraft(deps, view.draft.id);
|
|
30
35
|
if (!fresh.ok)
|
|
31
36
|
return fresh;
|
|
32
37
|
if (fresh.value.draft.version !== view.draft.version ||
|
|
@@ -103,6 +108,7 @@ export function resolveReviewInputs(deps, view, font) {
|
|
|
103
108
|
draft: { ...draft, values },
|
|
104
109
|
staged,
|
|
105
110
|
requiredSlots: basePicked.requiredSlots,
|
|
111
|
+
keywordUses: basePicked.keywordUses,
|
|
106
112
|
});
|
|
107
113
|
const accepted = admitted.ok ? admitted.draft : draft;
|
|
108
114
|
const issues = [
|
|
@@ -8,11 +8,12 @@ import { resolveReviewInputs, reviewBinding, reviewRefusal } from "./review-inpu
|
|
|
8
8
|
import { draftViewSchema, playReviewSchema } from "./schema.js";
|
|
9
9
|
import { readDraft } from "./service.js";
|
|
10
10
|
export { resolveReviewInputs } from "./review-inputs.js";
|
|
11
|
-
export async function resolvePlayReview(deps, view) {
|
|
11
|
+
export async function resolvePlayReview(deps, view, options = {}) {
|
|
12
|
+
const unsaved = options.unsaved === true;
|
|
12
13
|
const parsed = draftViewSchema.safeParse(view);
|
|
13
14
|
if (!parsed.success)
|
|
14
15
|
return { ok: false, reason: "invalid-edit", currentVersion: null, fields: [] };
|
|
15
|
-
const before = resolveReviewInputs(deps, parsed.data, null);
|
|
16
|
+
const before = resolveReviewInputs(deps, parsed.data, null, unsaved);
|
|
16
17
|
if (!before.ok)
|
|
17
18
|
return before;
|
|
18
19
|
let font = null;
|
|
@@ -32,7 +33,7 @@ export async function resolvePlayReview(deps, view) {
|
|
|
32
33
|
]);
|
|
33
34
|
}
|
|
34
35
|
}
|
|
35
|
-
const after = resolveReviewInputs(deps, parsed.data, font);
|
|
36
|
+
const after = resolveReviewInputs(deps, parsed.data, font, unsaved);
|
|
36
37
|
if (!after.ok)
|
|
37
38
|
return after;
|
|
38
39
|
const fields = [];
|
|
@@ -55,7 +56,7 @@ export async function resolvePlayReview(deps, view) {
|
|
|
55
56
|
// without the font: `before` had none yet, and a Before Video checkpoint covers the render
|
|
56
57
|
// that burns the captions in, so comparing it with `after` always differed and refused every
|
|
57
58
|
// such review.
|
|
58
|
-
const unchanged = resolveReviewInputs(deps, parsed.data, null);
|
|
59
|
+
const unchanged = resolveReviewInputs(deps, parsed.data, null, unsaved);
|
|
59
60
|
if (!unchanged.ok)
|
|
60
61
|
return unchanged;
|
|
61
62
|
return reviewBinding(before.value) === reviewBinding(unchanged.value)
|
|
@@ -10,6 +10,7 @@ import { documentSettingsSchema } from "../document/theme-schema.js";
|
|
|
10
10
|
import { librarySnapshotSchema } from "../library/snapshot.js";
|
|
11
11
|
import { chunkModes } from "../narration/chunk.js";
|
|
12
12
|
import { reviewers, reviewModes, reviewStages } from "../reviews/model.js";
|
|
13
|
+
import { socialSettingsSchema } from "../social/schema.js";
|
|
13
14
|
import { subtitleModes, subtitlePositions } from "../subtitles/model.js";
|
|
14
15
|
import { ambientBedSources } from "../video/ambient-bed.js";
|
|
15
16
|
import { voicesSettingsSchema } from "../voices/model.js";
|
|
@@ -94,6 +95,9 @@ export const playDraftFormSchema = z
|
|
|
94
95
|
levelSentences: z.boolean().optional(),
|
|
95
96
|
// Absent on drafts and templates saved before the YouTube description: off, built-in prompt.
|
|
96
97
|
youtubeDescription: z.boolean().optional(),
|
|
98
|
+
// Which other sites the project posts to and what each gets (`slices/social`), as the run
|
|
99
|
+
// stores it. Absent on drafts and templates saved before posting: nowhere.
|
|
100
|
+
social: socialSettingsSchema.optional(),
|
|
97
101
|
showFigures: z.boolean().optional(),
|
|
98
102
|
descriptionPrompt: text.optional(),
|
|
99
103
|
// The project language (`kernel/ports/languages.ts`). Absent on drafts and templates saved
|
|
@@ -11,10 +11,13 @@ import { requestHash } from "../play-drafts/repo.js";
|
|
|
11
11
|
import { reviewSettingsForm } from "../reviews/model.js";
|
|
12
12
|
import { currentRevisionId, revisionById } from "../revisions/repo.js";
|
|
13
13
|
import { shortsExtrasForm } from "../shorts/model.js";
|
|
14
|
+
import { socialPlatforms } from "../social/model.js";
|
|
15
|
+
import { socialSettingsSchema } from "../social/schema.js";
|
|
14
16
|
import { ambientBedFormOf } from "../video/ambient-bed.js";
|
|
15
17
|
import { usesScriptPrompt } from "../voices/model.js";
|
|
16
18
|
import { templateNameMax } from "./schema.js";
|
|
17
19
|
import { createTemplate, readTemplate } from "./service.js";
|
|
20
|
+
import { withoutSampleStandIns } from "./stand-ins.js";
|
|
18
21
|
export const projectTemplateCreateSchema = z
|
|
19
22
|
.object({
|
|
20
23
|
id: z.uuid(),
|
|
@@ -88,6 +91,9 @@ export function documentFromProject(deps, revision) {
|
|
|
88
91
|
addPrompt(usesScriptPrompt(config) ? "script" : "article", config.articlePrompt, "article");
|
|
89
92
|
addPrompt("narration", config.narrationPrompt, "narration");
|
|
90
93
|
addPrompt("description", config.descriptionPrompt, "description");
|
|
94
|
+
for (const platform of socialPlatforms)
|
|
95
|
+
if (config.social?.[platform]?.text === "prompt")
|
|
96
|
+
addPrompt("post", config.social[platform]?.prompt, `social.${platform}`);
|
|
91
97
|
for (const [stage, picked] of Object.entries(config.reviews?.stages ?? {}))
|
|
92
98
|
addPrompt("review", picked.prompt, `review.${stage}`);
|
|
93
99
|
const definitions = revision.content.imageOrder.flatMap((key) => {
|
|
@@ -163,7 +169,7 @@ export function documentFromProject(deps, revision) {
|
|
|
163
169
|
return {
|
|
164
170
|
schemaVersion: 1,
|
|
165
171
|
librarySnapshot: { prompts, entries },
|
|
166
|
-
form: {
|
|
172
|
+
form: withoutSampleStandIns({
|
|
167
173
|
title: config.title,
|
|
168
174
|
format: config.format,
|
|
169
175
|
sources: config.sources,
|
|
@@ -191,6 +197,7 @@ export function documentFromProject(deps, revision) {
|
|
|
191
197
|
...(config.thumbnailCount === 3 ? { thumbnailCount: 3 } : {}),
|
|
192
198
|
...(config.narrationPrompt === undefined ? {} : { narrationPrompt: config.narrationPrompt }),
|
|
193
199
|
...(config.youtubeDescription === true ? { youtubeDescription: true } : {}),
|
|
200
|
+
...(config.social === undefined ? {} : { social: socialSettingsSchema.parse(config.social) }),
|
|
194
201
|
...(config.language === undefined ? {} : { language: config.language }),
|
|
195
202
|
...(config.descriptionPrompt === undefined
|
|
196
203
|
? {}
|
|
@@ -263,7 +270,7 @@ export function documentFromProject(deps, revision) {
|
|
|
263
270
|
motionStyle: config.motionStyle,
|
|
264
271
|
values: config.values,
|
|
265
272
|
provided,
|
|
266
|
-
},
|
|
273
|
+
}),
|
|
267
274
|
section: "content",
|
|
268
275
|
variants: [],
|
|
269
276
|
// The length a project that scales its images planned for, so the template plans the same.
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import { projectTemplateSchema } from "./schema.js";
|
|
3
|
+
import { withoutSampleStandIns } from "./stand-ins.js";
|
|
3
4
|
// A template in the trash (`deleted_at` set, Settings → Trash) is invisible to every read here.
|
|
4
5
|
const select = `SELECT t.id,r.version,r.name,t.created_at AS createdAt,r.created_at AS updatedAt,r.document_json AS document FROM project_templates t JOIN project_template_revisions r ON r.template_id=t.id AND t.deleted_at IS NULL`;
|
|
5
6
|
const templateSummarySchema = z
|
|
@@ -20,7 +21,11 @@ export function templateById(db, id, version) {
|
|
|
20
21
|
return undefined;
|
|
21
22
|
if (typeof row.document !== "string")
|
|
22
23
|
throw new Error("Template document is missing");
|
|
23
|
-
|
|
24
|
+
const template = projectTemplateSchema.parse({ ...row, document: JSON.parse(row.document) });
|
|
25
|
+
// A template made from a sample before stand-ins were cleared reads as one that asks for the
|
|
26
|
+
// person's own providers.
|
|
27
|
+
const form = withoutSampleStandIns(template.document.form);
|
|
28
|
+
return { ...template, document: { ...template.document, form } };
|
|
24
29
|
}
|
|
25
30
|
export function templateSummaries(db) {
|
|
26
31
|
return db
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { templateChannelId } from "../channels/repo.js";
|
|
2
2
|
import { snapshotEntry, snapshotPrompt } from "../library/snapshot.js";
|
|
3
|
+
import { socialPlatforms } from "../social/model.js";
|
|
3
4
|
import { templateDocument } from "./one-off.js";
|
|
4
5
|
export function templateSetup(deps, input) {
|
|
5
6
|
const prompts = [];
|
|
@@ -25,6 +26,13 @@ export function templateSetup(deps, input) {
|
|
|
25
26
|
kind: "image",
|
|
26
27
|
name: input.form.reference?.source === "prompt" ? input.form.reference.prompt : "",
|
|
27
28
|
},
|
|
29
|
+
...socialPlatforms.map((platform) => {
|
|
30
|
+
const choice = input.form.social?.[platform];
|
|
31
|
+
return {
|
|
32
|
+
kind: "post",
|
|
33
|
+
name: choice?.text === "prompt" ? (choice.prompt ?? "") : "",
|
|
34
|
+
};
|
|
35
|
+
}),
|
|
28
36
|
];
|
|
29
37
|
for (const choice of choices) {
|
|
30
38
|
if (choice.name === "")
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { isSampleStandIn } from "../settings/model.js";
|
|
2
|
+
// A template made from a bundled sample asks for the person's own providers: the samples'
|
|
3
|
+
// stand-ins can't run anything new, so their choices are left blank, the same as a template
|
|
4
|
+
// nobody has picked a provider in (Play then offers the providers this computer has).
|
|
5
|
+
export function withoutSampleStandIns(form) {
|
|
6
|
+
const blankVoice = { provider: "", model: "", voice: "" };
|
|
7
|
+
const voices = form.voices;
|
|
8
|
+
return {
|
|
9
|
+
...form,
|
|
10
|
+
llm: isSampleStandIn(form.llm.provider) ? { provider: "", model: "" } : form.llm,
|
|
11
|
+
audio: isSampleStandIn(form.audio.provider) ? { ...form.audio, ...blankVoice } : form.audio,
|
|
12
|
+
images: isSampleStandIn(form.images.provider) ? { provider: "", model: "" } : form.images,
|
|
13
|
+
...(voices === undefined
|
|
14
|
+
? {}
|
|
15
|
+
: {
|
|
16
|
+
voices: {
|
|
17
|
+
...voices,
|
|
18
|
+
speakers: voices.speakers.map((speaker) => isSampleStandIn(speaker.voice.provider) ? { ...speaker, voice: blankVoice } : speaker),
|
|
19
|
+
},
|
|
20
|
+
}),
|
|
21
|
+
};
|
|
22
|
+
}
|
|
@@ -50,6 +50,8 @@ export function videoActivity(db, projectId) {
|
|
|
50
50
|
return { label: "picking the shorts" };
|
|
51
51
|
if (running("youtube:description"))
|
|
52
52
|
return { label: "writing the YouTube description" };
|
|
53
|
+
if (rows.some((row) => row.key.startsWith("social:post:") && row.state === "running"))
|
|
54
|
+
return { label: "writing the posts for other sites" };
|
|
53
55
|
if (running("subtitles:timing"))
|
|
54
56
|
return percent("timing the captions", running("subtitles:timing"));
|
|
55
57
|
if (running("subtitles:cues") || running("subtitles:files"))
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { transact } from "../../kernel/db/tx.js";
|
|
2
|
+
import { internalError } from "../../kernel/errors.js";
|
|
2
3
|
import { setProjectPaused } from "../admission/repo.js";
|
|
3
4
|
import { requestHash as hash } from "../revisions/mutation-request.js";
|
|
4
5
|
import { currentRevisionId } from "../revisions/repo.js";
|
|
@@ -92,14 +93,14 @@ export function admitPreview(deps, input) {
|
|
|
92
93
|
continue;
|
|
93
94
|
}
|
|
94
95
|
if (existing?.state === "running")
|
|
95
|
-
throw new Error("
|
|
96
|
+
throw new Error(internalError("a step is already running for a different version of the project"));
|
|
96
97
|
deps.db
|
|
97
98
|
.prepare("DELETE FROM revision_work_reservations WHERE revision_id=? AND work_key=?")
|
|
98
99
|
.run(view.revision.id, recipe.key);
|
|
99
100
|
const key = reservationKey(recipe, view);
|
|
100
101
|
const fingerprint = snapshot.anchors[key];
|
|
101
102
|
if (fingerprint === undefined)
|
|
102
|
-
throw new Error("
|
|
103
|
+
throw new Error(internalError("a step has no saved starting point"));
|
|
103
104
|
const work = insertInvocation(deps, view, recipe, catalogue, { key, fingerprint }, false, view.revision.id, admissionId);
|
|
104
105
|
workIds.push(work.workId);
|
|
105
106
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { statSync } from "node:fs";
|
|
2
2
|
import { z } from "zod";
|
|
3
|
+
import { assetPathOrUndefined } from "../revisions/mutation-assets.js";
|
|
3
4
|
import { stagePieceSchema } from "../revisions/schema.js";
|
|
4
5
|
import { outputPath } from "../storage/layout.js";
|
|
5
6
|
export function retainedNarrationPieces(deps, projectId) {
|
|
@@ -32,11 +33,9 @@ export function retainedNarrationPieces(deps, projectId) {
|
|
|
32
33
|
}
|
|
33
34
|
export function referencedAssetsAvailable(deps, projectId, ids) {
|
|
34
35
|
return ids.filter((id) => {
|
|
35
|
-
const
|
|
36
|
-
|
|
37
|
-
.
|
|
38
|
-
return (row !== undefined &&
|
|
39
|
-
statSync(outputPath(deps.paths, projectId, z.string().parse(row.path)), {
|
|
36
|
+
const path = assetPathOrUndefined(deps, projectId, id);
|
|
37
|
+
return (path !== undefined &&
|
|
38
|
+
statSync(outputPath(deps.paths, projectId, path), {
|
|
40
39
|
throwIfNoEntry: false,
|
|
41
40
|
})?.isFile() === true);
|
|
42
41
|
});
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { createHash } from "node:crypto";
|
|
2
2
|
import { z } from "zod";
|
|
3
3
|
import { transact } from "../../kernel/db/tx.js";
|
|
4
|
+
import { errorText } from "../../kernel/errors.js";
|
|
4
5
|
import { currentRevisionId } from "../revisions/repo.js";
|
|
5
6
|
import { recoverProject } from "./recovery.js";
|
|
6
7
|
// How many times one narration chunk is recorded again by itself. A voice that garbles a
|
|
@@ -71,7 +72,7 @@ export function createNarrationRetries() {
|
|
|
71
72
|
.catch((error) => {
|
|
72
73
|
deps.log.write("error", "narration.retry", {
|
|
73
74
|
projectId: retry.projectId,
|
|
74
|
-
detail:
|
|
75
|
+
detail: errorText(error),
|
|
75
76
|
});
|
|
76
77
|
settle(deps.db, retry, "failed", "internal error", deps.clock.now().toISOString());
|
|
77
78
|
})
|
|
@@ -7,6 +7,7 @@ import { loudnessLabel } from "../loudness/model.js";
|
|
|
7
7
|
import { reviewModeLabels, reviewModeOf, reviewStageLabels, reviewStages, } from "../reviews/model.js";
|
|
8
8
|
import { getRevisionView } from "../revisions/view.js";
|
|
9
9
|
import { musicVolumeOf, shortsSpeedOf } from "../shorts/model.js";
|
|
10
|
+
import { platformLabels, socialPlatforms } from "../social/model.js";
|
|
10
11
|
import { ambientBedLabels } from "../video/ambient-bed.js";
|
|
11
12
|
import { videoEditOf, videoEditRows } from "../video/edit-settings.js";
|
|
12
13
|
export function previewDetails(deps, view, allRecipes, selected) {
|
|
@@ -76,15 +77,17 @@ export function previewDetails(deps, view, allRecipes, selected) {
|
|
|
76
77
|
? "Intro text"
|
|
77
78
|
: row.key.startsWith("entry:outro")
|
|
78
79
|
? "Outro text"
|
|
79
|
-
: row.
|
|
80
|
-
? "
|
|
81
|
-
: row.stage === "
|
|
82
|
-
? "
|
|
83
|
-
: row.
|
|
84
|
-
? "
|
|
85
|
-
: row.key
|
|
86
|
-
? "
|
|
87
|
-
:
|
|
80
|
+
: row.key === "article:digest"
|
|
81
|
+
? "Keyword digest"
|
|
82
|
+
: row.stage === "article"
|
|
83
|
+
? "Article"
|
|
84
|
+
: row.stage === "research"
|
|
85
|
+
? "Research"
|
|
86
|
+
: row.key.startsWith("shorts:")
|
|
87
|
+
? "Short image prompts"
|
|
88
|
+
: row.key === "images:scenes"
|
|
89
|
+
? "Image scenes"
|
|
90
|
+
: "Thumbnail prompt";
|
|
88
91
|
return [
|
|
89
92
|
{
|
|
90
93
|
key: row.key,
|
|
@@ -165,6 +168,7 @@ function inputChanges(parent, view) {
|
|
|
165
168
|
add("Level the volume", before.loudness === undefined ? "Off" : loudnessSummary(before.loudness), after.loudness === undefined ? "Off" : loudnessSummary(after.loudness));
|
|
166
169
|
add("YouTube description", before.youtubeDescription === true ? "On" : "Off", after.youtubeDescription === true ? "On" : "Off");
|
|
167
170
|
add("Description prompt", before.descriptionPrompt, after.descriptionPrompt);
|
|
171
|
+
add("Posts", postsSummary(before.social), postsSummary(after.social));
|
|
168
172
|
add("Shorts", before.shorts?.enabled === true ? "On" : "Off", after.shorts?.enabled === true ? "On" : "Off");
|
|
169
173
|
add("Number of shorts", before.shorts?.count, after.shorts?.count);
|
|
170
174
|
add("Short length (seconds)", before.shorts === undefined
|
|
@@ -261,3 +265,17 @@ function aliasLines(aliases) {
|
|
|
261
265
|
.map((alias) => `${alias.written} → ${alias.spoken}${alias.wholeWord ? "" : " (inside words too)"}${alias.caseSensitive ? " (match case)" : ""}`)
|
|
262
266
|
.join("\n");
|
|
263
267
|
}
|
|
268
|
+
// The sites a version posts to, each with where its words come from: "X (post prompt), Bluesky
|
|
269
|
+
// (summary)"; "Off" for none.
|
|
270
|
+
function postsSummary(social) {
|
|
271
|
+
const sites = socialPlatforms.flatMap((platform) => {
|
|
272
|
+
const choice = social?.[platform];
|
|
273
|
+
if (choice === undefined)
|
|
274
|
+
return [];
|
|
275
|
+
const source = choice.text === "prompt"
|
|
276
|
+
? `post prompt${choice.prompt?.trim() ? ` ${choice.prompt.trim()}` : ""}`
|
|
277
|
+
: choice.text;
|
|
278
|
+
return [`${platformLabels[platform]} (${source})`];
|
|
279
|
+
});
|
|
280
|
+
return sites.length === 0 ? "Off" : sites.join(", ");
|
|
281
|
+
}
|