@gentbajko/slopify 3.25.8 → 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (604) hide show
  1. package/dist/adapters/account-limits.js +30 -0
  2. package/dist/adapters/alignment/cache.js +3 -5
  3. package/dist/adapters/alignment/ctc.js +1 -2
  4. package/dist/adapters/alignment/lock.js +4 -3
  5. package/dist/adapters/alignment/multilingual.js +0 -3
  6. package/dist/adapters/alignment/prefetch.js +2 -1
  7. package/dist/adapters/alignment/worker.js +2 -1
  8. package/dist/adapters/explain.js +0 -3
  9. package/dist/adapters/ffmpeg.js +19 -1
  10. package/dist/adapters/host-cli/index.js +19 -3
  11. package/dist/adapters/http-failure.js +53 -0
  12. package/dist/adapters/image/codex.js +36 -4
  13. package/dist/adapters/image/fal.js +17 -50
  14. package/dist/adapters/image/google.js +31 -55
  15. package/dist/adapters/image/openai.js +20 -47
  16. package/dist/adapters/image/reference.js +36 -0
  17. package/dist/adapters/image/replicate.js +18 -47
  18. package/dist/adapters/interest/search-interest.js +113 -0
  19. package/dist/adapters/key-probes.js +53 -2
  20. package/dist/adapters/llm/antigravity.js +4 -0
  21. package/dist/adapters/llm/assistant-cli.js +388 -0
  22. package/dist/adapters/llm/child-session.js +83 -0
  23. package/dist/adapters/llm/claude-code-models.js +51 -98
  24. package/dist/adapters/llm/claude-code.js +13 -2
  25. package/dist/adapters/llm/codex-limits.js +27 -68
  26. package/dist/adapters/llm/codex-server-models.js +61 -109
  27. package/dist/adapters/llm/codex.js +12 -1
  28. package/dist/adapters/llm/openrouter.js +10 -47
  29. package/dist/adapters/llm/run-cli.js +6 -22
  30. package/dist/adapters/llm/sse-lines.js +5 -1
  31. package/dist/adapters/model-access.js +37 -0
  32. package/dist/adapters/tts/cartesia.js +15 -46
  33. package/dist/adapters/tts/elevenlabs.js +20 -52
  34. package/dist/adapters/tts/gemini.js +19 -40
  35. package/dist/adapters/tts/inworld-async.js +4 -1
  36. package/dist/adapters/tts/inworld.js +3 -0
  37. package/dist/adapters/tts/openai.js +20 -50
  38. package/dist/assets/models-lifecycle.yaml +6 -0
  39. package/dist/assistant-wiring.js +60 -0
  40. package/dist/autopilot-timers.js +59 -0
  41. package/dist/catalog/lifecycle.js +52 -0
  42. package/dist/catalog/propose.js +204 -0
  43. package/dist/catalog/registry.js +3 -1
  44. package/dist/catalog/schema.js +2 -0
  45. package/dist/catalog/store.js +39 -0
  46. package/dist/edge/autostart/native.js +3 -5
  47. package/dist/edge/autostart/prompt.js +2 -1
  48. package/dist/edge/autostart/service.js +3 -4
  49. package/dist/edge/cli-args.js +3 -4
  50. package/dist/edge/cli.js +2 -1
  51. package/dist/edge/docker-install/apply.js +11 -11
  52. package/dist/edge/docker-install/run.js +2 -1
  53. package/dist/edge/docker-install/state.js +4 -3
  54. package/dist/edge/docker-install/tree.js +2 -4
  55. package/dist/edge/docker-install/volume.js +3 -2
  56. package/dist/edge/docker.js +5 -4
  57. package/dist/edge/events/hub.js +5 -5
  58. package/dist/edge/http/actions.js +4 -25
  59. package/dist/edge/http/actor.js +5 -3
  60. package/dist/edge/http/app.js +85 -10
  61. package/dist/edge/http/assistant.js +127 -0
  62. package/dist/edge/http/audio-preview.js +4 -11
  63. package/dist/edge/http/auditions.js +1 -1
  64. package/dist/edge/http/autostart.js +5 -5
  65. package/dist/edge/http/backups.js +1 -3
  66. package/dist/edge/http/channel-memory.js +7 -20
  67. package/dist/edge/http/channels.js +13 -26
  68. package/dist/edge/http/checkpoints.js +33 -17
  69. package/dist/edge/http/design-templates.js +167 -0
  70. package/dist/edge/http/designs.js +178 -0
  71. package/dist/edge/http/diagnostics.js +5 -1
  72. package/dist/edge/http/document-themes.js +2 -11
  73. package/dist/edge/http/draft-files.js +1 -3
  74. package/dist/edge/http/draft-problem.js +4 -9
  75. package/dist/edge/http/drafts.js +3 -3
  76. package/dist/edge/http/entries.js +6 -9
  77. package/dist/edge/http/extension-auth.js +27 -0
  78. package/dist/edge/http/external-reviews.js +12 -11
  79. package/dist/edge/http/files.js +5 -11
  80. package/dist/edge/http/folder-location.js +1 -4
  81. package/dist/edge/http/fonts.js +0 -7
  82. package/dist/edge/http/home.js +38 -13
  83. package/dist/edge/http/host-cli.js +18 -8
  84. package/dist/edge/http/ids.js +8 -0
  85. package/dist/edge/http/keywords.js +35 -0
  86. package/dist/edge/http/model-checks.js +132 -0
  87. package/dist/edge/http/narration-peaks.js +5 -13
  88. package/dist/edge/http/onboarding.js +1 -14
  89. package/dist/edge/http/open-folder.js +5 -10
  90. package/dist/edge/http/outputs.js +4 -12
  91. package/dist/edge/http/patch-notes.js +4 -10
  92. package/dist/edge/http/planning.js +2 -6
  93. package/dist/edge/http/problem.js +2 -4
  94. package/dist/edge/http/project-create.js +1 -0
  95. package/dist/edge/http/project-templates.js +29 -17
  96. package/dist/edge/http/projects.js +2 -12
  97. package/dist/edge/http/prompts.js +7 -14
  98. package/dist/edge/http/pronunciations.js +1 -2
  99. package/dist/edge/http/providers.js +39 -24
  100. package/dist/edge/http/refusal.js +29 -0
  101. package/dist/edge/http/remote-access.js +40 -0
  102. package/dist/edge/http/remote-guard.js +71 -0
  103. package/dist/edge/http/request-guard.js +91 -0
  104. package/dist/edge/http/reviews.js +11 -24
  105. package/dist/edge/http/revision-files.js +5 -10
  106. package/dist/edge/http/revisions.js +10 -15
  107. package/dist/edge/http/run-cost.js +1 -2
  108. package/dist/edge/http/same-page.js +80 -0
  109. package/dist/edge/http/schedules.js +59 -32
  110. package/dist/edge/http/settings.js +22 -13
  111. package/dist/edge/http/social.js +282 -0
  112. package/dist/edge/http/staging.js +2 -4
  113. package/dist/edge/http/storage-files.js +5 -7
  114. package/dist/edge/http/storage.js +23 -23
  115. package/dist/edge/http/studio.js +23 -50
  116. package/dist/edge/http/style-preview.js +1 -4
  117. package/dist/edge/http/subtitles.js +3 -17
  118. package/dist/edge/http/template-studio.js +433 -0
  119. package/dist/edge/http/trash.js +10 -11
  120. package/dist/edge/http/tutorial.js +1 -2
  121. package/dist/edge/http/tutorials.js +5 -11
  122. package/dist/edge/http/update.js +7 -13
  123. package/dist/edge/http/waveform.js +3 -6
  124. package/dist/edge/http/youtube-edits.js +2 -3
  125. package/dist/edge/mcp/assistant.js +279 -0
  126. package/dist/edge/mcp/attribution.js +8 -2
  127. package/dist/edge/mcp/call-route.js +11 -2
  128. package/dist/edge/mcp/excluded-routes.js +25 -0
  129. package/dist/edge/mcp/http.js +11 -2
  130. package/dist/edge/mcp/instructions.js +5 -3
  131. package/dist/edge/mcp/library-tools.js +1 -0
  132. package/dist/edge/mcp/route-tool.js +35 -15
  133. package/dist/edge/mcp/server.js +13 -8
  134. package/dist/edge/mcp/tools-channels.js +2 -0
  135. package/dist/edge/mcp/tools-designs.js +165 -0
  136. package/dist/edge/mcp/tools-library.js +14 -2
  137. package/dist/edge/mcp/tools-planning.js +23 -4
  138. package/dist/edge/mcp/tools-projects.js +28 -1
  139. package/dist/edge/mcp/tools-runs.js +14 -1
  140. package/dist/edge/mcp/tools-schedules.js +28 -4
  141. package/dist/edge/mcp/tools-setup.js +61 -3
  142. package/dist/edge/mcp/tools-social.js +46 -0
  143. package/dist/edge/mcp/tools-storage.js +8 -0
  144. package/dist/edge/mcp/tools-template-studio.js +166 -0
  145. package/dist/edge/mcp/tools.js +6 -0
  146. package/dist/edge/remote-access/cli.js +71 -0
  147. package/dist/edge/remote-access/model.js +32 -0
  148. package/dist/edge/remote-access/rules.js +207 -0
  149. package/dist/edge/remote-access/service.js +203 -0
  150. package/dist/edge/remote-access/store.js +44 -0
  151. package/dist/edge/remote-access/views.js +43 -0
  152. package/dist/extension/slopify-studio-chrome.zip +0 -0
  153. package/dist/extension/slopify-studio-firefox.zip +0 -0
  154. package/dist/host-cli/install.js +2 -2
  155. package/dist/host-cli/open-folder.js +2 -2
  156. package/dist/host-cli/paths.js +2 -4
  157. package/dist/host-cli/server.js +4 -4
  158. package/dist/host-cli/service.js +3 -3
  159. package/dist/host-cli/status.js +7 -7
  160. package/dist/kernel/db/migrations/0063-model-checks.sql +20 -0
  161. package/dist/kernel/db/migrations/0064-template-studio.sql +46 -0
  162. package/dist/kernel/db/migrations/0065-promise-and-assistant-reviews.sql +58 -0
  163. package/dist/kernel/db/migrations/0066-assistant.sql +44 -0
  164. package/dist/kernel/db/migrations/0067-autopilot.sql +6 -0
  165. package/dist/kernel/db/migrations/0068-topic-scores.sql +17 -0
  166. package/dist/kernel/db/migrations/0070-designs.sql +53 -0
  167. package/dist/kernel/db/migrations/0071-design-usage.sql +33 -0
  168. package/dist/kernel/db/migrations/0072-design-templates.sql +33 -0
  169. package/dist/kernel/db/migrations/0073-schedule-design-kind.sql +5 -0
  170. package/dist/kernel/db/migrations/0074-template-bakeoffs.sql +44 -0
  171. package/dist/kernel/db/migrations/0075-social-posts.sql +25 -0
  172. package/dist/kernel/db/migrations/0076-channel-social.sql +5 -0
  173. package/dist/kernel/db/migrations/0077-post-prompts.sql +17 -0
  174. package/dist/kernel/db/tx.js +2 -4
  175. package/dist/kernel/errors.js +27 -1
  176. package/dist/kernel/json-answer.js +15 -0
  177. package/dist/kernel/lock.js +4 -9
  178. package/dist/kernel/paths.js +8 -0
  179. package/dist/kernel/ports/assistant-cli.js +4 -0
  180. package/dist/kernel/ports/host-cli.js +3 -0
  181. package/dist/kernel/ports/interest.js +4 -0
  182. package/dist/kernel/ports/languages.js +0 -3
  183. package/dist/kernel/ports/model.js +2 -0
  184. package/dist/kernel/runner/attempt.js +3 -1
  185. package/dist/kernel/runner/audition.js +3 -1
  186. package/dist/kernel/runner/checkpoint-authority.js +2 -1
  187. package/dist/kernel/runner/index.js +8 -10
  188. package/dist/kernel/runner/model-access.js +40 -0
  189. package/dist/kernel/runner/model-check.js +153 -0
  190. package/dist/kernel/runner/providers.js +15 -10
  191. package/dist/kernel/runner/standalone.js +9 -5
  192. package/dist/main.js +334 -19
  193. package/dist/model-checks.js +166 -0
  194. package/dist/patch-notes/3.25.9.md +5 -0
  195. package/dist/patch-notes/4.0.0.md +51 -0
  196. package/dist/patch-notes/index.json +12 -0
  197. package/dist/slices/admission/heads.js +2 -1
  198. package/dist/slices/admission/repo.js +2 -1
  199. package/dist/slices/admission/rules.js +43 -8
  200. package/dist/slices/admission/schema.js +8 -0
  201. package/dist/slices/admission/stage-writes.js +0 -3
  202. package/dist/slices/admission/start.js +48 -31
  203. package/dist/slices/admission/substitute.js +7 -4
  204. package/dist/slices/agents/attention-posts.js +31 -0
  205. package/dist/slices/agents/attention-templates.js +33 -0
  206. package/dist/slices/agents/attention.js +10 -1
  207. package/dist/slices/agents/connection.js +2 -6
  208. package/dist/slices/agents/model.js +6 -3
  209. package/dist/slices/agents/repo.js +15 -7
  210. package/dist/slices/article/continuation.js +0 -63
  211. package/dist/slices/article/plain.js +3 -2
  212. package/dist/slices/article/segments.js +2 -62
  213. package/dist/slices/assistant/access.js +1 -0
  214. package/dist/slices/assistant/asks.js +80 -0
  215. package/dist/slices/assistant/cost.js +54 -0
  216. package/dist/slices/assistant/gate.js +222 -0
  217. package/dist/slices/assistant/model.js +79 -0
  218. package/dist/slices/assistant/names.js +23 -0
  219. package/dist/slices/assistant/prompt.js +74 -0
  220. package/dist/slices/assistant/repo.js +74 -0
  221. package/dist/slices/assistant/tokens.js +18 -0
  222. package/dist/slices/assistant/turn.js +342 -0
  223. package/dist/slices/autopilot/buffer.js +76 -0
  224. package/dist/slices/autopilot/model.js +14 -0
  225. package/dist/slices/autopilot/notify.js +27 -0
  226. package/dist/slices/autopilot/repo.js +34 -0
  227. package/dist/slices/autopilot/signals.js +194 -0
  228. package/dist/slices/autopilot/warnings.js +85 -0
  229. package/dist/slices/autopilot/weekly.js +100 -0
  230. package/dist/slices/backups/files.js +2 -6
  231. package/dist/slices/backups/repo.js +3 -15
  232. package/dist/slices/backups/service.js +4 -3
  233. package/dist/slices/channels/cast-images.js +2 -1
  234. package/dist/slices/channels/model.js +0 -1
  235. package/dist/slices/channels/rebrand.js +0 -3
  236. package/dist/slices/channels/repo.js +4 -0
  237. package/dist/slices/channels/schema.js +6 -0
  238. package/dist/slices/channels/service.js +10 -0
  239. package/dist/slices/channels/videos.js +2 -14
  240. package/dist/slices/checkpoints/index.js +0 -1
  241. package/dist/slices/control/providers.js +0 -26
  242. package/dist/slices/designs/artwork.js +66 -0
  243. package/dist/slices/designs/budget.js +23 -0
  244. package/dist/slices/designs/calls.js +124 -0
  245. package/dist/slices/designs/check-context.js +38 -0
  246. package/dist/slices/designs/check-text.js +43 -0
  247. package/dist/slices/designs/fields.js +88 -0
  248. package/dist/slices/designs/frames.js +34 -0
  249. package/dist/slices/designs/gate.js +128 -0
  250. package/dist/slices/designs/layout.js +293 -0
  251. package/dist/slices/designs/model.js +35 -0
  252. package/dist/slices/designs/pdf-job.js +23 -0
  253. package/dist/slices/designs/pdf-pages.js +30 -0
  254. package/dist/slices/designs/pdf-runner.js +68 -0
  255. package/dist/slices/designs/pdf-worker.js +24 -0
  256. package/dist/slices/designs/picture-size.js +79 -0
  257. package/dist/slices/designs/pictures.js +55 -0
  258. package/dist/slices/designs/quote.js +24 -0
  259. package/dist/slices/designs/render-args.js +36 -0
  260. package/dist/slices/designs/render-input.js +59 -0
  261. package/dist/slices/designs/render.js +215 -0
  262. package/dist/slices/designs/repo.js +101 -0
  263. package/dist/slices/designs/requests.js +80 -0
  264. package/dist/slices/designs/runner.js +239 -0
  265. package/dist/slices/designs/sample-repo.js +91 -0
  266. package/dist/slices/designs/sample.js +222 -0
  267. package/dist/slices/designs/schema.js +87 -0
  268. package/dist/slices/designs/sections.js +44 -0
  269. package/dist/slices/designs/service.js +233 -0
  270. package/dist/slices/designs/steps-repo.js +102 -0
  271. package/dist/slices/designs/studio-kind.js +39 -0
  272. package/dist/slices/designs/template-checks.js +44 -0
  273. package/dist/slices/designs/template-make.js +118 -0
  274. package/dist/slices/designs/templates.js +218 -0
  275. package/dist/slices/document/fonts.js +2 -1
  276. package/dist/slices/episodes/summarize.js +5 -1
  277. package/dist/slices/estimate/index.js +45 -7
  278. package/dist/slices/fonts/catalog.js +3 -2
  279. package/dist/slices/fonts/discovery.js +3 -2
  280. package/dist/slices/fonts/files.js +2 -6
  281. package/dist/slices/fonts/index.js +0 -1
  282. package/dist/slices/fonts/sfnt.js +45 -10
  283. package/dist/slices/images/appearance.js +6 -15
  284. package/dist/slices/images/scenes.js +100 -27
  285. package/dist/slices/keywords/digest.js +84 -0
  286. package/dist/slices/keywords/facts.js +92 -0
  287. package/dist/slices/keywords/fill.js +80 -0
  288. package/dist/slices/keywords/model.js +75 -0
  289. package/dist/slices/keywords/rules.js +187 -0
  290. package/dist/slices/keywords/schema.js +28 -0
  291. package/dist/slices/keywords/specs.js +260 -0
  292. package/dist/slices/keywords/values.js +74 -0
  293. package/dist/slices/library/lint.js +29 -12
  294. package/dist/slices/library/model.js +2 -0
  295. package/dist/slices/library/photorealistic.js +4 -12
  296. package/dist/slices/library/rename.js +9 -7
  297. package/dist/slices/library/save.js +14 -10
  298. package/dist/slices/library/slots.js +37 -11
  299. package/dist/slices/library/transfer.js +2 -1
  300. package/dist/slices/library/used-by.js +25 -10
  301. package/dist/slices/loudness/loudnorm.js +51 -11
  302. package/dist/slices/model-checks/cost.js +61 -0
  303. package/dist/slices/model-checks/listing.js +124 -0
  304. package/dist/slices/model-checks/model.js +20 -0
  305. package/dist/slices/model-checks/record.js +32 -0
  306. package/dist/slices/model-checks/repo.js +120 -0
  307. package/dist/slices/model-checks/rules.js +112 -0
  308. package/dist/slices/model-checks/run.js +143 -0
  309. package/dist/slices/model-checks/service.js +198 -0
  310. package/dist/slices/model-upkeep/switch.js +70 -25
  311. package/dist/slices/model-upkeep/usage.js +26 -11
  312. package/dist/slices/narration/breaths.js +2 -1
  313. package/dist/slices/narration/clean-pieces.js +2 -1
  314. package/dist/slices/narration/concat.js +2 -1
  315. package/dist/slices/narration/peaks.js +3 -4
  316. package/dist/slices/narration/pronunciation-chunks.js +4 -3
  317. package/dist/slices/narration/pronunciation.js +3 -2
  318. package/dist/slices/narration/steering.js +4 -3
  319. package/dist/slices/notifications/notifier.js +4 -3
  320. package/dist/slices/notifications/rules.js +5 -2
  321. package/dist/slices/notifications/settings.js +4 -12
  322. package/dist/slices/notifications/subject.js +2 -1
  323. package/dist/slices/onboarding/copy.js +2 -1
  324. package/dist/slices/onboarding/first-run.js +3 -2
  325. package/dist/slices/onboarding/full-video.js +3 -2
  326. package/dist/slices/onboarding/install.js +4 -3
  327. package/dist/slices/onboarding/model.js +0 -16
  328. package/dist/slices/onboarding/packs.js +22 -22
  329. package/dist/slices/onboarding/quick-short.js +2 -1
  330. package/dist/slices/onboarding/sample.js +0 -1
  331. package/dist/slices/onboarding/state.js +2 -11
  332. package/dist/slices/onboarding/template.js +2 -1
  333. package/dist/slices/patch-notes/library.js +3 -2
  334. package/dist/slices/play-drafts/convert.js +4 -0
  335. package/dist/slices/play-drafts/review-inputs.js +8 -2
  336. package/dist/slices/play-drafts/review.js +5 -4
  337. package/dist/slices/play-drafts/schema.js +4 -0
  338. package/dist/slices/project-templates/from-project.js +9 -2
  339. package/dist/slices/project-templates/repo.js +6 -1
  340. package/dist/slices/project-templates/setup.js +8 -0
  341. package/dist/slices/project-templates/stand-ins.js +22 -0
  342. package/dist/slices/rebuild/activity.js +2 -0
  343. package/dist/slices/rebuild/admission-repo.js +3 -2
  344. package/dist/slices/rebuild/narration-history.js +4 -5
  345. package/dist/slices/rebuild/narration-retry.js +2 -1
  346. package/dist/slices/rebuild/preview-details.js +27 -9
  347. package/dist/slices/rebuild/preview-plan.js +3 -8
  348. package/dist/slices/rebuild/recipe-build.js +8 -3
  349. package/dist/slices/rebuild/recipe-describe.js +3 -3
  350. package/dist/slices/rebuild/recipe-digest.js +58 -0
  351. package/dist/slices/rebuild/recipe-input-schema.js +10 -0
  352. package/dist/slices/rebuild/recipe-keywords.js +71 -0
  353. package/dist/slices/rebuild/recipe-legacy.js +5 -1
  354. package/dist/slices/rebuild/recipe-model.js +4 -0
  355. package/dist/slices/rebuild/recipe-narration-text.js +2 -1
  356. package/dist/slices/rebuild/recipe-preparation.js +3 -3
  357. package/dist/slices/rebuild/recipe-reference.js +8 -4
  358. package/dist/slices/rebuild/recipe-reviews.js +27 -7
  359. package/dist/slices/rebuild/recipe-save.js +6 -3
  360. package/dist/slices/rebuild/recipe-scenes.js +40 -11
  361. package/dist/slices/rebuild/recipe-shorts.js +8 -8
  362. package/dist/slices/rebuild/recipe-social.js +46 -0
  363. package/dist/slices/rebuild/recipe-text.js +64 -20
  364. package/dist/slices/rebuild/recipe-validation.js +98 -28
  365. package/dist/slices/rebuild/recipe-visual.js +55 -16
  366. package/dist/slices/rebuild/recipe-work.js +15 -3
  367. package/dist/slices/rebuild/recipe-youtube.js +4 -3
  368. package/dist/slices/rebuild/recovery-selection.js +3 -1
  369. package/dist/slices/rebuild/recovery.js +3 -2
  370. package/dist/slices/rebuild/repo.js +4 -3
  371. package/dist/slices/rebuild/review-promise.js +25 -0
  372. package/dist/slices/rebuild/review-redo.js +2 -1
  373. package/dist/slices/rebuild/runtime-admission.js +4 -3
  374. package/dist/slices/rebuild/runtime-agent-review.js +11 -5
  375. package/dist/slices/rebuild/runtime-animate.js +9 -8
  376. package/dist/slices/rebuild/runtime-article.js +3 -2
  377. package/dist/slices/rebuild/runtime-checkpoints.js +5 -4
  378. package/dist/slices/rebuild/runtime-document.js +8 -11
  379. package/dist/slices/rebuild/runtime-export-bed.js +6 -11
  380. package/dist/slices/rebuild/runtime-export-edit.js +6 -15
  381. package/dist/slices/rebuild/runtime-export-inputs.js +7 -7
  382. package/dist/slices/rebuild/runtime-export-short.js +8 -4
  383. package/dist/slices/rebuild/runtime-export.js +34 -12
  384. package/dist/slices/rebuild/runtime-figure-card.js +2 -1
  385. package/dist/slices/rebuild/runtime-image.js +4 -9
  386. package/dist/slices/rebuild/runtime-instructions.js +2 -0
  387. package/dist/slices/rebuild/runtime-keywords.js +59 -0
  388. package/dist/slices/rebuild/runtime-lines.js +2 -11
  389. package/dist/slices/rebuild/runtime-local.js +14 -20
  390. package/dist/slices/rebuild/runtime-narration-publication.js +2 -5
  391. package/dist/slices/rebuild/runtime-narration-reuse.js +9 -13
  392. package/dist/slices/rebuild/runtime-narration-text.js +10 -15
  393. package/dist/slices/rebuild/runtime-pictures.js +2 -4
  394. package/dist/slices/rebuild/runtime-piece-label.js +10 -6
  395. package/dist/slices/rebuild/runtime-plan.js +31 -5
  396. package/dist/slices/rebuild/runtime-provider.js +60 -19
  397. package/dist/slices/rebuild/runtime-publication.js +10 -9
  398. package/dist/slices/rebuild/runtime-review.js +33 -28
  399. package/dist/slices/rebuild/runtime-run.js +4 -1
  400. package/dist/slices/rebuild/runtime-shorts.js +34 -50
  401. package/dist/slices/rebuild/runtime-store.js +3 -8
  402. package/dist/slices/rebuild/runtime-subtitles.js +16 -14
  403. package/dist/slices/rebuild/runtime-voices.js +8 -15
  404. package/dist/slices/rebuild/runtime-youtube.js +11 -29
  405. package/dist/slices/rebuild/transition-repo.js +6 -5
  406. package/dist/slices/rebuild/work-records.js +6 -0
  407. package/dist/slices/reruns/cascade.js +1 -2
  408. package/dist/slices/reruns/index.js +6 -9
  409. package/dist/slices/reviews/external-model.js +3 -0
  410. package/dist/slices/reviews/external-repo.js +2 -1
  411. package/dist/slices/reviews/external-rows.js +2 -3
  412. package/dist/slices/reviews/model.js +26 -8
  413. package/dist/slices/reviews/repo.js +2 -1
  414. package/dist/slices/reviews/rules.js +1 -0
  415. package/dist/slices/reviews/view.js +5 -2
  416. package/dist/slices/revisions/downloads.js +4 -5
  417. package/dist/slices/revisions/mutation-assets.js +7 -4
  418. package/dist/slices/revisions/mutation-cues.js +2 -5
  419. package/dist/slices/revisions/mutations.js +0 -1
  420. package/dist/slices/revisions/repo.js +3 -1
  421. package/dist/slices/revisions/schema.js +1 -0
  422. package/dist/slices/revisions/view.js +20 -0
  423. package/dist/slices/run-cost/limits.js +5 -2
  424. package/dist/slices/run-cost/meter.js +12 -5
  425. package/dist/slices/run-cost/panel.js +8 -74
  426. package/dist/slices/run-cost/plan-readings.js +127 -0
  427. package/dist/slices/run-cost/plan-use.js +169 -0
  428. package/dist/slices/run-cost/pricing.js +3 -3
  429. package/dist/slices/run-cost/week.js +32 -4
  430. package/dist/slices/schedules/agenda.js +11 -2
  431. package/dist/slices/schedules/by-date.js +42 -0
  432. package/dist/slices/schedules/calendar.js +5 -0
  433. package/dist/slices/schedules/design-agenda.js +36 -0
  434. package/dist/slices/schedules/design-check.js +41 -0
  435. package/dist/slices/schedules/design-run.js +126 -0
  436. package/dist/slices/schedules/next-run.js +62 -0
  437. package/dist/slices/schedules/prepare.js +18 -2
  438. package/dist/slices/schedules/repo.js +24 -16
  439. package/dist/slices/schedules/rescore.js +35 -0
  440. package/dist/slices/schedules/scheduler.js +13 -3
  441. package/dist/slices/schedules/schema.js +54 -3
  442. package/dist/slices/schedules/score.js +107 -0
  443. package/dist/slices/schedules/service.js +57 -24
  444. package/dist/slices/schedules/topic-list.js +15 -0
  445. package/dist/slices/schedules/topic-scores.js +104 -0
  446. package/dist/slices/schedules/topics.js +48 -36
  447. package/dist/slices/settings/cli-paths.js +4 -6
  448. package/dist/slices/settings/first-run.js +2 -11
  449. package/dist/slices/settings/model-reach.js +3 -17
  450. package/dist/slices/settings/model.js +10 -0
  451. package/dist/slices/settings/playback.js +33 -22
  452. package/dist/slices/settings/probe-read.js +16 -0
  453. package/dist/slices/settings/repo.js +33 -0
  454. package/dist/slices/settings/tutorial.js +2 -2
  455. package/dist/slices/settings/voices.js +4 -12
  456. package/dist/slices/shorts/pick.js +2 -15
  457. package/dist/slices/shorts/prompts.js +2 -13
  458. package/dist/slices/shorts/render.js +3 -0
  459. package/dist/slices/social/channel.js +44 -0
  460. package/dist/slices/social/defaults.js +17 -0
  461. package/dist/slices/social/due.js +36 -0
  462. package/dist/slices/social/extension.js +18 -0
  463. package/dist/slices/social/fit.js +115 -0
  464. package/dist/slices/social/limits.js +186 -0
  465. package/dist/slices/social/links.js +21 -0
  466. package/dist/slices/social/media.js +131 -0
  467. package/dist/slices/social/model.js +75 -0
  468. package/dist/slices/social/notice.js +19 -0
  469. package/dist/slices/social/pack.js +176 -0
  470. package/dist/slices/social/post-prompt.js +55 -0
  471. package/dist/slices/social/queue.js +31 -0
  472. package/dist/slices/social/repo.js +133 -0
  473. package/dist/slices/social/reshape.js +97 -0
  474. package/dist/slices/social/rules.js +5 -0
  475. package/dist/slices/social/schema.js +70 -0
  476. package/dist/slices/social/serve.js +51 -0
  477. package/dist/slices/social/service.js +128 -0
  478. package/dist/slices/social/settings.js +21 -0
  479. package/dist/slices/social/sources.js +114 -0
  480. package/dist/slices/social/state.js +110 -0
  481. package/dist/slices/social/text.js +149 -0
  482. package/dist/slices/storage/arrange.js +3 -1
  483. package/dist/slices/storage/assets.js +8 -10
  484. package/dist/slices/storage/backup-designs.js +74 -0
  485. package/dist/slices/storage/backup-export.js +8 -3
  486. package/dist/slices/storage/backup-format.js +10 -0
  487. package/dist/slices/storage/backup-import.js +20 -2
  488. package/dist/slices/storage/delete-project.js +6 -5
  489. package/dist/slices/storage/files-location.js +6 -8
  490. package/dist/slices/storage/layout.js +13 -2
  491. package/dist/slices/storage/model.js +3 -0
  492. package/dist/slices/storage/portable.js +16 -11
  493. package/dist/slices/storage/schema.js +2 -0
  494. package/dist/slices/storage/staging-refs.js +2 -1
  495. package/dist/slices/storage/staging.js +6 -9
  496. package/dist/slices/storage/trim.js +10 -3
  497. package/dist/slices/studio/calendar.js +4 -1
  498. package/dist/slices/studio/pick.js +2 -11
  499. package/dist/slices/studio/plan.js +6 -15
  500. package/dist/slices/studio/queue.js +3 -14
  501. package/dist/slices/studio/releases.js +26 -0
  502. package/dist/slices/studio/settings.js +14 -51
  503. package/dist/slices/studio/videos.js +12 -0
  504. package/dist/slices/style-preview/render.js +34 -13
  505. package/dist/slices/style-preview/schema.js +13 -0
  506. package/dist/slices/style-preview/service.js +2 -1
  507. package/dist/slices/style-preview/settings.js +33 -5
  508. package/dist/slices/telemetry/collector-client.js +2 -4
  509. package/dist/slices/telemetry/flush.js +2 -4
  510. package/dist/slices/telemetry/model.js +0 -7
  511. package/dist/slices/telemetry/record.js +10 -3
  512. package/dist/slices/template-studio/anatomy-view.js +118 -0
  513. package/dist/slices/template-studio/anatomy.js +73 -0
  514. package/dist/slices/template-studio/bakeoff-make.js +225 -0
  515. package/dist/slices/template-studio/bakeoff-repo.js +83 -0
  516. package/dist/slices/template-studio/bakeoff.js +333 -0
  517. package/dist/slices/template-studio/budget.js +103 -0
  518. package/dist/slices/template-studio/checks.js +273 -0
  519. package/dist/slices/template-studio/document-sample.js +56 -0
  520. package/dist/slices/template-studio/edit.js +15 -0
  521. package/dist/slices/template-studio/for-all.js +161 -0
  522. package/dist/slices/template-studio/free-video.js +31 -0
  523. package/dist/slices/template-studio/free.js +176 -0
  524. package/dist/slices/template-studio/gate.js +40 -0
  525. package/dist/slices/template-studio/hidden.js +20 -0
  526. package/dist/slices/template-studio/jobs.js +79 -0
  527. package/dist/slices/template-studio/loudness.js +111 -0
  528. package/dist/slices/template-studio/make.js +40 -0
  529. package/dist/slices/template-studio/model.js +54 -0
  530. package/dist/slices/template-studio/pack-import.js +253 -0
  531. package/dist/slices/template-studio/pack-samples.js +60 -0
  532. package/dist/slices/template-studio/pack.js +205 -0
  533. package/dist/slices/template-studio/paid-view.js +66 -0
  534. package/dist/slices/template-studio/paid.js +348 -0
  535. package/dist/slices/template-studio/quote.js +148 -0
  536. package/dist/slices/template-studio/ready.js +104 -0
  537. package/dist/slices/template-studio/repo.js +134 -0
  538. package/dist/slices/template-studio/reviews-path.js +58 -0
  539. package/dist/slices/template-studio/runner.js +84 -0
  540. package/dist/slices/template-studio/save.js +236 -0
  541. package/dist/slices/template-studio/say-it-as.js +248 -0
  542. package/dist/slices/template-studio/schedule-gate.js +34 -0
  543. package/dist/slices/template-studio/schedule-price.js +30 -0
  544. package/dist/slices/template-studio/schedule-sample.js +87 -0
  545. package/dist/slices/template-studio/schema.js +218 -0
  546. package/dist/slices/template-studio/scope.js +124 -0
  547. package/dist/slices/template-studio/sections.js +176 -0
  548. package/dist/slices/template-studio/service.js +173 -0
  549. package/dist/slices/template-studio/status.js +174 -0
  550. package/dist/slices/template-studio/topic.js +223 -0
  551. package/dist/slices/trash/designs.js +76 -0
  552. package/dist/slices/trash/model.js +13 -4
  553. package/dist/slices/trash/service.js +52 -2
  554. package/dist/slices/tutorials/library.js +3 -2
  555. package/dist/slices/video/ass-text.js +17 -0
  556. package/dist/slices/video/audio-export.js +2 -64
  557. package/dist/slices/video/encoding.js +160 -0
  558. package/dist/slices/video/ffmpeg.js +23 -21
  559. package/dist/slices/video/figure-card.js +1 -15
  560. package/dist/slices/video/slideshow.js +43 -18
  561. package/dist/slices/voices/palette.js +0 -3
  562. package/dist/slices/youtube/answer.js +2 -15
  563. package/dist/slices/youtube/edits-repo.js +2 -11
  564. package/dist/tutorials/Agents-MCP.md +2 -1
  565. package/dist/tutorials/Assistant.md +42 -0
  566. package/dist/tutorials/Channels.md +2 -0
  567. package/dist/tutorials/Home-and-Projects.md +19 -0
  568. package/dist/tutorials/Install.md +1 -0
  569. package/dist/tutorials/Keywords-Slopify-Fills.md +87 -0
  570. package/dist/tutorials/Models.md +33 -1
  571. package/dist/tutorials/Notifications.md +6 -0
  572. package/dist/tutorials/Play-Images.md +4 -0
  573. package/dist/tutorials/Posting-to-Social-Sites.md +121 -0
  574. package/dist/tutorials/Prompts.md +10 -6
  575. package/dist/tutorials/Remote-Access.md +63 -0
  576. package/dist/tutorials/Reviews-and-Checkpoints.md +13 -2
  577. package/dist/tutorials/Schedules.md +21 -1
  578. package/dist/tutorials/Settings-Reference.md +50 -8
  579. package/dist/tutorials/Template-Studio.md +125 -0
  580. package/dist/tutorials/Templates.md +3 -0
  581. package/dist/tutorials/_Sidebar.md +5 -0
  582. package/dist/updater/work-in-progress.js +42 -12
  583. package/dist/web/assets/index-CkAI_2E7.css +1 -0
  584. package/dist/web/assets/index-DcD0cdfo.js +334 -0
  585. package/dist/web/assets/{pdf-T7MCwjIv.js → pdf-TODRwF31.js} +1 -1
  586. package/dist/web/index.html +2 -2
  587. package/package.json +5 -1
  588. package/dist/slices/article/provided-entries.js +0 -66
  589. package/dist/slices/article/run.js +0 -145
  590. package/dist/slices/images/run.js +0 -234
  591. package/dist/slices/narration/legacy-plan.js +0 -58
  592. package/dist/slices/narration/run.js +0 -270
  593. package/dist/slices/rebuild/runtime-actions.js +0 -90
  594. package/dist/slices/research/run.js +0 -224
  595. package/dist/slices/subtitles/prepare.js +0 -194
  596. package/dist/slices/subtitles/transcript.js +0 -34
  597. package/dist/slices/thumbnail/run.js +0 -219
  598. package/dist/slices/video/audio-inputs.js +0 -33
  599. package/dist/slices/video/reuse-audio.js +0 -62
  600. package/dist/slices/video/run.js +0 -78
  601. package/dist/slices/video/write-export.js +0 -158
  602. package/dist/slices/video/write-subtitles.js +0 -59
  603. package/dist/web/assets/index-BadsoORk.css +0 -1
  604. package/dist/web/assets/index-D8LqNsCl.js +0 -326
