videobook 0.0.0-stage → 0.2.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 (565) hide show
  1. package/CHANGELOG.md +54 -0
  2. package/LICENSE +21 -0
  3. package/README.md +195 -2
  4. package/bin/videobook.js +7 -0
  5. package/dist/acestep/client.js +203 -0
  6. package/dist/acestep/config.js +62 -0
  7. package/dist/acestep/errors.js +8 -0
  8. package/dist/acestep/process.js +175 -0
  9. package/dist/alive-captions/analyze.js +117 -0
  10. package/dist/alive-captions/audio.js +179 -0
  11. package/dist/alive-captions/frames.js +59 -0
  12. package/dist/alive-captions/model.js +37 -0
  13. package/dist/alive-captions/schema.js +49 -0
  14. package/dist/alive-captions/track.js +9 -0
  15. package/dist/api-key.js +33 -0
  16. package/dist/app-state.js +56 -0
  17. package/dist/app.js +257 -0
  18. package/dist/archive-b2.js +332 -0
  19. package/dist/archive-store.js +169 -0
  20. package/dist/artifact-label.js +36 -0
  21. package/dist/artifact-refs.js +49 -0
  22. package/dist/asset-tag-extraction.js +169 -0
  23. package/dist/asset-tags.js +228 -0
  24. package/dist/asset-usage.js +23 -0
  25. package/dist/audio-cue.js +71 -0
  26. package/dist/audio-encoding.js +32 -0
  27. package/dist/audio-sync-request.js +1 -0
  28. package/dist/audio-sync.js +223 -0
  29. package/dist/audio-trim-range.js +31 -0
  30. package/dist/book-context.js +31 -0
  31. package/dist/book-manager.js +374 -0
  32. package/dist/catalog-gc.js +26 -0
  33. package/dist/chain-executor.js +815 -0
  34. package/dist/chain-generation.js +115 -0
  35. package/dist/chain-plan.js +746 -0
  36. package/dist/chain-step-review.js +60 -0
  37. package/dist/character-name.js +25 -0
  38. package/dist/chat-generation-routing.js +73 -0
  39. package/dist/chat-generation-settings.js +78 -0
  40. package/dist/chat-models.js +44 -0
  41. package/dist/chat-prompt-rewrite.js +67 -0
  42. package/dist/chat-router.js +628 -0
  43. package/dist/chat-view-actions.js +49 -0
  44. package/dist/cli/args.js +242 -0
  45. package/dist/cli/config-command.js +103 -0
  46. package/dist/cli/doctor-command.js +289 -0
  47. package/dist/cli/entry.js +2 -0
  48. package/dist/cli/key-report.js +16 -0
  49. package/dist/cli/main.js +104 -0
  50. package/dist/cli/mcp-command.js +88 -0
  51. package/dist/cli/mcp-relay.js +51 -0
  52. package/dist/cli/open-browser.js +14 -0
  53. package/dist/cli/run-command.js +231 -0
  54. package/dist/cli/serve-command.js +62 -0
  55. package/dist/cli/setup-command.js +60 -0
  56. package/dist/cli/stdio-guard.js +8 -0
  57. package/dist/cold-open-model.js +7 -0
  58. package/dist/cold-open.js +79 -0
  59. package/dist/command-reference.js +95 -0
  60. package/dist/content-store.js +74 -0
  61. package/dist/cost.js +8 -0
  62. package/dist/crop-geometry.js +23 -0
  63. package/dist/dancing-workflow.js +447 -0
  64. package/dist/data-home.js +44 -0
  65. package/dist/diagnostics.js +109 -0
  66. package/dist/dialog-quality.js +34 -0
  67. package/dist/downloads-dest.js +56 -0
  68. package/dist/editing-moments.js +194 -0
  69. package/dist/elevenlabs-audio-extension.js +66 -0
  70. package/dist/engine.js +54 -0
  71. package/dist/env-file.js +91 -0
  72. package/dist/env-secrets.js +148 -0
  73. package/dist/ffmpeg-binary.js +12 -0
  74. package/dist/ffmpeg.js +425 -0
  75. package/dist/ffprobe-binary.js +77 -0
  76. package/dist/forget-asset.js +216 -0
  77. package/dist/frame-utils.js +27 -0
  78. package/dist/generation-credit-error.js +11 -0
  79. package/dist/generation-input-mentions.js +117 -0
  80. package/dist/generation-input-policy.js +68 -0
  81. package/dist/generation-reference-mentions.js +97 -0
  82. package/dist/goal-characters.js +49 -0
  83. package/dist/goal-plan-v3.js +273 -0
  84. package/dist/goal-plan.js +220 -0
  85. package/dist/goal-planner-prompt.js +28 -0
  86. package/dist/goal-prompt-budget.js +4 -0
  87. package/dist/goal-reference-images.js +25 -0
  88. package/dist/goal-state.js +261 -0
  89. package/dist/goal-stills.js +153 -0
  90. package/dist/goal-store.js +144 -0
  91. package/dist/goal-styles.js +144 -0
  92. package/dist/goal-v3-runtime.js +157 -0
  93. package/dist/guides/character_schema_guide.md +70 -0
  94. package/dist/guides/gpt_image_2_5_prompting_guide.md +21 -0
  95. package/dist/guides/grok_imagine_prompting_guide.md +72 -0
  96. package/dist/guides/image_reproduction_guide.md +84 -0
  97. package/dist/guides/kling_3_0_prompting_guide.md +136 -0
  98. package/dist/guides/nano_banana_pro_prompting_guide.md +28 -0
  99. package/dist/guides/seedance_2_prompting_guide.md +172 -0
  100. package/dist/http-access.js +49 -0
  101. package/dist/http-byte-range.js +31 -0
  102. package/dist/hydration.js +56 -0
  103. package/dist/image-compress.js +77 -0
  104. package/dist/image-edit-default.js +1 -0
  105. package/dist/image-edit-models.js +41 -0
  106. package/dist/image-edit-settings.js +11 -0
  107. package/dist/image-region-edit.js +32 -0
  108. package/dist/image-subject-map.js +523 -0
  109. package/dist/image.js +46 -0
  110. package/dist/index.js +12 -0
  111. package/dist/job-deadline.js +60 -0
  112. package/dist/jobs/_alibaba-upload.js +30 -0
  113. package/dist/jobs/_audio-chunks.js +31 -0
  114. package/dist/jobs/_download-into-asset.js +15 -0
  115. package/dist/jobs/_fal-shared.js +22 -0
  116. package/dist/jobs/_fal-upload.js +35 -0
  117. package/dist/jobs/_image-edit-adapter.js +213 -0
  118. package/dist/jobs/_kie-poll.js +119 -0
  119. package/dist/jobs/_kie-upload.js +32 -0
  120. package/dist/jobs/_lease.js +163 -0
  121. package/dist/jobs/_persist-output.js +19 -0
  122. package/dist/jobs/_storage-retry.js +21 -0
  123. package/dist/jobs/_transcribe.js +245 -0
  124. package/dist/jobs/_translate-transcript.js +270 -0
  125. package/dist/jobs/analyze-alive-captions.js +10 -0
  126. package/dist/jobs/analyze-editing-moments.js +104 -0
  127. package/dist/jobs/analyze-jokes.js +143 -0
  128. package/dist/jobs/analyze-keyword-placement.js +155 -0
  129. package/dist/jobs/analyze-music.js +14 -0
  130. package/dist/jobs/analyze-video.js +282 -0
  131. package/dist/jobs/apply-cuts.js +83 -0
  132. package/dist/jobs/apply-sfx.js +107 -0
  133. package/dist/jobs/archive-clip.js +458 -0
  134. package/dist/jobs/assemble-goal.js +98 -0
  135. package/dist/jobs/audio-boost.js +71 -0
  136. package/dist/jobs/audio-mix.js +161 -0
  137. package/dist/jobs/backfill-asset-tags.js +144 -0
  138. package/dist/jobs/burn-watermark.js +316 -0
  139. package/dist/jobs/change-video-speed.js +176 -0
  140. package/dist/jobs/clean-video-audio.js +207 -0
  141. package/dist/jobs/cold-open.js +166 -0
  142. package/dist/jobs/combine-goal.js +108 -0
  143. package/dist/jobs/complete-provider-task.js +185 -0
  144. package/dist/jobs/copy-library-asset.js +33 -0
  145. package/dist/jobs/cost-estimate-assessment.js +113 -0
  146. package/dist/jobs/crop-image.js +47 -0
  147. package/dist/jobs/crop-video.js +71 -0
  148. package/dist/jobs/describe-image.js +181 -0
  149. package/dist/jobs/detect-scenes.js +33 -0
  150. package/dist/jobs/doctor-fix.js +100 -0
  151. package/dist/jobs/download-video.js +427 -0
  152. package/dist/jobs/enqueue-search-index.js +24 -0
  153. package/dist/jobs/even-split.js +122 -0
  154. package/dist/jobs/export-sequence.js +365 -0
  155. package/dist/jobs/extend-audio.js +229 -0
  156. package/dist/jobs/extract-audio.js +72 -0
  157. package/dist/jobs/extract-frame.js +58 -0
  158. package/dist/jobs/extract-notebook-audio.js +82 -0
  159. package/dist/jobs/extract-notebook-frame.js +93 -0
  160. package/dist/jobs/extract-video-clip.js +8 -0
  161. package/dist/jobs/extract-video-poster.js +55 -0
  162. package/dist/jobs/extract-waveform.js +25 -0
  163. package/dist/jobs/finish-goal.js +255 -0
  164. package/dist/jobs/forget-asset.js +11 -0
  165. package/dist/jobs/generate-acestep-cover.js +219 -0
  166. package/dist/jobs/generate-media.js +70 -0
  167. package/dist/jobs/image-subjects.js +1059 -0
  168. package/dist/jobs/index.js +18 -0
  169. package/dist/jobs/inject-first-frame.js +175 -0
  170. package/dist/jobs/isolate-vocals.js +69 -0
  171. package/dist/jobs/kie-paygate.js +177 -0
  172. package/dist/jobs/label-music-sections.js +5 -0
  173. package/dist/jobs/osg-placement.js +135 -0
  174. package/dist/jobs/pad-video.js +72 -0
  175. package/dist/jobs/plan-goal.js +97 -0
  176. package/dist/jobs/post-record.js +21 -0
  177. package/dist/jobs/post-to-x.js +21 -0
  178. package/dist/jobs/prepare-search-reference.js +190 -0
  179. package/dist/jobs/prepare-temporal-search.js +16 -0
  180. package/dist/jobs/process-audio.js +67 -0
  181. package/dist/jobs/process-image.js +58 -0
  182. package/dist/jobs/process-upload.js +166 -0
  183. package/dist/jobs/process-video.js +438 -0
  184. package/dist/jobs/register-all.js +161 -0
  185. package/dist/jobs/relayout-notebook.js +78 -0
  186. package/dist/jobs/remove-sound.js +299 -0
  187. package/dist/jobs/render-project.js +380 -0
  188. package/dist/jobs/render-qr-outro.js +138 -0
  189. package/dist/jobs/render-timeline.js +283 -0
  190. package/dist/jobs/repair-search-indexes.js +42 -0
  191. package/dist/jobs/replace-video-audio.js +64 -0
  192. package/dist/jobs/restore-archive-clip.js +53 -0
  193. package/dist/jobs/reverse-video.js +53 -0
  194. package/dist/jobs/rewrite-script.js +173 -0
  195. package/dist/jobs/run-notebook.js +3335 -0
  196. package/dist/jobs/semantic-index.js +797 -0
  197. package/dist/jobs/smooth-scene-concat.js +257 -0
  198. package/dist/jobs/splice-video.js +280 -0
  199. package/dist/jobs/split-video.js +127 -0
  200. package/dist/jobs/suggest-cuts.js +149 -0
  201. package/dist/jobs/suggest-sfx.js +135 -0
  202. package/dist/jobs/sync-video-to-audio.js +329 -0
  203. package/dist/jobs/tag-asset.js +266 -0
  204. package/dist/jobs/task-failure.js +16 -0
  205. package/dist/jobs/timewarp-video.js +152 -0
  206. package/dist/jobs/transcribe-video-audio.js +117 -0
  207. package/dist/jobs/transcribe.js +35 -0
  208. package/dist/jobs/translate-transcript.js +55 -0
  209. package/dist/jobs/trim-audio.js +133 -0
  210. package/dist/jobs/trim-video.js +291 -0
  211. package/dist/jobs/xai-paygate.js +26 -0
  212. package/dist/keyword-placement-cache.js +74 -0
  213. package/dist/lazy-render.js +142 -0
  214. package/dist/library-browse.js +78 -0
  215. package/dist/lightning-defaults.js +206 -0
  216. package/dist/load-env.js +12 -0
  217. package/dist/local-search-models.js +206 -0
  218. package/dist/local-upload.js +318 -0
  219. package/dist/logger.js +69 -0
  220. package/dist/media/adapters/alibaba.js +20 -0
  221. package/dist/media/adapters/elevenlabs.js +58 -0
  222. package/dist/media/adapters/fal.js +45 -0
  223. package/dist/media/adapters/index.js +26 -0
  224. package/dist/media/adapters/kie.js +120 -0
  225. package/dist/media/adapters/pending.js +21 -0
  226. package/dist/media/adapters/types.js +5 -0
  227. package/dist/media/adapters/xai.js +18 -0
  228. package/dist/media/catalog.js +236 -0
  229. package/dist/media/complete.js +191 -0
  230. package/dist/media/cost.js +45 -0
  231. package/dist/media/descriptor.js +157 -0
  232. package/dist/media/endpoints.js +11 -0
  233. package/dist/media/frame-options.js +18 -0
  234. package/dist/media/insert-video-timing.js +17 -0
  235. package/dist/media/json-schema.js +75 -0
  236. package/dist/media/legacy-task-types.js +129 -0
  237. package/dist/media/listing.js +24 -0
  238. package/dist/media/model-id.js +14 -0
  239. package/dist/media/preview.js +86 -0
  240. package/dist/media/prompt-dialects.js +65 -0
  241. package/dist/media/ref-fields.js +106 -0
  242. package/dist/media/refs.js +131 -0
  243. package/dist/media/request.js +188 -0
  244. package/dist/media/types.js +6 -0
  245. package/dist/media/wire.js +161 -0
  246. package/dist/media-library.js +535 -0
  247. package/dist/media-output-path.js +33 -0
  248. package/dist/multyculty-workflow.js +757 -0
  249. package/dist/notebook-action-catalog.js +608 -0
  250. package/dist/notebook-cell-outputs.js +726 -0
  251. package/dist/notebook-credit-retry.js +45 -0
  252. package/dist/notebook-fixtures.js +8 -0
  253. package/dist/notebook-generation-contract.js +77 -0
  254. package/dist/notebook-generation-controls.js +145 -0
  255. package/dist/notebook-goal-layout.js +40 -0
  256. package/dist/notebook-graph.js +37 -0
  257. package/dist/notebook-image-edit.js +84 -0
  258. package/dist/notebook-initial-generation-prompt.js +222 -0
  259. package/dist/notebook-live-analysis.js +941 -0
  260. package/dist/notebook-media-ops.js +579 -0
  261. package/dist/notebook-mutations.js +20 -0
  262. package/dist/notebook-placement.js +41 -0
  263. package/dist/notebook-provider-failure.js +87 -0
  264. package/dist/notebook-published-post.js +26 -0
  265. package/dist/notebook-reference-resolver.js +227 -0
  266. package/dist/notebook-relayout.js +270 -0
  267. package/dist/notebook-run-plan.js +519 -0
  268. package/dist/notebook-shots.js +162 -0
  269. package/dist/notebook-workflow.js +856 -0
  270. package/dist/one-password.js +200 -0
  271. package/dist/openai-intelligence.js +99 -0
  272. package/dist/original-media-file.js +12 -0
  273. package/dist/osg-assets.js +36 -0
  274. package/dist/osg-placement-cache.js +64 -0
  275. package/dist/osg-settings.js +27 -0
  276. package/dist/paid-tools.js +22 -0
  277. package/dist/platform-guidance.js +26 -0
  278. package/dist/posts/dropbox-auth.js +91 -0
  279. package/dist/posts/dropbox-upload.js +132 -0
  280. package/dist/posts/icloud-drive.js +134 -0
  281. package/dist/posts/icloud-status.js +64 -0
  282. package/dist/posts/post-contract.js +2 -0
  283. package/dist/posts/post-copy-format.js +43 -0
  284. package/dist/posts/post-copy.js +193 -0
  285. package/dist/posts/post-folder.js +18 -0
  286. package/dist/posts/post-metrics.js +119 -0
  287. package/dist/posts/post-store.js +340 -0
  288. package/dist/posts/x-post-target.js +43 -0
  289. package/dist/preview-payload.js +90 -0
  290. package/dist/prompt-surfaces.js +22 -0
  291. package/dist/provider-prompt-transform.js +77 -0
  292. package/dist/provider-status-link.js +21 -0
  293. package/dist/provider-task-record.js +78 -0
  294. package/dist/provider-task-status.js +47 -0
  295. package/dist/provider-usage.js +294 -0
  296. package/dist/queue.js +810 -0
  297. package/dist/reference-video-duration.js +17 -0
  298. package/dist/remotion/BlurFillVideo.js +51 -0
  299. package/dist/remotion/KeywordGraphicsOverlay.js +68 -0
  300. package/dist/remotion/OsgOverlay.js +30 -0
  301. package/dist/remotion/QrOutroComposition.js +47 -0
  302. package/dist/remotion/RenderComposition.js +11 -0
  303. package/dist/remotion/browser.js +59 -0
  304. package/dist/remotion/constants.js +35 -0
  305. package/dist/remotion/index.js +66 -0
  306. package/dist/remotion/keyword-graphics.js +151 -0
  307. package/dist/remotion/keyword-placement.js +182 -0
  308. package/dist/remotion/osg-spec.js +198 -0
  309. package/dist/remotion/public/qr-outro-impact.wav +0 -0
  310. package/dist/remotion/qr-outro-audio.js +1 -0
  311. package/dist/remotion/qr-outro-spec.js +211 -0
  312. package/dist/remotion/shared-bundle.js +37 -0
  313. package/dist/remotion/subtitles/AliveCaptions.js +83 -0
  314. package/dist/remotion/subtitles/Highlight.js +58 -0
  315. package/dist/remotion/subtitles/Impact.js +67 -0
  316. package/dist/remotion/subtitles/SubtitleOverlay.js +9 -0
  317. package/dist/remotion/subtitles/alive-layout.js +321 -0
  318. package/dist/remotion/subtitles/alive-types.js +17 -0
  319. package/dist/remotion/subtitles/chunker.js +68 -0
  320. package/dist/remotion/subtitles/segments.js +42 -0
  321. package/dist/remotion/subtitles/styles.js +4 -0
  322. package/dist/remotion/subtitles/types.js +1 -0
  323. package/dist/remotion/util.js +18 -0
  324. package/dist/remotion-cancellation.js +15 -0
  325. package/dist/rename-helpers.js +204 -0
  326. package/dist/rhythm/analyze.js +128 -0
  327. package/dist/rhythm/contract.js +14 -0
  328. package/dist/rhythm/draft-model.js +19 -0
  329. package/dist/rhythm/energy.js +133 -0
  330. package/dist/rhythm/fft.js +44 -0
  331. package/dist/rhythm/model.js +71 -0
  332. package/dist/rhythm/music-analysis.js +124 -0
  333. package/dist/rhythm/music-draft.js +261 -0
  334. package/dist/rhythm/onset.js +101 -0
  335. package/dist/rhythm/run-worker.js +51 -0
  336. package/dist/rhythm/score.js +47 -0
  337. package/dist/rhythm/section-labels.js +168 -0
  338. package/dist/rhythm/sequence-rhythm.js +67 -0
  339. package/dist/rhythm/synthesize.js +103 -0
  340. package/dist/rhythm/timing.js +98 -0
  341. package/dist/rhythm/track.js +320 -0
  342. package/dist/rhythm/visual-fit.js +4 -0
  343. package/dist/rhythm/worker.js +25 -0
  344. package/dist/scene-detect.js +200 -0
  345. package/dist/scene-transition.js +12 -0
  346. package/dist/scheduled-posts.js +200 -0
  347. package/dist/search-index-coverage.js +13 -0
  348. package/dist/search-index-media.js +71 -0
  349. package/dist/search-reference-store.js +60 -0
  350. package/dist/search-scoring.js +17 -0
  351. package/dist/serve.js +125 -0
  352. package/dist/server-lock.js +143 -0
  353. package/dist/server.js +42 -0
  354. package/dist/srt.js +16 -0
  355. package/dist/tag-backfill-state.js +121 -0
  356. package/dist/tag-settings.js +30 -0
  357. package/dist/tag-vocabulary.js +237 -0
  358. package/dist/test-queue-cleanup.js +1 -0
  359. package/dist/time-parse.js +50 -0
  360. package/dist/timeline-helpers.js +554 -0
  361. package/dist/timewarp.js +87 -0
  362. package/dist/tools/_image-inputs.js +9 -0
  363. package/dist/tools/_media-refs.js +84 -0
  364. package/dist/tools/_shared.js +59 -0
  365. package/dist/tools/_suggest-shared.js +279 -0
  366. package/dist/tools/add-timeline-audio.js +73 -0
  367. package/dist/tools/alive-captions.js +157 -0
  368. package/dist/tools/analyze-jokes.js +56 -0
  369. package/dist/tools/analyze-video.js +66 -0
  370. package/dist/tools/animate-keywords.js +217 -0
  371. package/dist/tools/api-status.js +42 -0
  372. package/dist/tools/application-commands.js +34 -0
  373. package/dist/tools/apply-cuts.js +112 -0
  374. package/dist/tools/apply-sfx.js +152 -0
  375. package/dist/tools/apply-watermark.js +670 -0
  376. package/dist/tools/archive-clip.js +74 -0
  377. package/dist/tools/asset-history.js +61 -0
  378. package/dist/tools/asset-manifest.js +24 -0
  379. package/dist/tools/asset-tags.js +151 -0
  380. package/dist/tools/assign-slot.js +97 -0
  381. package/dist/tools/audio-boost.js +107 -0
  382. package/dist/tools/audio-mix.js +121 -0
  383. package/dist/tools/book-usage.js +16 -0
  384. package/dist/tools/chain.js +136 -0
  385. package/dist/tools/change-video-speed.js +105 -0
  386. package/dist/tools/chat-history.js +5 -0
  387. package/dist/tools/chat.js +848 -0
  388. package/dist/tools/clean-video-audio.js +97 -0
  389. package/dist/tools/clear-failed-tasks.js +66 -0
  390. package/dist/tools/cold-open.js +114 -0
  391. package/dist/tools/command-plan.js +1680 -0
  392. package/dist/tools/commands.js +1666 -0
  393. package/dist/tools/concat-images.js +236 -0
  394. package/dist/tools/connect-service.js +55 -0
  395. package/dist/tools/copy-file-to-clipboard.js +58 -0
  396. package/dist/tools/create-character.js +114 -0
  397. package/dist/tools/create-qart.js +253 -0
  398. package/dist/tools/create-qr-outro.js +149 -0
  399. package/dist/tools/create-qrbtf.js +215 -0
  400. package/dist/tools/create-watermark.js +97 -0
  401. package/dist/tools/crop-asset.js +18 -0
  402. package/dist/tools/crop-image.js +120 -0
  403. package/dist/tools/crop-video.js +97 -0
  404. package/dist/tools/delete-asset.js +104 -0
  405. package/dist/tools/describe-image.js +69 -0
  406. package/dist/tools/detect-scenes.js +44 -0
  407. package/dist/tools/doctor.js +126 -0
  408. package/dist/tools/download-video.js +114 -0
  409. package/dist/tools/duplicate-asset.js +184 -0
  410. package/dist/tools/edit-timeline.js +59 -0
  411. package/dist/tools/editing-moments.js +105 -0
  412. package/dist/tools/estimate-cost.js +171 -0
  413. package/dist/tools/even-split.js +295 -0
  414. package/dist/tools/export-asset-file.js +22 -0
  415. package/dist/tools/export-asset.js +140 -0
  416. package/dist/tools/export-sequence.js +250 -0
  417. package/dist/tools/export-to-downloads.js +54 -0
  418. package/dist/tools/export-transcript-srt.js +79 -0
  419. package/dist/tools/extend-audio.js +100 -0
  420. package/dist/tools/extract-audio.js +174 -0
  421. package/dist/tools/extract-frame.js +108 -0
  422. package/dist/tools/extract-notebook-audio.js +173 -0
  423. package/dist/tools/extract-notebook-frame.js +160 -0
  424. package/dist/tools/extract-video-clip.js +101 -0
  425. package/dist/tools/generate-media.js +157 -0
  426. package/dist/tools/generation-payload.js +48 -0
  427. package/dist/tools/get-timeline.js +12 -0
  428. package/dist/tools/get-watermark-config.js +38 -0
  429. package/dist/tools/goal.js +644 -0
  430. package/dist/tools/image-subjects.js +711 -0
  431. package/dist/tools/index.js +323 -0
  432. package/dist/tools/inject-first-frame.js +154 -0
  433. package/dist/tools/invert-image.js +70 -0
  434. package/dist/tools/isolate-vocals.js +66 -0
  435. package/dist/tools/list-assets.js +98 -0
  436. package/dist/tools/list-cell-generations.js +225 -0
  437. package/dist/tools/list-elevenlabs-voices.js +163 -0
  438. package/dist/tools/log-wrapper.js +29 -0
  439. package/dist/tools/make-cover-song.js +95 -0
  440. package/dist/tools/mark-asset-seen.js +23 -0
  441. package/dist/tools/media-library.js +245 -0
  442. package/dist/tools/move-timeline-audio.js +35 -0
  443. package/dist/tools/music-analysis.js +60 -0
  444. package/dist/tools/music-draft.js +29 -0
  445. package/dist/tools/pad-video.js +87 -0
  446. package/dist/tools/post-record.js +83 -0
  447. package/dist/tools/post.js +168 -0
  448. package/dist/tools/prompt-history.js +164 -0
  449. package/dist/tools/provider-key-status.js +248 -0
  450. package/dist/tools/qrbtf-render.js +849 -0
  451. package/dist/tools/read-asset-metadata.js +26 -0
  452. package/dist/tools/read-file-at-commit.js +29 -0
  453. package/dist/tools/read-transcript.js +41 -0
  454. package/dist/tools/reconcile-project-work.js +1452 -0
  455. package/dist/tools/recover-asset.js +28 -0
  456. package/dist/tools/remove-sound.js +72 -0
  457. package/dist/tools/remove-timeline-audio.js +34 -0
  458. package/dist/tools/remove-timeline-slot.js +40 -0
  459. package/dist/tools/rename-all.js +434 -0
  460. package/dist/tools/rename-asset.js +34 -0
  461. package/dist/tools/render-settings.js +47 -0
  462. package/dist/tools/render-timeline.js +120 -0
  463. package/dist/tools/render.js +384 -0
  464. package/dist/tools/reorder-character-images.js +45 -0
  465. package/dist/tools/replace-video-audio.js +133 -0
  466. package/dist/tools/restore-archive-clips.js +209 -0
  467. package/dist/tools/restore-asset-version.js +37 -0
  468. package/dist/tools/retry-generation.js +54 -0
  469. package/dist/tools/reverse-video.js +74 -0
  470. package/dist/tools/rewrite-prompt.js +388 -0
  471. package/dist/tools/rewrite-script.js +67 -0
  472. package/dist/tools/schema-from-apicity.js +66 -0
  473. package/dist/tools/search-archive.js +150 -0
  474. package/dist/tools/semantic-search.js +1214 -0
  475. package/dist/tools/sequence-rhythm.js +43 -0
  476. package/dist/tools/set-character-metadata.js +84 -0
  477. package/dist/tools/set-env-secret.js +40 -0
  478. package/dist/tools/set-osg.js +143 -0
  479. package/dist/tools/show-folder.js +37 -0
  480. package/dist/tools/smooth-scene-concat.js +122 -0
  481. package/dist/tools/splice-video.js +149 -0
  482. package/dist/tools/split-video.js +202 -0
  483. package/dist/tools/suggest-cuts.js +45 -0
  484. package/dist/tools/suggest-sfx.js +43 -0
  485. package/dist/tools/sync-video-to-audio.js +115 -0
  486. package/dist/tools/tag-backfill.js +177 -0
  487. package/dist/tools/timewarp-video.js +85 -0
  488. package/dist/tools/tool-def.js +1 -0
  489. package/dist/tools/tool-json-schema.js +116 -0
  490. package/dist/tools/transcribe.js +90 -0
  491. package/dist/tools/translate-subtitles.js +59 -0
  492. package/dist/tools/trim-audio.js +139 -0
  493. package/dist/tools/trim-video.js +168 -0
  494. package/dist/tools/update-script.js +25 -0
  495. package/dist/tools/update-timeline-audio.js +40 -0
  496. package/dist/tools/upload-file.js +41 -0
  497. package/dist/tools/verify-x-mentions.js +141 -0
  498. package/dist/tools/video-editing-command-contract.js +291 -0
  499. package/dist/tools/video-source-reference.js +30 -0
  500. package/dist/tools/video-time-input.js +18 -0
  501. package/dist/tools/videobook-domain.js +2021 -0
  502. package/dist/tools/wait-for-asset-ready.js +143 -0
  503. package/dist/tools/workspace-actions.js +54 -0
  504. package/dist/transcript-projection.js +202 -0
  505. package/dist/transcript-srt.js +33 -0
  506. package/dist/upload.js +76 -0
  507. package/dist/usage-providers.js +25 -0
  508. package/dist/video-analysis-projection.js +46 -0
  509. package/dist/video-poster.js +33 -0
  510. package/dist/video-proxy.js +99 -0
  511. package/dist/vision-regions.js +111 -0
  512. package/dist/voice-actions.js +90 -0
  513. package/dist/voice-audio.js +55 -0
  514. package/dist/voice-config.js +122 -0
  515. package/dist/voice-continuation.js +54 -0
  516. package/dist/voice-contract.js +1 -0
  517. package/dist/voice-http.js +145 -0
  518. package/dist/voice-reply-progress.js +55 -0
  519. package/dist/voice-session.js +992 -0
  520. package/dist/watermark-badge.js +259 -0
  521. package/dist/watermark-config.js +111 -0
  522. package/dist/watermark-handle-position.js +55 -0
  523. package/dist/watermark-platform.js +15 -0
  524. package/dist/watermark-timing.js +16 -0
  525. package/dist/workspace-action-catalog.js +315 -0
  526. package/dist/workspace-action-contract.js +21 -0
  527. package/dist/workspace-action-groups.js +98 -0
  528. package/dist/workspace-action-surfaces.js +7 -0
  529. package/dist/x/account.js +88 -0
  530. package/dist/x/authenticated-handle.js +30 -0
  531. package/dist/x/oauth-flow.js +191 -0
  532. package/dist/x/post-contract.js +1 -0
  533. package/dist/x/post-metadata.js +44 -0
  534. package/dist/x/post-to-x.js +456 -0
  535. package/dist/x/published-post-cell.js +90 -0
  536. package/dist/x/x-tokens.js +69 -0
  537. package/dist/ytdlp-binary.js +65 -0
  538. package/dist/zod-slots.js +334 -0
  539. package/package.json +84 -4
  540. package/ui/assets/alive-captions-BWb5nLKj.css +1 -0
  541. package/ui/assets/alive-captions-DPEr1nKM.js +1 -0
  542. package/ui/assets/confirm-bodies-D8ouHXKy.js +1 -0
  543. package/ui/assets/confirm-bodies-DrMhaXC6.css +1 -0
  544. package/ui/assets/fullscreen-B7nw4YbE.js +1 -0
  545. package/ui/assets/goal-ui-DK-xTCK0.js +2 -0
  546. package/ui/assets/goal-ui-DXdUM2KF.css +1 -0
  547. package/ui/assets/index-DzPAnCUj.css +1 -0
  548. package/ui/assets/index-kS1905s5.js +37 -0
  549. package/ui/assets/inspector-MlzQbTVo.js +1 -0
  550. package/ui/assets/jobs-ui-CoinOWx0.js +1 -0
  551. package/ui/assets/music-video-Cbe80kmQ.js +1 -0
  552. package/ui/assets/music-video-DPaiKKEq.css +1 -0
  553. package/ui/assets/ui-Oirr9VOf.css +1 -0
  554. package/ui/assets/ui-xo_Y1yQg.js +2 -0
  555. package/ui/assets/vendor-D2rfiZ5j.css +1 -0
  556. package/ui/assets/vendor-DfTCWgKm.js +19 -0
  557. package/ui/assets/vendor-flow-BXbeWxW7.js +7 -0
  558. package/ui/assets/vendor-flow-BnuhLJ6X.css +1 -0
  559. package/ui/assets/vendor-icons-CGqhCIXV.js +1 -0
  560. package/ui/assets/vendor-mcp-BTlEJcHV.js +67 -0
  561. package/ui/assets/vendor-react-Dj7D1fD4.js +9 -0
  562. package/ui/assets/vendor-remotion-CH1HXrlc.js +95 -0
  563. package/ui/assets/videobook-Qlp9HQFu.js +20 -0
  564. package/ui/favicon.svg +8 -0
  565. package/ui/index.html +126 -0
