@gentbajko/slopify 3.25.9 → 4.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/adapters/account-limits.js +30 -0
- package/dist/adapters/alignment/audio.js +1 -1
- package/dist/adapters/alignment/cache.js +4 -6
- package/dist/adapters/alignment/ctc.js +1 -2
- package/dist/adapters/alignment/lock.js +4 -3
- package/dist/adapters/alignment/multilingual.js +2 -4
- package/dist/adapters/alignment/prefetch.js +2 -1
- package/dist/adapters/alignment/runner.js +1 -1
- package/dist/adapters/alignment/worker.js +3 -2
- package/dist/adapters/explain.js +10 -12
- package/dist/adapters/ffmpeg.js +19 -1
- package/dist/adapters/host-cli/index.js +21 -4
- package/dist/adapters/host-cli/transport.js +2 -1
- package/dist/adapters/http-failure.js +53 -0
- package/dist/adapters/image/bytes.js +2 -1
- package/dist/adapters/image/codex.js +42 -9
- package/dist/adapters/image/fal.js +21 -53
- package/dist/adapters/image/google.js +33 -56
- package/dist/adapters/image/models.js +2 -2
- package/dist/adapters/image/openai.js +22 -48
- package/dist/adapters/image/reference.js +36 -0
- package/dist/adapters/image/replicate.js +21 -49
- package/dist/adapters/image/video.js +2 -1
- package/dist/adapters/interest/search-interest.js +113 -0
- package/dist/adapters/key-probes.js +54 -3
- package/dist/adapters/llm/antigravity-models.js +1 -1
- package/dist/adapters/llm/antigravity.js +11 -6
- package/dist/adapters/llm/assistant-cli.js +388 -0
- package/dist/adapters/llm/child-session.js +83 -0
- package/dist/adapters/llm/claude-code-models.js +52 -99
- package/dist/adapters/llm/claude-code.js +16 -4
- package/dist/adapters/llm/codex-limits.js +27 -68
- package/dist/adapters/llm/codex-models.js +1 -1
- package/dist/adapters/llm/codex-server-models.js +61 -109
- package/dist/adapters/llm/codex.js +12 -1
- package/dist/adapters/llm/document-workspace.js +3 -2
- package/dist/adapters/llm/image-workspace.js +3 -2
- package/dist/adapters/llm/openrouter.js +12 -48
- package/dist/adapters/llm/run-cli.js +9 -24
- package/dist/adapters/llm/sse-lines.js +5 -1
- package/dist/adapters/model-access.js +37 -0
- package/dist/adapters/tts/cartesia.js +15 -46
- package/dist/adapters/tts/elevenlabs.js +20 -52
- package/dist/adapters/tts/gemini.js +21 -41
- package/dist/adapters/tts/inworld-async.js +6 -2
- package/dist/adapters/tts/inworld.js +6 -2
- package/dist/adapters/tts/openai.js +20 -50
- package/dist/adapters/tts/system.js +2 -1
- package/dist/assets/models-lifecycle.yaml +6 -0
- package/dist/assistant-wiring.js +60 -0
- package/dist/autopilot-timers.js +59 -0
- package/dist/catalog/lifecycle.js +52 -0
- package/dist/catalog/propose.js +204 -0
- package/dist/catalog/registry.js +23 -14
- package/dist/catalog/schema.js +4 -1
- package/dist/catalog/store.js +39 -0
- package/dist/catalog/validate.js +5 -2
- package/dist/edge/autostart/native.js +3 -5
- package/dist/edge/autostart/prompt.js +2 -1
- package/dist/edge/autostart/service.js +3 -4
- package/dist/edge/cli-args.js +3 -4
- package/dist/edge/cli.js +2 -1
- package/dist/edge/docker-install/apply.js +11 -11
- package/dist/edge/docker-install/run.js +2 -1
- package/dist/edge/docker-install/state.js +4 -3
- package/dist/edge/docker-install/tree.js +2 -4
- package/dist/edge/docker-install/volume.js +3 -2
- package/dist/edge/docker.js +5 -4
- package/dist/edge/events/hub.js +5 -5
- package/dist/edge/http/actions.js +11 -32
- package/dist/edge/http/actor.js +5 -3
- package/dist/edge/http/app.js +86 -11
- package/dist/edge/http/assistant.js +129 -0
- package/dist/edge/http/audio-preview.js +4 -11
- package/dist/edge/http/auditions.js +1 -1
- package/dist/edge/http/autostart.js +5 -5
- package/dist/edge/http/backups.js +2 -4
- package/dist/edge/http/channel-memory.js +9 -22
- package/dist/edge/http/channels.js +14 -27
- package/dist/edge/http/checkpoints.js +39 -21
- package/dist/edge/http/design-templates.js +167 -0
- package/dist/edge/http/designs.js +178 -0
- package/dist/edge/http/diagnostics.js +5 -1
- package/dist/edge/http/document-themes.js +5 -14
- package/dist/edge/http/draft-files.js +1 -3
- package/dist/edge/http/draft-problem.js +5 -10
- package/dist/edge/http/drafts.js +3 -3
- package/dist/edge/http/entries.js +6 -9
- package/dist/edge/http/extension-auth.js +27 -0
- package/dist/edge/http/external-reviews.js +12 -11
- package/dist/edge/http/files.js +5 -11
- package/dist/edge/http/folder-location.js +1 -4
- package/dist/edge/http/fonts.js +0 -7
- package/dist/edge/http/home.js +47 -14
- package/dist/edge/http/host-cli.js +18 -8
- package/dist/edge/http/ids.js +8 -0
- package/dist/edge/http/keywords.js +35 -0
- package/dist/edge/http/model-checks.js +132 -0
- package/dist/edge/http/narration-peaks.js +5 -13
- package/dist/edge/http/onboarding.js +30 -26
- package/dist/edge/http/open-folder.js +5 -10
- package/dist/edge/http/outputs.js +7 -14
- package/dist/edge/http/patch-notes.js +6 -12
- package/dist/edge/http/planning.js +3 -7
- package/dist/edge/http/problem.js +2 -4
- package/dist/edge/http/project-create.js +2 -1
- package/dist/edge/http/project-templates.js +31 -19
- package/dist/edge/http/projects.js +24 -16
- package/dist/edge/http/prompts.js +9 -16
- package/dist/edge/http/pronunciations.js +1 -2
- package/dist/edge/http/providers.js +48 -34
- package/dist/edge/http/refusal.js +29 -0
- package/dist/edge/http/remote-access.js +40 -0
- package/dist/edge/http/remote-guard.js +71 -0
- package/dist/edge/http/request-guard.js +91 -0
- package/dist/edge/http/reviews.js +12 -25
- package/dist/edge/http/revision-files.js +6 -11
- package/dist/edge/http/revisions.js +14 -19
- package/dist/edge/http/run-cost.js +1 -2
- package/dist/edge/http/same-page.js +80 -0
- package/dist/edge/http/schedules.js +69 -40
- package/dist/edge/http/settings.js +27 -14
- package/dist/edge/http/social.js +283 -0
- package/dist/edge/http/staging.js +3 -5
- package/dist/edge/http/storage-files.js +5 -7
- package/dist/edge/http/storage.js +33 -25
- package/dist/edge/http/studio.js +94 -69
- package/dist/edge/http/style-preview.js +3 -6
- package/dist/edge/http/subtitles.js +3 -17
- package/dist/edge/http/template-studio.js +436 -0
- package/dist/edge/http/trash.js +11 -12
- package/dist/edge/http/tutorial.js +1 -2
- package/dist/edge/http/tutorials.js +5 -11
- package/dist/edge/http/update.js +7 -13
- package/dist/edge/http/waveform.js +3 -6
- package/dist/edge/http/youtube-edits.js +3 -4
- package/dist/edge/mcp/assistant.js +279 -0
- package/dist/edge/mcp/attribution.js +8 -2
- package/dist/edge/mcp/call-route.js +11 -2
- package/dist/edge/mcp/excluded-routes.js +29 -3
- package/dist/edge/mcp/http.js +11 -2
- package/dist/edge/mcp/instructions.js +6 -4
- package/dist/edge/mcp/library-tools.js +9 -5
- package/dist/edge/mcp/remake-tools.js +7 -4
- package/dist/edge/mcp/route-tool.js +35 -15
- package/dist/edge/mcp/server.js +13 -8
- package/dist/edge/mcp/tools-channels.js +11 -9
- package/dist/edge/mcp/tools-designs.js +165 -0
- package/dist/edge/mcp/tools-library.js +19 -7
- package/dist/edge/mcp/tools-planning.js +40 -21
- package/dist/edge/mcp/tools-projects.js +38 -11
- package/dist/edge/mcp/tools-publishing.js +9 -9
- package/dist/edge/mcp/tools-runs.js +23 -10
- package/dist/edge/mcp/tools-schedules.js +32 -8
- package/dist/edge/mcp/tools-setup.js +75 -11
- package/dist/edge/mcp/tools-social.js +47 -0
- package/dist/edge/mcp/tools-storage.js +11 -3
- package/dist/edge/mcp/tools-template-studio.js +166 -0
- package/dist/edge/mcp/tools.js +6 -0
- package/dist/edge/remote-access/cli.js +71 -0
- package/dist/edge/remote-access/model.js +32 -0
- package/dist/edge/remote-access/rules.js +207 -0
- package/dist/edge/remote-access/service.js +203 -0
- package/dist/edge/remote-access/store.js +44 -0
- package/dist/edge/remote-access/views.js +43 -0
- package/dist/extension/slopify-studio-chrome.zip +0 -0
- package/dist/extension/slopify-studio-firefox.zip +0 -0
- package/dist/host-cli/install.js +2 -2
- package/dist/host-cli/open-folder.js +2 -2
- package/dist/host-cli/paths.js +2 -4
- package/dist/host-cli/server.js +4 -4
- package/dist/host-cli/service.js +3 -3
- package/dist/host-cli/status.js +7 -7
- package/dist/kernel/db/migrations/0063-model-checks.sql +20 -0
- package/dist/kernel/db/migrations/0064-template-studio.sql +46 -0
- package/dist/kernel/db/migrations/0065-promise-and-assistant-reviews.sql +58 -0
- package/dist/kernel/db/migrations/0066-assistant.sql +44 -0
- package/dist/kernel/db/migrations/0067-autopilot.sql +6 -0
- package/dist/kernel/db/migrations/0068-topic-scores.sql +17 -0
- package/dist/kernel/db/migrations/0070-designs.sql +53 -0
- package/dist/kernel/db/migrations/0071-design-usage.sql +33 -0
- package/dist/kernel/db/migrations/0072-design-templates.sql +33 -0
- package/dist/kernel/db/migrations/0073-schedule-design-kind.sql +5 -0
- package/dist/kernel/db/migrations/0074-template-bakeoffs.sql +44 -0
- package/dist/kernel/db/migrations/0075-social-posts.sql +25 -0
- package/dist/kernel/db/migrations/0076-channel-social.sql +5 -0
- package/dist/kernel/db/migrations/0077-post-prompts.sql +17 -0
- package/dist/kernel/db/migrations/0078-uploaded-from-links.sql +7 -0
- package/dist/kernel/db/tx.js +2 -4
- package/dist/kernel/errors.js +27 -1
- package/dist/kernel/json-answer.js +15 -0
- package/dist/kernel/lock.js +4 -9
- package/dist/kernel/paths.js +8 -0
- package/dist/kernel/pipeline.js +12 -0
- package/dist/kernel/ports/assistant-cli.js +4 -0
- package/dist/kernel/ports/host-cli.js +3 -0
- package/dist/kernel/ports/interest.js +4 -0
- package/dist/kernel/ports/languages.js +0 -3
- package/dist/kernel/ports/model.js +2 -0
- package/dist/kernel/ports/settings-places.js +31 -0
- package/dist/kernel/ports/system-speech.js +31 -3
- package/dist/kernel/runner/attempt.js +14 -4
- package/dist/kernel/runner/audition.js +3 -1
- package/dist/kernel/runner/checkpoint-authority.js +2 -1
- package/dist/kernel/runner/index.js +8 -10
- package/dist/kernel/runner/model-access.js +40 -0
- package/dist/kernel/runner/model-check.js +153 -0
- package/dist/kernel/runner/providers.js +18 -12
- package/dist/kernel/runner/standalone.js +11 -7
- package/dist/main.js +338 -21
- package/dist/model-catalog.js +20 -0
- package/dist/model-checks.js +166 -0
- package/dist/patch-notes/4.0.0.md +51 -0
- package/dist/patch-notes/4.1.0.md +42 -0
- package/dist/patch-notes/index.json +12 -0
- package/dist/slices/admission/heads.js +2 -1
- package/dist/slices/admission/listing-facts.js +95 -0
- package/dist/slices/admission/repo.js +11 -7
- package/dist/slices/admission/rules.js +50 -15
- package/dist/slices/admission/schema.js +8 -0
- package/dist/slices/admission/stage-writes.js +0 -3
- package/dist/slices/admission/start.js +48 -31
- package/dist/slices/admission/state-words.js +34 -5
- package/dist/slices/admission/substitute.js +7 -4
- package/dist/slices/agents/attention-posts.js +31 -0
- package/dist/slices/agents/attention-templates.js +33 -0
- package/dist/slices/agents/attention.js +10 -1
- package/dist/slices/agents/connection.js +2 -6
- package/dist/slices/agents/model.js +6 -3
- package/dist/slices/agents/repo.js +15 -7
- package/dist/slices/article/continuation.js +0 -63
- package/dist/slices/article/plain.js +3 -2
- package/dist/slices/article/segments.js +2 -62
- package/dist/slices/assistant/access.js +1 -0
- package/dist/slices/assistant/asks.js +80 -0
- package/dist/slices/assistant/cost.js +54 -0
- package/dist/slices/assistant/gate.js +222 -0
- package/dist/slices/assistant/model.js +86 -0
- package/dist/slices/assistant/names.js +23 -0
- package/dist/slices/assistant/prompt.js +74 -0
- package/dist/slices/assistant/repo.js +74 -0
- package/dist/slices/assistant/tokens.js +18 -0
- package/dist/slices/assistant/turn.js +344 -0
- package/dist/slices/autopilot/buffer.js +76 -0
- package/dist/slices/autopilot/model.js +14 -0
- package/dist/slices/autopilot/notify.js +27 -0
- package/dist/slices/autopilot/repo.js +34 -0
- package/dist/slices/autopilot/signals.js +194 -0
- package/dist/slices/autopilot/warnings.js +85 -0
- package/dist/slices/autopilot/weekly.js +100 -0
- package/dist/slices/backups/files.js +2 -6
- package/dist/slices/backups/repo.js +3 -15
- package/dist/slices/backups/service.js +8 -7
- package/dist/slices/channels/cast-images.js +3 -2
- package/dist/slices/channels/model.js +0 -1
- package/dist/slices/channels/rebrand.js +0 -3
- package/dist/slices/channels/repo.js +4 -0
- package/dist/slices/channels/schema.js +7 -1
- package/dist/slices/channels/service.js +10 -0
- package/dist/slices/channels/videos.js +3 -15
- package/dist/slices/checkpoints/index.js +0 -1
- package/dist/slices/control/providers.js +2 -28
- package/dist/slices/designs/artwork.js +66 -0
- package/dist/slices/designs/budget.js +23 -0
- package/dist/slices/designs/calls.js +124 -0
- package/dist/slices/designs/check-context.js +38 -0
- package/dist/slices/designs/check-text.js +43 -0
- package/dist/slices/designs/fields.js +88 -0
- package/dist/slices/designs/frames.js +34 -0
- package/dist/slices/designs/gate.js +130 -0
- package/dist/slices/designs/layout.js +293 -0
- package/dist/slices/designs/model.js +35 -0
- package/dist/slices/designs/pdf-job.js +23 -0
- package/dist/slices/designs/pdf-pages.js +30 -0
- package/dist/slices/designs/pdf-runner.js +68 -0
- package/dist/slices/designs/pdf-worker.js +24 -0
- package/dist/slices/designs/picture-size.js +79 -0
- package/dist/slices/designs/pictures.js +55 -0
- package/dist/slices/designs/quote.js +24 -0
- package/dist/slices/designs/render-args.js +36 -0
- package/dist/slices/designs/render-input.js +59 -0
- package/dist/slices/designs/render.js +215 -0
- package/dist/slices/designs/repo.js +101 -0
- package/dist/slices/designs/requests.js +80 -0
- package/dist/slices/designs/runner.js +239 -0
- package/dist/slices/designs/sample-repo.js +91 -0
- package/dist/slices/designs/sample.js +223 -0
- package/dist/slices/designs/schema.js +87 -0
- package/dist/slices/designs/sections.js +44 -0
- package/dist/slices/designs/service.js +233 -0
- package/dist/slices/designs/steps-repo.js +102 -0
- package/dist/slices/designs/studio-kind.js +39 -0
- package/dist/slices/designs/template-checks.js +44 -0
- package/dist/slices/designs/template-make.js +118 -0
- package/dist/slices/designs/templates.js +218 -0
- package/dist/slices/document/fonts.js +2 -1
- package/dist/slices/document/model.js +7 -4
- package/dist/slices/document/render.js +2 -1
- package/dist/slices/document/theme-schema.js +1 -1
- package/dist/slices/document/theme.js +49 -3
- package/dist/slices/episodes/summarize.js +6 -2
- package/dist/slices/estimate/index.js +72 -28
- package/dist/slices/estimate/requests.js +4 -4
- package/dist/slices/fixes/rules.js +3 -1
- package/dist/slices/fonts/catalog.js +5 -3
- package/dist/slices/fonts/coverage.js +2 -1
- package/dist/slices/fonts/discovery.js +3 -2
- package/dist/slices/fonts/files.js +2 -6
- package/dist/slices/fonts/index.js +0 -1
- package/dist/slices/fonts/sfnt.js +45 -10
- package/dist/slices/images/appearance.js +8 -16
- package/dist/slices/images/scenes.js +102 -28
- package/dist/slices/keywords/digest.js +85 -0
- package/dist/slices/keywords/facts.js +92 -0
- package/dist/slices/keywords/fill.js +80 -0
- package/dist/slices/keywords/model.js +75 -0
- package/dist/slices/keywords/rules.js +187 -0
- package/dist/slices/keywords/schema.js +28 -0
- package/dist/slices/keywords/specs.js +260 -0
- package/dist/slices/keywords/values.js +74 -0
- package/dist/slices/library/lint.js +29 -12
- package/dist/slices/library/model.js +2 -0
- package/dist/slices/library/photorealistic.js +4 -12
- package/dist/slices/library/rename.js +9 -7
- package/dist/slices/library/save.js +14 -10
- package/dist/slices/library/slots.js +37 -11
- package/dist/slices/library/transfer.js +5 -4
- package/dist/slices/library/used-by.js +25 -10
- package/dist/slices/loudness/loudnorm.js +53 -12
- package/dist/slices/loudness/model.js +3 -2
- package/dist/slices/loudness/sentence-level.js +2 -1
- package/dist/slices/model-checks/cost.js +61 -0
- package/dist/slices/model-checks/listing.js +124 -0
- package/dist/slices/model-checks/model.js +20 -0
- package/dist/slices/model-checks/record.js +32 -0
- package/dist/slices/model-checks/repo.js +120 -0
- package/dist/slices/model-checks/rules.js +125 -0
- package/dist/slices/model-checks/run.js +143 -0
- package/dist/slices/model-checks/service.js +198 -0
- package/dist/slices/model-upkeep/model.js +1 -1
- package/dist/slices/model-upkeep/switch.js +72 -27
- package/dist/slices/model-upkeep/usage.js +39 -13
- package/dist/slices/narration/breaths.js +3 -1
- package/dist/slices/narration/clean-pieces.js +3 -1
- package/dist/slices/narration/concat.js +2 -1
- package/dist/slices/narration/pauses-model.js +3 -2
- package/dist/slices/narration/peaks.js +3 -4
- package/dist/slices/narration/pronunciation-chunks.js +4 -3
- package/dist/slices/narration/pronunciation.js +6 -4
- package/dist/slices/narration/steering.js +4 -3
- package/dist/slices/notifications/notifier.js +4 -3
- package/dist/slices/notifications/rules.js +5 -2
- package/dist/slices/notifications/settings.js +4 -12
- package/dist/slices/notifications/subject.js +4 -3
- package/dist/slices/onboarding/copy.js +21 -3
- package/dist/slices/onboarding/first-run.js +16 -40
- package/dist/slices/onboarding/full-video.js +3 -2
- package/dist/slices/onboarding/install.js +6 -4
- package/dist/slices/onboarding/model.js +26 -37
- package/dist/slices/onboarding/packs.js +22 -22
- package/dist/slices/onboarding/preferred-model.js +14 -0
- package/dist/slices/onboarding/quick-short.js +105 -65
- package/dist/slices/onboarding/sample.js +4 -2
- package/dist/slices/onboarding/state.js +9 -11
- package/dist/slices/onboarding/template.js +8 -6
- package/dist/slices/outputs/add.js +3 -2
- package/dist/slices/outputs/service.js +2 -2
- package/dist/slices/patch-notes/library.js +4 -3
- package/dist/slices/play-drafts/convert.js +4 -0
- package/dist/slices/play-drafts/readiness.js +3 -3
- package/dist/slices/play-drafts/review-inputs.js +9 -3
- package/dist/slices/play-drafts/review.js +5 -4
- package/dist/slices/play-drafts/schema.js +4 -0
- package/dist/slices/play-drafts/service.js +17 -7
- package/dist/slices/project-templates/from-project.js +9 -2
- package/dist/slices/project-templates/next-chapter.js +2 -1
- package/dist/slices/project-templates/provider-defaults.js +22 -0
- package/dist/slices/project-templates/repo.js +6 -1
- package/dist/slices/project-templates/setup-sections.js +26 -0
- package/dist/slices/project-templates/setup.js +14 -1
- package/dist/slices/project-templates/stand-ins.js +22 -0
- package/dist/slices/rebuild/activity.js +2 -0
- package/dist/slices/rebuild/admission-repo.js +3 -2
- package/dist/slices/rebuild/narration-history.js +4 -5
- package/dist/slices/rebuild/narration-retry.js +2 -1
- package/dist/slices/rebuild/preview-details.js +32 -14
- package/dist/slices/rebuild/preview-plan.js +3 -8
- package/dist/slices/rebuild/recipe-build.js +8 -3
- package/dist/slices/rebuild/recipe-describe.js +3 -3
- package/dist/slices/rebuild/recipe-digest.js +58 -0
- package/dist/slices/rebuild/recipe-input-schema.js +10 -0
- package/dist/slices/rebuild/recipe-keywords.js +71 -0
- package/dist/slices/rebuild/recipe-legacy.js +5 -1
- package/dist/slices/rebuild/recipe-model.js +4 -0
- package/dist/slices/rebuild/recipe-narration-text.js +2 -1
- package/dist/slices/rebuild/recipe-preparation.js +4 -4
- package/dist/slices/rebuild/recipe-reference.js +8 -4
- package/dist/slices/rebuild/recipe-reviews.js +27 -7
- package/dist/slices/rebuild/recipe-save.js +8 -5
- package/dist/slices/rebuild/recipe-scenes.js +40 -11
- package/dist/slices/rebuild/recipe-shorts.js +8 -8
- package/dist/slices/rebuild/recipe-social.js +46 -0
- package/dist/slices/rebuild/recipe-text.js +64 -20
- package/dist/slices/rebuild/recipe-validation.js +102 -31
- package/dist/slices/rebuild/recipe-visual.js +55 -16
- package/dist/slices/rebuild/recipe-voices.js +3 -2
- package/dist/slices/rebuild/recipe-work.js +19 -7
- package/dist/slices/rebuild/recipe-youtube.js +4 -3
- package/dist/slices/rebuild/recovery-selection.js +3 -1
- package/dist/slices/rebuild/recovery.js +9 -8
- package/dist/slices/rebuild/remake-outdated.js +5 -5
- package/dist/slices/rebuild/repo.js +4 -3
- package/dist/slices/rebuild/review-promise.js +25 -0
- package/dist/slices/rebuild/review-redo.js +3 -2
- package/dist/slices/rebuild/runtime-admission.js +4 -3
- package/dist/slices/rebuild/runtime-agent-review.js +11 -5
- package/dist/slices/rebuild/runtime-animate.js +10 -9
- package/dist/slices/rebuild/runtime-article.js +7 -5
- package/dist/slices/rebuild/runtime-checkpoints.js +5 -4
- package/dist/slices/rebuild/runtime-document.js +11 -13
- package/dist/slices/rebuild/runtime-export-bed.js +8 -12
- package/dist/slices/rebuild/runtime-export-edit.js +8 -16
- package/dist/slices/rebuild/runtime-export-inputs.js +12 -11
- package/dist/slices/rebuild/runtime-export-short.js +9 -5
- package/dist/slices/rebuild/runtime-export.js +38 -15
- package/dist/slices/rebuild/runtime-figure-card.js +2 -1
- package/dist/slices/rebuild/runtime-image.js +8 -12
- package/dist/slices/rebuild/runtime-instructions.js +2 -0
- package/dist/slices/rebuild/runtime-keywords.js +59 -0
- package/dist/slices/rebuild/runtime-lines.js +2 -11
- package/dist/slices/rebuild/runtime-local.js +17 -22
- package/dist/slices/rebuild/runtime-narration-publication.js +2 -5
- package/dist/slices/rebuild/runtime-narration-reuse.js +9 -13
- package/dist/slices/rebuild/runtime-narration-text.js +13 -17
- package/dist/slices/rebuild/runtime-pictures.js +2 -4
- package/dist/slices/rebuild/runtime-piece-label.js +10 -6
- package/dist/slices/rebuild/runtime-plan.js +31 -5
- package/dist/slices/rebuild/runtime-provider.js +67 -25
- package/dist/slices/rebuild/runtime-publication.js +10 -9
- package/dist/slices/rebuild/runtime-review.js +39 -33
- package/dist/slices/rebuild/runtime-run.js +4 -1
- package/dist/slices/rebuild/runtime-shorts.js +31 -50
- package/dist/slices/rebuild/runtime-store.js +20 -10
- package/dist/slices/rebuild/runtime-subtitles.js +28 -25
- package/dist/slices/rebuild/runtime-voices.js +10 -16
- package/dist/slices/rebuild/runtime-youtube.js +14 -31
- package/dist/slices/rebuild/service-readiness.js +11 -3
- package/dist/slices/rebuild/transition-repo.js +6 -5
- package/dist/slices/rebuild/work-records.js +6 -0
- package/dist/slices/reruns/cascade.js +1 -2
- package/dist/slices/reruns/index.js +6 -9
- package/dist/slices/research/synthesis.js +3 -2
- package/dist/slices/reviews/external-model.js +4 -1
- package/dist/slices/reviews/external-repo.js +2 -1
- package/dist/slices/reviews/external-rows.js +2 -3
- package/dist/slices/reviews/holds.js +5 -4
- package/dist/slices/reviews/model.js +32 -11
- package/dist/slices/reviews/repo.js +2 -1
- package/dist/slices/reviews/rules.js +4 -3
- package/dist/slices/reviews/verdict.js +2 -1
- package/dist/slices/reviews/view.js +5 -2
- package/dist/slices/revisions/downloads.js +4 -5
- package/dist/slices/revisions/image-plan.js +1 -1
- package/dist/slices/revisions/mutation-assets.js +9 -5
- package/dist/slices/revisions/mutation-cues.js +2 -5
- package/dist/slices/revisions/mutations.js +3 -3
- package/dist/slices/revisions/repo.js +3 -1
- package/dist/slices/revisions/schema.js +1 -0
- package/dist/slices/revisions/view.js +20 -0
- package/dist/slices/run-cost/limits.js +5 -2
- package/dist/slices/run-cost/meter.js +12 -5
- package/dist/slices/run-cost/panel.js +8 -74
- package/dist/slices/run-cost/plan-readings.js +127 -0
- package/dist/slices/run-cost/plan-use.js +169 -0
- package/dist/slices/run-cost/pricing.js +3 -3
- package/dist/slices/run-cost/week.js +32 -4
- package/dist/slices/schedules/agenda.js +18 -7
- package/dist/slices/schedules/by-date.js +42 -0
- package/dist/slices/schedules/calendar.js +5 -0
- package/dist/slices/schedules/design-agenda.js +36 -0
- package/dist/slices/schedules/design-check.js +41 -0
- package/dist/slices/schedules/design-run.js +126 -0
- package/dist/slices/schedules/next-run.js +62 -0
- package/dist/slices/schedules/prepare.js +18 -2
- package/dist/slices/schedules/repo.js +30 -21
- package/dist/slices/schedules/rescore.js +35 -0
- package/dist/slices/schedules/scheduler.js +13 -3
- package/dist/slices/schedules/schema.js +57 -3
- package/dist/slices/schedules/score.js +107 -0
- package/dist/slices/schedules/service.js +57 -24
- package/dist/slices/schedules/topic-list.js +15 -0
- package/dist/slices/schedules/topic-scores.js +104 -0
- package/dist/slices/schedules/topics.js +53 -41
- package/dist/slices/settings/cli-paths.js +4 -6
- package/dist/slices/settings/first-run.js +8 -43
- package/dist/slices/settings/health.js +30 -15
- package/dist/slices/settings/key-test.js +1 -1
- package/dist/slices/settings/model-reach.js +3 -17
- package/dist/slices/settings/model.js +14 -2
- package/dist/slices/settings/playback.js +34 -23
- package/dist/slices/settings/probe-read.js +16 -0
- package/dist/slices/settings/repo.js +33 -0
- package/dist/slices/settings/tutorial.js +2 -2
- package/dist/slices/settings/voices.js +4 -12
- package/dist/slices/shorts/keep.js +2 -1
- package/dist/slices/shorts/pick.js +6 -18
- package/dist/slices/shorts/prompts.js +4 -14
- package/dist/slices/shorts/render.js +6 -2
- package/dist/slices/social/channel.js +44 -0
- package/dist/slices/social/defaults.js +17 -0
- package/dist/slices/social/due.js +36 -0
- package/dist/slices/social/extension.js +18 -0
- package/dist/slices/social/fit.js +115 -0
- package/dist/slices/social/limits.js +186 -0
- package/dist/slices/social/links.js +21 -0
- package/dist/slices/social/media.js +132 -0
- package/dist/slices/social/model.js +75 -0
- package/dist/slices/social/notice.js +19 -0
- package/dist/slices/social/pack.js +176 -0
- package/dist/slices/social/post-prompt.js +56 -0
- package/dist/slices/social/queue.js +31 -0
- package/dist/slices/social/repo.js +133 -0
- package/dist/slices/social/reshape.js +97 -0
- package/dist/slices/social/rules.js +5 -0
- package/dist/slices/social/schema.js +70 -0
- package/dist/slices/social/serve.js +51 -0
- package/dist/slices/social/service.js +129 -0
- package/dist/slices/social/settings.js +21 -0
- package/dist/slices/social/sources.js +114 -0
- package/dist/slices/social/state.js +110 -0
- package/dist/slices/social/text.js +149 -0
- package/dist/slices/storage/arrange.js +3 -1
- package/dist/slices/storage/assets.js +8 -10
- package/dist/slices/storage/backup-designs.js +74 -0
- package/dist/slices/storage/backup-export.js +8 -3
- package/dist/slices/storage/backup-format.js +10 -0
- package/dist/slices/storage/backup-import.js +22 -4
- package/dist/slices/storage/delete-project.js +6 -5
- package/dist/slices/storage/files-location.js +6 -8
- package/dist/slices/storage/layout.js +13 -2
- package/dist/slices/storage/model.js +3 -0
- package/dist/slices/storage/portable.js +17 -12
- package/dist/slices/storage/schema.js +2 -0
- package/dist/slices/storage/staging-refs.js +2 -1
- package/dist/slices/storage/staging.js +6 -9
- package/dist/slices/storage/trim.js +26 -9
- package/dist/slices/studio/calendar.js +7 -2
- package/dist/slices/studio/disclosure.js +4 -4
- package/dist/slices/studio/model.js +1 -1
- package/dist/slices/studio/pack.js +9 -8
- package/dist/slices/studio/pick.js +2 -11
- package/dist/slices/studio/plan.js +7 -16
- package/dist/slices/studio/queue.js +3 -14
- package/dist/slices/studio/releases.js +26 -0
- package/dist/slices/studio/settings.js +20 -57
- package/dist/slices/studio/videos.js +35 -4
- package/dist/slices/style-preview/render.js +37 -16
- package/dist/slices/style-preview/schema.js +14 -1
- package/dist/slices/style-preview/service.js +2 -1
- package/dist/slices/style-preview/settings.js +33 -5
- package/dist/slices/subtitles/captions.js +1 -1
- package/dist/slices/telemetry/collector-client.js +2 -4
- package/dist/slices/telemetry/flush.js +2 -4
- package/dist/slices/telemetry/model.js +0 -7
- package/dist/slices/telemetry/record.js +10 -3
- package/dist/slices/template-studio/anatomy-view.js +161 -0
- package/dist/slices/template-studio/anatomy.js +73 -0
- package/dist/slices/template-studio/bakeoff-make.js +225 -0
- package/dist/slices/template-studio/bakeoff-repo.js +83 -0
- package/dist/slices/template-studio/bakeoff.js +333 -0
- package/dist/slices/template-studio/budget.js +106 -0
- package/dist/slices/template-studio/cards.js +78 -0
- package/dist/slices/template-studio/checks.js +322 -0
- package/dist/slices/template-studio/document-sample.js +56 -0
- package/dist/slices/template-studio/edit.js +15 -0
- package/dist/slices/template-studio/for-all.js +161 -0
- package/dist/slices/template-studio/free-video.js +31 -0
- package/dist/slices/template-studio/free.js +176 -0
- package/dist/slices/template-studio/gate.js +40 -0
- package/dist/slices/template-studio/hidden.js +20 -0
- package/dist/slices/template-studio/jobs.js +79 -0
- package/dist/slices/template-studio/loudness.js +111 -0
- package/dist/slices/template-studio/make.js +40 -0
- package/dist/slices/template-studio/model.js +58 -0
- package/dist/slices/template-studio/pack-import.js +253 -0
- package/dist/slices/template-studio/pack-samples.js +60 -0
- package/dist/slices/template-studio/pack.js +207 -0
- package/dist/slices/template-studio/paid-view.js +66 -0
- package/dist/slices/template-studio/paid.js +355 -0
- package/dist/slices/template-studio/quote.js +155 -0
- package/dist/slices/template-studio/ready.js +104 -0
- package/dist/slices/template-studio/repo.js +134 -0
- package/dist/slices/template-studio/reviews-path.js +58 -0
- package/dist/slices/template-studio/runner.js +84 -0
- package/dist/slices/template-studio/save.js +236 -0
- package/dist/slices/template-studio/say-it-as.js +248 -0
- package/dist/slices/template-studio/schedule-gate.js +34 -0
- package/dist/slices/template-studio/schedule-price.js +32 -0
- package/dist/slices/template-studio/schedule-sample.js +91 -0
- package/dist/slices/template-studio/schema.js +243 -0
- package/dist/slices/template-studio/scope.js +124 -0
- package/dist/slices/template-studio/sections.js +176 -0
- package/dist/slices/template-studio/service.js +175 -0
- package/dist/slices/template-studio/status.js +191 -0
- package/dist/slices/template-studio/topic.js +223 -0
- package/dist/slices/thumbnail/by-llm.js +1 -1
- package/dist/slices/trash/designs.js +76 -0
- package/dist/slices/trash/model.js +13 -4
- package/dist/slices/trash/service.js +52 -2
- package/dist/slices/tutorials/library.js +3 -2
- package/dist/slices/uploads/repo.js +37 -1
- package/dist/slices/uploads/rules.js +3 -2
- package/dist/slices/video/ass-text.js +17 -0
- package/dist/slices/video/audio-export.js +2 -64
- package/dist/slices/video/edit-list.js +2 -2
- package/dist/slices/video/edit-settings.js +1 -1
- package/dist/slices/video/encoding.js +169 -0
- package/dist/slices/video/ffmpeg.js +23 -21
- package/dist/slices/video/figure-card.js +1 -15
- package/dist/slices/video/plan.js +2 -1
- package/dist/slices/video/slideshow.js +43 -18
- package/dist/slices/voices/attribution.js +3 -2
- package/dist/slices/voices/model.js +9 -8
- package/dist/slices/voices/palette.js +0 -3
- package/dist/slices/voices/script.js +2 -1
- package/dist/slices/youtube/answer.js +4 -16
- package/dist/slices/youtube/edits-repo.js +3 -12
- package/dist/tutorials/AI-CLIs.md +25 -25
- package/dist/tutorials/Agents-MCP.md +34 -33
- package/dist/tutorials/Assistant.md +42 -0
- package/dist/tutorials/Backups.md +7 -7
- package/dist/tutorials/Calendar.md +17 -25
- package/dist/tutorials/Cast-Library.md +19 -19
- package/dist/tutorials/Channels.md +42 -35
- package/dist/tutorials/Costs-and-Run-Cost.md +38 -40
- package/dist/tutorials/Create-Article.md +114 -0
- package/dist/tutorials/Create-Extras.md +112 -0
- package/dist/tutorials/Create-Images.md +165 -0
- package/dist/tutorials/Create-Narration.md +178 -0
- package/dist/tutorials/Create-Overview.md +244 -0
- package/dist/tutorials/Create-Video-and-Style.md +144 -0
- package/dist/tutorials/Docker.md +3 -3
- package/dist/tutorials/Document-Themes.md +32 -32
- package/dist/tutorials/Editing-a-Project.md +94 -94
- package/dist/tutorials/FAQ.md +18 -18
- package/dist/tutorials/First-Launch-and-Welcome.md +50 -64
- package/dist/tutorials/Home-and-Projects.md +115 -71
- package/dist/tutorials/Home.md +33 -33
- package/dist/tutorials/Install.md +14 -13
- package/dist/tutorials/Intros-and-Outros.md +33 -34
- package/dist/tutorials/Keyboard-Shortcuts-and-Command-Palette.md +62 -58
- package/dist/tutorials/Keywords-Slopify-Fills.md +87 -0
- package/dist/tutorials/Models.md +53 -21
- package/dist/tutorials/Multiple-Voices.md +41 -40
- package/dist/tutorials/Narration-Aliases-and-Glossary.md +14 -14
- package/dist/tutorials/Notifications.md +27 -17
- package/dist/tutorials/Other-Languages.md +15 -15
- package/dist/tutorials/PDF-Documents.md +38 -29
- package/dist/tutorials/Posting-to-Social-Sites.md +121 -0
- package/dist/tutorials/Project-Page.md +118 -120
- package/dist/tutorials/Prompts-and-Templates.md +84 -0
- package/dist/tutorials/Prompts.md +48 -44
- package/dist/tutorials/Providers-and-Keys.md +105 -98
- package/dist/tutorials/Publishing-to-YouTube.md +31 -31
- package/dist/tutorials/Recovery-and-Retries.md +31 -31
- package/dist/tutorials/Remote-Access.md +63 -0
- package/dist/tutorials/Reviews-and-Checkpoints.md +98 -90
- package/dist/tutorials/Schedules.md +46 -27
- package/dist/tutorials/Settings-Reference.md +194 -174
- package/dist/tutorials/Shorts.md +34 -33
- package/dist/tutorials/Start-at-Login.md +3 -3
- package/dist/tutorials/Studio-Extension.md +22 -24
- package/dist/tutorials/Template-Studio.md +128 -0
- package/dist/tutorials/Templates.md +51 -77
- package/dist/tutorials/Trash.md +4 -4
- package/dist/tutorials/Troubleshooting.md +44 -44
- package/dist/tutorials/Uninstalling-and-Moving.md +5 -5
- package/dist/tutorials/Updating-and-Patch-Notes.md +18 -18
- package/dist/tutorials/Video-Editing.md +34 -34
- package/dist/tutorials/Where-Your-Files-Live.md +10 -10
- package/dist/tutorials/YouTube-Description.md +26 -26
- package/dist/tutorials/Your-First-Short.md +35 -35
- package/dist/tutorials/_Sidebar.md +19 -14
- package/dist/updater/work-in-progress.js +42 -12
- package/dist/web/assets/index-BNftKQrA.css +1 -0
- package/dist/web/assets/index-Cpa58woP.js +459 -0
- package/dist/web/assets/pdf-BKh8f7R6.js +56 -0
- package/dist/web/assets/pdf.worker.min-BmVo14Nb.mjs +28 -0
- package/dist/web/assets/pdf.worker.min-D7i8o3wR.js +1 -0
- package/dist/web/index.html +2 -2
- package/package.json +6 -2
- package/dist/slices/article/provided-entries.js +0 -66
- package/dist/slices/article/run.js +0 -145
- package/dist/slices/images/run.js +0 -234
- package/dist/slices/narration/legacy-plan.js +0 -58
- package/dist/slices/narration/run.js +0 -270
- package/dist/slices/rebuild/runtime-actions.js +0 -90
- package/dist/slices/research/run.js +0 -224
- package/dist/slices/subtitles/prepare.js +0 -194
- package/dist/slices/subtitles/transcript.js +0 -34
- package/dist/slices/thumbnail/run.js +0 -219
- package/dist/slices/video/audio-inputs.js +0 -33
- package/dist/slices/video/reuse-audio.js +0 -62
- package/dist/slices/video/run.js +0 -78
- package/dist/slices/video/write-export.js +0 -158
- package/dist/slices/video/write-subtitles.js +0 -59
- package/dist/tutorials/Library-Overview.md +0 -76
- package/dist/tutorials/Play-Images.md +0 -161
- package/dist/tutorials/Play-Narration.md +0 -167
- package/dist/tutorials/Play-Outputs.md +0 -109
- package/dist/tutorials/Play-Overview.md +0 -227
- package/dist/tutorials/Play-Title-and-Article.md +0 -136
- package/dist/tutorials/Play-Video-and-Style.md +0 -143
- package/dist/web/assets/index-BadsoORk.css +0 -1
- package/dist/web/assets/index-D8LqNsCl.js +0 -326
- package/dist/web/assets/pdf-T7MCwjIv.js +0 -54
- package/dist/web/assets/pdf.worker.min-Dswkl-cV.mjs +0 -29
- package/dist/web/assets/pdf.worker.min-zC6nfbxG.js +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var e=`/assets/pdf.worker.min-BmVo14Nb.mjs`;export{e as default};
|
package/dist/web/index.html
CHANGED
|
@@ -6,8 +6,8 @@
|
|
|
6
6
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
7
7
|
<meta name="color-scheme" content="dark light" />
|
|
8
8
|
<title>Slopify</title>
|
|
9
|
-
<script type="module" crossorigin src="/assets/index-
|
|
10
|
-
<link rel="stylesheet" crossorigin href="/assets/index-
|
|
9
|
+
<script type="module" crossorigin src="/assets/index-Cpa58woP.js"></script>
|
|
10
|
+
<link rel="stylesheet" crossorigin href="/assets/index-BNftKQrA.css">
|
|
11
11
|
</head>
|
|
12
12
|
<body>
|
|
13
13
|
<div id="root"></div>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gentbajko/slopify",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "4.1.0",
|
|
4
4
|
"description": "Turn a prompt into a finished video, locally, with your own provider keys",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"author": "Gent Bajko",
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
"@modelcontextprotocol/sdk": "^1.32.1",
|
|
36
36
|
"fflate": "^0.8.3",
|
|
37
37
|
"ffmpeg-static": "^5.3.0",
|
|
38
|
-
"hono": "^4.13.
|
|
38
|
+
"hono": "^4.13.17",
|
|
39
39
|
"jspdf": "4.2.1",
|
|
40
40
|
"onnxruntime-node": "1.30.0",
|
|
41
41
|
"onnxruntime-web": "1.30.0",
|
|
@@ -45,5 +45,9 @@
|
|
|
45
45
|
"ulid": "^3.0.2",
|
|
46
46
|
"yaml": "^2.9.1",
|
|
47
47
|
"zod": "^4.5.4"
|
|
48
|
+
},
|
|
49
|
+
"devDependencies": {
|
|
50
|
+
"@types/mdast": "^4.0.4",
|
|
51
|
+
"esbuild": "^0.28.1"
|
|
48
52
|
}
|
|
49
53
|
}
|
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
import { readFileSync } from "node:fs";
|
|
2
|
-
import { piecesOf } from "../../kernel/runner/piece-repo.js";
|
|
3
|
-
import { projectById, stagesOf } from "../admission/repo.js";
|
|
4
|
-
import { outputPath } from "../storage/layout.js";
|
|
5
|
-
import { outputsOf } from "../storage/repo.js";
|
|
6
|
-
import { storeText } from "../storage/staging.js";
|
|
7
|
-
import { categories, instructionsText, keepSegment, writeSegment } from "./segments.js";
|
|
8
|
-
// A provided Article never runs its writer. Prepare its selected entries as part
|
|
9
|
-
// of Audio's cancellable work, retaining Article ownership of the resulting text.
|
|
10
|
-
export async function prepareProvidedArticleSegments(deps, audioContext, providers) {
|
|
11
|
-
const { projectId } = audioContext.stage;
|
|
12
|
-
const project = projectById(deps.db, projectId);
|
|
13
|
-
if (!project)
|
|
14
|
-
throw new Error("This project no longer exists; it may have been deleted while it was running.");
|
|
15
|
-
const { config } = project;
|
|
16
|
-
if (config.sources.article !== "provide" || config.sources.audio !== "generate")
|
|
17
|
-
return "done";
|
|
18
|
-
if (!config.intro && !config.outro)
|
|
19
|
-
return "done";
|
|
20
|
-
audioContext.signal.throwIfAborted();
|
|
21
|
-
const article = stagesOf(deps.db, projectId).find((stage) => stage.kind === "article");
|
|
22
|
-
if (!article)
|
|
23
|
-
throw new Error("Slopify hit an internal error (the project has no article stage). Try again; if it happens again, use Download diagnostics in Settings and report it.");
|
|
24
|
-
const outputs = outputsOf(deps.db, projectId);
|
|
25
|
-
const plain = outputs.find((output) => output.role === "article_txt");
|
|
26
|
-
if (!plain)
|
|
27
|
-
throw new Error("The article text you provided is missing, so the intro and outro can't be written from it. Paste the article again in Edit project → Article, then Try again.");
|
|
28
|
-
const narration = readFileSync(outputPath(deps.paths, projectId, plain.path), "utf8");
|
|
29
|
-
const saved = outputs.find((output) => output.stageKind === "article" && output.role === "instructions");
|
|
30
|
-
let instructions = saved
|
|
31
|
-
? readFileSync(outputPath(deps.paths, projectId, saved.path), "utf8")
|
|
32
|
-
: "";
|
|
33
|
-
const completed = piecesOf(deps.db, article.id, "segment");
|
|
34
|
-
for (const [index, category] of categories.entries()) {
|
|
35
|
-
audioContext.signal.throwIfAborted();
|
|
36
|
-
if (completed.some((piece) => piece.idx === index + 1 && piece.state === "done"))
|
|
37
|
-
continue;
|
|
38
|
-
const sent = [];
|
|
39
|
-
const result = await writeSegment(providers, config.llm, config, category, narration, sent);
|
|
40
|
-
audioContext.signal.throwIfAborted();
|
|
41
|
-
if (!result.ok)
|
|
42
|
-
return "held";
|
|
43
|
-
const segment = result.value;
|
|
44
|
-
if (!segment)
|
|
45
|
-
continue;
|
|
46
|
-
if (sent.length > 0) {
|
|
47
|
-
instructions += `${instructions === "" ? "" : "\n"}${instructionsText(sent)}`;
|
|
48
|
-
storeText(deps, {
|
|
49
|
-
projectId,
|
|
50
|
-
stageKind: "article",
|
|
51
|
-
role: "instructions",
|
|
52
|
-
text: instructions,
|
|
53
|
-
});
|
|
54
|
-
}
|
|
55
|
-
keepSegment(deps, { stage: article }, segment, index + 1);
|
|
56
|
-
deps.count("stage.completed", {
|
|
57
|
-
stage: "article",
|
|
58
|
-
segment: category,
|
|
59
|
-
...(segment.mode === "llm" && config.llm
|
|
60
|
-
? { provider: config.llm.provider, model: config.llm.model }
|
|
61
|
-
: {}),
|
|
62
|
-
...segment.tokens,
|
|
63
|
-
});
|
|
64
|
-
}
|
|
65
|
-
return "done";
|
|
66
|
-
}
|
|
@@ -1,145 +0,0 @@
|
|
|
1
|
-
import { existsSync, readFileSync } from "node:fs";
|
|
2
|
-
import { z } from "zod";
|
|
3
|
-
import { messageRoles } from "../../kernel/ports/llm.js";
|
|
4
|
-
import { insertPiece, piecesOf, setPiece } from "../../kernel/runner/piece-repo.js";
|
|
5
|
-
import { projectById } from "../admission/repo.js";
|
|
6
|
-
import { withEarlierEpisodes } from "../episodes/related.js";
|
|
7
|
-
import { outputPath } from "../storage/layout.js";
|
|
8
|
-
import { outputsOf } from "../storage/repo.js";
|
|
9
|
-
import { storeText } from "../storage/staging.js";
|
|
10
|
-
import { writeArticle } from "./continuation.js";
|
|
11
|
-
import { categories, instructionsText, keepSegment, writeSegment } from "./segments.js";
|
|
12
|
-
import { storeArticleText } from "./store.js";
|
|
13
|
-
export async function runArticle(deps, context, providers) {
|
|
14
|
-
const { projectId } = context.stage;
|
|
15
|
-
const project = projectById(deps.db, projectId);
|
|
16
|
-
if (project === undefined) {
|
|
17
|
-
throw new Error("This project no longer exists; it may have been deleted while it was running.");
|
|
18
|
-
}
|
|
19
|
-
const choice = project.config.llm;
|
|
20
|
-
const articlePrompt = project.config.rendered.article;
|
|
21
|
-
if (choice === undefined || articlePrompt === undefined) {
|
|
22
|
-
// Admission refuses a run whose article is Generate without both, so
|
|
23
|
-
// reaching here is a bug in admission rather than something the user did.
|
|
24
|
-
throw new Error("No AI model or article prompt is set for writing the article. Choose a model in Edit project → Providers and check Edit project → Prompts, then Try again.");
|
|
25
|
-
}
|
|
26
|
-
const notes = researchNotes(deps, projectId);
|
|
27
|
-
const brief = {
|
|
28
|
-
articlePrompt: withEarlierEpisodes(articlePrompt, project.config.earlierEpisodes),
|
|
29
|
-
...(notes === undefined ? {} : { notes }),
|
|
30
|
-
};
|
|
31
|
-
const result = await articleBody(deps, context, providers, choice, brief);
|
|
32
|
-
if (!result.ok)
|
|
33
|
-
return "held";
|
|
34
|
-
const completed = result.value;
|
|
35
|
-
const { narration } = completed;
|
|
36
|
-
const sent = [...completed.sent];
|
|
37
|
-
for (const [index, category] of categories.entries()) {
|
|
38
|
-
if (project.config.sources.audio !== "generate")
|
|
39
|
-
break;
|
|
40
|
-
if (completed.resumed &&
|
|
41
|
-
piecesOf(deps.db, context.stage.id, "segment").some((piece) => piece.idx === index + 1 && piece.state === "done"))
|
|
42
|
-
continue;
|
|
43
|
-
const result = await writeSegment(providers, choice, project.config, category, narration, sent);
|
|
44
|
-
if (!result.ok)
|
|
45
|
-
return "held";
|
|
46
|
-
const segment = result.value;
|
|
47
|
-
if (segment !== undefined) {
|
|
48
|
-
keepSegment(deps, context, segment, index + 1);
|
|
49
|
-
checkpointArticle(deps, context, sent);
|
|
50
|
-
// One event per intro/outro text, named by its segment. A text-mode entry is
|
|
51
|
-
// rendered rather than written, so it made no call, names no provider and reports
|
|
52
|
-
// zero tokens rather than an estimate.
|
|
53
|
-
deps.count("stage.completed", {
|
|
54
|
-
stage: "article",
|
|
55
|
-
segment: category,
|
|
56
|
-
...(segment.mode === "llm" ? { provider: choice.provider, model: choice.model } : {}),
|
|
57
|
-
...segment.tokens,
|
|
58
|
-
});
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
// The exact messages sent, the continuations and the entry calls among them.
|
|
62
|
-
storeText(deps, {
|
|
63
|
-
projectId,
|
|
64
|
-
stageKind: "article",
|
|
65
|
-
role: "instructions",
|
|
66
|
-
text: instructionsText(sent),
|
|
67
|
-
});
|
|
68
|
-
deps.log.write("info", "article.done", {
|
|
69
|
-
projectId,
|
|
70
|
-
stage: "article",
|
|
71
|
-
detail: `${String(narration.length)} characters to narrate`,
|
|
72
|
-
});
|
|
73
|
-
return "done";
|
|
74
|
-
}
|
|
75
|
-
// Once the article is stored, a pause during end matter resumes that end matter
|
|
76
|
-
// instead of buying and replacing the article again. Re-run clears this checkpoint.
|
|
77
|
-
const articleCheckpoint = z.object({
|
|
78
|
-
sent: z.array(z.object({
|
|
79
|
-
label: z.string(),
|
|
80
|
-
messages: z.array(z.object({ role: z.enum(messageRoles), content: z.string() })),
|
|
81
|
-
})),
|
|
82
|
-
});
|
|
83
|
-
async function articleBody(deps, context, providers, choice, brief) {
|
|
84
|
-
const { projectId } = context.stage;
|
|
85
|
-
const saved = piecesOf(deps.db, context.stage.id, "article_written")[0];
|
|
86
|
-
const outputs = outputsOf(deps.db, projectId);
|
|
87
|
-
const plain = outputs.find((output) => output.role === "article_txt");
|
|
88
|
-
const markdown = outputs.find((output) => output.role === "article_md");
|
|
89
|
-
if (saved?.payload !== null &&
|
|
90
|
-
saved?.payload !== undefined &&
|
|
91
|
-
plain &&
|
|
92
|
-
markdown &&
|
|
93
|
-
existsSync(outputPath(deps.paths, projectId, plain.path)) &&
|
|
94
|
-
existsSync(outputPath(deps.paths, projectId, markdown.path))) {
|
|
95
|
-
return {
|
|
96
|
-
ok: true,
|
|
97
|
-
value: {
|
|
98
|
-
narration: readFileSync(outputPath(deps.paths, projectId, plain.path), "utf8"),
|
|
99
|
-
sent: articleCheckpoint.parse(JSON.parse(saved.payload)).sent,
|
|
100
|
-
resumed: true,
|
|
101
|
-
},
|
|
102
|
-
};
|
|
103
|
-
}
|
|
104
|
-
const result = await writeArticle(providers, choice, brief, (text) => {
|
|
105
|
-
context.emit({ type: "article.delta", projectId, text });
|
|
106
|
-
});
|
|
107
|
-
if (!result.ok)
|
|
108
|
-
return result;
|
|
109
|
-
const written = result.value;
|
|
110
|
-
storeText(deps, { projectId, stageKind: "article", role: "article_md", text: written.markdown });
|
|
111
|
-
const narration = storeArticleText(deps, { projectId, markdown: written.markdown });
|
|
112
|
-
checkpointArticle(deps, context, written.sent);
|
|
113
|
-
deps.count("stage.completed", {
|
|
114
|
-
stage: "article",
|
|
115
|
-
provider: choice.provider,
|
|
116
|
-
model: choice.model,
|
|
117
|
-
...written.tokens,
|
|
118
|
-
});
|
|
119
|
-
return { ok: true, value: { narration, sent: written.sent, resumed: false } };
|
|
120
|
-
}
|
|
121
|
-
function checkpointArticle(deps, context, sent) {
|
|
122
|
-
const existing = piecesOf(deps.db, context.stage.id, "article_written")[0];
|
|
123
|
-
const payload = JSON.stringify({ sent });
|
|
124
|
-
if (existing)
|
|
125
|
-
setPiece(deps.db, existing.id, "done", payload);
|
|
126
|
-
else
|
|
127
|
-
insertPiece(deps.db, {
|
|
128
|
-
id: deps.ids.next(),
|
|
129
|
-
stageId: context.stage.id,
|
|
130
|
-
kind: "article_written",
|
|
131
|
-
idx: 1,
|
|
132
|
-
state: "done",
|
|
133
|
-
payload,
|
|
134
|
-
});
|
|
135
|
-
}
|
|
136
|
-
// Research writes its notes as an output of its own, and a provided research stage stores the
|
|
137
|
-
// pasted text the same way, so one lookup covers both. No row means research was Off or
|
|
138
|
-
// skipped, and the article is written from the prompt alone.
|
|
139
|
-
function researchNotes(deps, projectId) {
|
|
140
|
-
const notes = outputsOf(deps.db, projectId).find((output) => output.role === "notes");
|
|
141
|
-
if (notes === undefined) {
|
|
142
|
-
return undefined;
|
|
143
|
-
}
|
|
144
|
-
return readFileSync(outputPath(deps.paths, projectId, notes.path), "utf8");
|
|
145
|
-
}
|
|
@@ -1,234 +0,0 @@
|
|
|
1
|
-
import { existsSync, mkdirSync, writeFileSync } from "node:fs";
|
|
2
|
-
import { dirname } from "node:path";
|
|
3
|
-
import { z } from "zod";
|
|
4
|
-
import { transact } from "../../kernel/db/tx.js";
|
|
5
|
-
import { insertPiece, piecesOf, setPiece } from "../../kernel/runner/piece-repo.js";
|
|
6
|
-
import { projectById } from "../admission/repo.js";
|
|
7
|
-
import { setStageProgress } from "../admission/stage-writes.js";
|
|
8
|
-
import { outputFileName, outputPath } from "../storage/layout.js";
|
|
9
|
-
import { insertOutput, outputsOf } from "../storage/repo.js";
|
|
10
|
-
import { imageCountsOf } from "./scale.js";
|
|
11
|
-
// What an image piece carries between runs: what was asked for, and the file it came back
|
|
12
|
-
// as once the provider answered. That is the whole of the resume.
|
|
13
|
-
const imagePayload = z.object({
|
|
14
|
-
promptName: z.string(),
|
|
15
|
-
prompt: z.string(),
|
|
16
|
-
// Which ticked prompt this send belongs to, and which send of that prompt it is. Both
|
|
17
|
-
// are stored rather than derived, because the user can delete an image and the pieces
|
|
18
|
-
// that are left must still say where each one came from.
|
|
19
|
-
promptIndex: z.number(),
|
|
20
|
-
indexInPrompt: z.number(),
|
|
21
|
-
file: z.string().optional(),
|
|
22
|
-
});
|
|
23
|
-
export async function runImages(deps, context, providers) {
|
|
24
|
-
const { projectId } = context.stage;
|
|
25
|
-
const project = projectById(deps.db, projectId);
|
|
26
|
-
if (project === undefined) {
|
|
27
|
-
throw new Error("This project no longer exists; it may have been deleted while it was running.");
|
|
28
|
-
}
|
|
29
|
-
const choice = project.config.images;
|
|
30
|
-
if (choice === undefined) {
|
|
31
|
-
// Admission refuses a run whose images are Generate without a provider and a model, so
|
|
32
|
-
// reaching here is a bug in admission rather than the user's.
|
|
33
|
-
throw new Error("No image model is set for this project. Choose one in Edit project → Providers, then Try again.");
|
|
34
|
-
}
|
|
35
|
-
const pieces = plan(deps, context, project.config);
|
|
36
|
-
if (pieces.length === 0) {
|
|
37
|
-
// Admission makes an image source mandatory and puts the Number at one or more, so an
|
|
38
|
-
// empty plan is a bug upstream rather than a run with no pictures.
|
|
39
|
-
throw new Error("Slopify hit an internal error (no image prompt was selected). Try again; if it happens again, use Download diagnostics in Settings and report it.");
|
|
40
|
-
}
|
|
41
|
-
// The run's own frame. The adapter turns it into whatever its provider spells the
|
|
42
|
-
// closest supported size, and the render crops whatever is left over.
|
|
43
|
-
const result = await sendAll(deps, context, providers, choice, pieces, project.format);
|
|
44
|
-
if (!result.ok)
|
|
45
|
-
return "held";
|
|
46
|
-
const made = result.value;
|
|
47
|
-
// Images made means images stored, and only the ones this run stored: a resume does not
|
|
48
|
-
// count an image the previous run made, and a regenerated image counts again.
|
|
49
|
-
//
|
|
50
|
-
// ceiling: a run that fails partway records nothing, so the images it did store are
|
|
51
|
-
// counted by no event and the resume counts only its own. One event is written when the
|
|
52
|
-
// stage completes; the upgrade, if the drift ever matters, is an event per image.
|
|
53
|
-
deps.count("stage.completed", {
|
|
54
|
-
stage: "images",
|
|
55
|
-
provider: choice.provider,
|
|
56
|
-
model: choice.model,
|
|
57
|
-
images: made,
|
|
58
|
-
});
|
|
59
|
-
deps.log.write("info", "images.done", {
|
|
60
|
-
projectId,
|
|
61
|
-
stage: "images",
|
|
62
|
-
detail: `${String(pieces.length)} images from ${String(project.config.imagePrompts.length)} prompts`,
|
|
63
|
-
});
|
|
64
|
-
return "done";
|
|
65
|
-
}
|
|
66
|
-
// For each ticked image prompt, its rendered text is sent Number times as independent
|
|
67
|
-
// parallel calls. The plan is made once and kept, so a retry finds the rows the first run
|
|
68
|
-
// wrote and sends only what did not land.
|
|
69
|
-
//
|
|
70
|
-
// `idx` is the slideshow order - prompts in selection order, then the index within each
|
|
71
|
-
// prompt - so the order is fixed here and never depends on which image arrives first.
|
|
72
|
-
function plan(deps, context, config) {
|
|
73
|
-
const existing = piecesOf(deps.db, context.stage.id, "image");
|
|
74
|
-
if (existing.length > 0) {
|
|
75
|
-
return existing;
|
|
76
|
-
}
|
|
77
|
-
const planned = [];
|
|
78
|
-
// Each prompt's Number, or more when the run scales its images (`scale.ts`).
|
|
79
|
-
const counts = imageCountsOf(config);
|
|
80
|
-
for (const [at, picked] of config.imagePrompts.entries()) {
|
|
81
|
-
// `slices/library/slots.ts` names the rendered body after the draft field that picked
|
|
82
|
-
// it, so the run carries the substituted text under this key.
|
|
83
|
-
const prompt = config.rendered[`imagePrompts.${String(at)}`];
|
|
84
|
-
if (prompt === undefined) {
|
|
85
|
-
throw new Error(`Slopify hit an internal error (the image prompt ${picked.name} was never filled in). Try again; if it happens again, use Download diagnostics in Settings and report it.`);
|
|
86
|
-
}
|
|
87
|
-
for (let send = 1; send <= (counts[at] ?? picked.number); send += 1) {
|
|
88
|
-
planned.push({
|
|
89
|
-
id: deps.ids.next(),
|
|
90
|
-
stageId: context.stage.id,
|
|
91
|
-
kind: "image",
|
|
92
|
-
idx: planned.length + 1,
|
|
93
|
-
state: "pending",
|
|
94
|
-
payload: JSON.stringify({
|
|
95
|
-
promptName: picked.name,
|
|
96
|
-
prompt,
|
|
97
|
-
promptIndex: at + 1,
|
|
98
|
-
indexInPrompt: send,
|
|
99
|
-
}),
|
|
100
|
-
});
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
transact(deps.db, () => {
|
|
104
|
-
for (const piece of planned) {
|
|
105
|
-
insertPiece(deps.db, piece);
|
|
106
|
-
}
|
|
107
|
-
});
|
|
108
|
-
return planned;
|
|
109
|
-
}
|
|
110
|
-
// An image a previous run stored is not made again, and one that fails takes down the
|
|
111
|
-
// whole stage while its siblings finish and keep their images for the next resume. A
|
|
112
|
-
// refusal is the wrapper's to make terminal; nothing here counts attempts.
|
|
113
|
-
async function sendAll(deps, context, providers, choice, pieces, format) {
|
|
114
|
-
const { projectId } = context.stage;
|
|
115
|
-
// Read once, before anything is written: a piece counts as landed only when its row and
|
|
116
|
-
// its file both survived, and the parallel sends below each add one of each.
|
|
117
|
-
const stored = outputsOf(deps.db, projectId);
|
|
118
|
-
const total = pieces.length;
|
|
119
|
-
let done = pieces.filter((piece) => landed(deps, projectId, piece, stored)).length;
|
|
120
|
-
report(deps, context, done, total);
|
|
121
|
-
const outcomes = await Promise.all(pieces.map(async (piece) => {
|
|
122
|
-
const asked = payloadOf(piece);
|
|
123
|
-
if (landed(deps, projectId, piece, stored)) {
|
|
124
|
-
return { ok: true, made: false };
|
|
125
|
-
}
|
|
126
|
-
setPiece(deps.db, piece.id, "running", piece.payload);
|
|
127
|
-
try {
|
|
128
|
-
const result = await providers.forPiece(piece.id).image({
|
|
129
|
-
provider: choice.provider,
|
|
130
|
-
model: choice.model,
|
|
131
|
-
prompt: asked.prompt,
|
|
132
|
-
aspect: format,
|
|
133
|
-
});
|
|
134
|
-
if (!result.ok) {
|
|
135
|
-
setPiece(deps.db, piece.id, "pending", piece.payload);
|
|
136
|
-
return result;
|
|
137
|
-
}
|
|
138
|
-
const made = result.value;
|
|
139
|
-
const file = keep(deps, projectId, piece.idx, made);
|
|
140
|
-
// The prompt text, the prompt name, the index within the prompt, the
|
|
141
|
-
// provider and the model travel with the image.
|
|
142
|
-
const output = record(deps, projectId, piece, asked, file, made, choice);
|
|
143
|
-
// The row and the file are both there before the piece says so: a crash between
|
|
144
|
-
// them leaves a piece that is not `done`, which the next run simply sends again.
|
|
145
|
-
setPiece(deps.db, piece.id, "done", JSON.stringify({ ...asked, file }));
|
|
146
|
-
done += 1;
|
|
147
|
-
// The project page fills in as each one arrives.
|
|
148
|
-
context.emit({ type: "image.landed", projectId, outputId: output.id, index: piece.idx });
|
|
149
|
-
report(deps, context, done, total);
|
|
150
|
-
return { ok: true, made: true };
|
|
151
|
-
}
|
|
152
|
-
catch (error) {
|
|
153
|
-
// A cancel is not this image failing: an aborted call counts as nothing, and the
|
|
154
|
-
// resume runs a `pending` image exactly as a failed one.
|
|
155
|
-
setPiece(deps.db, piece.id, context.signal.aborted ? "pending" : "failed", piece.payload);
|
|
156
|
-
return { ok: false, error };
|
|
157
|
-
}
|
|
158
|
-
}));
|
|
159
|
-
let made = 0;
|
|
160
|
-
for (const outcome of outcomes) {
|
|
161
|
-
if (!outcome.ok) {
|
|
162
|
-
if ("reason" in outcome)
|
|
163
|
-
return outcome;
|
|
164
|
-
throw outcome.error;
|
|
165
|
-
}
|
|
166
|
-
made += outcome.made ? 1 : 0;
|
|
167
|
-
}
|
|
168
|
-
return { ok: true, value: made };
|
|
169
|
-
}
|
|
170
|
-
// An image counts as landed only when its row and its file are both still there: they are
|
|
171
|
-
// written one after the other, the boot reconcile can remove a file whose row survived,
|
|
172
|
-
// and the user can delete one on purpose. Answering "done" for a missing file would hand
|
|
173
|
-
// the render a path to nothing.
|
|
174
|
-
function landed(deps, projectId, piece, stored) {
|
|
175
|
-
const file = payloadOf(piece).file;
|
|
176
|
-
if (file === undefined) {
|
|
177
|
-
return false;
|
|
178
|
-
}
|
|
179
|
-
if (!stored.some((output) => output.role === "image" && output.path === file)) {
|
|
180
|
-
return false;
|
|
181
|
-
}
|
|
182
|
-
return existsSync(outputPath(deps.paths, projectId, file));
|
|
183
|
-
}
|
|
184
|
-
function keep(deps, projectId, idx, made) {
|
|
185
|
-
// Stored as received, png or jpg. The adapter read the mime off the bytes,
|
|
186
|
-
// so the extension is what the file actually is rather than what a header claimed.
|
|
187
|
-
const name = outputFileName("image", idx, made.mime === "image/png" ? ".png" : ".jpg", "images");
|
|
188
|
-
const target = outputPath(deps.paths, projectId, name);
|
|
189
|
-
mkdirSync(dirname(target), { recursive: true, mode: 0o700 });
|
|
190
|
-
writeFileSync(target, made.bytes, { mode: 0o600 });
|
|
191
|
-
return name;
|
|
192
|
-
}
|
|
193
|
-
function record(deps, projectId, piece, asked, file, made, choice) {
|
|
194
|
-
const output = {
|
|
195
|
-
id: deps.ids.next(),
|
|
196
|
-
projectId,
|
|
197
|
-
stageKind: "images",
|
|
198
|
-
role: "image",
|
|
199
|
-
path: file,
|
|
200
|
-
originalFilename: null,
|
|
201
|
-
bytes: made.bytes.byteLength,
|
|
202
|
-
durationMs: null,
|
|
203
|
-
// `index` is the slideshow place the render sorts on, and it is the piece's own `idx`
|
|
204
|
-
// rather than the order the images came back in.
|
|
205
|
-
meta: {
|
|
206
|
-
index: piece.idx,
|
|
207
|
-
promptName: asked.promptName,
|
|
208
|
-
prompt: asked.prompt,
|
|
209
|
-
provider: choice.provider,
|
|
210
|
-
model: choice.model,
|
|
211
|
-
},
|
|
212
|
-
createdAt: deps.clock.now().toISOString(),
|
|
213
|
-
};
|
|
214
|
-
insertOutput(deps.db, output);
|
|
215
|
-
return output;
|
|
216
|
-
}
|
|
217
|
-
// K of N images made. Written as well as emitted, so a page opened mid-stage reads the count
|
|
218
|
-
// off the row rather than waiting for the next image.
|
|
219
|
-
function report(deps, context, done, total) {
|
|
220
|
-
setStageProgress(deps.db, context.stage.id, done, total);
|
|
221
|
-
context.emit({
|
|
222
|
-
type: "stage.progress",
|
|
223
|
-
projectId: context.stage.projectId,
|
|
224
|
-
stage: "images",
|
|
225
|
-
current: done,
|
|
226
|
-
total,
|
|
227
|
-
});
|
|
228
|
-
}
|
|
229
|
-
function payloadOf(piece) {
|
|
230
|
-
if (piece.payload === null) {
|
|
231
|
-
throw new Error("Slopify hit an internal error (a saved image step is empty). Try again; if it happens again, use Download diagnostics in Settings and report it.");
|
|
232
|
-
}
|
|
233
|
-
return imagePayload.parse(JSON.parse(piece.payload));
|
|
234
|
-
}
|
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
import { z } from "zod";
|
|
2
|
-
import { transact } from "../../kernel/db/tx.js";
|
|
3
|
-
import { splitText } from "../../kernel/ports/text.js";
|
|
4
|
-
import { insertPiece, piecesOf } from "../../kernel/runner/piece-repo.js";
|
|
5
|
-
const payload = z.object({ text: z.string(), file: z.string().optional() });
|
|
6
|
-
// Old whole-text plans can exceed a newly known account limit. Preserve finished
|
|
7
|
-
// pieces and their paths, and split only unfinished work before any request starts.
|
|
8
|
-
export function planLegacyNarration(deps, stageId, texts, maxCharacters, finished) {
|
|
9
|
-
const old = piecesOf(deps.db, stageId, "chunk");
|
|
10
|
-
const source = old.length
|
|
11
|
-
? old
|
|
12
|
-
: texts.map((text, idx) => ({
|
|
13
|
-
id: deps.ids.next(),
|
|
14
|
-
stageId,
|
|
15
|
-
kind: "chunk",
|
|
16
|
-
idx: idx + 1,
|
|
17
|
-
state: "pending",
|
|
18
|
-
payload: JSON.stringify({ text }),
|
|
19
|
-
}));
|
|
20
|
-
const planned = [];
|
|
21
|
-
for (const piece of source) {
|
|
22
|
-
const data = payload.parse(JSON.parse(piece.payload ?? "null"));
|
|
23
|
-
if (finished(piece)) {
|
|
24
|
-
planned.push({ ...piece, idx: planned.length + 1 });
|
|
25
|
-
continue;
|
|
26
|
-
}
|
|
27
|
-
for (const [part, text] of splitText(data.text, maxCharacters).entries())
|
|
28
|
-
planned.push({
|
|
29
|
-
...piece,
|
|
30
|
-
id: part === 0 ? piece.id : deps.ids.next(),
|
|
31
|
-
idx: planned.length + 1,
|
|
32
|
-
state: "pending",
|
|
33
|
-
payload: JSON.stringify({ text }),
|
|
34
|
-
});
|
|
35
|
-
}
|
|
36
|
-
if (old.length &&
|
|
37
|
-
planned.length === old.length &&
|
|
38
|
-
planned.every((p, i) => p.id === old[i]?.id &&
|
|
39
|
-
payload.parse(JSON.parse(p.payload ?? "null")).text ===
|
|
40
|
-
payload.parse(JSON.parse(old[i]?.payload ?? "null")).text))
|
|
41
|
-
return old;
|
|
42
|
-
transact(deps.db, () => {
|
|
43
|
-
// Negative temporary indices avoid colliding with a retained completed piece.
|
|
44
|
-
deps.db
|
|
45
|
-
.prepare("UPDATE stage_pieces SET idx=-idx WHERE stage_id=? AND kind='chunk'")
|
|
46
|
-
.run(stageId);
|
|
47
|
-
const known = new Set(old.map((p) => p.id));
|
|
48
|
-
for (const piece of planned) {
|
|
49
|
-
if (known.has(piece.id))
|
|
50
|
-
deps.db
|
|
51
|
-
.prepare("UPDATE stage_pieces SET idx=?,state=?,payload=? WHERE id=?")
|
|
52
|
-
.run(piece.idx, piece.state, piece.payload, piece.id);
|
|
53
|
-
else
|
|
54
|
-
insertPiece(deps.db, piece);
|
|
55
|
-
}
|
|
56
|
-
});
|
|
57
|
-
return planned;
|
|
58
|
-
}
|