@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,203 @@
|
|
|
1
|
+
import { tailscaleCommands } from "./cli.js";
|
|
2
|
+
import { freePort, isProblem, machineOf, parseServeStatus, portTakenProblem, portUse, problemOf, sameTarget, serveRefusedProblem, } from "./rules.js";
|
|
3
|
+
import { remoteAccessStore } from "./store.js";
|
|
4
|
+
import { remoteAccessViews } from "./views.js";
|
|
5
|
+
// ceiling: a view is a few CLI calls; an open Settings tab and agents reading it together
|
|
6
|
+
// share one answer for this long.
|
|
7
|
+
const cacheMs = 5_000;
|
|
8
|
+
export function createRemoteAccessService(deps) {
|
|
9
|
+
const store = remoteAccessStore(deps.db);
|
|
10
|
+
const { saved, record } = store;
|
|
11
|
+
const { loopbackTarget, base, fromProblem, dockerView, offView, funnelProblem, onView } = remoteAccessViews(deps, saved);
|
|
12
|
+
const diagnose = async () => {
|
|
13
|
+
const status = await deps.run(tailscaleCommands.status());
|
|
14
|
+
// `status --json` exits 1 while signed out but still prints the state.
|
|
15
|
+
const machine = status.stdout.trim().startsWith("{") && !status.missing
|
|
16
|
+
? machineOf(status.stdout)
|
|
17
|
+
: problemOf(status, deps.platform);
|
|
18
|
+
if (isProblem(machine))
|
|
19
|
+
return machine;
|
|
20
|
+
const serveStatus = await deps.run(tailscaleCommands.serveStatus());
|
|
21
|
+
if (serveStatus.code !== 0)
|
|
22
|
+
return problemOf(serveStatus, deps.platform);
|
|
23
|
+
const serve = parseServeStatus(serveStatus.stdout);
|
|
24
|
+
if (serve === undefined)
|
|
25
|
+
return {
|
|
26
|
+
state: "failed",
|
|
27
|
+
summary: "Slopify couldn't read tailscale serve status --json.",
|
|
28
|
+
fix: "Update Tailscale to a current version (tailscale.com/download), then press Check again.",
|
|
29
|
+
link: "https://tailscale.com/download",
|
|
30
|
+
};
|
|
31
|
+
return { machine, serve };
|
|
32
|
+
};
|
|
33
|
+
const ready = (value) => !("state" in value);
|
|
34
|
+
const ownerOf = (machine) => machine.owner === undefined ? {} : { owner: machine.owner };
|
|
35
|
+
// Removes the handler Slopify added, only while it is still exactly that.
|
|
36
|
+
const removeOurs = async (now) => {
|
|
37
|
+
const ours = store.applied();
|
|
38
|
+
if (ours === undefined)
|
|
39
|
+
return undefined;
|
|
40
|
+
if (ours.dnsName === now.machine.dnsName) {
|
|
41
|
+
const use = portUse(now.serve, ours.dnsName, ours.httpsPort);
|
|
42
|
+
if (use.kind === "proxy" && sameTarget(use.target, ours.target)) {
|
|
43
|
+
const off = await deps.run(tailscaleCommands.serveOff(ours.httpsPort));
|
|
44
|
+
if (off.code !== 0)
|
|
45
|
+
return problemOf(off, deps.platform);
|
|
46
|
+
}
|
|
47
|
+
else if (use.kind !== "free")
|
|
48
|
+
deps.log.write("info", "remote-access.left", {
|
|
49
|
+
detail: `port ${ours.httpsPort} was changed outside Slopify, so it is left as it is`,
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
record(undefined);
|
|
53
|
+
return undefined;
|
|
54
|
+
};
|
|
55
|
+
const apply = async () => {
|
|
56
|
+
const want = saved();
|
|
57
|
+
const target = loopbackTarget();
|
|
58
|
+
let now = await diagnose();
|
|
59
|
+
if (!ready(now))
|
|
60
|
+
return fromProblem(now);
|
|
61
|
+
const ours = store.applied();
|
|
62
|
+
if (ours !== undefined &&
|
|
63
|
+
(ours.httpsPort !== want.httpsPort ||
|
|
64
|
+
!sameTarget(ours.target, target) ||
|
|
65
|
+
ours.dnsName !== now.machine.dnsName)) {
|
|
66
|
+
const removed = await removeOurs(now);
|
|
67
|
+
if (removed !== undefined)
|
|
68
|
+
return fromProblem(removed);
|
|
69
|
+
now = await diagnose();
|
|
70
|
+
if (!ready(now))
|
|
71
|
+
return fromProblem(now);
|
|
72
|
+
}
|
|
73
|
+
const { dnsName } = now.machine;
|
|
74
|
+
const use = portUse(now.serve, dnsName, want.httpsPort);
|
|
75
|
+
const before = store.applied();
|
|
76
|
+
const mine = before !== undefined && use.kind === "proxy" && sameTarget(use.target, before.target);
|
|
77
|
+
if (!mine && use.kind !== "free")
|
|
78
|
+
return fromProblem(portTakenProblem(want.httpsPort, use, target, freePort(now.serve, dnsName, want.httpsPort)), { suggestedPort: freePort(now.serve, dnsName, want.httpsPort) });
|
|
79
|
+
if (!mine) {
|
|
80
|
+
const on = await deps.run(tailscaleCommands.serveOn(want.httpsPort, target));
|
|
81
|
+
if (on.code !== 0)
|
|
82
|
+
return fromProblem(serveRefusedProblem(on, deps.platform));
|
|
83
|
+
record({ dnsName, httpsPort: want.httpsPort, target, ...ownerOf(now.machine) });
|
|
84
|
+
}
|
|
85
|
+
else if (before !== undefined &&
|
|
86
|
+
before.owner === undefined &&
|
|
87
|
+
now.machine.owner !== undefined)
|
|
88
|
+
record({ ...before, owner: now.machine.owner });
|
|
89
|
+
const after = await diagnose();
|
|
90
|
+
if (!ready(after))
|
|
91
|
+
return fromProblem(after);
|
|
92
|
+
const check = portUse(after.serve, dnsName, want.httpsPort);
|
|
93
|
+
if (check.kind !== "proxy" || !sameTarget(check.target, target))
|
|
94
|
+
return base("not-applied", "Tailscale accepted the command, but Slopify's address isn't in its serve settings.", {
|
|
95
|
+
fix: "Run tailscale serve status in a terminal to see what Tailscale has, then press Check again.",
|
|
96
|
+
});
|
|
97
|
+
if (check.funnel) {
|
|
98
|
+
await removeOurs(after);
|
|
99
|
+
return fromProblem(funnelProblem(want.httpsPort));
|
|
100
|
+
}
|
|
101
|
+
return onView(dnsName, want.httpsPort);
|
|
102
|
+
};
|
|
103
|
+
// A read: what is true now, without changing Tailscale.
|
|
104
|
+
const read = async () => {
|
|
105
|
+
if (deps.container)
|
|
106
|
+
return dockerView();
|
|
107
|
+
const want = saved();
|
|
108
|
+
if (!want.enabled)
|
|
109
|
+
return offView();
|
|
110
|
+
const now = await diagnose();
|
|
111
|
+
if (!ready(now))
|
|
112
|
+
return fromProblem(now);
|
|
113
|
+
const { dnsName } = now.machine;
|
|
114
|
+
const use = portUse(now.serve, dnsName, want.httpsPort);
|
|
115
|
+
const ours = store.applied();
|
|
116
|
+
if (ours !== undefined &&
|
|
117
|
+
ours.httpsPort === want.httpsPort &&
|
|
118
|
+
use.kind === "proxy" &&
|
|
119
|
+
sameTarget(use.target, ours.target))
|
|
120
|
+
return use.funnel
|
|
121
|
+
? fromProblem(funnelProblem(want.httpsPort))
|
|
122
|
+
: onView(dnsName, want.httpsPort);
|
|
123
|
+
if (use.kind !== "free") {
|
|
124
|
+
const suggested = freePort(now.serve, dnsName, want.httpsPort);
|
|
125
|
+
return fromProblem(portTakenProblem(want.httpsPort, use, loopbackTarget(), suggested), {
|
|
126
|
+
suggestedPort: suggested,
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
return base("not-applied", "The switch is on, but Slopify's address isn't in Tailscale right now.", {
|
|
130
|
+
fix: "Press Check again to set it up again.",
|
|
131
|
+
});
|
|
132
|
+
};
|
|
133
|
+
// One change to Tailscale at a time.
|
|
134
|
+
let queue = Promise.resolve();
|
|
135
|
+
const serial = (work) => {
|
|
136
|
+
const next = queue.then(work, work);
|
|
137
|
+
queue = next.catch(() => undefined);
|
|
138
|
+
return next;
|
|
139
|
+
};
|
|
140
|
+
let cached;
|
|
141
|
+
const fresh = (view) => {
|
|
142
|
+
cached = { at: deps.now(), view };
|
|
143
|
+
view.catch(() => {
|
|
144
|
+
cached = undefined;
|
|
145
|
+
});
|
|
146
|
+
return view;
|
|
147
|
+
};
|
|
148
|
+
const turnOff = async () => {
|
|
149
|
+
if (store.applied() === undefined)
|
|
150
|
+
return offView();
|
|
151
|
+
const now = await diagnose();
|
|
152
|
+
const problem = ready(now) ? await removeOurs(now) : now;
|
|
153
|
+
if (problem === undefined)
|
|
154
|
+
return offView();
|
|
155
|
+
const port = store.applied()?.httpsPort ?? saved().httpsPort;
|
|
156
|
+
return fromProblem(problem, {
|
|
157
|
+
state: problem.state,
|
|
158
|
+
summary: `The switch is off, but Slopify couldn't remove its address from Tailscale yet: ${problem.summary} Slopify tries again at every start.`,
|
|
159
|
+
fix: `${problem.fix} Or remove it yourself with tailscale serve --https=${port} off.`,
|
|
160
|
+
});
|
|
161
|
+
};
|
|
162
|
+
return {
|
|
163
|
+
view: () => {
|
|
164
|
+
if (cached !== undefined && deps.now() - cached.at < cacheMs)
|
|
165
|
+
return cached.view;
|
|
166
|
+
return fresh(serial(read));
|
|
167
|
+
},
|
|
168
|
+
set: (enabled, httpsPort) => fresh(serial(async () => {
|
|
169
|
+
if (deps.container)
|
|
170
|
+
return dockerView();
|
|
171
|
+
store.save({ enabled, httpsPort: httpsPort ?? saved().httpsPort });
|
|
172
|
+
return enabled ? apply() : turnOff();
|
|
173
|
+
})),
|
|
174
|
+
start: () => serial(async () => {
|
|
175
|
+
cached = undefined;
|
|
176
|
+
if (deps.container)
|
|
177
|
+
return;
|
|
178
|
+
const view = saved().enabled ? await apply() : await turnOff();
|
|
179
|
+
if (view.state !== "on" && view.state !== "off")
|
|
180
|
+
deps.log.write("warn", "remote-access.start", {
|
|
181
|
+
detail: `${view.summary} ${view.fix ?? ""}`,
|
|
182
|
+
});
|
|
183
|
+
}),
|
|
184
|
+
stop: () => serial(async () => {
|
|
185
|
+
cached = undefined;
|
|
186
|
+
if (deps.container || store.applied() === undefined)
|
|
187
|
+
return;
|
|
188
|
+
const now = await diagnose();
|
|
189
|
+
const problem = ready(now) ? await removeOurs(now) : now;
|
|
190
|
+
if (problem !== undefined)
|
|
191
|
+
deps.log.write("warn", "remote-access.stop", { detail: problem.summary });
|
|
192
|
+
}),
|
|
193
|
+
owner: () => store.applied()?.owner,
|
|
194
|
+
remoteHost: () => {
|
|
195
|
+
const ours = store.applied();
|
|
196
|
+
return ours === undefined
|
|
197
|
+
? undefined
|
|
198
|
+
: ours.httpsPort === 443
|
|
199
|
+
? ours.dnsName
|
|
200
|
+
: `${ours.dnsName}:${ours.httpsPort}`;
|
|
201
|
+
},
|
|
202
|
+
};
|
|
203
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { deleteSetting, readSetting, writeSetting } from "../../slices/settings/repo.js";
|
|
3
|
+
import { defaultHttpsPort, remoteAccessAppliedKey, remoteAccessKey } from "./model.js";
|
|
4
|
+
// The two settings rows remote access keeps: the switch as the person set it, and the exact
|
|
5
|
+
// serve handler Slopify added (removed again only when it is still exactly that).
|
|
6
|
+
const savedShape = z.object({
|
|
7
|
+
enabled: z.boolean(),
|
|
8
|
+
httpsPort: z.number().int().min(1).max(65535),
|
|
9
|
+
});
|
|
10
|
+
const appliedShape = z.object({
|
|
11
|
+
dnsName: z.string(),
|
|
12
|
+
httpsPort: z.number().int(),
|
|
13
|
+
target: z.string(),
|
|
14
|
+
// The Tailscale account the computer was signed in to when Slopify added its address: the
|
|
15
|
+
// only one let in over the tailnet. Absent in what older versions saved.
|
|
16
|
+
owner: z.string().optional(),
|
|
17
|
+
});
|
|
18
|
+
function readJson(db, key, shape) {
|
|
19
|
+
const raw = readSetting(db, key);
|
|
20
|
+
if (raw === undefined)
|
|
21
|
+
return undefined;
|
|
22
|
+
try {
|
|
23
|
+
const parsed = shape.safeParse(JSON.parse(raw));
|
|
24
|
+
return parsed.success ? parsed.data : undefined;
|
|
25
|
+
}
|
|
26
|
+
catch {
|
|
27
|
+
return undefined;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
export function remoteAccessStore(db) {
|
|
31
|
+
let applied = readJson(db, remoteAccessAppliedKey, appliedShape);
|
|
32
|
+
return {
|
|
33
|
+
saved: () => readJson(db, remoteAccessKey, savedShape) ?? { enabled: false, httpsPort: defaultHttpsPort },
|
|
34
|
+
applied: () => applied,
|
|
35
|
+
record: (next) => {
|
|
36
|
+
applied = next;
|
|
37
|
+
if (next === undefined)
|
|
38
|
+
deleteSetting(db, remoteAccessAppliedKey);
|
|
39
|
+
else
|
|
40
|
+
writeSetting(db, remoteAccessAppliedKey, JSON.stringify(next));
|
|
41
|
+
},
|
|
42
|
+
save: (next) => writeSetting(db, remoteAccessKey, JSON.stringify(next)),
|
|
43
|
+
};
|
|
44
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { addressOf } from "./rules.js";
|
|
2
|
+
export function remoteAccessViews(deps, saved) {
|
|
3
|
+
const loopbackTarget = () => {
|
|
4
|
+
const host = deps.listenHost;
|
|
5
|
+
const name = host === "" || host === "0.0.0.0" || host === "localhost" || host === "127.0.0.1"
|
|
6
|
+
? "127.0.0.1"
|
|
7
|
+
: host === "::" || host === "::1"
|
|
8
|
+
? "[::1]"
|
|
9
|
+
: host.includes(":")
|
|
10
|
+
? `[${host}]`
|
|
11
|
+
: host;
|
|
12
|
+
return `http://${name}:${deps.port()}`;
|
|
13
|
+
};
|
|
14
|
+
const local = () => loopbackTarget();
|
|
15
|
+
const base = (state, summary, rest = {}) => ({
|
|
16
|
+
available: !deps.container,
|
|
17
|
+
enabled: saved().enabled,
|
|
18
|
+
state,
|
|
19
|
+
address: null,
|
|
20
|
+
httpsPort: saved().httpsPort,
|
|
21
|
+
suggestedPort: null,
|
|
22
|
+
summary,
|
|
23
|
+
fix: null,
|
|
24
|
+
link: null,
|
|
25
|
+
local: local(),
|
|
26
|
+
changeable: !deps.container,
|
|
27
|
+
...rest,
|
|
28
|
+
});
|
|
29
|
+
const fromProblem = (problem, rest = {}) => base(problem.state, problem.summary, { fix: problem.fix, link: problem.link, ...rest });
|
|
30
|
+
const dockerView = () => base("docker", "Slopify runs in Docker here, so it can't set up Tailscale on the computer itself.", {
|
|
31
|
+
enabled: false,
|
|
32
|
+
fix: "Remote access needs Slopify started on the computer itself (npx @gentbajko/slopify). Or set Tailscale up yourself on the host: tailscale serve --bg --https=443 http://127.0.0.1:<Slopify's port>.",
|
|
33
|
+
});
|
|
34
|
+
const offView = () => base("off", `Off: Slopify answers only on this computer, at ${local()}.`);
|
|
35
|
+
const funnelProblem = (httpsPort) => ({
|
|
36
|
+
state: "funnel",
|
|
37
|
+
summary: "Tailscale Funnel was on for Slopify's address, which would put Slopify on the public internet. Slopify removed its address and refuses every request that comes through Funnel.",
|
|
38
|
+
fix: `Turn Funnel off with tailscale funnel --https=${httpsPort} off, then press Check again.`,
|
|
39
|
+
link: null,
|
|
40
|
+
});
|
|
41
|
+
const onView = (dnsName, httpsPort) => base("on", "On: any device in your tailnet can open this address, never the public internet. It works while Slopify runs: Slopify removes it when it stops and adds it back when it starts.", { address: addressOf(dnsName, httpsPort) });
|
|
42
|
+
return { loopbackTarget, base, fromProblem, dockerView, offView, funnelProblem, onView };
|
|
43
|
+
}
|
|
Binary file
|
|
Binary file
|
package/dist/host-cli/install.js
CHANGED
|
@@ -2,9 +2,9 @@ import { execFile } from "node:child_process";
|
|
|
2
2
|
import { access, lstat, mkdir, mkdtemp, readFile, rename, rm, writeFile } from "node:fs/promises";
|
|
3
3
|
import { basename, join } from "node:path";
|
|
4
4
|
import { z } from "zod";
|
|
5
|
+
import { hasErrnoCode } from "../kernel/errors.js";
|
|
5
6
|
import { isStableVersion, updatePackage } from "../updater/model.js";
|
|
6
7
|
import { installArgs, npmCommand } from "../updater/plan.js";
|
|
7
|
-
import { hasCode } from "./paths.js";
|
|
8
8
|
export const nodeHostSetupRunner = {
|
|
9
9
|
exec: (file, args, signal) => new Promise((resolve, reject) => {
|
|
10
10
|
execFile(file, [...args], { signal, timeout: 15 * 60_000, maxBuffer: 1024 * 1024, windowsHide: true }, (error, stdout, stderr) => {
|
|
@@ -55,7 +55,7 @@ export async function installHostPackage(options) {
|
|
|
55
55
|
return { entry: await entryAt(directory, version) };
|
|
56
56
|
}
|
|
57
57
|
catch (error) {
|
|
58
|
-
if (!
|
|
58
|
+
if (!hasErrnoCode(error, "ENOENT"))
|
|
59
59
|
throw new Error(`The installed host helper in ${directory} is damaged. Delete that folder and run the launcher again. Nothing else was changed.`);
|
|
60
60
|
}
|
|
61
61
|
await mkdir(versions, { recursive: true, mode: 0o700 });
|
|
@@ -2,8 +2,8 @@ import { spawn } from "node:child_process";
|
|
|
2
2
|
import { lstat, readdir } from "node:fs/promises";
|
|
3
3
|
import { isAbsolute, join, relative, sep } from "node:path";
|
|
4
4
|
import { installSchema, readState } from "../edge/docker-install/state.js";
|
|
5
|
+
import { hasErrnoCode } from "../kernel/errors.js";
|
|
5
6
|
import { HostFolderRefused } from "../kernel/ports/host-cli.js";
|
|
6
|
-
import { hasCode } from "./paths.js";
|
|
7
7
|
const again = "run the Docker install again (npx @gentbajko/slopify@latest --docker)";
|
|
8
8
|
/** Starts the desktop's opener and returns once it is running; the file manager is not awaited. */
|
|
9
9
|
export function launchXdgOpen(directory) {
|
|
@@ -14,7 +14,7 @@ export function launchXdgOpen(directory) {
|
|
|
14
14
|
stdio: "ignore",
|
|
15
15
|
});
|
|
16
16
|
child.once("error", (error) => {
|
|
17
|
-
reject(new Error(
|
|
17
|
+
reject(new Error(hasErrnoCode(error, "ENOENT")
|
|
18
18
|
? "xdg-open isn't installed on this machine, so the Slopify host helper can't open a file manager. Install xdg-utils (for example sudo pacman -S xdg-utils or sudo apt install xdg-utils), then use Open folder again."
|
|
19
19
|
: `The Slopify host helper could not start xdg-open to open ${directory}. Check that you are signed in to this computer's desktop, then use Open folder again.`));
|
|
20
20
|
});
|
package/dist/host-cli/paths.js
CHANGED
|
@@ -2,6 +2,7 @@ import { randomBytes } from "node:crypto";
|
|
|
2
2
|
import { constants } from "node:fs";
|
|
3
3
|
import { chmod, lstat, mkdir, open } from "node:fs/promises";
|
|
4
4
|
import { isAbsolute, join, resolve } from "node:path";
|
|
5
|
+
import { hasErrnoCode } from "../kernel/errors.js";
|
|
5
6
|
export async function prepareHostPaths(root) {
|
|
6
7
|
if (!isAbsolute(root) || /[\p{Cc}]/u.test(root))
|
|
7
8
|
throw new Error(`Unsafe host helper directory ${JSON.stringify(root)}: it must be a full path. Check XDG_DATA_HOME and HOME, then run the launcher again.`);
|
|
@@ -55,7 +56,7 @@ export async function ensureBridgeToken(path) {
|
|
|
55
56
|
}
|
|
56
57
|
}
|
|
57
58
|
catch (error) {
|
|
58
|
-
if (!
|
|
59
|
+
if (!hasErrnoCode(error, "EEXIST"))
|
|
59
60
|
throw error;
|
|
60
61
|
}
|
|
61
62
|
const entry = await lstat(path);
|
|
@@ -63,6 +64,3 @@ export async function ensureBridgeToken(path) {
|
|
|
63
64
|
throw new Error(`The host helper token file ${path} is a link or belongs to another user. Delete it and run the launcher again.`);
|
|
64
65
|
return readBridgeToken(path);
|
|
65
66
|
}
|
|
66
|
-
export function hasCode(error, code) {
|
|
67
|
-
return typeof error === "object" && error !== null && "code" in error && error.code === code;
|
|
68
|
-
}
|
package/dist/host-cli/server.js
CHANGED
|
@@ -4,7 +4,7 @@ import { connect } from "node:net";
|
|
|
4
4
|
import { join } from "node:path";
|
|
5
5
|
import { createAdaptorServer } from "@hono/node-server";
|
|
6
6
|
import { hostCliRoutes, hostGate } from "../edge/http/host-cli.js";
|
|
7
|
-
import {
|
|
7
|
+
import { hasErrnoCode } from "../kernel/errors.js";
|
|
8
8
|
export async function startHostServer(options) {
|
|
9
9
|
const socket = join(options.directory, "cli.sock");
|
|
10
10
|
if (Buffer.byteLength(socket) > 100)
|
|
@@ -23,7 +23,7 @@ export async function startHostServer(options) {
|
|
|
23
23
|
await unlink(socket);
|
|
24
24
|
}
|
|
25
25
|
catch (error) {
|
|
26
|
-
if (!
|
|
26
|
+
if (!hasErrnoCode(error, "ENOENT"))
|
|
27
27
|
throw error;
|
|
28
28
|
}
|
|
29
29
|
const gate = hostGate();
|
|
@@ -67,7 +67,7 @@ export async function startHostServer(options) {
|
|
|
67
67
|
await unlink(socket);
|
|
68
68
|
}
|
|
69
69
|
catch (error) {
|
|
70
|
-
if (!
|
|
70
|
+
if (!hasErrnoCode(error, "ENOENT"))
|
|
71
71
|
throw error;
|
|
72
72
|
}
|
|
73
73
|
})();
|
|
@@ -89,7 +89,7 @@ function listening(path) {
|
|
|
89
89
|
});
|
|
90
90
|
socket.once("error", (error) => {
|
|
91
91
|
socket.destroy();
|
|
92
|
-
if (
|
|
92
|
+
if (hasErrnoCode(error, "ECONNREFUSED"))
|
|
93
93
|
resolve(false);
|
|
94
94
|
else
|
|
95
95
|
reject(new Error("Could not verify existing host socket."));
|
package/dist/host-cli/service.js
CHANGED
|
@@ -3,9 +3,9 @@ import { lstat, mkdir, open, rename, unlink } from "node:fs/promises";
|
|
|
3
3
|
import { isAbsolute, join } from "node:path";
|
|
4
4
|
import { setTimeout as delay } from "node:timers/promises";
|
|
5
5
|
import { hostRequest, readHostBytes } from "../adapters/host-cli/transport.js";
|
|
6
|
+
import { hasErrnoCode } from "../kernel/errors.js";
|
|
6
7
|
import { bridgeLimits, hostHealthSchema } from "../kernel/ports/host-cli.js";
|
|
7
8
|
import { hostEnvironment } from "./environment.js";
|
|
8
|
-
import { hasCode } from "./paths.js";
|
|
9
9
|
const marker = "# Managed by Slopify host CLI bridge, protocol 1";
|
|
10
10
|
export const hostUnit = "slopify-cli-bridge.service";
|
|
11
11
|
function unitArg(value) {
|
|
@@ -51,7 +51,7 @@ export async function privateRead(path, uid) {
|
|
|
51
51
|
}
|
|
52
52
|
}
|
|
53
53
|
catch (error) {
|
|
54
|
-
if (
|
|
54
|
+
if (hasErrnoCode(error, "ENOENT"))
|
|
55
55
|
return undefined;
|
|
56
56
|
throw error;
|
|
57
57
|
}
|
|
@@ -71,7 +71,7 @@ export async function privateWrite(path, text) {
|
|
|
71
71
|
}
|
|
72
72
|
finally {
|
|
73
73
|
await unlink(temporary).catch((error) => {
|
|
74
|
-
if (!
|
|
74
|
+
if (!hasErrnoCode(error, "ENOENT"))
|
|
75
75
|
throw error;
|
|
76
76
|
});
|
|
77
77
|
}
|
package/dist/host-cli/status.js
CHANGED
|
@@ -6,6 +6,7 @@ import { z } from "zod";
|
|
|
6
6
|
import { parseAntigravityModels } from "../adapters/llm/antigravity-models.js";
|
|
7
7
|
import { cliLoginError } from "../adapters/llm/cli-login-error.js";
|
|
8
8
|
import { cliCommand } from "../kernel/cli-command.js";
|
|
9
|
+
import { errorText, hasErrnoCode } from "../kernel/errors.js";
|
|
9
10
|
import { cliProbeTimeoutMs, readinessFromProbe, } from "../slices/settings/cli-status.js";
|
|
10
11
|
export function hostCommandName(id) {
|
|
11
12
|
if (id === "claude-code")
|
|
@@ -25,7 +26,9 @@ export async function resolveHostCommand(id, env) {
|
|
|
25
26
|
return path;
|
|
26
27
|
}
|
|
27
28
|
catch (error) {
|
|
28
|
-
if (!
|
|
29
|
+
if (!hasErrnoCode(error, "ENOENT") &&
|
|
30
|
+
!hasErrnoCode(error, "ENOTDIR") &&
|
|
31
|
+
!hasErrnoCode(error, "EACCES"))
|
|
29
32
|
throw error;
|
|
30
33
|
}
|
|
31
34
|
}
|
|
@@ -89,10 +92,10 @@ export function createHostStatus(deps) {
|
|
|
89
92
|
command: hostCommandName(id),
|
|
90
93
|
installed: false,
|
|
91
94
|
login: "unknown",
|
|
92
|
-
issueKind:
|
|
93
|
-
issue:
|
|
95
|
+
issueKind: hasErrnoCode(error, "ENOENT") ? "missing" : "bridge",
|
|
96
|
+
issue: hasErrnoCode(error, "ENOENT")
|
|
94
97
|
? `${hostCommandName(id)} was not found on this machine. Install it and sign in there, then run the launcher again: npx @gentbajko/slopify --docker`
|
|
95
|
-
: `Slopify could not check for ${hostCommandName(id)} on this machine (${
|
|
98
|
+
: `Slopify could not check for ${hostCommandName(id)} on this machine (${errorText(error)}). Fix the problem, then run the launcher again: npx @gentbajko/slopify --docker`,
|
|
96
99
|
};
|
|
97
100
|
}
|
|
98
101
|
const readiness = readinessFromProbe(await deps.probe(command, ["--version"], cliProbeTimeoutMs), {
|
|
@@ -149,6 +152,3 @@ export function createHostStatus(deps) {
|
|
|
149
152
|
return { ...(await entry.value), id };
|
|
150
153
|
};
|
|
151
154
|
}
|
|
152
|
-
function isCode(error, code) {
|
|
153
|
-
return typeof error === "object" && error !== null && "code" in error && error.code === code;
|
|
154
|
-
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
-- What Settings → Models and the pickers know about each model for the person's own key or
|
|
2
|
+
-- CLI login (`slices/model-checks`): whether the key's live list names it, and the last check
|
|
3
|
+
-- or real run's verdict. Only pickers read it; no run does. `account` is the key generation or
|
|
4
|
+
-- the CLI's id, so a new key starts every row over.
|
|
5
|
+
CREATE TABLE model_checks (
|
|
6
|
+
provider TEXT NOT NULL,
|
|
7
|
+
family TEXT NOT NULL CHECK (family IN ('llm','tts','image')),
|
|
8
|
+
model TEXT NOT NULL,
|
|
9
|
+
account TEXT NOT NULL,
|
|
10
|
+
listed INTEGER CHECK (listed IN (0,1)),
|
|
11
|
+
listed_at TEXT,
|
|
12
|
+
verdict TEXT CHECK (verdict IN ('works','no-access','failed')),
|
|
13
|
+
verdict_source TEXT CHECK (verdict_source IN ('check','run')),
|
|
14
|
+
sentence TEXT,
|
|
15
|
+
checked_at TEXT,
|
|
16
|
+
cost REAL NOT NULL DEFAULT 0,
|
|
17
|
+
first_works_at TEXT,
|
|
18
|
+
notice_seen INTEGER NOT NULL DEFAULT 0 CHECK (notice_seen IN (0,1)),
|
|
19
|
+
PRIMARY KEY(provider, family, model)
|
|
20
|
+
);
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
-- Template studio (4.0, `slices/template-studio`). A version is runnable by schedules when its
|
|
2
|
+
-- gate is ready, carried (a system writer copied a runnable gate) or legacy (saved before the
|
|
3
|
+
-- studio). A version with no row was never checked.
|
|
4
|
+
CREATE TABLE template_gates (
|
|
5
|
+
template_id TEXT NOT NULL,
|
|
6
|
+
version INTEGER NOT NULL CHECK(version >= 1),
|
|
7
|
+
state TEXT NOT NULL CHECK(state IN ('legacy','ready','carried')),
|
|
8
|
+
carried_from INTEGER CHECK(carried_from IS NULL OR carried_from >= 1),
|
|
9
|
+
checks_json TEXT CHECK(checks_json IS NULL OR json_valid(checks_json)),
|
|
10
|
+
marked_at TEXT,
|
|
11
|
+
PRIMARY KEY(template_id, version),
|
|
12
|
+
FOREIGN KEY(template_id, version) REFERENCES project_template_revisions(template_id, version) ON DELETE CASCADE
|
|
13
|
+
);
|
|
14
|
+
INSERT INTO template_gates (template_id, version, state)
|
|
15
|
+
SELECT template_id, version, 'legacy' FROM project_template_revisions;
|
|
16
|
+
-- The hidden project each template's samples are made on. It never appears in a list the user
|
|
17
|
+
-- sees (`notTemplateSample`), and its project may be gone: the next sample makes it again.
|
|
18
|
+
CREATE TABLE template_samples (
|
|
19
|
+
template_id TEXT PRIMARY KEY REFERENCES project_templates(id) ON DELETE CASCADE,
|
|
20
|
+
project_id TEXT NOT NULL UNIQUE,
|
|
21
|
+
topic TEXT NOT NULL CHECK(length(trim(topic)) BETWEEN 1 AND 300),
|
|
22
|
+
topic_source TEXT NOT NULL CHECK(topic_source IN ('fixed','queued')),
|
|
23
|
+
full_script INTEGER NOT NULL DEFAULT 0 CHECK(full_script IN (0,1)),
|
|
24
|
+
created_at TEXT NOT NULL
|
|
25
|
+
);
|
|
26
|
+
CREATE TABLE template_sample_versions (
|
|
27
|
+
template_id TEXT NOT NULL REFERENCES project_templates(id) ON DELETE CASCADE,
|
|
28
|
+
template_version INTEGER NOT NULL CHECK(template_version >= 1),
|
|
29
|
+
revision_id TEXT,
|
|
30
|
+
state TEXT NOT NULL CHECK(state IN ('queued','making','done','failed','skipped','held')),
|
|
31
|
+
quoted_high REAL,
|
|
32
|
+
held_reason TEXT,
|
|
33
|
+
updated_at TEXT NOT NULL,
|
|
34
|
+
PRIMARY KEY(template_id, template_version)
|
|
35
|
+
);
|
|
36
|
+
-- At most one queued and one running sample job per template: a newer Save replaces the queued
|
|
37
|
+
-- one and waits behind the running one, which is never stopped.
|
|
38
|
+
CREATE TABLE template_sample_jobs (
|
|
39
|
+
template_id TEXT NOT NULL REFERENCES project_templates(id) ON DELETE CASCADE,
|
|
40
|
+
template_version INTEGER NOT NULL CHECK(template_version >= 1),
|
|
41
|
+
ack_high REAL NOT NULL DEFAULT 0 CHECK(ack_high >= 0),
|
|
42
|
+
kind TEXT NOT NULL CHECK(kind IN ('save','topic','full-script','bakeoff','free')),
|
|
43
|
+
requested_at TEXT NOT NULL,
|
|
44
|
+
state TEXT NOT NULL CHECK(state IN ('queued','running')),
|
|
45
|
+
PRIMARY KEY(template_id, state)
|
|
46
|
+
);
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
-- The promise check is a review stage of its own (`reviews/model.ts`), and the in-app assistant
|
|
2
|
+
-- acts on and answers reviews as itself rather than as an agent. SQLite cannot change a CHECK in
|
|
3
|
+
-- place, so both tables are copied, as 0055 and 0059 did.
|
|
4
|
+
CREATE TABLE review_verdicts_promise_upgrade (
|
|
5
|
+
id TEXT PRIMARY KEY,
|
|
6
|
+
project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
|
|
7
|
+
revision_id TEXT NOT NULL,
|
|
8
|
+
item_key TEXT NOT NULL,
|
|
9
|
+
stage TEXT NOT NULL CHECK(stage IN ('article','images','narration','thumbnail','shorts','promise')),
|
|
10
|
+
item_fingerprint TEXT NOT NULL,
|
|
11
|
+
review_fingerprint TEXT NOT NULL,
|
|
12
|
+
passed INTEGER NOT NULL CHECK(passed IN (0,1)),
|
|
13
|
+
reasons TEXT NOT NULL,
|
|
14
|
+
outcome TEXT NOT NULL CHECK(outcome IN ('passed','flagged','redo','auto-passed')),
|
|
15
|
+
attempt INTEGER NOT NULL CHECK(attempt >= 1),
|
|
16
|
+
action TEXT CHECK(action IN ('overruled','redone')),
|
|
17
|
+
action_at TEXT,
|
|
18
|
+
action_by TEXT CHECK(action_by IN ('person','agent','assistant')),
|
|
19
|
+
redo_state TEXT CHECK(redo_state IN ('pending','started','failed')),
|
|
20
|
+
redo_error TEXT,
|
|
21
|
+
answered_by TEXT NOT NULL DEFAULT 'model' CHECK(answered_by IN ('model','agent','person','nobody')),
|
|
22
|
+
created_at TEXT NOT NULL,
|
|
23
|
+
UNIQUE(project_id,review_fingerprint)
|
|
24
|
+
);
|
|
25
|
+
INSERT INTO review_verdicts_promise_upgrade (id,project_id,revision_id,item_key,stage,item_fingerprint,review_fingerprint,passed,reasons,outcome,attempt,action,action_at,action_by,redo_state,redo_error,answered_by,created_at)
|
|
26
|
+
SELECT id,project_id,revision_id,item_key,stage,item_fingerprint,review_fingerprint,passed,reasons,outcome,attempt,action,action_at,action_by,redo_state,redo_error,answered_by,created_at
|
|
27
|
+
FROM review_verdicts ORDER BY rowid;
|
|
28
|
+
DROP TABLE review_verdicts;
|
|
29
|
+
ALTER TABLE review_verdicts_promise_upgrade RENAME TO review_verdicts;
|
|
30
|
+
CREATE INDEX review_verdicts_item ON review_verdicts(project_id,item_key);
|
|
31
|
+
CREATE INDEX review_verdicts_redo ON review_verdicts(redo_state);
|
|
32
|
+
|
|
33
|
+
CREATE TABLE external_reviews_promise_upgrade (
|
|
34
|
+
id TEXT PRIMARY KEY,
|
|
35
|
+
project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
|
|
36
|
+
revision_id TEXT NOT NULL,
|
|
37
|
+
work_id TEXT NOT NULL,
|
|
38
|
+
piece_id TEXT NOT NULL,
|
|
39
|
+
work_key TEXT NOT NULL,
|
|
40
|
+
item_key TEXT NOT NULL,
|
|
41
|
+
stage TEXT NOT NULL CHECK(stage IN ('article','images','narration','thumbnail','shorts','promise')),
|
|
42
|
+
item_fingerprint TEXT NOT NULL,
|
|
43
|
+
review_fingerprint TEXT NOT NULL,
|
|
44
|
+
material TEXT NOT NULL CHECK(json_valid(material)),
|
|
45
|
+
state TEXT NOT NULL CHECK(state IN ('waiting','answered','auto-passed','superseded','canceled')),
|
|
46
|
+
waiting_since TEXT NOT NULL,
|
|
47
|
+
deadline_at TEXT NOT NULL,
|
|
48
|
+
verdict TEXT CHECK(verdict IS NULL OR json_valid(verdict)),
|
|
49
|
+
answered_by TEXT CHECK(answered_by IN ('person','agent','assistant')),
|
|
50
|
+
answered_at TEXT,
|
|
51
|
+
UNIQUE(project_id,review_fingerprint)
|
|
52
|
+
);
|
|
53
|
+
INSERT INTO external_reviews_promise_upgrade (id,project_id,revision_id,work_id,piece_id,work_key,item_key,stage,item_fingerprint,review_fingerprint,material,state,waiting_since,deadline_at,verdict,answered_by,answered_at)
|
|
54
|
+
SELECT id,project_id,revision_id,work_id,piece_id,work_key,item_key,stage,item_fingerprint,review_fingerprint,material,state,waiting_since,deadline_at,verdict,answered_by,answered_at
|
|
55
|
+
FROM external_reviews ORDER BY rowid;
|
|
56
|
+
DROP TABLE external_reviews;
|
|
57
|
+
ALTER TABLE external_reviews_promise_upgrade RENAME TO external_reviews;
|
|
58
|
+
CREATE INDEX external_reviews_waiting ON external_reviews(state, deadline_at);
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
-- The in-app assistant acts through the same API as an agent but is told apart: its changes
|
|
2
|
+
-- show "by assistant", and it can start a project's work. Its chat is kept per session, each
|
|
3
|
+
-- turn replayed to a fresh CLI, and what it asked the person first ("Ask first") is kept with
|
|
4
|
+
-- the person's answer, which a later call may use once. SQLite cannot change a CHECK in place,
|
|
5
|
+
-- so project_starts is copied, as 0055 did.
|
|
6
|
+
ALTER TABLE agent_actions ADD COLUMN actor TEXT NOT NULL DEFAULT 'agent' CHECK(actor IN ('agent','assistant'));
|
|
7
|
+
|
|
8
|
+
CREATE TABLE project_starts_assistant_upgrade (
|
|
9
|
+
project_id TEXT PRIMARY KEY REFERENCES projects(id) ON DELETE CASCADE,
|
|
10
|
+
actor TEXT NOT NULL CHECK(actor IN ('person','agent','assistant')),
|
|
11
|
+
started_at TEXT NOT NULL
|
|
12
|
+
);
|
|
13
|
+
INSERT INTO project_starts_assistant_upgrade (project_id,actor,started_at)
|
|
14
|
+
SELECT project_id,actor,started_at FROM project_starts ORDER BY rowid;
|
|
15
|
+
DROP TABLE project_starts;
|
|
16
|
+
ALTER TABLE project_starts_assistant_upgrade RENAME TO project_starts;
|
|
17
|
+
|
|
18
|
+
CREATE TABLE assistant_sessions (
|
|
19
|
+
id TEXT PRIMARY KEY,
|
|
20
|
+
cli TEXT NOT NULL,
|
|
21
|
+
created_at TEXT NOT NULL,
|
|
22
|
+
updated_at TEXT NOT NULL
|
|
23
|
+
);
|
|
24
|
+
CREATE TABLE assistant_messages (
|
|
25
|
+
id TEXT PRIMARY KEY,
|
|
26
|
+
session_id TEXT NOT NULL REFERENCES assistant_sessions(id) ON DELETE CASCADE,
|
|
27
|
+
turn_id TEXT NOT NULL,
|
|
28
|
+
role TEXT NOT NULL CHECK(role IN ('person','assistant','tool','ask','error')),
|
|
29
|
+
text TEXT NOT NULL,
|
|
30
|
+
meta TEXT NOT NULL DEFAULT '{}' CHECK(json_valid(meta)),
|
|
31
|
+
created_at TEXT NOT NULL
|
|
32
|
+
);
|
|
33
|
+
CREATE INDEX assistant_messages_session ON assistant_messages(session_id, created_at);
|
|
34
|
+
CREATE TABLE assistant_asks (
|
|
35
|
+
id TEXT PRIMARY KEY,
|
|
36
|
+
session_id TEXT NOT NULL REFERENCES assistant_sessions(id) ON DELETE CASCADE,
|
|
37
|
+
tool TEXT NOT NULL,
|
|
38
|
+
args_hash TEXT NOT NULL,
|
|
39
|
+
text TEXT NOT NULL,
|
|
40
|
+
state TEXT NOT NULL CHECK(state IN ('asked','allowed','denied','used','expired')),
|
|
41
|
+
created_at TEXT NOT NULL,
|
|
42
|
+
decided_at TEXT
|
|
43
|
+
);
|
|
44
|
+
CREATE INDEX assistant_asks_session ON assistant_asks(session_id, state);
|