@oh-story/dsh 0.1.7 → 0.1.9

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 (272) hide show
  1. package/README.md +30 -15
  2. package/lib/client.js +93 -16
  3. package/lib/client.js.map +2 -2
  4. package/lib/drama/manifest.json +165 -69
  5. package/lib/drama/skills/short-drama/SKILL.md +5 -1
  6. package/lib/drama/skills/short-drama/scripts/creator_markdown_check.py +126 -9
  7. package/lib/drama/skills/short-drama/scripts/project_tool.py +11 -0
  8. package/lib/drama/skills/short-drama-assets/references/character-and-look.md +18 -0
  9. package/lib/drama/skills/short-drama-assets/references/continuity-lock.md +10 -1
  10. package/lib/drama/skills/short-drama-edit/SKILL.md +148 -0
  11. package/lib/drama/skills/short-drama-edit/agents/openai.yaml +4 -0
  12. package/lib/drama/skills/short-drama-edit/assets/remotion/README.md +60 -0
  13. package/lib/drama/skills/short-drama-edit/assets/remotion/package.json +15 -0
  14. package/lib/drama/skills/short-drama-edit/assets/remotion/remotion.config.ts +6 -0
  15. package/lib/drama/skills/short-drama-edit/assets/remotion/src/Root.tsx +26 -0
  16. package/lib/drama/skills/short-drama-edit/assets/remotion/src/Subtitles.tsx +88 -0
  17. package/lib/drama/skills/short-drama-edit/assets/remotion/src/font.ts +46 -0
  18. package/lib/drama/skills/short-drama-edit/assets/remotion/src/index.ts +4 -0
  19. package/lib/drama/skills/short-drama-edit/assets/remotion/src/schema.ts +32 -0
  20. package/lib/drama/skills/short-drama-edit/assets/remotion/tsconfig.json +13 -0
  21. package/lib/drama/skills/short-drama-edit/assets//345/211/252/350/276/221/345/215/225.md +43 -0
  22. package/lib/drama/skills/short-drama-edit/references/cut-craft.md +81 -0
  23. package/lib/drama/skills/short-drama-edit/references/delivery-verify.md +58 -0
  24. package/lib/drama/skills/short-drama-edit/references/generated-footage.md +96 -0
  25. package/lib/drama/skills/short-drama-edit/references/sound-and-subtitles.md +113 -0
  26. package/lib/drama/skills/short-drama-edit/references/stage-contract.md +55 -0
  27. package/lib/drama/skills/short-drama-edit/scripts/edit_tool.py +1041 -0
  28. package/lib/drama/skills/short-drama-edit/scripts/selftest.py +456 -0
  29. package/lib/drama/skills/short-drama-image-prompts/assets/image-prompts.md +5 -0
  30. package/lib/drama/skills/short-drama-image-prompts/assets/lookdev-prompts.md +3 -0
  31. package/lib/drama/skills/short-drama-novel-analyze/references/aggregation-and-entities.md +2 -2
  32. package/lib/drama/skills/short-drama-novel-analyze/references/chapter-extraction.md +4 -1
  33. package/lib/drama/skills/short-drama-produce/SKILL.md +24 -3
  34. package/lib/drama/skills/short-drama-produce/references/adapter-contract.md +28 -0
  35. package/lib/drama/skills/short-drama-produce/references/providers/minimax-h3-video.md +24 -5
  36. package/lib/drama/skills/short-drama-produce/references/providers/seedance.md +7 -0
  37. package/lib/drama/skills/short-drama-produce/scripts/fixture_adapter.py +18 -1
  38. package/lib/drama/skills/short-drama-produce/scripts/production_tool.py +181 -2
  39. package/lib/drama/skills/short-drama-produce/scripts/provider_adapters.py +57 -2
  40. package/lib/drama/skills/short-drama-review/SKILL.md +3 -0
  41. package/lib/drama/skills/short-drama-review/references/production-quality-gates.md +20 -0
  42. package/lib/drama/skills/short-drama-review/references/rubric-visual-motion.md +36 -0
  43. package/lib/drama/skills/short-drama-storyboard/SKILL.md +7 -0
  44. package/lib/drama/skills/short-drama-storyboard/assets/keyframe-prompts.md +4 -0
  45. package/lib/drama/skills/short-drama-storyboard/references/shot-craft.md +39 -0
  46. package/lib/drama/skills/short-drama-storyboard/references/stage-contract.md +2 -0
  47. package/lib/drama/skills/short-drama-video-prompts/SKILL.md +7 -1
  48. package/lib/drama/skills/short-drama-video-prompts/references/minimax-h3.md +101 -6
  49. package/lib/drama/skills/short-drama-video-prompts/references/motion-recipe.md +7 -1
  50. package/lib/drama/skills/short-drama-video-prompts/references/performance-action-timing.md +35 -0
  51. package/lib/drama/skills/short-drama-video-prompts/references/production-prompt-grammar.md +3 -1
  52. package/lib/drama/skills/short-drama-video-prompts/references/seedance-2.0.md +13 -3
  53. package/lib/drama/skills/short-drama-video-prompts/references/seedance-2.5.md +35 -4
  54. package/lib/drama/skills/short-drama-video-prompts/references/stage-contract.md +1 -1
  55. package/lib/drama/skills/short-drama-write/SKILL.md +13 -2
  56. package/lib/drama/skills/short-drama-write/references/screenplay-format.md +6 -0
  57. package/lib/drama/skills/short-drama-write/references/stage-contract.md +1 -0
  58. package/lib/index.js +4 -2
  59. package/lib/index.js.map +2 -2
  60. package/lib/novel-to-game/VERSION +1 -1
  61. package/lib/novel-to-game/manifest.json +28 -28
  62. package/lib/novel-to-game/skills/game-art-direction/SKILL.md +6 -27
  63. package/lib/novel-to-game/skills/game-build/SKILL.md +12 -29
  64. package/lib/novel-to-game/skills/game-concept/SKILL.md +10 -26
  65. package/lib/novel-to-game/skills/game-qa/SKILL.md +5 -15
  66. package/lib/novel-to-game/skills/game-qa/references/test-design-method.md +1 -1
  67. package/lib/novel-to-game/skills/game-world-design/SKILL.md +19 -28
  68. package/lib/novel-to-game/skills/game-world-design/references/dialogue-design-method.md +1 -2
  69. package/lib/novel-to-game/skills/novel-game-analyze/SKILL.md +6 -9
  70. package/lib/novel-to-game/skills/novel-to-game/SKILL.md +6 -11
  71. package/lib/novel-to-game/skills/novel-to-game/references/intake-benchmark-reference.md +0 -4
  72. package/lib/novel-to-game/skills/novel-to-game/references/intake-method.md +1 -3
  73. package/lib/novel-to-game/skills/novel-to-game/references/pipeline-contract.md +3 -5
  74. package/lib/oh-story/manifest.json +292 -172
  75. package/lib/oh-story/roles/character-designer.md +1 -1
  76. package/lib/oh-story/roles/narrative-writer.md +56 -242
  77. package/lib/oh-story/roles/story-architect.md +1 -1
  78. package/lib/oh-story/skills/story/SKILL.md +1 -1
  79. package/lib/oh-story/skills/story/VERSION +1 -1
  80. package/lib/oh-story/skills/story/references/author-memory.md +10 -8
  81. package/lib/oh-story/skills/story-deslop/SKILL.md +20 -182
  82. package/lib/oh-story/skills/story-deslop/references/anti-ai-writing.md +19 -47
  83. package/lib/oh-story/skills/story-deslop/references/author-memory.md +10 -8
  84. package/lib/oh-story/skills/story-deslop/references/banned-words.md +3 -1
  85. package/lib/oh-story/skills/story-deslop/references/deslop-gates.md +154 -0
  86. package/lib/oh-story/skills/story-deslop/references/style-resolution.md +27 -0
  87. package/lib/oh-story/skills/story-deslop/scripts/check-ai-patterns.js +6 -1
  88. package/lib/oh-story/skills/story-deslop/scripts/check-degeneration.js +39 -20
  89. package/lib/oh-story/skills/story-deslop/scripts/normalize-punctuation.js +10 -5
  90. package/lib/oh-story/skills/story-deslop/scripts/style-whitelist.js +39 -0
  91. package/lib/oh-story/skills/story-import/SKILL.md +2 -2
  92. package/lib/oh-story/skills/story-import/references/format-and-structure.md +2 -2
  93. package/lib/oh-story/skills/story-import/references/tracking-initialization.md +31 -0
  94. package/lib/oh-story/skills/story-import/references/tracking-transaction.md +2 -29
  95. package/lib/oh-story/skills/story-import/scripts/check-outline-contract.js +176 -12
  96. package/lib/oh-story/skills/story-long-analyze/SKILL.md +1 -1
  97. package/lib/oh-story/skills/story-long-write/SKILL.md +20 -193
  98. package/lib/oh-story/skills/story-long-write/references/anti-ai-writing.md +19 -47
  99. package/lib/oh-story/skills/story-long-write/references/artifact-protocols.md +62 -7
  100. package/lib/oh-story/skills/story-long-write/references/author-memory.md +10 -8
  101. package/lib/oh-story/skills/story-long-write/references/banned-words.md +3 -1
  102. package/lib/oh-story/skills/story-long-write/references/benchmark-recall.md +20 -0
  103. package/lib/oh-story/skills/story-long-write/references/dialogue-mastery.md +6 -4
  104. package/lib/oh-story/skills/story-long-write/references/long-chapter-quality.md +2 -2
  105. package/lib/oh-story/skills/story-long-write/references/long-format.md +2 -0
  106. package/lib/oh-story/skills/story-long-write/references/outline-structure-theory.md +2 -0
  107. package/lib/oh-story/skills/story-long-write/references/project-files.md +108 -0
  108. package/lib/oh-story/skills/story-long-write/references/reference-index.md +87 -0
  109. package/lib/oh-story/skills/story-long-write/references/style-combat-face.md +1 -1
  110. package/lib/oh-story/skills/story-long-write/references/style-craft.md +9 -29
  111. package/lib/oh-story/skills/story-long-write/references/style-genre-modules.md +1 -1
  112. package/lib/oh-story/skills/story-long-write/references/style-resolution.md +27 -0
  113. package/lib/oh-story/skills/story-long-write/references/tracking-initialization.md +31 -0
  114. package/lib/oh-story/skills/story-long-write/references/tracking-transaction.md +2 -29
  115. package/lib/oh-story/skills/story-long-write/references/workflow-chapter.md +51 -52
  116. package/lib/oh-story/skills/story-long-write/references/workflow-daily.md +8 -7
  117. package/lib/oh-story/skills/story-long-write/references/workflow-setup.md +36 -15
  118. package/lib/oh-story/skills/story-long-write/references/writer-prompt-fallback.md +22 -0
  119. package/lib/oh-story/skills/story-long-write/references/writing-craft.md +69 -2
  120. package/lib/oh-story/skills/story-long-write/scripts/build_writer_prompt.py +410 -0
  121. package/lib/oh-story/skills/story-long-write/scripts/check-ai-patterns.js +6 -1
  122. package/lib/oh-story/skills/story-long-write/scripts/check-degeneration.js +39 -20
  123. package/lib/oh-story/skills/story-long-write/scripts/check-outline-contract.js +176 -12
  124. package/lib/oh-story/skills/story-long-write/scripts/check-outline-copy.js +90 -23
  125. package/lib/oh-story/skills/story-long-write/scripts/normalize-punctuation.js +10 -5
  126. package/lib/oh-story/skills/story-long-write/scripts/outline_view.py +283 -0
  127. package/lib/oh-story/skills/story-long-write/scripts/style-whitelist.js +39 -0
  128. package/lib/oh-story/skills/story-review/SKILL.md +13 -3
  129. package/lib/oh-story/skills/story-review/references/anti-ai-writing.md +19 -47
  130. package/lib/oh-story/skills/story-review/references/author-memory.md +10 -8
  131. package/lib/oh-story/skills/story-review/references/banned-words.md +3 -1
  132. package/lib/oh-story/skills/story-review/references/dialogue-mastery.md +6 -4
  133. package/lib/oh-story/skills/story-review/references/review-quality.md +2 -2
  134. package/lib/oh-story/skills/story-review/references/style-resolution.md +27 -0
  135. package/lib/oh-story/skills/story-review/references/tracking-initialization.md +31 -0
  136. package/lib/oh-story/skills/story-review/references/tracking-transaction.md +2 -29
  137. package/lib/oh-story/skills/story-review/scripts/check-ai-patterns.js +6 -1
  138. package/lib/oh-story/skills/story-review/scripts/check-degeneration.js +39 -20
  139. package/lib/oh-story/skills/story-review/scripts/normalize-punctuation.js +10 -5
  140. package/lib/oh-story/skills/story-review/scripts/style-whitelist.js +39 -0
  141. package/lib/oh-story/skills/story-setup/SKILL.md +17 -10
  142. package/lib/oh-story/skills/story-setup/references/agent-references/anti-ai-writing.md +19 -47
  143. package/lib/oh-story/skills/story-setup/references/agent-references/banned-words.md +3 -1
  144. package/lib/oh-story/skills/story-setup/references/agent-references/deslop-gates.md +154 -0
  145. package/lib/oh-story/skills/story-setup/references/agent-references/dialogue-mastery.md +6 -4
  146. package/lib/oh-story/skills/story-setup/references/agent-references/format-and-structure.md +2 -2
  147. package/lib/oh-story/skills/story-setup/references/agent-references/short-genre-formulas.md +1 -1
  148. package/lib/oh-story/skills/story-setup/references/agent-references/style-combat-face.md +1 -1
  149. package/lib/oh-story/skills/story-setup/references/agent-references/style-genre-modules.md +1 -1
  150. package/lib/oh-story/skills/story-setup/references/agent-references/style-resolution.md +27 -0
  151. package/lib/oh-story/skills/story-setup/references/agent-references/writing-craft.md +69 -2
  152. package/lib/oh-story/skills/story-setup/references/diagnostics.md +38 -0
  153. package/lib/oh-story/skills/story-short-analyze/references/analysis-writing-techniques.md +1 -1
  154. package/lib/oh-story/skills/story-short-analyze/references/source-story-quality.md +2 -2
  155. package/lib/oh-story/skills/story-short-write/SKILL.md +18 -186
  156. package/lib/oh-story/skills/story-short-write/references/author-memory.md +10 -8
  157. package/lib/oh-story/skills/story-short-write/references/banned-words.md +3 -1
  158. package/lib/oh-story/skills/story-short-write/references/benchmark-recall.md +60 -0
  159. package/lib/oh-story/skills/story-short-write/references/dialogue-mastery.md +6 -4
  160. package/lib/oh-story/skills/story-short-write/references/genre-styles//344/270/226/346/203/205/346/211/223/350/204/270.md +2 -2
  161. package/lib/oh-story/skills/story-short-write/references/genre-styles//345/217/214/347/224/267/344/270/273.md +1 -1
  162. package/lib/oh-story/skills/story-short-write/references/genre-styles//345/244/215/344/273/207/346/211/223/350/204/270.md +3 -3
  163. package/lib/oh-story/skills/story-short-write/references/genre-styles//345/256/205/346/226/227/345/256/253/346/226/227.md +3 -3
  164. package/lib/oh-story/skills/story-short-write/references/genre-styles//346/200/273/350/243/201/350/261/252/351/227/250.md +3 -3
  165. package/lib/oh-story/skills/story-short-write/references/genre-styles//346/202/254/347/226/221.md +5 -5
  166. package/lib/oh-story/skills/story-short-write/references/genre-styles//346/260/221/344/277/227/346/200/252/350/260/210.md +4 -4
  167. package/lib/oh-story/skills/story-short-write/references/genre-styles//347/224/234/345/256/240.md +5 -5
  168. package/lib/oh-story/skills/story-short-write/references/genre-styles//350/277/275/345/246/273/347/201/253/350/221/254/345/234/272.md +3 -3
  169. package/lib/oh-story/skills/story-short-write/references/genre-writing-formulas.md +1 -1
  170. package/lib/oh-story/skills/story-short-write/references/genre-writing-techniques.md +1 -1
  171. package/lib/oh-story/skills/story-short-write/references/reference-index.md +53 -0
  172. package/lib/oh-story/skills/story-short-write/references/short-craft.md +12 -14
  173. package/lib/oh-story/skills/story-short-write/references/short-deslop.md +10 -10
  174. package/lib/oh-story/skills/story-short-write/references/short-format.md +3 -1
  175. package/lib/oh-story/skills/story-short-write/references/short-prose-quality.md +2 -2
  176. package/lib/oh-story/skills/story-short-write/references/style-resolution.md +27 -0
  177. package/lib/oh-story/skills/story-short-write/references/workflow-design.md +77 -0
  178. package/lib/oh-story/skills/story-short-write/references/writing-workflow.md +5 -5
  179. package/lib/oh-story/skills/story-short-write/scripts/check-ai-patterns.js +6 -1
  180. package/lib/oh-story/skills/story-short-write/scripts/check-degeneration.js +39 -20
  181. package/lib/oh-story/skills/story-short-write/scripts/check-delivery-contract.js +34 -5
  182. package/lib/oh-story/skills/story-short-write/scripts/check-outline-copy.js +90 -23
  183. package/lib/oh-story/skills/story-short-write/scripts/normalize-punctuation.js +10 -5
  184. package/lib/oh-story/skills/story-short-write/scripts/style-whitelist.js +39 -0
  185. package/lib/types/client/drama-production-view.d.ts.map +1 -1
  186. package/lib/types/client/index.d.ts.map +1 -1
  187. package/lib/types/client/production-prompts.d.ts.map +1 -1
  188. package/lib/types/client/production-runtime.d.ts +17 -0
  189. package/lib/types/client/production-runtime.d.ts.map +1 -1
  190. package/lib/types/skill-provider.d.ts.map +1 -1
  191. package/lib/video-recap/CHANGELOG.md +31 -1
  192. package/lib/video-recap/manifest.json +162 -162
  193. package/lib/video-recap/skills/video-assemble/scripts/artifacts.py +4 -9
  194. package/lib/video-recap/skills/video-assemble/scripts/assemble.py +47 -60
  195. package/lib/video-recap/skills/video-assemble/scripts/assembly_contract.py +77 -115
  196. package/lib/video-recap/skills/video-assemble/scripts/assembly_settings.py +41 -40
  197. package/lib/video-recap/skills/video-assemble/scripts/audio_automation.py +22 -32
  198. package/lib/video-recap/skills/video-assemble/scripts/audio_mix.py +102 -192
  199. package/lib/video-recap/skills/video-assemble/scripts/jianying_builders.py +14 -35
  200. package/lib/video-recap/skills/video-assemble/scripts/jianying_model.py +14 -12
  201. package/lib/video-recap/skills/video-assemble/scripts/jianying_optional.py +8 -9
  202. package/lib/video-recap/skills/video-assemble/scripts/jianying_schema.py +3 -14
  203. package/lib/video-recap/skills/video-assemble/scripts/jianying_timeline_contract.py +23 -12
  204. package/lib/video-recap/skills/video-assemble/scripts/jianying_tracks.py +1 -4
  205. package/lib/video-recap/skills/video-assemble/scripts/jianying_writer.py +24 -25
  206. package/lib/video-recap/skills/video-assemble/scripts/lib.py +31 -85
  207. package/lib/video-recap/skills/video-assemble/scripts/media.py +100 -144
  208. package/lib/video-recap/skills/video-assemble/scripts/narration_audio.py +101 -195
  209. package/lib/video-recap/skills/video-assemble/scripts/render_preflight.py +10 -21
  210. package/lib/video-recap/skills/video-assemble/scripts/source_subtitles.py +90 -169
  211. package/lib/video-recap/skills/video-assemble/scripts/subtitle_core.py +69 -122
  212. package/lib/video-recap/skills/video-assemble/scripts/subtitle_render.py +10 -17
  213. package/lib/video-recap/skills/video-assemble/scripts/timeline.py +33 -48
  214. package/lib/video-recap/skills/video-assemble/scripts/timeline_emit.py +14 -20
  215. package/lib/video-recap/skills/video-assemble/scripts/visual_render.py +135 -213
  216. package/lib/video-recap/skills/video-cut/scripts/cut_cli.py +49 -57
  217. package/lib/video-recap/skills/video-cut/scripts/cut_contract.py +38 -74
  218. package/lib/video-recap/skills/video-cut/scripts/cut_render.py +46 -95
  219. package/lib/video-recap/skills/video-cut/scripts/lib.py +23 -25
  220. package/lib/video-recap/skills/video-cut/scripts/media_geometry.py +70 -173
  221. package/lib/video-recap/skills/video-cut/scripts/narration_mapping.py +28 -53
  222. package/lib/video-recap/skills/video-cut/scripts/sentence_boundaries.py +162 -322
  223. package/lib/video-recap/skills/video-recap/references/timeline-and-jianying.md +6 -7
  224. package/lib/video-recap/skills/video-recap/scripts/doctor.py +104 -124
  225. package/lib/video-recap/skills/video-recap/scripts/final_qc.py +255 -412
  226. package/lib/video-recap/skills/video-recap/scripts/lib.py +30 -52
  227. package/lib/video-recap/skills/video-recap/scripts/materials.py +97 -120
  228. package/lib/video-recap/skills/video-recap/scripts/mimo_qc_client.py +7 -12
  229. package/lib/video-recap/skills/video-recap/scripts/mimo_qc_evidence.py +46 -97
  230. package/lib/video-recap/skills/video-recap/scripts/mimo_qc_observations.py +18 -36
  231. package/lib/video-recap/skills/video-recap/scripts/mimo_qc_payload.py +29 -47
  232. package/lib/video-recap/skills/video-recap/scripts/mimo_qc_report.py +43 -76
  233. package/lib/video-recap/skills/video-recap/scripts/mimo_qc_runner.py +2 -1
  234. package/lib/video-recap/skills/video-recap/scripts/qc_contract.py +2 -1
  235. package/lib/video-recap/skills/video-recap/scripts/recap_cli.py +2 -2
  236. package/lib/video-recap/skills/video-recap/scripts/recap_inspect.py +129 -145
  237. package/lib/video-recap/skills/video-recap/scripts/recap_review.py +27 -20
  238. package/lib/video-recap/skills/video-recap/scripts/recap_runner.py +20 -31
  239. package/lib/video-recap/skills/video-recap/scripts/recap_runtime.py +31 -106
  240. package/lib/video-recap/skills/video-recap/scripts/recap_stage_qc.py +43 -113
  241. package/lib/video-recap/skills/video-recap/scripts/recap_timeline.py +196 -377
  242. package/lib/video-recap/skills/video-script/scripts/agent_brief.py +1 -1
  243. package/lib/video-recap/skills/video-script/scripts/agent_text.py +63 -172
  244. package/lib/video-recap/skills/video-script/scripts/brief_context.py +80 -135
  245. package/lib/video-recap/skills/video-script/scripts/brief_inputs.py +125 -167
  246. package/lib/video-recap/skills/video-script/scripts/brief_timeline.py +93 -208
  247. package/lib/video-recap/skills/video-script/scripts/deslop_qc.py +20 -46
  248. package/lib/video-recap/skills/video-script/scripts/lib.py +30 -26
  249. package/lib/video-recap/skills/video-script/scripts/narration_lint.py +145 -140
  250. package/lib/video-recap/skills/video-script/scripts/review_response.py +12 -42
  251. package/lib/video-recap/skills/video-script/scripts/review_runner.py +0 -6
  252. package/lib/video-recap/skills/video-script/scripts/speech_ownership.py +39 -100
  253. package/lib/video-recap/skills/video-script/scripts/timeline_fusion.py +33 -124
  254. package/lib/video-recap/skills/video-understanding/scripts/agent_brief.py +1 -1
  255. package/lib/video-recap/skills/video-understanding/scripts/agent_text.py +63 -172
  256. package/lib/video-recap/skills/video-understanding/scripts/asr.py +1 -2
  257. package/lib/video-recap/skills/video-understanding/scripts/brief_context.py +80 -135
  258. package/lib/video-recap/skills/video-understanding/scripts/brief_inputs.py +125 -167
  259. package/lib/video-recap/skills/video-understanding/scripts/brief_timeline.py +93 -208
  260. package/lib/video-recap/skills/video-understanding/scripts/consolidate.py +1 -1
  261. package/lib/video-recap/skills/video-understanding/scripts/deslop_qc.py +20 -46
  262. package/lib/video-recap/skills/video-understanding/scripts/lib.py +31 -26
  263. package/lib/video-recap/skills/video-understanding/scripts/narration_lint.py +145 -140
  264. package/lib/video-recap/skills/video-understanding/scripts/speech_ownership.py +39 -100
  265. package/lib/video-recap/skills/video-understanding/scripts/timeline_fusion.py +33 -124
  266. package/lib/video-recap/skills/video-understanding/scripts/vlm.py +1 -4
  267. package/lib/video-recap/skills/video-voiceover/scripts/dub.py +7 -13
  268. package/lib/video-recap/skills/video-voiceover/scripts/fish_audio.py +12 -30
  269. package/lib/video-recap/skills/video-voiceover/scripts/lib.py +98 -131
  270. package/lib/video-recap/skills/video-voiceover/scripts/tts_audio.py +17 -28
  271. package/lib/video-recap/skills/video-voiceover/scripts/voiceover.py +151 -240
  272. package/package.json +41 -41
