@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
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
// The address of what connected to this server: the browser, or a proxy in front of it.
|
|
2
|
+
// Undefined for an in-process request, which has no socket.
|
|
3
|
+
export function peerAddress(c) {
|
|
4
|
+
const env = c.env;
|
|
5
|
+
if (typeof env !== "object" || env === null || !("incoming" in env))
|
|
6
|
+
return undefined;
|
|
7
|
+
const incoming = env.incoming;
|
|
8
|
+
if (typeof incoming !== "object" || incoming === null || !("socket" in incoming))
|
|
9
|
+
return undefined;
|
|
10
|
+
const socket = incoming.socket;
|
|
11
|
+
if (typeof socket !== "object" || socket === null || !("remoteAddress" in socket))
|
|
12
|
+
return undefined;
|
|
13
|
+
return typeof socket.remoteAddress === "string" ? socket.remoteAddress : undefined;
|
|
14
|
+
}
|
|
15
|
+
const loopbackPeer = (address) => address !== undefined &&
|
|
16
|
+
(address === "::1" || /^(?:::ffff:)?127\.\d{1,3}\.\d{1,3}\.\d{1,3}$/u.test(address));
|
|
17
|
+
// The name the browser used, as a proxy on this computer passes it on in X-Forwarded-Host
|
|
18
|
+
// (its first value). Only trusted from a loopback peer: anyone else could write the header.
|
|
19
|
+
export function forwardedHost(c) {
|
|
20
|
+
if (!loopbackPeer(peerAddress(c)))
|
|
21
|
+
return undefined;
|
|
22
|
+
const first = c.req.header("x-forwarded-host")?.split(",")[0]?.trim();
|
|
23
|
+
return first === undefined || first === "" ? undefined : first;
|
|
24
|
+
}
|
|
25
|
+
// host[:port] with the scheme's default port left out, as an Origin's own host has it.
|
|
26
|
+
function hostOf(host, scheme) {
|
|
27
|
+
const lower = host.trim().toLowerCase();
|
|
28
|
+
const fallback = scheme === "https:" ? ":443" : scheme === "http:" ? ":80" : undefined;
|
|
29
|
+
return fallback !== undefined && lower.endsWith(fallback)
|
|
30
|
+
? lower.slice(0, -fallback.length)
|
|
31
|
+
: lower;
|
|
32
|
+
}
|
|
33
|
+
// Standard same-origin protection: a browser's Origin names the page that sent the request,
|
|
34
|
+
// and a page at the very host:port the browser addressed is Slopify's own, whatever proxy
|
|
35
|
+
// (Slopify's remote access, a `tailscale serve` set up by hand, Caddy, nginx) stands in front.
|
|
36
|
+
// A cross-site page names its own host, so it never matches; which names may reach Slopify at
|
|
37
|
+
// all is `request-guard.ts`'s Host check.
|
|
38
|
+
function sameHost(c, origin) {
|
|
39
|
+
let url;
|
|
40
|
+
try {
|
|
41
|
+
url = new URL(origin);
|
|
42
|
+
}
|
|
43
|
+
catch {
|
|
44
|
+
return false;
|
|
45
|
+
}
|
|
46
|
+
if (url.host === "")
|
|
47
|
+
return false;
|
|
48
|
+
const own = url.host.toLowerCase();
|
|
49
|
+
return [c.req.header("host"), forwardedHost(c)].some((host) => host !== undefined && hostOf(host, url.protocol) === own);
|
|
50
|
+
}
|
|
51
|
+
// Whether a request with an Origin comes from the Slopify page itself: the page this server
|
|
52
|
+
// serves, the page at the address the browser used for this request (through any proxy), or
|
|
53
|
+
// the same page at the exact https address Slopify set up in Tailscale.
|
|
54
|
+
export function fromSlopifyPage(c, remoteHost) {
|
|
55
|
+
const origin = c.req.header("origin");
|
|
56
|
+
if (origin === undefined || origin === new URL(c.req.url).origin)
|
|
57
|
+
return true;
|
|
58
|
+
if (sameHost(c, origin))
|
|
59
|
+
return true;
|
|
60
|
+
const remote = remoteHost?.();
|
|
61
|
+
return (remote !== undefined &&
|
|
62
|
+
origin === `https://${remote}` &&
|
|
63
|
+
(c.req.header("x-forwarded-host") ?? c.req.header("host")) === remote);
|
|
64
|
+
}
|
|
65
|
+
// A request that reached Slopify through a forwarding proxy, Tailscale serve included: it sets
|
|
66
|
+
// X-Forwarded-For on every request and keeps the ts.net Host. Agents' endpoints answer only
|
|
67
|
+
// requests made on this computer.
|
|
68
|
+
export function viaProxy(headers) {
|
|
69
|
+
if (headers.has("x-forwarded-for") || headers.has("x-forwarded-host"))
|
|
70
|
+
return true;
|
|
71
|
+
if (headers.has("tailscale-user-login") || headers.has("tailscale-funnel-request"))
|
|
72
|
+
return true;
|
|
73
|
+
const host = headers.get("host") ?? "";
|
|
74
|
+
const name = host.replace(/:\d+$/u, "").toLowerCase();
|
|
75
|
+
return name.endsWith(".ts.net");
|
|
76
|
+
}
|
|
77
|
+
// Tailscale marks every request that came through Funnel, from the public internet.
|
|
78
|
+
export function viaFunnel(headers) {
|
|
79
|
+
return headers.has("tailscale-funnel-request");
|
|
80
|
+
}
|
|
@@ -5,15 +5,22 @@ import { z } from "zod";
|
|
|
5
5
|
import { calendarRange } from "../../slices/schedules/agenda.js";
|
|
6
6
|
import { rejectHeldTopics, restoreRejectedTopics } from "../../slices/schedules/held-bulk.js";
|
|
7
7
|
import { preparedTopics, prepareTopic } from "../../slices/schedules/prepare.js";
|
|
8
|
-
import {
|
|
8
|
+
import { rescoreTopics } from "../../slices/schedules/rescore.js";
|
|
9
|
+
import { calendarMaxDays, calendarSchema, heldTopicEditSchema, heldTopicSchema, queueMax, scheduleCreateSchema, scheduleRunSchema, scheduleSaveBodySchema, scheduleSummarySchema, scheduleVersionBodySchema, topicMoveSchema, topicQueueSchema, topicTransferSchema, } from "../../slices/schedules/schema.js";
|
|
9
10
|
import { cancelSchedule, createSchedule, deleteSchedule, listScheduleRuns, listSchedules, pauseSchedule, resumeSchedule, updateSchedule, } from "../../slices/schedules/service.js";
|
|
11
|
+
import { scoresFor } from "../../slices/schedules/topic-scores.js";
|
|
10
12
|
import { approveHeldTopics, editHeldTopic, heldTopics, moveTopic, rejectHeldTopic, replaceTopics, transferTopic, } from "../../slices/schedules/topics.js";
|
|
11
|
-
import { onInvalid, problem
|
|
13
|
+
import { onInvalid, problem } from "./problem.js";
|
|
14
|
+
import { refusal } from "./refusal.js";
|
|
12
15
|
const id = z.object({ id: z.uuid() });
|
|
13
16
|
const topicParam = z.object({ id: z.uuid(), topicId: z.string().min(1).max(100) });
|
|
14
17
|
const topicIds = z.array(z.string().min(1).max(100)).min(1).max(queueMax);
|
|
15
|
-
|
|
16
|
-
const
|
|
18
|
+
// Prepare one queued topic: its title as the queue lists it.
|
|
19
|
+
export const prepareTopicBody = z.object({ topic: z.string().min(1).max(500) }).strict();
|
|
20
|
+
// Approve one held topic, optionally under another title.
|
|
21
|
+
export const approveHeldTopicBody = z.object({ title: z.string().optional() }).strict();
|
|
22
|
+
export const heldIds = z.object({ ids: topicIds }).strict();
|
|
23
|
+
export const heldRestore = z
|
|
17
24
|
.object({
|
|
18
25
|
topics: z
|
|
19
26
|
.array(z
|
|
@@ -27,18 +34,6 @@ const heldRestore = z
|
|
|
27
34
|
})
|
|
28
35
|
.strict();
|
|
29
36
|
function refused(c, result) {
|
|
30
|
-
const status = ["not-found", "missing-template", "topic-not-found"].includes(result.reason)
|
|
31
|
-
? 404
|
|
32
|
-
: [
|
|
33
|
-
"conflict",
|
|
34
|
-
"cancel-required",
|
|
35
|
-
"spend-limit",
|
|
36
|
-
"unsupported-media",
|
|
37
|
-
"queue-full",
|
|
38
|
-
"busy",
|
|
39
|
-
].includes(result.reason)
|
|
40
|
-
? 409
|
|
41
|
-
: 400;
|
|
42
37
|
const detail = {
|
|
43
38
|
"invalid-input": "Some schedule settings are not valid. Check each field and save again.",
|
|
44
39
|
"not-found": "This schedule no longer exists; it may have been deleted. Reload the page to see your schedules.",
|
|
@@ -52,13 +47,23 @@ function refused(c, result) {
|
|
|
52
47
|
"queue-full": `A schedule's topic queue holds at most ${String(queueMax)} topics. Remove some under Schedules → Edit, then try again.`,
|
|
53
48
|
"topic-not-found": "This topic was already approved, turned down or used. Reload the page to see the topics waiting now.",
|
|
54
49
|
busy: "Slopify is already generating topics for this schedule. Wait for it to finish, then try again.",
|
|
50
|
+
"not-ready": "This schedule's template has no version marked ready. Open it in Library → Templates → Open studio and press Mark ready.",
|
|
55
51
|
"invalid-topics": "Some topics name keywords this template does not use. Check each topic under Schedules → Edit and save again.",
|
|
56
52
|
};
|
|
57
|
-
return
|
|
58
|
-
|
|
59
|
-
|
|
53
|
+
return refusal(c, result.reason, {
|
|
54
|
+
statuses: {
|
|
55
|
+
"not-found": 404,
|
|
56
|
+
"missing-template": 404,
|
|
57
|
+
"topic-not-found": 404,
|
|
58
|
+
conflict: 409,
|
|
59
|
+
"cancel-required": 409,
|
|
60
|
+
"spend-limit": 409,
|
|
61
|
+
"unsupported-media": 409,
|
|
62
|
+
"queue-full": 409,
|
|
63
|
+
busy: 409,
|
|
64
|
+
},
|
|
65
|
+
otherwise: 400,
|
|
60
66
|
detail: result.message ?? detail[result.reason],
|
|
61
|
-
extensions: { reason: result.reason },
|
|
62
67
|
});
|
|
63
68
|
}
|
|
64
69
|
export function scheduleRoutes(deps) {
|
|
@@ -90,38 +95,44 @@ function routes(deps) {
|
|
|
90
95
|
? c.json({
|
|
91
96
|
schedule: scheduleSummarySchema.parse(schedule),
|
|
92
97
|
runs: runs.value.map((run) => scheduleRunSchema.parse(run)),
|
|
98
|
+
// Each queued and held topic's score and reasons, by `topicKey`, while ranking
|
|
99
|
+
// is on.
|
|
100
|
+
scores: scoresFor(service().db, schedule.id, [
|
|
101
|
+
...schedule.items.map((item) => item.title),
|
|
102
|
+
...heldTopics(service(), schedule.id).map((topic) => topic.title),
|
|
103
|
+
]),
|
|
93
104
|
})
|
|
94
105
|
: refused(c, runs);
|
|
95
106
|
})
|
|
96
|
-
.put("/:id", zValidator("param", id, onInvalid), zValidator("json",
|
|
107
|
+
.put("/:id", zValidator("param", id, onInvalid), zValidator("json", scheduleSaveBodySchema, onInvalid), (c) => {
|
|
97
108
|
const result = updateSchedule(service(), {
|
|
98
109
|
...c.req.valid("json"),
|
|
99
110
|
id: c.req.valid("param").id,
|
|
100
111
|
});
|
|
101
112
|
return result.ok ? c.json(scheduleSummarySchema.parse(result.value)) : refused(c, result);
|
|
102
113
|
})
|
|
103
|
-
.post("/:id/pause", zValidator("param", id, onInvalid), zValidator("json",
|
|
114
|
+
.post("/:id/pause", zValidator("param", id, onInvalid), zValidator("json", scheduleVersionBodySchema, onInvalid), (c) => {
|
|
104
115
|
const result = pauseSchedule(service(), {
|
|
105
116
|
...c.req.valid("json"),
|
|
106
117
|
id: c.req.valid("param").id,
|
|
107
118
|
});
|
|
108
119
|
return result.ok ? c.json(scheduleSummarySchema.parse(result.value)) : refused(c, result);
|
|
109
120
|
})
|
|
110
|
-
.post("/:id/resume", zValidator("param", id, onInvalid), zValidator("json",
|
|
121
|
+
.post("/:id/resume", zValidator("param", id, onInvalid), zValidator("json", scheduleVersionBodySchema, onInvalid), (c) => {
|
|
111
122
|
const result = resumeSchedule(service(), {
|
|
112
123
|
...c.req.valid("json"),
|
|
113
124
|
id: c.req.valid("param").id,
|
|
114
125
|
});
|
|
115
126
|
return result.ok ? c.json(scheduleSummarySchema.parse(result.value)) : refused(c, result);
|
|
116
127
|
})
|
|
117
|
-
.post("/:id/cancel", zValidator("param", id, onInvalid), zValidator("json",
|
|
128
|
+
.post("/:id/cancel", zValidator("param", id, onInvalid), zValidator("json", scheduleVersionBodySchema, onInvalid), (c) => {
|
|
118
129
|
const result = cancelSchedule(service(), {
|
|
119
130
|
...c.req.valid("json"),
|
|
120
131
|
id: c.req.valid("param").id,
|
|
121
132
|
});
|
|
122
133
|
return result.ok ? c.json(scheduleSummarySchema.parse(result.value)) : refused(c, result);
|
|
123
134
|
})
|
|
124
|
-
.delete("/:id", zValidator("param", id, onInvalid), zValidator("json",
|
|
135
|
+
.delete("/:id", zValidator("param", id, onInvalid), zValidator("json", scheduleVersionBodySchema, onInvalid), (c) => {
|
|
125
136
|
const result = deleteSchedule(service(), {
|
|
126
137
|
...c.req.valid("json"),
|
|
127
138
|
id: c.req.valid("param").id,
|
|
@@ -132,14 +143,30 @@ function routes(deps) {
|
|
|
132
143
|
const scheduleId = c.req.valid("param").id;
|
|
133
144
|
if (listSchedules(service()).every((item) => item.id !== scheduleId))
|
|
134
145
|
return refused(c, { ok: false, reason: "not-found" });
|
|
146
|
+
const topics = heldTopics(service(), scheduleId).map((topic) => heldTopicSchema.parse(topic));
|
|
135
147
|
return c.json({
|
|
136
|
-
topics
|
|
148
|
+
topics,
|
|
149
|
+
scores: scoresFor(service().db, scheduleId, topics.map((topic) => topic.title)),
|
|
137
150
|
});
|
|
151
|
+
})
|
|
152
|
+
// Rescore: every queued and held topic scored again, then put in score order. With search
|
|
153
|
+
// ranking it asks Google, DuckDuckGo and Wikipedia, up to 15 seconds.
|
|
154
|
+
.post("/:id/topics/score", zValidator("param", id, onInvalid), async (c) => {
|
|
155
|
+
const result = await rescoreTopics(service(), c.req.valid("param").id);
|
|
156
|
+
if (result.ok)
|
|
157
|
+
return c.json(scheduleSummarySchema.parse(result.value));
|
|
158
|
+
if (result.reason === "scoring-off")
|
|
159
|
+
return problem(c, {
|
|
160
|
+
status: 409,
|
|
161
|
+
detail: result.message,
|
|
162
|
+
extensions: { reason: result.reason },
|
|
163
|
+
});
|
|
164
|
+
return refused(c, result);
|
|
138
165
|
})
|
|
139
166
|
// Which queued topics are prepared ahead, and their projects.
|
|
140
167
|
.get("/:id/prepared", zValidator("param", id, onInvalid), (c) => c.json({ prepared: preparedTopics(service(), c.req.valid("param").id) }))
|
|
141
168
|
// Prepare one queued topic now: everything but the video, which its scheduled day renders.
|
|
142
|
-
.post("/:id/topics/prepare", zValidator("param", id, onInvalid), zValidator("json",
|
|
169
|
+
.post("/:id/topics/prepare", zValidator("param", id, onInvalid), zValidator("json", prepareTopicBody, onInvalid), async (c) => {
|
|
143
170
|
const result = await prepareTopic(service(), {
|
|
144
171
|
scheduleId: c.req.valid("param").id,
|
|
145
172
|
title: c.req.valid("json").topic,
|
|
@@ -149,13 +176,15 @@ function routes(deps) {
|
|
|
149
176
|
const detail = {
|
|
150
177
|
"not-found": "This topic is no longer in the schedule's queue. Reload the page to see the queue as it is now.",
|
|
151
178
|
"already-prepared": "This topic is already prepared: its project is in Projects under the same title.",
|
|
179
|
+
paused: "Its schedule is paused, so it makes nothing, ahead or on its day. Resume it under Calendar → Schedules, then press Prepare again.",
|
|
152
180
|
"missing-template": "This schedule's template was deleted, so there is nothing to prepare from. Choose another template under Edit.",
|
|
153
181
|
"spend-limit": "Preparing it would go over this schedule's spend limit. Raise the limit under Edit, or prepare it from Play instead.",
|
|
182
|
+
design: "A design schedule makes each piece on its day, so there is nothing to prepare ahead. To have a piece now, open the design template (Library → Designs → Templates) and press Make a piece; to have it sooner on a schedule, give its row an earlier date in the Schedule section.",
|
|
154
183
|
};
|
|
155
184
|
return problem(c, {
|
|
156
185
|
status: result.reason === "not-found" ? 404 : 409,
|
|
157
|
-
|
|
158
|
-
|
|
186
|
+
detail: (result.reason === "not-ready" ? result.detail : undefined) ??
|
|
187
|
+
detail[result.reason] ??
|
|
159
188
|
(result.detail === undefined
|
|
160
189
|
? `This topic couldn't be prepared (${result.reason}). Open Play with the schedule's template to see what the setup needs, then try again.`
|
|
161
190
|
: `This topic couldn't be prepared: ${result.detail} Fix it in the schedule's template (Library → Templates), then try again.`),
|
|
@@ -181,7 +210,6 @@ function routes(deps) {
|
|
|
181
210
|
if (refusal !== undefined)
|
|
182
211
|
return problem(c, {
|
|
183
212
|
status: 409,
|
|
184
|
-
title: titleOf(409),
|
|
185
213
|
detail: refusal,
|
|
186
214
|
extensions: { reason: "busy" },
|
|
187
215
|
});
|
|
@@ -206,7 +234,7 @@ function routes(deps) {
|
|
|
206
234
|
const result = restoreRejectedTopics(service(), c.req.valid("param").id, c.req.valid("json").topics);
|
|
207
235
|
return result.ok ? c.json(scheduleSummarySchema.parse(result.value)) : refused(c, result);
|
|
208
236
|
})
|
|
209
|
-
.post("/:id/topics/held/:topicId/approve", zValidator("param", topicParam, onInvalid), zValidator("json",
|
|
237
|
+
.post("/:id/topics/held/:topicId/approve", zValidator("param", topicParam, onInvalid), zValidator("json", approveHeldTopicBody, onInvalid), (c) => {
|
|
210
238
|
const { id: scheduleId, topicId } = c.req.valid("param");
|
|
211
239
|
const { title } = c.req.valid("json");
|
|
212
240
|
const result = approveHeldTopics(service(), scheduleId, [topicId], title === undefined ? {} : { [topicId]: title });
|
|
@@ -257,7 +285,6 @@ export function calendarRoutes(deps) {
|
|
|
257
285
|
if (!result.ok)
|
|
258
286
|
return problem(c, {
|
|
259
287
|
status: 400,
|
|
260
|
-
title: titleOf(400),
|
|
261
288
|
detail: `Choose a range whose end is after its start and at most ${String(calendarMaxDays)} days long.`,
|
|
262
289
|
extensions: { reason: result.reason },
|
|
263
290
|
});
|
|
@@ -10,9 +10,10 @@ import { readNotificationUrl, saveNotificationUrl } from "../../slices/notificat
|
|
|
10
10
|
import { appearances, providerIds } from "../../slices/settings/model.js";
|
|
11
11
|
import { readSettings, saveSettings } from "../../slices/settings/playback.js";
|
|
12
12
|
import { addVoice, removeVoice, setVoiceImitatesRealPerson, setVoiceLanguages, voiceIdMax, voiceNameMax, voices, } from "../../slices/settings/voices.js";
|
|
13
|
+
import { clipEncodeSpeeds, noNvenc, renderPriorities, videoEncoders, } from "../../slices/video/encoding.js";
|
|
13
14
|
import { readChannelLinks, writeChannelLinks } from "../../slices/youtube/edits-repo.js";
|
|
14
15
|
import { channelLinkNameMax, channelLinksMax, channelLinksProblem, channelLinkUrlMax, } from "../../slices/youtube/placeholders.js";
|
|
15
|
-
import { onInvalid, problem
|
|
16
|
+
import { onInvalid, problem } from "./problem.js";
|
|
16
17
|
const idParam = z.object({ id: z.string().min(1).max(64) });
|
|
17
18
|
// Shape only. The rules - trimming, emptiness, length, the provider speaking at all -
|
|
18
19
|
// are the slice's, so one set of messages reaches the form.
|
|
@@ -26,7 +27,7 @@ const voiceLanguagesBody = z.object({ languages: z.array(z.string().max(20)).max
|
|
|
26
27
|
const voiceRealPersonBody = z.object({ imitatesRealPerson: z.boolean() });
|
|
27
28
|
// Length and scheme are the slice's rules, so their sentences reach the field; this bound only
|
|
28
29
|
// keeps a pasted novel off the parser.
|
|
29
|
-
const notificationBody = z.object({ url: z.string().max(notificationUrlMax * 2) });
|
|
30
|
+
export const notificationBody = z.object({ url: z.string().max(notificationUrlMax * 2) });
|
|
30
31
|
// Shape and a generous bound only; `channelLinksProblem` says what is wrong in Settings' words.
|
|
31
32
|
export const channelLinksBody = z.object({
|
|
32
33
|
links: z
|
|
@@ -45,6 +46,10 @@ const playbackBody = z.object({
|
|
|
45
46
|
.optional(),
|
|
46
47
|
// Absent keeps what is saved, as with loudness.
|
|
47
48
|
subtitleModel: z.enum(englishSubtitleModels).optional(),
|
|
49
|
+
// Absent keeps what is saved, as with loudness.
|
|
50
|
+
videoEncoder: z.enum(videoEncoders).optional(),
|
|
51
|
+
clipEncodeSpeed: z.enum(clipEncodeSpeeds).optional(),
|
|
52
|
+
renderPriority: z.enum(renderPriorities).optional(),
|
|
48
53
|
});
|
|
49
54
|
// The return type is inferred so Hono keeps the route types the SPA's client is
|
|
50
55
|
// generated from; see stagingRoutes.
|
|
@@ -61,16 +66,30 @@ export function settingsRoutes(deps) {
|
|
|
61
66
|
...body,
|
|
62
67
|
loudness: body.loudness ?? saved.loudness,
|
|
63
68
|
subtitleModel: body.subtitleModel ?? saved.subtitleModel,
|
|
69
|
+
videoEncoder: body.videoEncoder ?? saved.videoEncoder,
|
|
70
|
+
clipEncodeSpeed: body.clipEncodeSpeed ?? saved.clipEncodeSpeed,
|
|
71
|
+
renderPriority: body.renderPriority ?? saved.renderPriority,
|
|
64
72
|
});
|
|
65
73
|
if (!result.ok) {
|
|
66
74
|
return problem(c, {
|
|
67
75
|
status: 400,
|
|
68
|
-
title: titleOf(400),
|
|
69
76
|
detail: "These settings cannot be saved yet. Fix the highlighted fields and try again.",
|
|
70
77
|
extensions: { fields: result.fields },
|
|
71
78
|
});
|
|
72
79
|
}
|
|
73
80
|
return c.json(result.settings);
|
|
81
|
+
})
|
|
82
|
+
// Settings → Production defaults → Video encoder offers the NVIDIA card only where its
|
|
83
|
+
// encoder works; the first ask runs a test encode, later ones answer from memory.
|
|
84
|
+
.get("/encoders", async (c) => {
|
|
85
|
+
const status = deps.nvenc === undefined
|
|
86
|
+
? { available: false, reason: noNvenc }
|
|
87
|
+
: await deps.nvenc();
|
|
88
|
+
return c.json({
|
|
89
|
+
nvidia: status.available
|
|
90
|
+
? { available: true }
|
|
91
|
+
: { available: false, reason: status.reason },
|
|
92
|
+
});
|
|
74
93
|
})
|
|
75
94
|
// The named links `{{Name}}` placeholders in YouTube descriptions fill from
|
|
76
95
|
// (`slices/youtube/placeholders.ts`).
|
|
@@ -81,7 +100,6 @@ export function settingsRoutes(deps) {
|
|
|
81
100
|
if (refused !== undefined)
|
|
82
101
|
return problem(c, {
|
|
83
102
|
status: 400,
|
|
84
|
-
title: titleOf(400),
|
|
85
103
|
detail: `The channel links weren't saved: ${refused} Then press Save in Settings → Channel links.`,
|
|
86
104
|
});
|
|
87
105
|
writeChannelLinks(deps.db, links);
|
|
@@ -93,7 +111,6 @@ export function settingsRoutes(deps) {
|
|
|
93
111
|
if (!result.ok) {
|
|
94
112
|
return problem(c, {
|
|
95
113
|
status: 400,
|
|
96
|
-
title: titleOf(400),
|
|
97
114
|
detail: `The Notification URL wasn't saved: ${result.message} Fix it in Settings → Notifications → Notification URL, then press Save.`,
|
|
98
115
|
extensions: { fields: [{ field: "url", message: result.message }] },
|
|
99
116
|
});
|
|
@@ -108,7 +125,6 @@ export function settingsRoutes(deps) {
|
|
|
108
125
|
if (invalid !== undefined) {
|
|
109
126
|
return problem(c, {
|
|
110
127
|
status: 400,
|
|
111
|
-
title: titleOf(400),
|
|
112
128
|
detail: `The test notification wasn't sent: ${invalid}`,
|
|
113
129
|
extensions: { fields: [{ field: "url", message: invalid }] },
|
|
114
130
|
});
|
|
@@ -118,7 +134,6 @@ export function settingsRoutes(deps) {
|
|
|
118
134
|
deps.log.write("warn", "notification.test", { detail: sendFailureText(result) });
|
|
119
135
|
return problem(c, {
|
|
120
136
|
status: 502,
|
|
121
|
-
title: titleOf(502),
|
|
122
137
|
detail: `The test notification wasn't delivered: ${sendFailureText(result)}. Check the address in Settings → Notifications → Notification URL (for ntfy, https://ntfy.sh/your-topic), then press Send test notification again.`,
|
|
123
138
|
});
|
|
124
139
|
}
|
|
@@ -147,12 +162,10 @@ export function settingsRoutes(deps) {
|
|
|
147
162
|
return result.reason === "duplicate-voice-id"
|
|
148
163
|
? problem(c, {
|
|
149
164
|
status: 409,
|
|
150
|
-
title: titleOf(409),
|
|
151
165
|
detail: "This voice ID is already saved for this provider. Use the existing voice, or enter a different voice ID.",
|
|
152
166
|
})
|
|
153
167
|
: problem(c, {
|
|
154
168
|
status: 400,
|
|
155
|
-
title: titleOf(400),
|
|
156
169
|
detail: "This voice cannot be added yet. Fix the highlighted field and try again.",
|
|
157
170
|
extensions: { fields: [fieldOf(result.reason)] },
|
|
158
171
|
});
|
|
@@ -166,12 +179,10 @@ export function settingsRoutes(deps) {
|
|
|
166
179
|
return result.reason === "missing"
|
|
167
180
|
? problem(c, {
|
|
168
181
|
status: 404,
|
|
169
|
-
title: titleOf(404),
|
|
170
182
|
detail: "This voice no longer exists; it may have been deleted. Reload Settings → Voices to see your voices.",
|
|
171
183
|
})
|
|
172
184
|
: problem(c, {
|
|
173
185
|
status: 400,
|
|
174
|
-
title: titleOf(400),
|
|
175
186
|
detail: "The languages weren't saved. Fix the highlighted field and try again.",
|
|
176
187
|
extensions: { fields: [fieldOf("unknown-language")] },
|
|
177
188
|
});
|
|
@@ -183,7 +194,6 @@ export function settingsRoutes(deps) {
|
|
|
183
194
|
? c.body(null, 204)
|
|
184
195
|
: problem(c, {
|
|
185
196
|
status: 404,
|
|
186
|
-
title: titleOf(404),
|
|
187
197
|
detail: "This voice no longer exists; it may have been deleted. Reload Settings → Voices to see your voices.",
|
|
188
198
|
});
|
|
189
199
|
})
|
|
@@ -191,7 +201,6 @@ export function settingsRoutes(deps) {
|
|
|
191
201
|
if (!removeVoice(voiceDeps, c.req.valid("param").id).ok) {
|
|
192
202
|
return problem(c, {
|
|
193
203
|
status: 404,
|
|
194
|
-
title: titleOf(404),
|
|
195
204
|
detail: "This voice no longer exists; it may have been deleted already. Reload the page to see your voices.",
|
|
196
205
|
});
|
|
197
206
|
}
|