@@ -1,5 +1,9 @@
1
1
  import { z } from "zod";
2
2
  import { readinessIsUsable } from "../../kernel/ports/model.js";
3
+ import { quoteBody } from "../http/auditions.js";
4
+ import { checkBody } from "../http/model-checks.js";
5
+ import { switchBody } from "../http/providers.js";
6
+ import { notificationBody } from "../http/settings.js";
3
7
  import { formBody } from "./route-tool.js";
4
8
  const readinessShape = z.discriminatedUnion("kind", [
5
9
  z.object({ kind: z.literal("keyed"), hasKey: z.boolean() }).loose(),
@@ -48,17 +52,29 @@ export function notificationUrlState(value) {
48
52
  return { notificationUrl: url === null || url.trim() === "" ? "missing" : "configured" };
49
53
  }
50
54
  const settings = [
55
+ {
56
+ name: "get_remote_access",
57
+ route: "GET /api/settings/remote-access",
58
+ title: "Read remote access",
59
+ description: "Settings → General → Remote access: whether Slopify's page is open on the person's other devices through Tailscale serve (their tailnet only, never the public internet), its https address, and any problem with the exact fix. Turning it on or off is the person's; agents can't.",
60
+ },
51
61
  {
52
62
  name: "get_settings",
53
63
  route: "GET /api/settings",
54
64
  title: "Read production defaults",
55
- description: "Settings → Production defaults: silence gap, appearance, loudness and the English subtitle timing model.",
65
+ description: "Settings → Production defaults: silence gap, appearance, loudness, the English subtitle timing model and the render settings (video encoder, clip encoding, render priority).",
56
66
  },
57
67
  {
58
68
  name: "update_settings",
59
69
  route: "PUT /api/settings",
60
70
  title: "Save production defaults",
61
- description: "Body: {silenceGapSeconds, appearance: system | light | dark, loudness?: {enabled, videoLufs, audioFilesLufs}, subtitleModel?: fp32 | fp16 | int8}. subtitleModel is this computer's English caption-timing model (fp32 378 MB most accurate, the default; fp16 189 MB; int8 95 MB, less accurate); it never marks subtitles outdated.",
71
+ description: "Body: {silenceGapSeconds, appearance: system | light | dark, loudness?: {enabled, videoLufs, audioFilesLufs}, subtitleModel?: fp32 | fp16 | int8, videoEncoder?: cpu | nvidia, clipEncodeSpeed?: thorough | fast, renderPriority?: normal | background}. subtitleModel is this computer's English caption-timing model (fp32 378 MB most accurate, the default; fp16 189 MB; int8 95 MB, less accurate). videoEncoder nvidia encodes on the NVIDIA card (check get_video_encoders first; a render falls back to the processor when it does not work); clipEncodeSpeed fast encodes the clips under burned-in captions with x264 veryfast; renderPriority background runs renders below normal priority. None of these marks anything outdated.",
72
+ },
73
+ {
74
+ name: "get_video_encoders",
75
+ route: "GET /api/settings/encoders",
76
+ title: "Check the NVIDIA encoder",
77
+ description: "Settings → Production defaults → Video encoder: whether this computer's NVIDIA encoder (NVENC) works, and why not when it does not. The first check runs a tiny test encode.",
62
78
  },
63
79
  {
64
80
  name: "get_default_channel_links",
@@ -82,6 +98,7 @@ const settings = [
82
98
  {
83
99
  name: "set_notification_url",
84
100
  route: "PUT /api/settings/notifications",
101
+ body: notificationBody,
85
102
  title: "Save the Notification URL",
86
103
  description: "Body: {url: an http(s) address, or empty to stop}. Answers configured or missing, never the address.",
87
104
  shape: notificationUrlState,
@@ -128,6 +145,7 @@ const settings = [
128
145
  {
129
146
  name: "quote_voice_sample",
130
147
  route: "POST /api/auditions/quote",
148
+ body: quoteBody,
131
149
  title: "Price a voice sample",
132
150
  description: "Try a sample's price, as Play shows it before playing one. Body: {lines: [{speaker, provider, model, text}]}.",
133
151
  unrecorded: true,
@@ -176,7 +194,46 @@ const providers = [
176
194
  name: "list_models",
177
195
  route: "GET /api/providers/:id/models",
178
196
  title: "List a provider's models",
179
- description: "The models Slopify offers for the provider, with prices where known.",
197
+ description: "The models Slopify offers for the provider, with prices where known, and each model's standing for the saved key or CLI under standings: works (a check or a run succeeded), listed (the key's own model list names it), known (only Slopify's model list does), no-access (the provider said it is not on the plan, with its sentence), and retiring with its replacement when one is due. Standings never stop a run: a model chosen anywhere keeps working as before.",
198
+ },
199
+ {
200
+ name: "get_model_checks",
201
+ route: "GET /api/model-checks",
202
+ title: "Read Settings → Models' model checks",
203
+ description: "Per provider: when its models were last checked, how many work, are listed or are not on the plan, whether a check is running and what checks have cost; the New for you list; and whether automatic checks are free-only or off.",
204
+ },
205
+ {
206
+ name: "estimate_model_checks",
207
+ route: "GET /api/providers/:id/models/check/estimate",
208
+ title: "Estimate checking a provider's models",
209
+ description: "What Check models in Settings → Models would check for this provider and what it costs at list price, before anything is sent. Query: models (optional, comma-separated ids).",
210
+ },
211
+ {
212
+ name: "check_models",
213
+ route: "POST /api/providers/:id/models/check",
214
+ body: checkBody,
215
+ title: "Check a provider's models",
216
+ description: "Settings → Models' Check models: sends each model the smallest request (one word, a spoken Hi, one small image) to learn whether it works for the saved key or CLI, in the background. A check that costs money is refused with its estimate until the body carries confirmedDollars of at least the estimate's totalDollars (read estimate_model_checks first). Body: {models?: [ids], confirmedDollars?: number}.",
217
+ confirm: "Each model checked is sent one small paid request at list price (a CLI's checks use its plan's allowance instead).",
218
+ confirmFrom: {
219
+ route: "/api/providers/:id/models/check/estimate",
220
+ text: (value) => {
221
+ const estimate = z
222
+ .object({ count: z.number(), text: z.string(), planAccounts: z.array(z.string()) })
223
+ .safeParse(value);
224
+ if (!estimate.success)
225
+ return undefined;
226
+ const { count, text, planAccounts } = estimate.data;
227
+ return `Checks ${String(count)} model${count === 1 ? "" : "s"}, one small request each: ${text} at list price${planAccounts.length > 0 ? ", using the CLI plan's allowance" : ""}.`;
228
+ },
229
+ },
230
+ reachesOut: "asks",
231
+ },
232
+ {
233
+ name: "dismiss_model_notices",
234
+ route: "POST /api/model-checks/notices/dismiss",
235
+ title: "Dismiss New for you models",
236
+ description: "Settings → Models' Dismiss on New for you. Body: {keys: [{provider, family, model}]} as get_model_checks lists them.",
180
237
  },
181
238
  {
182
239
  name: "list_system_voices",
@@ -221,6 +278,7 @@ const providers = [
221
278
  {
222
279
  name: "switch_retired_model",
223
280
  route: "POST /api/providers/catalogue/retired/switch",
281
+ body: switchBody,
224
282
  title: "Switch a retired model",
225
283
  description: formBody("Settings → Models' Switch"),
226
284
  },
@@ -0,0 +1,46 @@
1
+ import { choiceBody, linkBody, redditBody, textBody } from "../../slices/social/schema.js";
2
+ // A project's posts to X, LinkedIn, Instagram, TikTok, Reddit and Bluesky, as Prepare upload
3
+ // shows them. Agents prepare them; Fill in <site> and posting are the person's.
4
+ export const socialTools = [
5
+ {
6
+ name: "get_post_packs",
7
+ route: "GET /api/social/packs/:projectId",
8
+ title: "Read the posts for other sites",
9
+ description: "Prepare upload's posts: for each site the project posts to, the text as it goes in (with its count and limit), hashtags, link, media, AI label, when it goes out, warnings and where the post stands. The agent's work ends here: filling a site's form and posting are the person's.",
10
+ },
11
+ {
12
+ name: "set_post_choice",
13
+ route: "PUT /api/social/packs/:projectId/:platform/choice",
14
+ title: "Change what a post carries",
15
+ description: "The project's own settings for one site (platform: x, linkedin, instagram, tiktok, reddit or bluesky): its text source, media, hashtags and link; {off: true} to not post there; null to go back to the template's. A post prompt (text \"prompt\") is a paid step picked only in the template (Template Studio → Upload pack) or on Play, where Save shows its cost. Body: {choice}.",
16
+ body: choiceBody,
17
+ },
18
+ {
19
+ name: "edit_post_text",
20
+ route: "PUT /api/social/packs/:projectId/:platform/text",
21
+ title: "Edit a post's text",
22
+ description: "Hand-edits one site's post text. Body: {text: the new text, base: the text you edited from (get_post_packs' generated)}.",
23
+ body: textBody,
24
+ },
25
+ {
26
+ name: "reset_post_text",
27
+ route: "DELETE /api/social/packs/:projectId/:platform/text",
28
+ title: "Drop a post's hand edit",
29
+ description: "Drops the hand edit of one site's post; the written text comes back.",
30
+ confirm: "This drops your hand edit of this post for good; the text Slopify wrote comes back.",
31
+ },
32
+ {
33
+ name: "set_reddit_post",
34
+ route: "PUT /api/social/packs/:projectId/:platform/reddit",
35
+ title: "Set the Reddit post's fields",
36
+ description: "The Reddit post's subreddit (without r/), title, flair and kind (link, text or media); platform must be reddit. Body: {reddit: {subreddit, title, flair, kind}}.",
37
+ body: redditBody,
38
+ },
39
+ {
40
+ name: "set_post_link",
41
+ route: "PUT /api/social/packs/:projectId/:platform/link",
42
+ title: "Record a post's link",
43
+ description: "Marks one site's post as posted with its link (a post the person made by hand, or one the extension missed); null removes the link so the post can be filled again. Body: {url: the post's address | null}.",
44
+ body: linkBody,
45
+ },
46
+ ];
@@ -1,3 +1,6 @@
1
+ import { fullVideoInputSchema, quickShortInputSchema } from "../../slices/onboarding/model.js";
2
+ import { moveFilesBody } from "../http/storage-files.js";
3
+ import { manySchema } from "../http/trash.js";
1
4
  import { formBody } from "./route-tool.js";
2
5
  const storage = [
3
6
  {
@@ -9,6 +12,7 @@ const storage = [
9
12
  {
10
13
  name: "move_files_folder",
11
14
  route: "POST /api/storage/files/move",
15
+ body: moveFilesBody,
12
16
  title: "Move the files folder",
13
17
  description: "Body: {target: the new folder's full path; it must be empty or new}.",
14
18
  confirm: "This moves every project and backup file to the new folder; Slopify refuses a folder that is not empty.",
@@ -34,6 +38,7 @@ const storage = [
34
38
  {
35
39
  name: "restore_from_trash_many",
36
40
  route: "POST /api/trash/bulk/restore",
41
+ body: manySchema,
37
42
  title: "Restore several from the trash",
38
43
  description: "Restore for the ticked rows. Body: {items: [{kind, id}]}.",
39
44
  },
@@ -47,6 +52,7 @@ const storage = [
47
52
  {
48
53
  name: "delete_from_trash_many",
49
54
  route: "POST /api/trash/bulk/delete",
55
+ body: manySchema,
50
56
  title: "Delete several for good",
51
57
  description: "Delete now for the ticked rows. Body: {items: [{kind, id}]}.",
52
58
  confirm: "The projects and every file they produced are removed from disk (deleted schedules keep their run history on Schedules). Nothing removed here can be restored. This cannot be undone.",
@@ -68,12 +74,14 @@ const onboarding = [
68
74
  {
69
75
  name: "make_quick_short",
70
76
  route: "POST /api/onboarding/short",
77
+ body: quickShortInputSchema,
71
78
  title: "Make a quick short",
72
79
  description: `${formBody("the welcome's Make a short")} It starts a paid run.`,
73
80
  },
74
81
  {
75
82
  name: "make_full_video_draft",
76
83
  route: "POST /api/onboarding/full-video",
84
+ body: fullVideoInputSchema,
77
85
  title: "Draft a full video",
78
86
  description: formBody("the welcome's Make a full video"),
79
87
  },
@@ -0,0 +1,166 @@
1
+ import { bakeoffStartSchema } from "../../slices/template-studio/bakeoff.js";
2
+ import { studioSettingsSchema } from "../../slices/template-studio/budget.js";
3
+ import { samplesForAllSchema } from "../../slices/template-studio/for-all.js";
4
+ import { markReadySchema } from "../../slices/template-studio/ready.js";
5
+ import { makeSampleSchema, saveStudioSchema } from "../../slices/template-studio/save.js";
6
+ import { sayItAsSchema } from "../../slices/template-studio/say-it-as.js";
7
+ import { fullScriptSchema, topicSchema } from "../../slices/template-studio/topic.js";
8
+ // The template studio (Library → Templates → Open studio). Not the YouTube Studio tools.
9
+ export const templateStudioTools = [
10
+ {
11
+ name: "get_template_studio",
12
+ route: "GET /api/template-studio/:id",
13
+ title: "Read a template's studio",
14
+ description: "The template's sections with each sample's state (current, making, waiting, needs-fix, stale, off, provided), the sample topic, and which version schedules run. Its checks are read with get_template_checks.",
15
+ },
16
+ {
17
+ name: "get_template_checks",
18
+ route: "GET /api/template-studio/:id/checks",
19
+ title: "Read a template's checks",
20
+ description: "The free checks the template's current version passes before Mark ready, each failing one with what is wrong and where it is fixed: keywords filled, providers set up, a voice that is one of yours (Settings → Voices), release slots, a known monthly cost, someone to answer each checkpoint.",
21
+ },
22
+ {
23
+ name: "mark_template_ready",
24
+ route: "POST /api/template-studio/:id/ready",
25
+ body: markReadySchema,
26
+ title: "Mark a template ready for its schedules",
27
+ description: "Marks the template's newest version (pass it as version) ready, so its schedules run it from their next run on. Refused, marking nothing, while a check fails or a section's sample isn't current, with each thing to fix (problems). A version already ready is answered again. Until a template's first Mark ready its schedules run its newest version; from then on a schedule runs only a version marked ready, saved before the studio, or carried over from one by Slopify, and each version saved later waits until it is marked ready.",
28
+ confirm: "Schedules run this version from their next run, and each version saved later waits until it is marked ready.",
29
+ },
30
+ {
31
+ name: "get_prompt_anatomy",
32
+ route: "GET /api/template-studio/:id/anatomy",
33
+ title: "Read a section's prompt anatomy",
34
+ description: "One of the prompts a template section sends (section: subject, script, voice, pictures, thumbnail, shorts, upload, reviews; item: the prompt's key from items), cut into segments: the person's own words (yours), their keywords' values (keyword), what Slopify fills itself (slopify) and what settings add (setting). Read from the prompt the sample sent when it was made from this setup.",
35
+ },
36
+ {
37
+ name: "quote_template_save",
38
+ route: "POST /api/template-studio/:id/quote",
39
+ title: "Price a template Save's sample",
40
+ description: 'Prices a sample before anything is spent. Send one of: document (what a Save of this template document would make), topic (a new sample topic, "next-queued" or "fixed": every section) or fullScript (the whole script switched on or off: the script and what follows). It answers the sections it outdates, each step\'s cost, the total high estimate, how many steps have no price, and whether it fits today\'s sample budget. Changes nothing. Pass its high as acknowledgedHigh to save_template_studio.',
41
+ unrecorded: true,
42
+ },
43
+ {
44
+ name: "save_template_studio",
45
+ route: "POST /api/template-studio/:id/save",
46
+ body: saveStudioSchema,
47
+ title: "Save a template in its studio",
48
+ description: 'Saves the template document as its next version. With sample "make" it also makes the paid sample of what changed, which spends money: price it first with quote_template_save and pass that quote\'s high as acknowledgedHigh (and acknowledgedUnknown: true when the quote counts steps with no price). A higher price, an unaccepted unknown one or a sample past today\'s budget is refused with the new quote and nothing is saved. With sample "skip" only the free samples are made. Send the same mutationId to retry the very same Save.',
49
+ },
50
+ {
51
+ name: "make_template_sample",
52
+ route: "POST /api/template-studio/:id/samples/make",
53
+ body: makeSampleSchema,
54
+ title: "Make a template's paid sample again",
55
+ description: "Queues the paid sample of the template's current version again, which spends money: after it waited (a higher price, steps with no price, today's budget) or failed. Pass the version and the price get_template_studio shows for it as acknowledgedHigh, and acknowledgedUnknown: true to accept steps with no price. A sample that would cost more still waits.",
56
+ },
57
+ {
58
+ name: "set_sample_topic",
59
+ route: "PUT /api/template-studio/:id/topic",
60
+ body: topicSchema,
61
+ title: "Change a template's sample topic",
62
+ description: 'Changes the topic the template\'s samples are made about and remakes every section\'s paid sample, which spends money: a typed topic, "next-queued" for the next topic one of its schedules has queued, or "fixed" for the topic every sample starts on. Pass the price as acknowledgedHigh (and acknowledgedUnknown: true to accept steps with no price); a higher price, an unaccepted unknown one or one past today\'s budget is refused with the new quote and nothing changes.',
63
+ },
64
+ {
65
+ name: "set_sample_full_script",
66
+ route: "POST /api/template-studio/:id/full-script",
67
+ body: fullScriptSchema,
68
+ title: "Write a template sample's full script",
69
+ description: "Switches the template's sample between the whole script (fullScript: true) and the outline and first chapter (false), and remakes the script and what is made from it, which spends money. Pass the price as acknowledgedHigh; it is refused with the new quote at a higher price, unaccepted unknown prices or past today's budget.",
70
+ },
71
+ {
72
+ name: "get_sample_pronunciations",
73
+ route: "GET /api/template-studio/:id/pronunciations",
74
+ title: "Read the names a template's voice may say wrong",
75
+ description: "The names the template's sample script says that a voice may get wrong (its Pronunciation Glossary, and words Library → Narration aliases already change), each with its IPA, the first line it is said in and the alias it has (spokenAs). aliasesOn says whether the template's voice uses Library → Narration aliases.",
76
+ },
77
+ {
78
+ name: "quote_say_it_as",
79
+ route: "POST /api/template-studio/:id/say-it-as/quote",
80
+ title: "Price saying a word another way",
81
+ description: "Prices voicing again, with written said as spoken, only the template sample's lines that say it: how many lines, the high estimate, steps with no price and whether it fits today's sample budget. Changes nothing. Pass its high as acknowledgedHigh to say_it_as.",
82
+ unrecorded: true,
83
+ },
84
+ {
85
+ name: "say_it_as",
86
+ route: "POST /api/template-studio/:id/say-it-as",
87
+ body: sayItAsSchema,
88
+ title: "Say a word another way",
89
+ description: "Writes a Library → Narration aliases row (written said as spoken, whole word, any case; it replaces one for the same word) and voices again only the template sample's lines that say it, which spends money: price it first with quote_say_it_as and pass its high as acknowledgedHigh. The alias applies to every project started after it. Refused, writing nothing, at a higher price, with unaccepted unknown prices, past today's budget, or when the template's voice doesn't use aliases.",
90
+ },
91
+ {
92
+ name: "get_template_studio_settings",
93
+ route: "GET /api/template-studio/settings",
94
+ title: "Read the template studio's settings",
95
+ description: "The most the studio's samples may spend in one day (dailyBudget, US dollars), whether they may run steps on a CLI plan (samplesUsePlans; off by default, such a sample waits; it applies to designed pieces' samples too), the most designed pieces' template samples may spend in one day (designDailyBudget, $1 by default), and what each spent today and has left (today, designToday).",
96
+ },
97
+ {
98
+ name: "update_template_studio_settings",
99
+ route: "PUT /api/template-studio/settings",
100
+ body: studioSettingsSchema,
101
+ title: "Change the template studio's daily budgets",
102
+ description: "Sets any of: dailyBudget, the most the studio's samples may spend in one day, in US dollars (0 to 1000); designDailyBudget, the same for designed pieces' template samples (0 to 1000); samplesUsePlans, whether either may run steps on a Claude Code or Codex plan, which the dollar budgets can't limit. A field left out keeps what it was. A sample that would go over its budget, or needs a plan while plans are off, waits.",
103
+ },
104
+ {
105
+ name: "quote_samples_for_all",
106
+ route: "POST /api/template-studio/samples-for-all/quote",
107
+ title: "Price the samples of every template",
108
+ description: "Prices the paid sample of every template whose newest version has none (or changed since its last one), before anything is spent: each template's high estimate, whether it fits what is left of today's sample budget (spent in name order), the total and a sentence saying how many fit. Changes nothing. Pass its total as acknowledgedTotal to make_samples_for_all.",
109
+ unrecorded: true,
110
+ },
111
+ {
112
+ name: "make_samples_for_all",
113
+ route: "POST /api/template-studio/samples-for-all",
114
+ body: samplesForAllSchema,
115
+ title: "Make the samples of every template",
116
+ description: "Makes the paid sample of every template that needs one, which spends money: price them first with quote_samples_for_all and pass its total as acknowledgedTotal (and acknowledgedUnknown: true to accept steps with no price). The ones that fit today's budget are queued; the rest wait, saying so, until tomorrow or a higher budget. A higher total is refused with the new quote and nothing is queued.",
117
+ confirm: "This spends money on the samples of every template that needs one.",
118
+ },
119
+ {
120
+ name: "make_template_free_samples",
121
+ route: "POST /api/template-studio/:id/free-samples",
122
+ title: "Make a template's free samples",
123
+ description: "Queues the samples made on this computer at no cost for the template's current version: the 30-second video, the loudness before and after, the PDF, and the schedules' cost a month. Read them back with get_template_studio.",
124
+ },
125
+ {
126
+ name: "import_template_pack",
127
+ route: "POST /api/template-studio/packs/import",
128
+ title: "Import a template pack",
129
+ description: "Makes a new template from a template pack (the .zip a template studio's Export pack made, at most 30 MB): its prompts and intros join the Library (a name taken by other text comes in as \"<name> (2)\" and the template names that one), its voice is used as it is, and it is not checked in the studio yet: look its samples over and mark it ready (mark_template_ready). A pack holding anything that looks like a key, a file a pack never has or a newer format is refused, writing nothing. Answers templateId, the name it got, how many Library items it added and which were renamed, whether Settings → Voices has its voice (voiceKnown; when false, get_template_checks' voice check says what to do) and how many samples it brought.",
130
+ upload: "multipart",
131
+ },
132
+ {
133
+ name: "get_template_pack_samples",
134
+ route: "GET /api/template-studio/:id/pack-samples",
135
+ title: "List the samples a template's pack brought",
136
+ description: "The samples an imported pack came with (role: thumbnail, picture or narration; name; url), shown in the studio until the template makes its own. Empty for a template that didn't come from a pack.",
137
+ },
138
+ {
139
+ name: "quote_bakeoff",
140
+ route: "POST /api/template-studio/:id/bakeoff/quote",
141
+ title: "Price comparing models on a template's sample",
142
+ description: "Prices making one section's sample again on one or two other models (section: script, voice or pictures; models: [{provider, model}], not the model the section uses now, which is compared from the current sample; voice models only of the template's voice provider). Needs a current sample of the newest version. Answers each model's high estimate, steps with no price, the total, today's sample budget and whether it fits. Changes nothing. Pass its high as acknowledgedHigh to start_bakeoff.",
143
+ unrecorded: true,
144
+ },
145
+ {
146
+ name: "start_bakeoff",
147
+ route: "POST /api/template-studio/:id/bakeoff",
148
+ body: bakeoffStartSchema,
149
+ title: "Compare models on a template's sample",
150
+ description: "Makes the section's sample again on each model, each on a hidden copy of the template's sample with only that section's work started, which spends money: price it first with quote_bakeoff and pass its high as acknowledgedHigh (and acknowledgedUnknown: true to accept steps with no price). A higher total, an unaccepted unknown price or a total past today's budget is refused with the new quote, starting nothing. The template doesn't change: read the results with get_bakeoff, then switch the model with save_template_studio and discard the copies with discard_bakeoff.",
151
+ confirm: "This spends money making the section's sample again on each model.",
152
+ },
153
+ {
154
+ name: "get_bakeoff",
155
+ route: "GET /api/template-studio/:id/bakeoff",
156
+ title: "Read a template's model bake-off",
157
+ description: "The template's bake-off, or null: its section, the version it was made for (stale when the template was saved since), its state (queued, making, done, held with why, failed with why) and one entry per model, the one in use first (state current), each with what it was charged (cost, US dollars), how long its section took (seconds), its failure, and what it made (outputs; article: the script's opening).",
158
+ },
159
+ {
160
+ name: "discard_bakeoff",
161
+ route: "DELETE /api/template-studio/:id/bakeoff",
162
+ title: "Discard a template's model bake-off",
163
+ description: "Removes the bake-off's copies and what they made. What they were charged today still counts against the sample budget. Refused while a copy still has work going.",
164
+ confirm: "The bake-off's copies and what they made are removed.",
165
+ },
166
+ ];
@@ -1,4 +1,5 @@
1
1
  import { channelTools } from "./tools-channels.js";
2
+ import { designTools } from "./tools-designs.js";
2
3
  import { libraryTools } from "./tools-library.js";
3
4
  import { planningTools } from "./tools-planning.js";
4
5
  import { projectTools } from "./tools-projects.js";
@@ -6,16 +7,21 @@ import { publishingTools } from "./tools-publishing.js";
6
7
  import { runTools } from "./tools-runs.js";
7
8
  import { scheduleTools } from "./tools-schedules.js";
8
9
  import { setupTools } from "./tools-setup.js";
10
+ import { socialTools } from "./tools-social.js";
9
11
  import { storageTools } from "./tools-storage.js";
12
+ import { templateStudioTools } from "./tools-template-studio.js";
10
13
  // Every API route an agent may call, as a tool; `excluded-routes.ts` names the rest and why.
11
14
  export const routeTools = [
12
15
  ...projectTools,
13
16
  ...publishingTools,
17
+ ...socialTools,
14
18
  ...runTools,
15
19
  ...planningTools,
16
20
  ...scheduleTools,
17
21
  ...channelTools,
22
+ ...designTools,
18
23
  ...libraryTools,
19
24
  ...setupTools,
20
25
  ...storageTools,
26
+ ...templateStudioTools,
21
27
  ];
@@ -0,0 +1,71 @@
1
+ import { execFile } from "node:child_process";
2
+ // Every command Slopify sends. Serve only: Funnel puts an address on the public internet, and
3
+ // Slopify has no login and holds API keys, so no path through Slopify may ever reach it.
4
+ export const tailscaleCommands = {
5
+ status: () => ["status", "--json"],
6
+ serveStatus: () => ["serve", "status", "--json"],
7
+ serveOn: (httpsPort, target) => [
8
+ "serve",
9
+ "--bg",
10
+ "--yes",
11
+ `--https=${httpsPort}`,
12
+ target,
13
+ ],
14
+ serveOff: (httpsPort) => ["serve", "--yes", `--https=${httpsPort}`, "off"],
15
+ };
16
+ const allowed = new Set(["status", "serve"]);
17
+ // The last line of defence: a command that names Funnel, or isn't one of the above, never runs.
18
+ export function assertServeOnly(args) {
19
+ const [command] = args;
20
+ if (command === undefined || !allowed.has(command))
21
+ throw new Error(`Slopify only runs tailscale status and tailscale serve, not "${command}".`);
22
+ if (args.some((arg) => /funnel/iu.test(arg)))
23
+ throw new Error("Slopify never turns on Tailscale Funnel.");
24
+ }
25
+ export function guarded(run) {
26
+ return async (args) => {
27
+ assertServeOnly(args);
28
+ return run(args);
29
+ };
30
+ }
31
+ // Where the command is when it isn't on PATH: the macOS app bundle and the Windows installer.
32
+ export function tailscaleCandidates(platform) {
33
+ if (platform === "darwin")
34
+ return ["tailscale", "/Applications/Tailscale.app/Contents/MacOS/Tailscale"];
35
+ if (platform === "win32")
36
+ return ["tailscale", "C:\\Program Files\\Tailscale\\tailscale.exe"];
37
+ return ["tailscale"];
38
+ }
39
+ function execOnce(file, args, timeoutMs) {
40
+ return new Promise((resolve) => {
41
+ execFile(file, [...args], { windowsHide: true, timeout: timeoutMs, encoding: "utf8", maxBuffer: 4 * 1024 * 1024 }, (error, stdout, stderr) => {
42
+ if (error === null) {
43
+ resolve({ code: 0, stdout, stderr, missing: false, timedOut: false });
44
+ return;
45
+ }
46
+ const missing = error.code === "ENOENT";
47
+ const timedOut = error.killed === true && error.signal !== null;
48
+ resolve({
49
+ code: typeof error.code === "number" ? error.code : 1,
50
+ stdout,
51
+ stderr: stderr || error.message,
52
+ missing,
53
+ timedOut,
54
+ });
55
+ });
56
+ });
57
+ }
58
+ // ceiling: a status or serve call answers within a second on a healthy machine; a hung
59
+ // daemon must not hold a request, so each call is cut off.
60
+ export function nodeTailscaleRun(platform, timeoutMs = 10_000) {
61
+ const candidates = tailscaleCandidates(platform);
62
+ return guarded(async (args) => {
63
+ let last;
64
+ for (const file of candidates) {
65
+ last = await execOnce(file, args, timeoutMs);
66
+ if (!last.missing)
67
+ return last;
68
+ }
69
+ return last ?? { code: 127, stdout: "", stderr: "", missing: true, timedOut: false };
70
+ });
71
+ }
@@ -0,0 +1,32 @@
1
+ // What Settings → General → Remote access shows. The web client imports this file, so it stays
2
+ // free of Node imports.
3
+ export const remoteAccessStates = [
4
+ // The switch is off: Slopify answers only on this computer.
5
+ "off",
6
+ // Tailscale serves Slopify's address on the tailnet.
7
+ "on",
8
+ // Slopify runs in Docker; the switch needs Slopify started on the computer itself.
9
+ "docker",
10
+ "not-installed",
11
+ "not-running",
12
+ "signed-out",
13
+ // The tailnet has no HTTPS certificates (MagicDNS and HTTPS in the admin console).
14
+ "https-off",
15
+ // Tailscale refused this user (Linux: not the operator).
16
+ "denied",
17
+ // Another serve setting already uses the HTTPS port.
18
+ "port-taken",
19
+ // Tailscale Funnel was found on Slopify's address; Slopify removed its own setting.
20
+ "funnel",
21
+ // The switch is on, but Slopify's address isn't in Tailscale right now.
22
+ "not-applied",
23
+ "failed",
24
+ ];
25
+ export const defaultHttpsPort = 443;
26
+ // The ports Slopify offers when one is taken, in order. Any port works for Serve; these are the
27
+ // ones Tailscale's own documentation uses.
28
+ export const httpsPortChoices = [443, 8443, 10000];
29
+ // Settings rows: the switch as the person set it, and the exact serve handler Slopify added
30
+ // (removed again only when it is still exactly that).
31
+ export const remoteAccessKey = "remote-access";
32
+ export const remoteAccessAppliedKey = "remote-access.applied";