@@ -17,21 +17,22 @@ def assembly_settings_fingerprint(work_dir=None):
17
17
  """Settings that affect the rendered video, used by pipeline resume cache. When work_dir is
18
18
  given, a user_subtitles presence flag is included so dropping in a user-subtitle file rebuilds
19
19
  the cached subtitles."""
20
- burn_subtitles = bool(CONFIG.get("burn_subtitles", False))
20
+ burn_subtitles = CONFIG["burn_subtitles"]
21
21
  mask_policy = _source_subtitle_mask_policy(work_dir)
22
- mask_source_subtitles = bool(mask_policy["active"])
23
- user_subtitles = _has_user_subtitles(work_dir)
24
- overlay_path = Path(work_dir) / VISUAL_OVERLAYS if work_dir is not None else None
22
+ mask_source_subtitles = mask_policy["active"]
23
+ overlay_fingerprint = (
24
+ _artifact_fingerprint(Path(work_dir) / VISUAL_OVERLAYS) if work_dir is not None else None
25
+ )
25
26
  fingerprint = {
26
27
  "version": SUBTITLE_RENDER_VERSION,
27
28
  "subtitle_text_normalize": SUBTITLE_TEXT_NORMALIZE_VERSION,
28
- "user_subtitles": user_subtitles,
29
+ "user_subtitles": _has_user_subtitles(work_dir),
29
30
  "burn_subtitles": burn_subtitles,
30
- "force_video_reencode": bool(CONFIG.get("force_video_reencode", False)),
31
+ "force_video_reencode": CONFIG["force_video_reencode"],
31
32
  "encode": {
32
- "output_crf": CONFIG.get("output_crf", 18),
33
- "output_preset": CONFIG.get("output_preset", "veryfast"),
34
- "output_max_height": CONFIG.get("output_max_height", 0),
33
+ "output_crf": CONFIG["output_crf"],
34
+ "output_preset": CONFIG["output_preset"],
35
+ "output_max_height": CONFIG["output_max_height"],
35
36
  },
36
37
  "video_filters": {
37
38
  "mask_source_subtitles": mask_source_subtitles,
@@ -39,53 +40,53 @@ def assembly_settings_fingerprint(work_dir=None):
39
40
  "source_subtitle_mask_policy_declared": mask_policy["declared"],
40
41
  "source_subtitle_mask_policy_trigger": mask_policy["trigger"],
41
42
  "source_subtitle_mask_ratio": (
42
- CONFIG.get("source_subtitle_mask_ratio", 0.14) if mask_source_subtitles else None
43
+ CONFIG["source_subtitle_mask_ratio"] if mask_source_subtitles else None
43
44
  ),
44
45
  "source_subtitle_mask_timing": (
45
- CONFIG.get("source_subtitle_mask_timing", "narration") if mask_source_subtitles else None
46
+ CONFIG["source_subtitle_mask_timing"] if mask_source_subtitles else None
46
47
  ),
47
48
  "subtitle_mask_opacity": (
48
- CONFIG.get("subtitle_mask_opacity", 0.6) if mask_source_subtitles else None
49
+ CONFIG["subtitle_mask_opacity"] if mask_source_subtitles else None
49
50
  ),
50
51
  "subtitle_mask_padding": (
51
- CONFIG.get("subtitle_mask_padding", 4) if mask_source_subtitles else None
52
+ CONFIG["subtitle_mask_padding"] if mask_source_subtitles else None
52
53
  ),
53
- "subtitle_y_top": CONFIG.get("subtitle_y_top", -1),
54
- "subtitle_y_bot": CONFIG.get("subtitle_y_bot", -1),
54
+ "subtitle_y_top": CONFIG["subtitle_y_top"],
55
+ "subtitle_y_bot": CONFIG["subtitle_y_bot"],
55
56
  "visual_overlays": {
56
57
  "artifact": VISUAL_OVERLAYS,
57
- "present": bool(overlay_path and overlay_path.exists()),
58
- "fingerprint": _artifact_fingerprint(overlay_path) if overlay_path and overlay_path.exists() else None,
58
+ "present": overlay_fingerprint is not None,
59
+ "fingerprint": overlay_fingerprint,
59
60
  },
60
61
  },
61
62
  "narration_timing": {
62
- "delay_seconds": CONFIG.get("narration_delay_seconds", 0.0),
63
- "tail_pad_seconds": CONFIG.get("narration_tail_pad_seconds", 0.1),
64
- "fade_ms": CONFIG.get("fade_ms", 120),
65
- "narration_speed": CONFIG.get("narration_speed", 1.0),
66
- "narration_cumulative_tempo_max": CONFIG.get("narration_cumulative_tempo_max", 1.35),
67
- "tts_segment_tempo_max": CONFIG.get("tts_segment_tempo_max", 1.20),
63
+ "delay_seconds": CONFIG["narration_delay_seconds"],
64
+ "tail_pad_seconds": CONFIG["narration_tail_pad_seconds"],
65
+ "fade_ms": CONFIG["fade_ms"],
66
+ "narration_speed": CONFIG["narration_speed"],
67
+ "narration_cumulative_tempo_max": CONFIG["narration_cumulative_tempo_max"],
68
+ "tts_segment_tempo_max": CONFIG["tts_segment_tempo_max"],
68
69
  },
69
70
  "audio_mix": {
70
- "ducking_mode": CONFIG.get("ducking_mode", "fixed"),
71
- "duck_fade_seconds": CONFIG.get("duck_fade_seconds", 0.3),
72
- "duck_bridge_seconds": CONFIG.get("duck_bridge_seconds", 1.5),
73
- "ducking_narr_weight": CONFIG.get("ducking_narr_weight", 1.5),
74
- "ducking_orig_volume": CONFIG.get("ducking_orig_volume", 0.3),
75
- "idle_orig_volume": CONFIG.get("idle_orig_volume", 1.0),
76
- "speech_ducking_volume": CONFIG.get("speech_ducking_volume", 0.2),
77
- "zone_ducking_volume": CONFIG.get("zone_ducking_volume", 0.12),
78
- "ducking_threshold": CONFIG.get("ducking_threshold", 0.15),
79
- "ducking_ratio": CONFIG.get("ducking_ratio", 3),
80
- "ducking_attack": CONFIG.get("ducking_attack", 10),
81
- "ducking_release": CONFIG.get("ducking_release", 300),
82
- "ducking_level_sc": CONFIG.get("ducking_level_sc", 2.0),
83
- "ducking_makeup": CONFIG.get("ducking_makeup", 1.2),
71
+ "ducking_mode": CONFIG["ducking_mode"],
72
+ "duck_fade_seconds": CONFIG["duck_fade_seconds"],
73
+ "duck_bridge_seconds": CONFIG["duck_bridge_seconds"],
74
+ "ducking_narr_weight": CONFIG["ducking_narr_weight"],
75
+ "ducking_orig_volume": CONFIG["ducking_orig_volume"],
76
+ "idle_orig_volume": CONFIG["idle_orig_volume"],
77
+ "speech_ducking_volume": CONFIG["speech_ducking_volume"],
78
+ "zone_ducking_volume": CONFIG["zone_ducking_volume"],
79
+ "ducking_threshold": CONFIG["ducking_threshold"],
80
+ "ducking_ratio": CONFIG["ducking_ratio"],
81
+ "ducking_attack": CONFIG["ducking_attack"],
82
+ "ducking_release": CONFIG["ducking_release"],
83
+ "ducking_level_sc": CONFIG["ducking_level_sc"],
84
+ "ducking_makeup": CONFIG["ducking_makeup"],
84
85
  "final_loudnorm": final_loudnorm_filter(),
85
86
  "loudness_mode": _loudness_mode(),
86
- "bgm_path": CONFIG.get("bgm_path", ""),
87
- "bgm_volume": CONFIG.get("bgm_volume", 0.18),
88
- "bgm_ducking_volume": CONFIG.get("bgm_ducking_volume", 0.10),
87
+ "bgm_path": CONFIG["bgm_path"],
88
+ "bgm_volume": CONFIG["bgm_volume"],
89
+ "bgm_ducking_volume": CONFIG["bgm_ducking_volume"],
89
90
  },
90
91
  }
