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,168 @@
1
+ import { z } from "zod";
2
+ import { queue } from "../queue.js";
3
+ import { schedulePost } from "../scheduled-posts.js";
4
+ import { X_PREMIUM_POST_MAX_CHARACTERS } from "../x/account.js";
5
+ const SCHEDULE_LEAD_MS = 5_000;
6
+ function postToolResultMessage(result) {
7
+ const posted = result.status === "partially_posted"
8
+ ? `Root post published, but follow-up ${result.followup_error?.reply_number ?? ""} failed: ${result.followup_error?.message ?? "unknown error"}`
9
+ : `Posted to X${result.replies.length > 0 ? ` with ${result.replies.length} follow-up replies` : ""}`;
10
+ if (result.cell_address) {
11
+ return result.status === "partially_posted"
12
+ ? `Root post published as ${result.cell_address}, but follow-up ${result.followup_error?.reply_number ?? ""} failed: ${result.followup_error?.message ?? "unknown error"}`
13
+ : `${posted} as ${result.cell_address}`;
14
+ }
15
+ if (result.cell_error) {
16
+ return `${posted}; notebook cell could not be created: ${result.cell_error}`;
17
+ }
18
+ return posted;
19
+ }
20
+ export function postToolResultPayload(result, platform) {
21
+ return {
22
+ status: result.status,
23
+ platform,
24
+ tweet_id: result.tweet_id,
25
+ tweet_url: result.tweet_url,
26
+ replies: result.replies,
27
+ followup_error: result.followup_error,
28
+ ...(result.cell_id ? { cell_id: result.cell_id } : {}),
29
+ ...(result.cell_address ? { cell_address: result.cell_address } : {}),
30
+ message: postToolResultMessage(result),
31
+ };
32
+ }
33
+ const followupSchema = z.object({
34
+ text: z.string().max(X_PREMIUM_POST_MAX_CHARACTERS).optional(),
35
+ image_asset_ids: z.array(z.string()).max(4).optional(),
36
+ }).refine((value) => Boolean(value.text?.length || value.image_asset_ids?.length), { message: "A follow-up needs text or at least one image" });
37
+ export function postDef() {
38
+ return {
39
+ name: "post",
40
+ description: "Publish a video or image asset to a social platform. Currently supports X (Twitter); Instagram is planned. Scheduled posts persist across server restarts.",
41
+ schema: {
42
+ post_cell_id: z.string().uuid().optional().describe("Existing Post cell to publish; uses its frozen media and caption"),
43
+ asset_id: z.string().optional().describe("Asset to post (e.g. vid-clip-name, img-photo-name)"),
44
+ book_id: z.string().describe("Book id containing the asset"),
45
+ platform: z.enum(["x"]).default("x").describe("Target platform; defaults to 'x'"),
46
+ text: z
47
+ .string()
48
+ .trim()
49
+ .max(X_PREMIUM_POST_MAX_CHARACTERS)
50
+ .optional()
51
+ .describe("Title of the root post (X limit 280 chars, or 25000 when the connected account has X Premium; service_status with service x reports post_max_characters). Publishing requires one; pass it only when the user supplied it, since the confirm sheet asks for a missing title before applying."),
52
+ orientation: z
53
+ .enum(["portrait", "landscape"])
54
+ .optional()
55
+ .describe("Force a target video orientation. Pads with black bars to 1080x1920 (portrait) or 1920x1080 (landscape) before upload. Skipped when source already matches."),
56
+ scheduled_for: z
57
+ .string()
58
+ .datetime()
59
+ .optional()
60
+ .describe("ISO 8601 timestamp to publish at. Omit to post immediately."),
61
+ followups: z
62
+ .array(followupSchema)
63
+ .max(25)
64
+ .optional()
65
+ .describe("Ordered replies to publish as a thread after the root post."),
66
+ },
67
+ handler: async (args) => {
68
+ const { asset_id, post_cell_id, book_id, platform = "x", text, orientation, scheduled_for, followups, } = args;
69
+ if (platform !== "x") {
70
+ return {
71
+ isError: true,
72
+ content: [
73
+ { type: "text", text: `Unsupported platform: ${platform}` },
74
+ ],
75
+ };
76
+ }
77
+ if (!text?.trim() && !post_cell_id) {
78
+ return {
79
+ isError: true,
80
+ content: [
81
+ { type: "text", text: "A post title is required" },
82
+ ],
83
+ };
84
+ }
85
+ let prepared;
86
+ try {
87
+ prepared = await queue.enqueueAndWait(`post-prepare-${post_cell_id ?? asset_id}-${Date.now()}`, { type: "post_prepare_x", bookId: book_id, assetId: asset_id, postCellId: post_cell_id, text, orientation, followups });
88
+ }
89
+ catch (error) {
90
+ return { isError: true, content: [{ type: "text", text: error instanceof Error ? error.message : String(error) }] };
91
+ }
92
+ const frozenAssetId = prepared.definition.source.snapshotArtifactId;
93
+ if (scheduled_for) {
94
+ const when = new Date(scheduled_for).getTime();
95
+ if (Number.isNaN(when)) {
96
+ return {
97
+ isError: true,
98
+ content: [
99
+ { type: "text", text: `Invalid scheduled_for: ${scheduled_for}` },
100
+ ],
101
+ };
102
+ }
103
+ if (when - Date.now() > SCHEDULE_LEAD_MS) {
104
+ try {
105
+ const result = await schedulePost({ asset_id: frozenAssetId, book_id, platform, text, post_cell_id: prepared.id }, scheduled_for);
106
+ return {
107
+ content: [
108
+ {
109
+ type: "text",
110
+ text: JSON.stringify({
111
+ status: "scheduled",
112
+ schedule_id: result.schedule_id,
113
+ scheduled_for: result.scheduled_for,
114
+ platform,
115
+ cell_id: prepared.id,
116
+ cell_address: prepared.address,
117
+ }),
118
+ },
119
+ ],
120
+ };
121
+ }
122
+ catch (err) {
123
+ return {
124
+ isError: true,
125
+ content: [
126
+ {
127
+ type: "text",
128
+ text: `Failed to schedule post: ${err instanceof Error ? err.message : String(err)}`,
129
+ },
130
+ ],
131
+ };
132
+ }
133
+ }
134
+ }
135
+ const jobId = `post-x-${prepared.id}`;
136
+ try {
137
+ const result = await queue.enqueueAndWait(jobId, {
138
+ type: "post_to_x",
139
+ assetId: frozenAssetId,
140
+ postCellId: prepared.id,
141
+ bookId: book_id,
142
+ text,
143
+ orientation,
144
+ followups,
145
+ });
146
+ return {
147
+ content: [
148
+ {
149
+ type: "text",
150
+ text: JSON.stringify(postToolResultPayload(result, platform)),
151
+ },
152
+ ],
153
+ };
154
+ }
155
+ catch (err) {
156
+ return {
157
+ isError: true,
158
+ content: [
159
+ {
160
+ type: "text",
161
+ text: `Post failed: ${err instanceof Error ? err.message : String(err)}`,
162
+ },
163
+ ],
164
+ };
165
+ }
166
+ },
167
+ };
168
+ }
@@ -0,0 +1,164 @@
1
+ import { z } from "zod";
2
+ import { PROMPT_SURFACES, isPromptSurface } from "../prompt-surfaces.js";
3
+ import { listBookEngines } from "../queue.js";
4
+ const SURFACE_LIST = PROMPT_SURFACES.join(", ");
5
+ const MAX_HISTORY_PAGE_SIZE = 1000;
6
+ function invalidSurface(value) {
7
+ return {
8
+ isError: true,
9
+ content: [
10
+ {
11
+ type: "text",
12
+ text: `Invalid surface "${String(value)}". Expected one of: ${SURFACE_LIST}`,
13
+ },
14
+ ],
15
+ };
16
+ }
17
+ export function recordPromptDef(engine) {
18
+ return {
19
+ name: "record_prompt",
20
+ description: "Append a user-typed prompt to the per-surface, per-project Dolt history. " +
21
+ "Surfaces: " +
22
+ SURFACE_LIST +
23
+ ".",
24
+ schema: {
25
+ book_id: z.string().describe("Book id"),
26
+ surface: z
27
+ .string()
28
+ .describe(`Which input surface generated this prompt (${SURFACE_LIST})`),
29
+ prompt: z.string().describe("The raw user-typed prompt to store"),
30
+ params: z
31
+ .record(z.string(), z.unknown())
32
+ .optional()
33
+ .describe("Optional params blob captured alongside the prompt (model, variant, platform, ...)"),
34
+ },
35
+ handler: async (args) => {
36
+ const { surface, prompt, params } = args;
37
+ if (!isPromptSurface(surface))
38
+ return invalidSurface(surface);
39
+ if (!prompt.trim()) {
40
+ return {
41
+ content: [
42
+ { type: "text", text: JSON.stringify({ id: null }) },
43
+ ],
44
+ };
45
+ }
46
+ const result = await engine.prompts.record({
47
+ surface,
48
+ prompt,
49
+ ...(params ? { context: params } : {}),
50
+ });
51
+ if (!result.ok)
52
+ return errorResult(result.error.message);
53
+ return {
54
+ content: [
55
+ { type: "text", text: JSON.stringify({ id: result.value.id }) },
56
+ ],
57
+ };
58
+ },
59
+ };
60
+ }
61
+ function errorResult(message) {
62
+ return {
63
+ isError: true,
64
+ content: [{ type: "text", text: message }],
65
+ };
66
+ }
67
+ function readBookPrompts(engine, surface, limit) {
68
+ const filter = surface ? { surface } : {};
69
+ const entries = engine.prompts.list({ ...filter, limit });
70
+ if (!entries.ok)
71
+ return entries.error.message;
72
+ const count = engine.prompts.count(filter);
73
+ if (!count.ok)
74
+ return count.error.message;
75
+ const book = engine.book.get().name;
76
+ return {
77
+ total: count.value,
78
+ entries: entries.value.map((entry) => ({
79
+ id: entry.id,
80
+ surface: entry.surface,
81
+ prompt: entry.prompt,
82
+ params: entry.context,
83
+ created_at: entry.createdAt,
84
+ book,
85
+ })),
86
+ };
87
+ }
88
+ function mergePromptPages(pages) {
89
+ return {
90
+ total: pages.reduce((sum, page) => sum + page.total, 0),
91
+ entries: pages
92
+ .flatMap((page) => page.entries)
93
+ .sort((left, right) => right.created_at - left.created_at),
94
+ };
95
+ }
96
+ async function scopeEngines(engine, scope) {
97
+ if (scope === "book")
98
+ return [engine];
99
+ const engines = await listBookEngines();
100
+ return engines.includes(engine) ? engines : [engine, ...engines];
101
+ }
102
+ export function listPromptHistoryDef(engine) {
103
+ return {
104
+ name: "list_prompt_history",
105
+ description: "List recent prompts newest-first, for one surface or every surface, in the current book or across the whole library.",
106
+ schema: {
107
+ book_id: z.string().describe("Book id"),
108
+ surface: z
109
+ .string()
110
+ .optional()
111
+ .describe(`Which input surface to read history for (${SURFACE_LIST}); omit for every surface`),
112
+ scope: z
113
+ .enum(["book", "library"])
114
+ .optional()
115
+ .describe("book (default) reads this book; library reads every book in the library"),
116
+ limit: z
117
+ .number()
118
+ .int()
119
+ .positive()
120
+ .max(MAX_HISTORY_PAGE_SIZE)
121
+ .optional()
122
+ .describe(`Max entries to return (default 100, capped at ${MAX_HISTORY_PAGE_SIZE})`),
123
+ offset: z
124
+ .number()
125
+ .int()
126
+ .nonnegative()
127
+ .optional()
128
+ .describe("Number of newer entries to skip"),
129
+ },
130
+ handler: async (args) => {
131
+ const { surface, scope, limit, offset } = args;
132
+ if (surface !== undefined && !isPromptSurface(surface)) {
133
+ return invalidSurface(surface);
134
+ }
135
+ const pageLimit = limit ?? 100;
136
+ const pageOffset = offset ?? 0;
137
+ const pages = [];
138
+ for (const bookEngine of await scopeEngines(engine, scope ?? "book")) {
139
+ const page = readBookPrompts(bookEngine, surface, pageOffset + pageLimit);
140
+ if (typeof page === "string")
141
+ return errorResult(page);
142
+ pages.push(page);
143
+ }
144
+ const merged = mergePromptPages(pages);
145
+ const pageEntries = merged.entries.slice(pageOffset, pageOffset + pageLimit);
146
+ return {
147
+ content: [
148
+ {
149
+ type: "text",
150
+ text: JSON.stringify({
151
+ entries: pageEntries,
152
+ page: {
153
+ offset: pageOffset,
154
+ limit: pageLimit,
155
+ total: merged.total,
156
+ has_more: pageOffset + pageEntries.length < merged.total,
157
+ },
158
+ }),
159
+ },
160
+ ],
161
+ };
162
+ },
163
+ };
164
+ }
@@ -0,0 +1,248 @@
1
+ import { createElevenLabs, createKie, createOpenAi, createXai } from "../usage-providers.js";
2
+ import { isPlaceholderApiKey } from "../api-key.js";
3
+ import { getDefaultSecretStore, isSecretEnvKey, maskEnvValue, } from "../env-secrets.js";
4
+ // Row order: live-checked providers first, then the rest grouped by provider.
5
+ const KEY_REGISTRY = {
6
+ KIE_API_KEY: { provider: "kie", label: "Kie", live: "kie-credits" },
7
+ ELEVENLABS_API_KEY: { provider: "elevenlabs", label: "ElevenLabs", live: "elevenlabs-credits" },
8
+ OPENAI_API_KEY: { provider: "openai", label: "OpenAI", live: "openai-tokens" },
9
+ XAI_API_KEY: { provider: "xai", label: "xAI", live: "xai-tokens" },
10
+ X_CLIENT_ID: { provider: "x", label: "X OAuth" },
11
+ X_CLIENT_SECRET: { provider: "x", label: "X OAuth" },
12
+ DROPBOX_CLIENT_ID: { provider: "dropbox", label: "Dropbox OAuth" },
13
+ DROPBOX_CLIENT_SECRET: { provider: "dropbox", label: "Dropbox OAuth" },
14
+ KIMI_CODING_API_KEY: { provider: "kimicoding", label: "Kimi Coding" },
15
+ FAL_API_KEY: { provider: "fal", label: "FAL" },
16
+ DASHSCOPE_API_KEY: { provider: "dashscope", label: "DashScope" },
17
+ B2_ACCESS_KEY_ID: { provider: "b2", label: "Backblaze B2" },
18
+ B2_SECRET_ACCESS_KEY: { provider: "b2", label: "Backblaze B2" },
19
+ B2_REGION: { provider: "b2", label: "Backblaze B2" },
20
+ B2_BUCKET: { provider: "b2", label: "Backblaze B2" },
21
+ B2_ENDPOINT: { provider: "b2", label: "Backblaze B2" },
22
+ B2_ARCHIVE_PREFIX: { provider: "b2", label: "Backblaze B2" },
23
+ };
24
+ const ROW_ORDER = [
25
+ "KIE_API_KEY",
26
+ "ELEVENLABS_API_KEY",
27
+ "OPENAI_API_KEY",
28
+ "XAI_API_KEY",
29
+ "X_CLIENT_ID",
30
+ "X_CLIENT_SECRET",
31
+ "DROPBOX_CLIENT_ID",
32
+ "DROPBOX_CLIENT_SECRET",
33
+ "KIMI_CODING_API_KEY",
34
+ "FAL_API_KEY",
35
+ "DASHSCOPE_API_KEY",
36
+ "B2_ACCESS_KEY_ID",
37
+ "B2_SECRET_ACCESS_KEY",
38
+ "B2_REGION",
39
+ "B2_BUCKET",
40
+ "B2_ENDPOINT",
41
+ "B2_ARCHIVE_PREFIX",
42
+ ];
43
+ const TOKEN_LOOKUP_TEXT = "Videobook token lookup";
44
+ const OPENAI_TOKEN_LOOKUP_MODEL = "gpt-5.4";
45
+ const XAI_TOKEN_LOOKUP_MODEL = "grok-4.20-reasoning";
46
+ function sanitizeMessage(error, apiKey) {
47
+ const message = error instanceof Error ? error.message : String(error);
48
+ return apiKey ? message.replaceAll(apiKey, "[redacted]") : message;
49
+ }
50
+ async function readKieCredits(apiKey) {
51
+ const provider = createKie({ apiKey, timeout: 30_000 });
52
+ const response = await provider.get.api.v1.chat.credit();
53
+ if (response.code !== 200) {
54
+ throw new Error(`Kie credit endpoint returned ${response.code}: ${response.msg}`);
55
+ }
56
+ if (typeof response.data !== "number") {
57
+ throw new Error("Kie credit endpoint did not return a numeric balance");
58
+ }
59
+ return response.data;
60
+ }
61
+ function formatInteger(value) {
62
+ return Math.round(value).toLocaleString("en-US");
63
+ }
64
+ function formatElevenLabsSubscriptionMessage(subscription) {
65
+ const remaining = formatInteger(subscription.remaining_character_count);
66
+ const limit = formatInteger(subscription.character_limit);
67
+ const used = formatInteger(subscription.character_count);
68
+ return `${subscription.tier} plan: ${remaining} of ${limit} characters remaining (${used} used)`;
69
+ }
70
+ async function readElevenLabsCredits(apiKey) {
71
+ const provider = createElevenLabs({ apiKey, timeout: 30_000 });
72
+ const subscription = await provider.v1.user.subscription();
73
+ if (!Number.isFinite(subscription.remaining_character_count)) {
74
+ throw new Error("ElevenLabs subscription endpoint did not return a numeric remaining character count");
75
+ }
76
+ return {
77
+ value: subscription.remaining_character_count,
78
+ message: formatElevenLabsSubscriptionMessage(subscription),
79
+ };
80
+ }
81
+ async function readOpenAiTokens(apiKey) {
82
+ const provider = createOpenAi({ apiKey, timeout: 30_000 });
83
+ const response = await provider.post.v1.responses.inputTokens({
84
+ model: OPENAI_TOKEN_LOOKUP_MODEL,
85
+ input: TOKEN_LOOKUP_TEXT,
86
+ });
87
+ return {
88
+ value: response.input_tokens,
89
+ model: OPENAI_TOKEN_LOOKUP_MODEL,
90
+ };
91
+ }
92
+ async function readXaiTokens(apiKey) {
93
+ const provider = createXai({ apiKey, timeout: 30_000 });
94
+ const response = await provider.post.v1.tokenizeText({
95
+ model: XAI_TOKEN_LOOKUP_MODEL,
96
+ text: TOKEN_LOOKUP_TEXT,
97
+ });
98
+ return {
99
+ value: response.token_ids.length,
100
+ model: XAI_TOKEN_LOOKUP_MODEL,
101
+ };
102
+ }
103
+ function creditsInfo(status, message) {
104
+ return { status, value: null, unit: "credits", fetchedAt: null, message };
105
+ }
106
+ function tokenLookupInfo(status, message) {
107
+ return { status, value: null, unit: "tokens", model: null, fetchedAt: null, message };
108
+ }
109
+ function unavailableCredits(message) {
110
+ return creditsInfo("unavailable", message);
111
+ }
112
+ function unavailableTokenLookup(message) {
113
+ return tokenLookupInfo("unavailable", message);
114
+ }
115
+ const NO_CREDITS_MESSAGE = "Credit balance is not available for this provider";
116
+ const NO_TOKEN_LOOKUP_MESSAGE = "Token lookup is not available for this provider";
117
+ function buildKeyBase(envKey, store) {
118
+ const entry = KEY_REGISTRY[envKey];
119
+ const source = store.getSource(envKey);
120
+ const secret = isSecretEnvKey(envKey);
121
+ const raw = store.getValue(envKey);
122
+ const value = !raw || raw.startsWith("op://") ? null : raw;
123
+ let keyStatus = "configured";
124
+ if (value === null)
125
+ keyStatus = "missing";
126
+ else if (isPlaceholderApiKey(value))
127
+ keyStatus = "placeholder";
128
+ const maskedKey = keyStatus !== "configured" || value === null
129
+ ? null
130
+ : secret
131
+ ? maskEnvValue(value)
132
+ : value;
133
+ return {
134
+ base: {
135
+ envKey,
136
+ provider: entry.provider,
137
+ label: entry.label,
138
+ keyStatus,
139
+ maskedKey,
140
+ secret,
141
+ source,
142
+ editable: source !== "1password",
143
+ },
144
+ value: keyStatus === "configured" ? value : null,
145
+ };
146
+ }
147
+ function statusOnlyInfo(base) {
148
+ if (base.keyStatus === "missing") {
149
+ const message = `${base.envKey} environment variable is not set`;
150
+ return { ...base, credits: creditsInfo("missing_key", message), tokenLookup: tokenLookupInfo("missing_key", message) };
151
+ }
152
+ if (base.keyStatus === "placeholder") {
153
+ const message = `${base.envKey} is a placeholder; refusing to call the real API`;
154
+ return { ...base, credits: creditsInfo("placeholder_key", message), tokenLookup: tokenLookupInfo("placeholder_key", message) };
155
+ }
156
+ return {
157
+ ...base,
158
+ credits: unavailableCredits(NO_CREDITS_MESSAGE),
159
+ tokenLookup: unavailableTokenLookup(NO_TOKEN_LOOKUP_MESSAGE),
160
+ };
161
+ }
162
+ function normalizeCreditLookupResult(result) {
163
+ if (typeof result === "number") {
164
+ return { value: result, message: null };
165
+ }
166
+ return result;
167
+ }
168
+ async function creditLookupInfo(base, apiKey, readCredits) {
169
+ const tokenLookup = unavailableTokenLookup(NO_TOKEN_LOOKUP_MESSAGE);
170
+ try {
171
+ const result = normalizeCreditLookupResult(await readCredits(apiKey));
172
+ return {
173
+ ...base,
174
+ credits: {
175
+ status: "ok",
176
+ value: result.value,
177
+ unit: "credits",
178
+ fetchedAt: new Date().toISOString(),
179
+ message: result.message,
180
+ },
181
+ tokenLookup,
182
+ };
183
+ }
184
+ catch (error) {
185
+ return {
186
+ ...base,
187
+ credits: creditsInfo("error", sanitizeMessage(error, apiKey)),
188
+ tokenLookup,
189
+ };
190
+ }
191
+ }
192
+ async function tokenLookupKeyInfo(base, apiKey, readTokens) {
193
+ const credits = unavailableCredits(NO_CREDITS_MESSAGE);
194
+ try {
195
+ const result = await readTokens(apiKey);
196
+ return {
197
+ ...base,
198
+ credits,
199
+ tokenLookup: {
200
+ status: "ok",
201
+ value: result.value,
202
+ unit: "tokens",
203
+ model: result.model,
204
+ fetchedAt: new Date().toISOString(),
205
+ message: null,
206
+ },
207
+ };
208
+ }
209
+ catch (error) {
210
+ return {
211
+ ...base,
212
+ credits,
213
+ tokenLookup: tokenLookupInfo("error", sanitizeMessage(error, apiKey)),
214
+ };
215
+ }
216
+ }
217
+ export async function getProviderKeyStatus(deps = {}) {
218
+ const store = deps.store ?? getDefaultSecretStore();
219
+ const creditReaders = {
220
+ "kie-credits": deps.readKieCredits ?? readKieCredits,
221
+ "elevenlabs-credits": deps.readElevenLabsCredits ?? readElevenLabsCredits,
222
+ };
223
+ const tokenReaders = {
224
+ "openai-tokens": deps.readOpenAiTokens ?? readOpenAiTokens,
225
+ "xai-tokens": deps.readXaiTokens ?? readXaiTokens,
226
+ };
227
+ const providers = await Promise.all(ROW_ORDER.map((envKey) => {
228
+ const { base, value } = buildKeyBase(envKey, store);
229
+ const live = KEY_REGISTRY[envKey].live;
230
+ if (!live || value === null)
231
+ return Promise.resolve(statusOnlyInfo(base));
232
+ if (live === "kie-credits" || live === "elevenlabs-credits") {
233
+ return creditLookupInfo(base, value, creditReaders[live]);
234
+ }
235
+ return tokenLookupKeyInfo(base, value, tokenReaders[live]);
236
+ }));
237
+ return { providers };
238
+ }
239
+ export function providerKeyStatusDef(deps = {}) {
240
+ return {
241
+ name: "provider_key_status",
242
+ description: "List all managed environment keys with their source (1password = injected via op run, read-only; env = from .env, editable), masked values, and live credit/token lookups for supported providers. Never exposes secret values.",
243
+ schema: {},
244
+ handler: async () => ({
245
+ content: [{ type: "text", text: JSON.stringify(await getProviderKeyStatus(deps)) }],
246
+ }),
247
+ };
248
+ }