@@ -0,0 +1,78 @@
1
+ export const LIBRARY_BROWSE_STATUSES = [
2
+ "ready",
3
+ "processing",
4
+ "error",
5
+ "all",
6
+ ];
7
+ const READY_STATUS = "ready";
8
+ const ERROR_STATUS = "error";
9
+ export function isLibraryBrowseStatus(value) {
10
+ return value === "ready"
11
+ || value === "processing"
12
+ || value === "error"
13
+ || value === "all";
14
+ }
15
+ function isLibraryBrowseRow(asset) {
16
+ return asset.type === "image"
17
+ || asset.type === "video"
18
+ || asset.type === "audio"
19
+ || asset.type === "final";
20
+ }
21
+ function isProcessingStatus(status) {
22
+ return status !== READY_STATUS && status !== ERROR_STATUS;
23
+ }
24
+ export function matchesBrowseStatus(status, browseStatus) {
25
+ if (browseStatus === "all")
26
+ return true;
27
+ if (browseStatus === "ready")
28
+ return status === READY_STATUS;
29
+ if (browseStatus === "error")
30
+ return status === ERROR_STATUS;
31
+ return isProcessingStatus(status);
32
+ }
33
+ export function emptyStatusCounts() {
34
+ return { ready: 0, processing: 0, error: 0 };
35
+ }
36
+ export function addStatusCounts(left, right) {
37
+ return {
38
+ ready: left.ready + right.ready,
39
+ processing: left.processing + right.processing,
40
+ error: left.error + right.error,
41
+ };
42
+ }
43
+ export function countBrowseStatuses(assets) {
44
+ const counts = emptyStatusCounts();
45
+ for (const asset of assets) {
46
+ if (asset.status === READY_STATUS)
47
+ counts.ready += 1;
48
+ else if (asset.status === ERROR_STATUS)
49
+ counts.error += 1;
50
+ else
51
+ counts.processing += 1;
52
+ }
53
+ return counts;
54
+ }
55
+ export function pageLibraryAssets(assets, input) {
56
+ const browseStatus = input.browseStatus;
57
+ const offset = input.offset ?? 0;
58
+ const limit = input.limit ?? 200;
59
+ const eligible = browseStatus === undefined
60
+ ? [...assets]
61
+ : assets.filter(isLibraryBrowseRow);
62
+ const statusCounts = countBrowseStatuses(eligible.filter(isLibraryBrowseRow));
63
+ const matching = browseStatus === undefined
64
+ ? eligible
65
+ : eligible.filter((asset) => matchesBrowseStatus(asset.status, browseStatus));
66
+ const pageAssets = matching.slice(offset, offset + limit);
67
+ return {
68
+ matching,
69
+ pageAssets,
70
+ page: {
71
+ offset,
72
+ limit,
73
+ total: matching.length,
74
+ hasMore: offset + pageAssets.length < matching.length,
75
+ },
76
+ statusCounts,
77
+ };
78
+ }
@@ -0,0 +1,206 @@
1
+ export const LIGHTNING_SCENE_MODEL = "kie:nano-banana-2-1";
2
+ export const LIGHTNING_SCENE_ASPECT_RATIO = "16:9";
3
+ export const LIGHTNING_SCENE_RESOLUTION = "2K";
4
+ export const LIGHTNING_SCENE_OUTPUT_FORMAT = "jpg";
5
+ export const LIGHTNING_SCENE_PROMPT_WORDS = 25;
6
+ export const LIGHTNING_VIDEO_MODEL = "kie:bytedance/seedance-2-5";
7
+ export const LIGHTNING_VIDEO_ASPECT_RATIO = "16:9";
8
+ export const LIGHTNING_VIDEO_RESOLUTION = "1080p";
9
+ export const LIGHTNING_VIDEO_DURATION_SECONDS = 13;
10
+ export const LIGHTNING_VIDEO_OUTPUT_FORMAT = "mp4";
11
+ export const LIGHTNING_VIDEO_GENERATE_AUDIO = true;
12
+ export const LIGHTNING_VIDEO_PROMPT_WORDS = 60;
13
+ export const LIGHTNING_VIDEO_OPTIONS = {
14
+ resolution: LIGHTNING_VIDEO_RESOLUTION,
15
+ aspect_ratio: LIGHTNING_VIDEO_ASPECT_RATIO,
16
+ duration: LIGHTNING_VIDEO_DURATION_SECONDS,
17
+ output_format: LIGHTNING_VIDEO_OUTPUT_FORMAT,
18
+ generate_audio: LIGHTNING_VIDEO_GENERATE_AUDIO,
19
+ };
20
+ export const LIGHTNING_SCENE_OPTIONS = {
21
+ aspect_ratio: LIGHTNING_SCENE_ASPECT_RATIO,
22
+ resolution: LIGHTNING_SCENE_RESOLUTION,
23
+ output_format: LIGHTNING_SCENE_OUTPUT_FORMAT,
24
+ };
25
+ export const LIGHTNING_COLD_OPEN_SECONDS = 2.3;
26
+ const LIGHTNING_HANDLE_SECONDS = 3;
27
+ const LIGHTNING_QR_LEAD_SECONDS = 2.3;
28
+ export const LIGHTNING_FADE_SECONDS = 0.3;
29
+ const LIGHTNING_POST_PLATFORM = "tiktok";
30
+ export const LIGHTNING_POST_LANGUAGE = "th";
31
+ export const LIGHTNING_POST_TAGS = ["fyp", "bkk"];
32
+ export const LIGHTNING_WATERMARK_PROFILE = {
33
+ platform: "tiktok",
34
+ handle: "jtbkk",
35
+ profileUrl: "https://www.tiktok.com/@jtbkk",
36
+ includePlatformIcon: true,
37
+ includeHandleBorder: true,
38
+ handlePaddingX: 15,
39
+ handlePaddingY: 12,
40
+ handleRounding: 56,
41
+ scale: 1,
42
+ mode: "burn",
43
+ handlePlacement: "center",
44
+ handleVerticalPercent: 10,
45
+ handleStartSeconds: 0,
46
+ handleEndSeconds: LIGHTNING_HANDLE_SECONDS,
47
+ handleOpacity: 0.28,
48
+ qrPosition: "bottom-right",
49
+ qrLeadSeconds: LIGHTNING_QR_LEAD_SECONDS,
50
+ qrOpacity: 0.37,
51
+ fadeSeconds: LIGHTNING_FADE_SECONDS,
52
+ };
53
+ export const X_WATERMARK_PROFILE = {
54
+ platform: "x",
55
+ handle: "justinwtanner",
56
+ profileUrl: "",
57
+ includePlatformIcon: true,
58
+ includeHandleBorder: true,
59
+ handlePaddingX: 32,
60
+ handlePaddingY: 32,
61
+ handleRounding: 100,
62
+ scale: 1,
63
+ mode: "burn",
64
+ handlePlacement: "center",
65
+ handleVerticalPercent: 33,
66
+ handleStartSeconds: 0,
67
+ handleEndSeconds: null,
68
+ handleOpacity: 0.5,
69
+ qrPosition: "auto",
70
+ qrLeadSeconds: null,
71
+ qrOpacity: 0.5,
72
+ fadeSeconds: 0.5,
73
+ };
74
+ export function watermarkProfileToSave(base, appearance, timing) {
75
+ if (!timing.explicit) {
76
+ return {
77
+ ...appearance,
78
+ handleStartSeconds: base.handleStartSeconds,
79
+ handleEndSeconds: base.handleEndSeconds,
80
+ qrLeadSeconds: base.qrLeadSeconds,
81
+ qrStartSeconds: null,
82
+ qrEndSeconds: null,
83
+ };
84
+ }
85
+ return {
86
+ ...appearance,
87
+ handleStartSeconds: timing.handleStartSeconds ?? base.handleStartSeconds,
88
+ handleEndSeconds: timing.handleEndSeconds ?? null,
89
+ qrLeadSeconds: null,
90
+ qrStartSeconds: timing.qrStartSeconds ?? null,
91
+ qrEndSeconds: timing.qrEndSeconds ?? null,
92
+ };
93
+ }
94
+ const PROFILE_KEYS = [
95
+ "handle",
96
+ "profileUrl",
97
+ "includePlatformIcon",
98
+ "includeHandleBorder",
99
+ "handlePaddingX",
100
+ "handlePaddingY",
101
+ "handleRounding",
102
+ "scale",
103
+ "mode",
104
+ "handlePlacement",
105
+ "handleVerticalPercent",
106
+ "handleStartSeconds",
107
+ "handleEndSeconds",
108
+ "handleOpacity",
109
+ "qrPosition",
110
+ "qrLeadSeconds",
111
+ "qrOpacity",
112
+ "fadeSeconds",
113
+ ];
114
+ function definedProfileFields(stored) {
115
+ if (!stored)
116
+ return {};
117
+ const next = {};
118
+ for (const key of PROFILE_KEYS) {
119
+ const value = stored[key];
120
+ if (value !== undefined)
121
+ next[key] = value;
122
+ }
123
+ return next;
124
+ }
125
+ export function watermarkProfileFor(platform, stored) {
126
+ const base = platform === "tiktok" ? LIGHTNING_WATERMARK_PROFILE : X_WATERMARK_PROFILE;
127
+ return { ...base, ...definedProfileFields(stored), platform };
128
+ }
129
+ function canonicalWatermarkProfile(profile) {
130
+ return watermarkProfileFor(profile.platform, profile);
131
+ }
132
+ export function watermarkWindowsFor(profile, durationSeconds) {
133
+ const duration = Number.isFinite(durationSeconds) ? Math.max(0, durationSeconds) : 0;
134
+ const handleStart = Math.min(duration, Math.max(0, profile.handleStartSeconds));
135
+ const handleEnd = profile.handleEndSeconds == null
136
+ ? duration
137
+ : Math.min(duration, Math.max(handleStart, profile.handleEndSeconds));
138
+ const qrEnd = duration;
139
+ const lead = profile.qrLeadSeconds;
140
+ const qrStart = lead == null ? 0 : Math.max(0, duration - Math.min(duration, Math.max(0, lead)));
141
+ return {
142
+ handleStartSeconds: handleStart,
143
+ handleEndSeconds: handleEnd,
144
+ qrStartSeconds: qrStart,
145
+ qrEndSeconds: qrEnd,
146
+ };
147
+ }
148
+ export function suggestedColdOpen(durationSeconds) {
149
+ const duration = Number.isFinite(durationSeconds) ? Math.max(0, durationSeconds) : 0;
150
+ const minimum = 0.5;
151
+ const preferred = Math.min(duration, LIGHTNING_COLD_OPEN_SECONDS);
152
+ const endSeconds = preferred >= minimum || duration < minimum ? preferred : Math.min(duration, minimum);
153
+ return { startSeconds: 0, endSeconds };
154
+ }
155
+ function finiteSeconds(value) {
156
+ return typeof value === "number" && Number.isFinite(value) ? Math.round(value * 1000) / 1000 : null;
157
+ }
158
+ export function finishingIdentityKey(input) {
159
+ const round = (value) => Math.round(value * 1000) / 1000;
160
+ const qrStart = finiteSeconds(input.qrStartSeconds !== undefined ? input.qrStartSeconds : input.profile.qrStartSeconds);
161
+ const qrEnd = finiteSeconds(input.qrEndSeconds !== undefined ? input.qrEndSeconds : input.profile.qrEndSeconds);
162
+ return JSON.stringify({
163
+ sourceObjectHash: input.sourceObjectHash,
164
+ startSeconds: round(input.startSeconds),
165
+ endSeconds: round(input.endSeconds),
166
+ profile: canonicalWatermarkProfile(input.profile),
167
+ ...(qrStart === null && qrEnd === null ? {} : { qrStartSeconds: qrStart, qrEndSeconds: qrEnd }),
168
+ });
169
+ }
170
+ function text(value) {
171
+ return typeof value === "string" ? value.trim() : "";
172
+ }
173
+ export function preservedPrompt(value, maxWords, authored) {
174
+ const trimmed = value.trim();
175
+ if (authored || maxWords < 1)
176
+ return trimmed;
177
+ const words = trimmed.split(/\s+/u).filter(Boolean);
178
+ return words.length <= maxWords ? trimmed : words.slice(0, maxWords).join(" ");
179
+ }
180
+ export function submittedGenerationPrompt(input) {
181
+ const dispatched = text(input.dispatchedPrompt);
182
+ if (dispatched)
183
+ return dispatched;
184
+ return text(input.cellPrompt);
185
+ }
186
+ export function freshPostLanguage(platform, language) {
187
+ if (language === "en" || language === "th")
188
+ return language;
189
+ return platform === LIGHTNING_POST_PLATFORM ? LIGHTNING_POST_LANGUAGE : "en";
190
+ }
191
+ export function freshPostTags(platform, tags) {
192
+ if (tags !== undefined)
193
+ return [...tags];
194
+ return platform === LIGHTNING_POST_PLATFORM ? [...LIGHTNING_POST_TAGS] : undefined;
195
+ }
196
+ export function payloadPrompt(payload) {
197
+ if (!payload)
198
+ return "";
199
+ const input = payload.input;
200
+ if (input && typeof input === "object" && !Array.isArray(input)) {
201
+ const nested = text(input.prompt);
202
+ if (nested)
203
+ return nested;
204
+ }
205
+ return text(payload.prompt);
206
+ }
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Side-effect module replacing `import "dotenv/config"`. Import this FIRST in
3
+ * every entry point: ESM executes it before the other imports' module bodies,
4
+ * so env vars are populated before any module reads them at import time. It
5
+ * also snapshots which managed keys were set before `.env` loaded, which is
6
+ * how the secret store tells 1Password-injected keys from `.env`-backed ones,
7
+ * then resolves op:// references and the configured vault through `op`.
8
+ */
9
+ import { getDefaultSecretStore } from "./env-secrets.js";
10
+ const store = getDefaultSecretStore();
11
+ store.loadDotenv();
12
+ store.resolveOnePassword();
@@ -0,0 +1,206 @@
1
+ import { createHash } from "node:crypto";
2
+ import { readFile } from "node:fs/promises";
3
+ import { homedir } from "node:os";
4
+ import { join } from "node:path";
5
+ import sharp from "sharp";
6
+ import { LocalClapTemporalProvider, LocalClipTemporalProvider, } from "videobook-engine";
7
+ const clipProvidersByEngine = new WeakMap();
8
+ const clapProvidersByEngine = new WeakMap();
9
+ const fixturesByBookId = new Map();
10
+ function modelCacheDir() {
11
+ return process.env.VIDEOBOOK_MODEL_CACHE_DIR?.trim()
12
+ || join(homedir(), ".cache", "videobook", "models");
13
+ }
14
+ function allowModelDownload() {
15
+ return process.env.VIDEOBOOK_MODEL_DOWNLOAD === "enabled";
16
+ }
17
+ export function localModelConfiguration() {
18
+ return {
19
+ modelCacheDir: modelCacheDir(),
20
+ allowModelDownload: allowModelDownload(),
21
+ };
22
+ }
23
+ async function withPreparationHint(model, run) {
24
+ try {
25
+ return await run();
26
+ }
27
+ catch (cause) {
28
+ if (cause instanceof Error && "error" in cause && cause.error && typeof cause.error === "object"
29
+ && "code" in cause.error && cause.error.code === "OFFLINE" && "message" in cause.error) {
30
+ const hint = `Local ${model} search is not ready. Run npm run prepare:search-models -- --download --models ${model} on the server, then retry.`;
31
+ cause.message = `${hint} ${cause.message}`;
32
+ cause.error.message = cause.message;
33
+ }
34
+ throw cause;
35
+ }
36
+ }
37
+ class ClipSearchProvider extends LocalClipTemporalProvider {
38
+ prepare(options = {}) { return withPreparationHint("visual", () => super.prepare(options)); }
39
+ embedText(text, options = {}) { return withPreparationHint("visual", () => super.embedText(text, options)); }
40
+ embedImage(path, options = {}) { return withPreparationHint("visual", () => super.embedImage(path, options)); }
41
+ }
42
+ class ClapSearchProvider extends LocalClapTemporalProvider {
43
+ prepare(options = {}) { return withPreparationHint("audio", () => super.prepare(options)); }
44
+ embedText(text, options = {}) { return withPreparationHint("audio", () => super.embedText(text, options)); }
45
+ embedAudio(path, startSeconds, durationSeconds, options = {}) {
46
+ return withPreparationHint("audio", () => super.embedAudio(path, startSeconds, durationSeconds, options));
47
+ }
48
+ }
49
+ function hasMatchingConfiguration(cached, current) {
50
+ return cached.modelCacheDir === current.modelCacheDir
51
+ && cached.allowModelDownload === current.allowModelDownload;
52
+ }
53
+ function fault(code, message) {
54
+ throw Object.assign(new Error(message), {
55
+ name: code,
56
+ error: { code, message },
57
+ });
58
+ }
59
+ function throwIfAborted(options = {}) {
60
+ if (!options.signal?.aborted)
61
+ return;
62
+ fault("CANCELLED", "Cancelled");
63
+ }
64
+ function invalidInput(message) {
65
+ fault("INVALID_INPUT", message);
66
+ }
67
+ function hashEmbedding(payload, dimensions) {
68
+ const digest = createHash("sha256").update(payload).digest();
69
+ const vector = new Float32Array(dimensions);
70
+ for (let index = 0; index < dimensions; index += 1) {
71
+ vector[index] = digest[index % digest.length] / 127.5 - 1;
72
+ }
73
+ let norm = 0;
74
+ for (const value of vector)
75
+ norm += value * value;
76
+ norm = Math.sqrt(norm);
77
+ if (norm > 0) {
78
+ for (let index = 0; index < dimensions; index += 1)
79
+ vector[index] /= norm;
80
+ }
81
+ return vector;
82
+ }
83
+ class HashClipSearchProvider extends LocalClipTemporalProvider {
84
+ constructor() {
85
+ super({ modelCacheDir: "/dev/null", allowModelDownload: false });
86
+ }
87
+ prepare(options = {}) {
88
+ throwIfAborted(options);
89
+ return Promise.resolve();
90
+ }
91
+ embedText(text, options = {}) {
92
+ throwIfAborted(options);
93
+ return Promise.resolve(hashEmbedding(text, this.dimensions));
94
+ }
95
+ async embedImage(sourcePath, options = {}) {
96
+ throwIfAborted(options);
97
+ try {
98
+ const decoded = await sharp(sourcePath, { failOn: "error", limitInputPixels: 40_000_000 })
99
+ .rotate()
100
+ .toColourspace("srgb")
101
+ .removeAlpha()
102
+ .raw()
103
+ .toBuffer();
104
+ return hashEmbedding(decoded, this.dimensions);
105
+ }
106
+ catch (error) {
107
+ if (error && typeof error === "object" && "error" in error)
108
+ throw error;
109
+ invalidInput("Unable to decode model image within the supported limits");
110
+ }
111
+ }
112
+ }
113
+ class HashClapSearchProvider extends LocalClapTemporalProvider {
114
+ constructor() {
115
+ super({ modelCacheDir: "/dev/null", allowModelDownload: false, ffmpegPath: "ffmpeg" });
116
+ }
117
+ prepare(options = {}) {
118
+ throwIfAborted(options);
119
+ return Promise.resolve();
120
+ }
121
+ embedText(text, options = {}) {
122
+ throwIfAborted(options);
123
+ return Promise.resolve(hashEmbedding(text, this.dimensions));
124
+ }
125
+ async embedAudio(sourcePath, startSeconds = 0, durationSeconds = 10, options = {}) {
126
+ throwIfAborted(options);
127
+ if (!(startSeconds >= 0) || !(durationSeconds > 0)) {
128
+ invalidInput("CLAP audio range must have a non-negative start and positive duration");
129
+ }
130
+ const bytes = await readFile(sourcePath);
131
+ return hashEmbedding(Buffer.concat([bytes, Buffer.from(`${startSeconds}:${durationSeconds}`)]), this.dimensions);
132
+ }
133
+ }
134
+ export function installLocalSearchProviderFixtures(engine) {
135
+ const configuration = localModelConfiguration();
136
+ const clip = new HashClipSearchProvider();
137
+ const clap = new HashClapSearchProvider();
138
+ clipProvidersByEngine.set(engine, { ...configuration, provider: clip, fixture: true });
139
+ clapProvidersByEngine.set(engine, {
140
+ ...configuration,
141
+ ffmpegPath: "ffmpeg",
142
+ provider: clap,
143
+ fixture: true,
144
+ });
145
+ fixturesByBookId.set(engine.book.get().bookId, { clip, clap });
146
+ engine.temporalSearch.providers.register(clip, { modelDownloads: false });
147
+ engine.temporalSearch.providers.register(clap, { modelDownloads: false });
148
+ }
149
+ function fixtureProviders(engine) {
150
+ const cached = clipProvidersByEngine.get(engine);
151
+ const clap = clapProvidersByEngine.get(engine);
152
+ if (cached?.fixture && clap?.fixture)
153
+ return { clip: cached.provider, clap: clap.provider };
154
+ try {
155
+ return fixturesByBookId.get(engine.book.get().bookId);
156
+ }
157
+ catch {
158
+ return undefined;
159
+ }
160
+ }
161
+ export function registerLocalClipSearchProvider(engine) {
162
+ const configuration = localModelConfiguration();
163
+ const fixture = fixtureProviders(engine);
164
+ if (fixture) {
165
+ engine.temporalSearch.providers.register(fixture.clip, { modelDownloads: false });
166
+ return fixture.clip;
167
+ }
168
+ const cached = clipProvidersByEngine.get(engine);
169
+ if (cached && hasMatchingConfiguration(cached, configuration)) {
170
+ engine.temporalSearch.providers.register(cached.provider, { modelDownloads: configuration.allowModelDownload });
171
+ return cached.provider;
172
+ }
173
+ const provider = new ClipSearchProvider(configuration);
174
+ clipProvidersByEngine.set(engine, {
175
+ ...configuration,
176
+ provider,
177
+ });
178
+ engine.temporalSearch.providers.register(provider, { modelDownloads: configuration.allowModelDownload });
179
+ return provider;
180
+ }
181
+ export function registerLocalClapSearchProvider(engine, ffmpegPath) {
182
+ const configuration = localModelConfiguration();
183
+ const fixture = fixtureProviders(engine);
184
+ if (fixture) {
185
+ engine.temporalSearch.providers.register(fixture.clap, { modelDownloads: false });
186
+ return fixture.clap;
187
+ }
188
+ const cached = clapProvidersByEngine.get(engine);
189
+ if (cached
190
+ && cached.ffmpegPath === ffmpegPath
191
+ && hasMatchingConfiguration(cached, configuration)) {
192
+ engine.temporalSearch.providers.register(cached.provider, { modelDownloads: configuration.allowModelDownload });
193
+ return cached.provider;
194
+ }
195
+ const provider = new ClapSearchProvider({
196
+ ...configuration,
197
+ ffmpegPath,
198
+ });
199
+ clapProvidersByEngine.set(engine, {
200
+ ...configuration,
201
+ ffmpegPath,
202
+ provider,
203
+ });
204
+ engine.temporalSearch.providers.register(provider, { modelDownloads: configuration.allowModelDownload });
205
+ return provider;
206
+ }