91
92
  if burn_subtitles:
@@ -10,7 +10,7 @@ def _round_keyframe(t_s, gain):
10
10
 
11
11
 
12
12
  def default_bridge(fade):
13
- return 2 * float(fade or 0)
13
+ return 2 * float(fade)
14
14
 
15
15
 
16
16
  def coalesce_duck_windows(windows, bridge):
@@ -25,7 +25,7 @@ def coalesce_duck_windows(windows, bridge):
25
25
  )
26
26
  if not rel:
27
27
  return []
28
- bridge = float(bridge or 0)
28
+ bridge = float(bridge)
29
29
  merged = [rel[0][:]]
30
30
  for s, e, gain in rel[1:]:
31
31
  if s - merged[-1][1] < bridge:
@@ -51,7 +51,7 @@ def duck_ramp_expression(start, end, fade):
51
51
  """
52
52
  start = float(start)
53
53
  end = float(end)
54
- fade = float(fade or 0)
54
+ fade = float(fade)
55
55
  if fade <= 0:
56
56
  return f"between(t,{start:.2f},{end:.2f})"
57
57
  ramp_start = start - fade
@@ -61,32 +61,25 @@ def duck_ramp_expression(start, end, fade):
61
61
 
62
62
  def ducking_expression(windows, idle, fade):
63
63
  """Build the ffmpeg volume expression for coalesced duck windows."""
64
- merged = list(windows or [])
65
- if not merged:
64
+ if not windows:
66
65
  return None
67
66
  idle = float(idle)
68
67
  terms = [
69
68
  f"+({float(level) - idle:.3f})*{duck_ramp_expression(s, e, fade)}"
70
- for s, e, level in merged
69
+ for s, e, level in windows
71
70
  ]
72
71
  return f"max(0,min(1,{idle}{''.join(terms)}))"
73
72
 
74
73
 
75
- def coalesce_release_duck_windows(windows, bridge, default_release_fade=0.0):
76
- """Merge [(start, hold_end, gain, restore_at?)] while preserving safe releases."""
77
- fade = max(0.0, float(default_release_fade or 0.0))
78
- rel = []
79
- for row in windows or []:
80
- if len(row) < 3:
81
- continue
82
- start, end, gain = map(float, row[:3])
83
- restore = float(row[3]) if len(row) > 3 and row[3] is not None else end + fade
84
- if end > start:
85
- rel.append([start, end, gain, max(end, restore)])
86
- rel.sort(key=lambda row: row[0])
74
+ def coalesce_release_duck_windows(windows, bridge):
75
+ """Merge [(start, hold_end, gain, restore_at)] while preserving safe releases."""
76
+ rel = sorted(
77
+ ([float(s), float(e), float(g), max(float(e), float(r))] for s, e, g, r in windows if float(e) > float(s)),
78
+ key=lambda row: row[0],
79
+ )
87
80
  if not rel:
88
81
  return []
89
- bridge = max(0.0, float(bridge or 0.0))
82
+ bridge = float(bridge)
90
83
  merged = [rel[0][:]]
91
84
  for start, end, gain, restore in rel[1:]:
92
85
  if start - merged[-1][1] < bridge:
@@ -100,10 +93,10 @@ def coalesce_release_duck_windows(windows, bridge, default_release_fade=0.0):
100
93
 
101
94
  def release_ducking_expression(windows, idle, attack_fade, bridge=None):
102
95
  """FFmpeg gain expression with a fixed attack and a per-window safe release end."""
103
- attack = max(0.0, float(attack_fade or 0.0))
96
+ attack = float(attack_fade)
104
97
  if bridge is None:
105
98
  bridge = default_bridge(attack)
106
- merged = coalesce_release_duck_windows(windows, bridge, attack)
99
+ merged = coalesce_release_duck_windows(windows, bridge)
107
100
  if not merged:
108
101
  return None
109
102
  idle = float(idle)
@@ -125,19 +118,16 @@ def release_ducking_expression(windows, idle, attack_fade, bridge=None):
125
118
 
126
119
  def release_ducking_keyframes(windows, idle, attack_fade, span_start, span_end, bridge=None):
127
120
  """Timeline keyframes matching `release_ducking_expression` exactly."""
128
- attack = max(0.0, float(attack_fade or 0.0))
121
+ attack = float(attack_fade)
129
122
  if bridge is None:
130
123
  bridge = default_bridge(attack)
131
124
  span_start, span_end = float(span_start), float(span_end)
132
- normalized = []
133
- for row in windows or []:
134
- if len(row) < 3:
135
- continue
136
- start, end, gain = map(float, row[:3])
137
- restore = float(row[3]) if len(row) > 3 and row[3] is not None else end + attack
138
- if end > span_start and start < span_end and end > start:
139
- normalized.append((max(span_start, start), min(span_end, end), gain, min(span_end, max(end, restore))))
140
- merged = coalesce_release_duck_windows(normalized, bridge, attack)
125
+ normalized = [
126
+ (max(span_start, start), min(span_end, end), gain, min(span_end, max(end, restore)))
127
+ for start, end, gain, restore in ((float(s), float(e), float(g), float(r)) for s, e, g, r in windows)
128
+ if end > span_start and start < span_end and end > start
129
+ ]
130
+ merged = coalesce_release_duck_windows(normalized, bridge)
141
131
  if not merged:
142
132
  return []
143
133
  points = [(span_start, float(idle))]
@@ -161,7 +151,7 @@ def release_ducking_keyframes(windows, idle, attack_fade, span_start, span_end,
161
151
 
162
152
  def variable_ducking_keyframes(windows, idle, fade, span_start, span_end, bridge=None):
163
153
  """Volume keyframes for per-window duck gains using canonical semantics."""
164
- fade = float(fade or 0)
154
+ fade = float(fade)
165
155
  if bridge is None:
166
156
  bridge = default_bridge(fade)
167
157
  span_start = float(span_start)