@oh-story/dsh 0.1.3 → 0.1.5

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 (524) hide show
  1. package/README.md +58 -12
  2. package/lib/client.js +2970 -537
  3. package/lib/client.js.map +4 -4
  4. package/lib/drama/manifest.json +218 -178
  5. package/lib/drama/skills/short-drama/SKILL.md +110 -117
  6. package/lib/drama/skills/short-drama/references/audience-reveal.md +14 -67
  7. package/lib/drama/skills/short-drama/references/contract-and-ownership.md +26 -77
  8. package/lib/drama/skills/short-drama/references/creator-documents.md +204 -0
  9. package/lib/drama/skills/short-drama/references/creator-workflow.md +73 -63
  10. package/lib/drama/skills/short-drama/references/knowhow-index.md +5 -0
  11. package/lib/drama/skills/short-drama/references/look-development.md +2 -3
  12. package/lib/drama/skills/short-drama/references/pickup-and-alternate.md +14 -48
  13. package/lib/drama/skills/short-drama/references/production-form-profiles.md +1 -1
  14. package/lib/drama/skills/short-drama/references/reference-roles.md +32 -135
  15. package/lib/drama/skills/short-drama/references/runtime-preflight.md +16 -19
  16. package/lib/drama/skills/short-drama/scripts/creator_markdown_check.py +1002 -0
  17. package/lib/drama/skills/short-drama/scripts/project_tool.py +485 -5
  18. package/lib/drama/skills/short-drama-assets/SKILL.md +59 -170
  19. package/lib/drama/skills/short-drama-assets/references/asset-review-checklist.md +18 -25
  20. package/lib/drama/skills/short-drama-assets/references/character-and-look.md +13 -15
  21. package/lib/drama/skills/short-drama-assets/references/continuity-delta.md +11 -14
  22. package/lib/drama/skills/short-drama-assets/references/continuity-lock.md +116 -0
  23. package/lib/drama/skills/short-drama-assets/references/identity-vs-variant.md +6 -12
  24. package/lib/drama/skills/short-drama-assets/references/occurrence-extraction.md +8 -11
  25. package/lib/drama/skills/short-drama-assets/references/prop-and-state.md +21 -2
  26. package/lib/drama/skills/short-drama-assets/references/stage-contract.md +12 -105
  27. package/lib/drama/skills/short-drama-assets/references/voice-direction.md +12 -32
  28. package/lib/drama/skills/short-drama-assets/scripts/asset_check.py +1 -1
  29. package/lib/drama/skills/short-drama-image-prompts/SKILL.md +45 -155
  30. package/lib/drama/skills/short-drama-image-prompts/references/character-and-look.md +12 -13
  31. package/lib/drama/skills/short-drama-image-prompts/references/common-recipe.md +12 -13
  32. package/lib/drama/skills/short-drama-image-prompts/references/edit-and-revision.md +39 -51
  33. package/lib/drama/skills/short-drama-image-prompts/references/location-plate.md +3 -4
  34. package/lib/drama/skills/short-drama-image-prompts/references/look-and-state-variant.md +15 -14
  35. package/lib/drama/skills/short-drama-image-prompts/references/lookdev-frame.md +11 -15
  36. package/lib/drama/skills/short-drama-image-prompts/references/production-sheet-recipes.md +1 -1
  37. package/lib/drama/skills/short-drama-image-prompts/references/prop-plate.md +4 -7
  38. package/lib/drama/skills/short-drama-image-prompts/references/review-and-fixtures.md +23 -23
  39. package/lib/drama/skills/short-drama-image-prompts/references/stage-contract.md +8 -65
  40. package/lib/drama/skills/short-drama-image-prompts/scripts/image_prompt_check.py +8 -8
  41. package/lib/drama/skills/short-drama-image-prompts/scripts/selftest.py +4 -2
  42. package/lib/drama/skills/short-drama-produce/SKILL.md +67 -15
  43. package/lib/drama/skills/short-drama-produce/references/adapter-contract.md +65 -8
  44. package/lib/drama/skills/short-drama-produce/references/providers/minimax-h3-video.md +85 -0
  45. package/lib/drama/skills/short-drama-produce/references/providers/seedance.md +27 -10
  46. package/lib/drama/skills/short-drama-produce/scripts/production_tool.py +362 -3
  47. package/lib/drama/skills/short-drama-produce/scripts/provider_adapters.py +627 -40
  48. package/lib/drama/skills/short-drama-produce/scripts/selftest.py +5 -4
  49. package/lib/drama/skills/short-drama-review/SKILL.md +61 -123
  50. package/lib/drama/skills/short-drama-review/references/anti-template-repair.md +10 -15
  51. package/lib/drama/skills/short-drama-review/references/production-quality-gates.md +15 -16
  52. package/lib/drama/skills/short-drama-review/references/project-calibration.md +7 -9
  53. package/lib/drama/skills/short-drama-review/references/review-method.md +8 -9
  54. package/lib/drama/skills/short-drama-review/references/rubric-assets-prompts.md +9 -13
  55. package/lib/drama/skills/short-drama-review/references/rubric-story-script.md +104 -4
  56. package/lib/drama/skills/short-drama-review/references/rubric-visual-motion.md +27 -19
  57. package/lib/drama/skills/short-drama-review/references/stage-contract.md +4 -63
  58. package/lib/drama/skills/short-drama-review/scripts/review_check.py +1 -1
  59. package/lib/drama/skills/short-drama-storyboard/SKILL.md +116 -238
  60. package/lib/drama/skills/short-drama-storyboard/assets/shot-template.jsonl +1 -1
  61. package/lib/drama/skills/short-drama-storyboard/references/blocking-playbooks.md +9 -34
  62. package/lib/drama/skills/short-drama-storyboard/references/comic-keyframe-lexicon.md +156 -0
  63. package/lib/drama/skills/short-drama-storyboard/references/coverage-audition.md +5 -10
  64. package/lib/drama/skills/short-drama-storyboard/references/keyframe-craft.md +12 -7
  65. package/lib/drama/skills/short-drama-storyboard/references/production-shot-grammar.md +19 -4
  66. package/lib/drama/skills/short-drama-storyboard/references/review-and-fixtures.md +27 -62
  67. package/lib/drama/skills/short-drama-storyboard/references/scene-visual-plan.md +16 -25
  68. package/lib/drama/skills/short-drama-storyboard/references/screenplay-to-keyframe-example.md +21 -23
  69. package/lib/drama/skills/short-drama-storyboard/references/shot-craft.md +8 -10
  70. package/lib/drama/skills/short-drama-storyboard/references/shot-revision-identity.md +9 -13
  71. package/lib/drama/skills/short-drama-storyboard/references/stage-contract.md +16 -71
  72. package/lib/drama/skills/short-drama-storyboard/scripts/storyboard_check.py +1 -1
  73. package/lib/drama/skills/short-drama-video-prompts/SKILL.md +123 -230
  74. package/lib/drama/skills/short-drama-video-prompts/assets/motion-spec.jsonl.md +6 -1
  75. package/lib/drama/skills/short-drama-video-prompts/assets/video-prompts.md +17 -1
  76. package/lib/drama/skills/short-drama-video-prompts/references/camera-audio-continuity.md +10 -8
  77. package/lib/drama/skills/short-drama-video-prompts/references/delivery-profile.md +24 -6
  78. package/lib/drama/skills/short-drama-video-prompts/references/generability.md +2 -2
  79. package/lib/drama/skills/short-drama-video-prompts/references/minimax-h3.md +154 -0
  80. package/lib/drama/skills/short-drama-video-prompts/references/motion-recipe.md +35 -27
  81. package/lib/drama/skills/short-drama-video-prompts/references/performance-action-timing.md +8 -11
  82. package/lib/drama/skills/short-drama-video-prompts/references/production-prompt-grammar.md +13 -10
  83. package/lib/drama/skills/short-drama-video-prompts/references/review-and-fixtures.md +34 -63
  84. package/lib/drama/skills/short-drama-video-prompts/references/seedance-2.0.md +41 -0
  85. package/lib/drama/skills/short-drama-video-prompts/references/seedance-2.5.md +66 -0
  86. package/lib/drama/skills/short-drama-video-prompts/references/stage-contract.md +17 -73
  87. package/lib/drama/skills/short-drama-video-prompts/references/target-model-profile.md +115 -0
  88. package/lib/drama/skills/short-drama-video-prompts/scripts/container_check.py +1 -1
  89. package/lib/drama/skills/short-drama-video-prompts/scripts/music_spec_check.py +1 -1
  90. package/lib/drama/skills/short-drama-write/SKILL.md +74 -268
  91. package/lib/drama/skills/short-drama-write/references/dialogue-craft.md +7 -0
  92. package/lib/drama/skills/short-drama-write/references/scene-handoff-capsule.md +17 -43
  93. package/lib/drama/skills/short-drama-write/references/screenplay-format.md +15 -15
  94. package/lib/drama/skills/short-drama-write/references/script-craft.md +208 -21
  95. package/lib/drama/skills/short-drama-write/references/stage-contract.md +11 -70
  96. package/lib/drama/skills/short-drama-write/scripts/duration_estimate.py +1 -1
  97. package/lib/drama/skills/short-drama-write/scripts/screenplay_index.py +2 -2
  98. package/lib/drama/skills/short-drama-write/scripts/voice_sheet_check.py +1 -1
  99. package/lib/index.js +971 -46
  100. package/lib/index.js.map +4 -4
  101. package/lib/novel-to-game/LICENSE +21 -0
  102. package/lib/novel-to-game/README.md +180 -0
  103. package/lib/novel-to-game/README_ZH.md +178 -0
  104. package/lib/novel-to-game/VERSION +1 -0
  105. package/lib/novel-to-game/examples/jin-ping-mei/build/BUILD_BRIEF.md +217 -0
  106. package/lib/novel-to-game/examples/jin-ping-mei/build/app/.vercelignore +3 -0
  107. package/lib/novel-to-game/examples/jin-ping-mei/build/app/RUN.md +130 -0
  108. package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/bg/compound_new_guofeng.webp +0 -0
  109. package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/cg/finale/fate_coda.webp +0 -0
  110. package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/cg/finale/meng.webp +0 -0
  111. package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/cg/finale/pan.webp +0 -0
  112. package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/cg/finale/pinger.webp +0 -0
  113. package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/cg/finale/xuee.webp +0 -0
  114. package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/cg/finale/yue.webp +0 -0
  115. package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/cg/group/inner_court_accord_five.webp +0 -0
  116. package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/cg/group/inner_court_afterglow_five.webp +0 -0
  117. package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/cg/group/inner_court_alliance.webp +0 -0
  118. package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/cg/group/public_day10.webp +0 -0
  119. package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/cg/group/public_day15.webp +0 -0
  120. package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/cg/group/public_day5.webp +0 -0
  121. package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/cg/group/title_new_guofeng.webp +0 -0
  122. package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/cg/joint/pan_pinger.webp +0 -0
  123. package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/cg/joint/pan_xuee.webp +0 -0
  124. package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/cg/joint/yue_meng.webp +0 -0
  125. package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/cg/joint/yue_pan.webp +0 -0
  126. package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/cg/joint/yue_pinger.webp +0 -0
  127. package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/cg/meng/explicit.webp +0 -0
  128. package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/cg/meng/prelude.webp +0 -0
  129. package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/cg/milestone/meng.webp +0 -0
  130. package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/cg/milestone/pan.webp +0 -0
  131. package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/cg/milestone/pinger.webp +0 -0
  132. package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/cg/milestone/xuee.webp +0 -0
  133. package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/cg/milestone/yue.webp +0 -0
  134. package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/cg/pan/explicit.webp +0 -0
  135. package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/cg/pan/prelude.webp +0 -0
  136. package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/cg/pinger/explicit.webp +0 -0
  137. package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/cg/pinger/prelude.webp +0 -0
  138. package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/cg/xuee/explicit.webp +0 -0
  139. package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/cg/xuee/prelude.webp +0 -0
  140. package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/cg/yue/explicit.webp +0 -0
  141. package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/cg/yue/prelude.webp +0 -0
  142. package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/heroine/meng/night.webp +0 -0
  143. package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/heroine/pan/night.webp +0 -0
  144. package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/heroine/pinger/night.webp +0 -0
  145. package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/heroine/xuee/night.webp +0 -0
  146. package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/heroine/yue/night.webp +0 -0
  147. package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/household/li_jiaoer.webp +0 -0
  148. package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/scene/gate_collector.webp +0 -0
  149. package/lib/novel-to-game/examples/jin-ping-mei/build/app/css/new-guofeng.css +1105 -0
  150. package/lib/novel-to-game/examples/jin-ping-mei/build/app/css/style.css +2539 -0
  151. package/lib/novel-to-game/examples/jin-ping-mei/build/app/index.html +18 -0
  152. package/lib/novel-to-game/examples/jin-ping-mei/build/app/js/assets.js +147 -0
  153. package/lib/novel-to-game/examples/jin-ping-mei/build/app/js/audio.js +332 -0
  154. package/lib/novel-to-game/examples/jin-ping-mei/build/app/js/data.js +7472 -0
  155. package/lib/novel-to-game/examples/jin-ping-mei/build/app/js/engine.js +13077 -0
  156. package/lib/novel-to-game/examples/jin-ping-mei/build/app/js/main.js +3028 -0
  157. package/lib/novel-to-game/examples/jin-ping-mei/build/app/js/text.js +32 -0
  158. package/lib/novel-to-game/examples/jin-ping-mei/build/app/package.json +10 -0
  159. package/lib/novel-to-game/examples/jin-ping-mei/build/app/vercel.json +23 -0
  160. package/lib/novel-to-game/examples/jin-ping-mei/build/art/generated-art.json +161 -0
  161. package/lib/novel-to-game/examples/jin-ping-mei/example.json +12 -0
  162. package/lib/novel-to-game/examples/jin-ping-mei/qa/README.md +31 -0
  163. package/lib/novel-to-game/examples/jin-ping-mei/qa/playable-model.json +99 -0
  164. package/lib/novel-to-game/examples/jin-ping-mei/qa/verification.json +41 -0
  165. package/lib/novel-to-game/examples/jin-ping-mei/qa/verify_playable_model.mjs +129 -0
  166. package/lib/novel-to-game/manifest.json +508 -0
  167. package/lib/novel-to-game/skills/game-art-direction/SKILL.md +73 -0
  168. package/lib/novel-to-game/skills/game-art-direction/agents/openai.yaml +4 -0
  169. package/lib/novel-to-game/skills/game-art-direction/references/art-direction-method.md +119 -0
  170. package/lib/novel-to-game/skills/game-build/SKILL.md +84 -0
  171. package/lib/novel-to-game/skills/game-build/agents/openai.yaml +4 -0
  172. package/lib/novel-to-game/skills/game-build/references/build-brief-contract.md +109 -0
  173. package/lib/novel-to-game/skills/game-build/references/generative-media-pipeline.md +56 -0
  174. package/lib/novel-to-game/skills/game-build/references/playable-model-contract.md +81 -0
  175. package/lib/novel-to-game/skills/game-build/references/tts-production-contract.md +37 -0
  176. package/lib/novel-to-game/skills/game-concept/SKILL.md +72 -0
  177. package/lib/novel-to-game/skills/game-concept/agents/openai.yaml +4 -0
  178. package/lib/novel-to-game/skills/game-concept/references/concept-method.md +94 -0
  179. package/lib/novel-to-game/skills/game-qa/SKILL.md +50 -0
  180. package/lib/novel-to-game/skills/game-qa/agents/openai.yaml +4 -0
  181. package/lib/novel-to-game/skills/game-qa/references/qa-contract.md +66 -0
  182. package/lib/novel-to-game/skills/game-qa/references/test-design-method.md +45 -0
  183. package/lib/novel-to-game/skills/game-world-design/SKILL.md +63 -0
  184. package/lib/novel-to-game/skills/game-world-design/agents/openai.yaml +4 -0
  185. package/lib/novel-to-game/skills/game-world-design/references/dialogue-design-method.md +59 -0
  186. package/lib/novel-to-game/skills/game-world-design/references/game-writing-craft.md +53 -0
  187. package/lib/novel-to-game/skills/game-world-design/references/narrative-design-method.md +84 -0
  188. package/lib/novel-to-game/skills/game-world-design/references/numeric-design-method.md +56 -0
  189. package/lib/novel-to-game/skills/game-world-design/references/world-design-method.md +124 -0
  190. package/lib/novel-to-game/skills/novel-game-analyze/SKILL.md +77 -0
  191. package/lib/novel-to-game/skills/novel-game-analyze/agents/openai.yaml +4 -0
  192. package/lib/novel-to-game/skills/novel-game-analyze/references/gameability-protocol.md +65 -0
  193. package/lib/novel-to-game/skills/novel-to-game/SKILL.md +71 -0
  194. package/lib/novel-to-game/skills/novel-to-game/agents/openai.yaml +4 -0
  195. package/lib/novel-to-game/skills/novel-to-game/references/intake-benchmark-reference.md +42 -0
  196. package/lib/novel-to-game/skills/novel-to-game/references/intake-method.md +51 -0
  197. package/lib/novel-to-game/skills/novel-to-game/references/pipeline-contract.md +65 -0
  198. package/lib/oh-story/manifest.json +419 -309
  199. package/lib/oh-story/roles/character-designer.md +4 -4
  200. package/lib/oh-story/roles/consistency-checker.md +1 -1
  201. package/lib/oh-story/roles/narrative-writer.md +41 -42
  202. package/lib/oh-story/roles/story-architect.md +19 -23
  203. package/lib/oh-story/roles/story-explorer.md +8 -5
  204. package/lib/oh-story/skills/browser-cdp/SKILL.md +1 -1
  205. package/lib/oh-story/skills/story/SKILL.md +16 -9
  206. package/lib/oh-story/skills/story/VERSION +1 -1
  207. package/lib/oh-story/skills/story/references/author-memory.md +163 -0
  208. package/lib/oh-story/skills/story/scripts/author_memory_commit.py +871 -0
  209. package/lib/oh-story/skills/story-cover/SKILL.md +1 -1
  210. package/lib/oh-story/skills/story-deslop/SKILL.md +10 -5
  211. package/lib/oh-story/skills/story-deslop/references/anti-ai-writing.md +2 -1
  212. package/lib/oh-story/skills/story-deslop/references/author-memory.md +163 -0
  213. package/lib/oh-story/skills/story-deslop/references/banned-words.md +6 -4
  214. package/lib/oh-story/skills/story-deslop/scripts/author_memory_commit.py +871 -0
  215. package/lib/oh-story/skills/story-deslop/scripts/check-ai-patterns.js +64 -1
  216. package/lib/oh-story/skills/story-import/SKILL.md +21 -8
  217. package/lib/oh-story/skills/story-import/references/format-and-structure.md +9 -10
  218. package/lib/oh-story/skills/story-import/references/structure-mapping-long.md +2 -2
  219. package/lib/oh-story/skills/story-import/references/structure-mapping-short.md +1 -1
  220. package/lib/oh-story/skills/story-import/references/tracking-transaction.md +14 -6
  221. package/lib/oh-story/skills/story-import/scripts/check-outline-contract.js +251 -0
  222. package/lib/oh-story/skills/story-import/scripts/tracking_commit.py +98 -9
  223. package/lib/oh-story/skills/story-import/scripts/wordcount_core.py +246 -0
  224. package/lib/oh-story/skills/story-long-analyze/SKILL.md +4 -4
  225. package/lib/oh-story/skills/story-long-scan/SKILL.md +1 -1
  226. package/lib/oh-story/skills/story-long-write/SKILL.md +35 -21
  227. package/lib/oh-story/skills/story-long-write/references/anti-ai-writing.md +2 -1
  228. package/lib/oh-story/skills/story-long-write/references/artifact-protocols.md +7 -3
  229. package/lib/oh-story/skills/story-long-write/references/author-memory.md +163 -0
  230. package/lib/oh-story/skills/story-long-write/references/banned-words.md +6 -4
  231. package/lib/oh-story/skills/story-long-write/references/cross-book-recall.md +6 -6
  232. package/lib/oh-story/skills/story-long-write/references/genre-prose-cards.md +1 -1
  233. package/lib/oh-story/skills/story-long-write/references/genre-readers.md +1 -1
  234. package/lib/oh-story/skills/{story-setup/references/agent-references/hooks-chapter.md → story-long-write/references/long-chapter-hooks.md} +5 -5
  235. package/lib/oh-story/skills/story-long-write/references/{quality-checklist.md → long-chapter-quality.md} +2 -1
  236. package/lib/oh-story/skills/story-long-write/references/long-format.md +42 -0
  237. package/lib/oh-story/skills/{story-setup/references/agent-references/genre-catalog.md → story-long-write/references/long-genre-catalog.md} +11 -97
  238. package/lib/oh-story/skills/story-long-write/references/{genre-core-mechanics.md → long-genre-mechanics.md} +1 -1
  239. package/lib/oh-story/skills/story-long-write/references/{reversal-toolkit.md → long-reversal.md} +18 -32
  240. package/lib/oh-story/skills/story-long-write/references/{hooks-suspense.md → long-suspense.md} +6 -6
  241. package/lib/oh-story/skills/story-long-write/references/opening-design.md +1 -1
  242. package/lib/oh-story/skills/story-long-write/references/outline-structure-theory.md +1 -1
  243. package/lib/oh-story/skills/story-long-write/references/style-genre-modules.md +1 -1
  244. package/lib/oh-story/skills/story-long-write/references/tracking-transaction.md +14 -6
  245. package/lib/oh-story/skills/story-long-write/references/workflow-chapter.md +32 -27
  246. package/lib/oh-story/skills/story-long-write/references/workflow-daily.md +5 -4
  247. package/lib/oh-story/skills/story-long-write/references/workflow-revision.md +2 -2
  248. package/lib/oh-story/skills/story-long-write/references/workflow-setup.md +17 -11
  249. package/lib/oh-story/skills/story-long-write/references/writing-craft.md +54 -54
  250. package/lib/oh-story/skills/story-long-write/scripts/author_memory_commit.py +871 -0
  251. package/lib/oh-story/skills/story-long-write/scripts/check-ai-patterns.js +64 -1
  252. package/lib/oh-story/skills/story-long-write/scripts/check-outline-contract.js +251 -0
  253. package/lib/oh-story/skills/story-long-write/scripts/storyctl.py +303 -0
  254. package/lib/oh-story/skills/story-long-write/scripts/tracking_commit.py +98 -9
  255. package/lib/oh-story/skills/story-long-write/scripts/wordcount_core.py +246 -0
  256. package/lib/oh-story/skills/story-review/SKILL.md +26 -17
  257. package/lib/oh-story/skills/story-review/references/anti-ai-writing.md +2 -1
  258. package/lib/oh-story/skills/story-review/references/author-memory.md +163 -0
  259. package/lib/oh-story/skills/story-review/references/banned-words.md +6 -4
  260. package/lib/oh-story/skills/story-review/references/{quality-checklist.md → review-quality.md} +22 -21
  261. package/lib/oh-story/skills/story-review/references/tracking-transaction.md +14 -6
  262. package/lib/oh-story/skills/story-review/scripts/author_memory_commit.py +871 -0
  263. package/lib/oh-story/skills/story-review/scripts/check-ai-patterns.js +64 -1
  264. package/lib/oh-story/skills/story-review/scripts/tracking_commit.py +98 -9
  265. package/lib/oh-story/skills/story-review/scripts/wordcount_core.py +246 -0
  266. package/lib/oh-story/skills/story-setup/SKILL.md +85 -41
  267. package/lib/oh-story/skills/story-setup/references/agent-references/agent-quality.md +72 -0
  268. package/lib/oh-story/skills/story-setup/references/agent-references/agent-reference-profiles.md +55 -0
  269. package/lib/oh-story/skills/story-setup/references/agent-references/anti-ai-writing.md +2 -1
  270. package/lib/oh-story/skills/story-setup/references/agent-references/banned-words.md +6 -4
  271. package/lib/oh-story/skills/story-setup/references/agent-references/format-and-structure.md +9 -10
  272. package/lib/oh-story/skills/story-setup/references/agent-references/genre-prose-cards.md +1 -1
  273. package/lib/oh-story/skills/story-setup/references/agent-references/genre-readers.md +1 -1
  274. package/lib/oh-story/skills/{story-short-analyze/references/hooks-chapter.md → story-setup/references/agent-references/long-chapter-hooks.md} +5 -5
  275. package/lib/oh-story/skills/story-setup/references/agent-references/long-emotional-methods.md +209 -0
  276. package/lib/oh-story/skills/{story-long-write/references/genre-catalog.md → story-setup/references/agent-references/long-genre-catalog.md} +11 -97
  277. package/lib/oh-story/skills/story-setup/references/agent-references/{genre-core-mechanics.md → long-genre-mechanics.md} +1 -1
  278. package/lib/oh-story/skills/story-setup/references/agent-references/long-quality.md +40 -0
  279. package/lib/oh-story/skills/{story-short-write/references/reversal-toolkit.md → story-setup/references/agent-references/long-reversal.md} +18 -32
  280. package/lib/oh-story/skills/{story-short-write/references/hooks-suspense.md → story-setup/references/agent-references/long-suspense.md} +6 -6
  281. package/lib/oh-story/skills/story-setup/references/agent-references/opening-design.md +1 -1
  282. package/lib/oh-story/skills/story-setup/references/agent-references/{emotional-methods.md → short-emotional-methods.md} +4 -4
  283. package/lib/oh-story/skills/{story-long-write/references/genre-writing-formulas.md → story-setup/references/agent-references/short-genre-formulas.md} +32 -44
  284. package/lib/oh-story/skills/story-setup/references/agent-references/short-quality.md +39 -0
  285. package/lib/oh-story/skills/story-setup/references/agent-references/{reversal-toolkit.md → short-reversal.md} +29 -23
  286. package/lib/oh-story/skills/story-setup/references/agent-references/{hooks-suspense.md → short-suspense.md} +31 -31
  287. package/lib/oh-story/skills/story-setup/references/agent-references/style-genre-modules.md +1 -1
  288. package/lib/oh-story/skills/story-setup/references/agent-references/writing-craft.md +55 -55
  289. package/lib/oh-story/skills/story-short-analyze/SKILL.md +28 -28
  290. package/lib/oh-story/skills/story-short-analyze/references/{character-basics.md → analysis-character-basics.md} +1 -1
  291. package/lib/oh-story/skills/story-short-analyze/references/{character-design-methods.md → analysis-character-design.md} +1 -1
  292. package/lib/oh-story/skills/story-short-analyze/references/{character-relations.md → analysis-character-relations.md} +1 -1
  293. package/lib/oh-story/skills/story-short-analyze/references/{hooks-paragraph.md → analysis-paragraph-hooks.md} +1 -1
  294. package/lib/oh-story/skills/story-short-analyze/references/{genre-readers.md → analysis-reader-profile.md} +2 -2
  295. package/lib/oh-story/skills/story-short-analyze/references/analysis-report-style.md +45 -0
  296. package/lib/oh-story/skills/story-short-analyze/references/analysis-short-genres.md +65 -0
  297. package/lib/oh-story/skills/story-short-analyze/references/analysis-short-hooks.md +77 -0
  298. package/lib/oh-story/skills/story-short-analyze/references/analysis-short-mechanics.md +82 -0
  299. package/lib/oh-story/skills/story-short-analyze/references/analysis-short-patterns.md +50 -0
  300. package/lib/oh-story/skills/story-short-analyze/references/analysis-short-suspense.md +98 -0
  301. package/lib/oh-story/skills/story-short-analyze/references/{genre-writing-techniques.md → analysis-writing-techniques.md} +21 -19
  302. package/lib/oh-story/skills/story-short-analyze/references/deconstruction-examples.md +1 -1
  303. package/lib/oh-story/skills/story-short-analyze/references/material-decomposition.md +21 -28
  304. package/lib/oh-story/skills/story-short-analyze/references/output-contract.md +1 -1
  305. package/lib/oh-story/skills/story-short-analyze/references/output-templates.md +17 -17
  306. package/lib/oh-story/skills/story-short-analyze/references/{quality-checklist.md → source-story-quality.md} +28 -49
  307. package/lib/oh-story/skills/story-short-analyze/references/zhihu-style.md +2 -2
  308. package/lib/oh-story/skills/story-short-scan/SKILL.md +1 -1
  309. package/lib/oh-story/skills/story-short-write/SKILL.md +78 -55
  310. package/lib/oh-story/skills/story-short-write/references/author-memory.md +163 -0
  311. package/lib/oh-story/skills/story-short-write/references/banned-words.md +6 -4
  312. package/lib/oh-story/skills/story-short-write/references/cross-book-recall.md +3 -3
  313. package/lib/oh-story/skills/story-short-write/references/emotional-methods.md +4 -4
  314. package/lib/oh-story/skills/story-short-write/references/genre-styles//344/270/226/346/203/205/346/211/223/350/204/270.md +3 -3
  315. package/lib/oh-story/skills/story-short-write/references/genre-styles//345/217/214/347/224/267/344/270/273.md +2 -2
  316. 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
  317. package/lib/oh-story/skills/story-short-write/references/genre-styles//345/256/205/346/226/227/345/256/253/346/226/227.md +6 -6
  318. 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
  319. package/lib/oh-story/skills/story-short-write/references/genre-styles//346/202/254/347/226/221.md +4 -4
  320. package/lib/oh-story/skills/story-short-write/references/genre-styles//346/260/221/344/277/227/346/200/252/350/260/210.md +7 -7
  321. package/lib/oh-story/skills/story-short-write/references/genre-styles//346/262/231/351/233/225/350/204/221/346/264/236.md +5 -5
  322. package/lib/oh-story/skills/story-short-write/references/genre-styles//347/224/234/345/256/240.md +4 -4
  323. 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
  324. package/lib/oh-story/skills/story-short-write/references/genre-writing-formulas.md +32 -44
  325. package/lib/oh-story/skills/story-short-write/references/genre-writing-techniques.md +20 -18
  326. package/lib/oh-story/skills/story-short-write/references/output-contract.md +1 -1
  327. package/lib/oh-story/skills/story-short-write/references/short-craft.md +18 -18
  328. package/lib/oh-story/skills/story-short-write/references/short-deslop.md +1 -1
  329. package/lib/oh-story/skills/story-short-write/references/short-format.md +38 -8
  330. package/lib/oh-story/skills/story-short-write/references/{quality-checklist.md → short-prose-quality.md} +22 -21
  331. package/lib/oh-story/skills/story-short-write/references/short-reversal.md +355 -0
  332. package/lib/oh-story/skills/{story-short-analyze/references/hooks-suspense.md → story-short-write/references/short-suspense.md} +31 -31
  333. package/lib/oh-story/skills/story-short-write/references/submission-craft.md +2 -2
  334. package/lib/oh-story/skills/story-short-write/references/writing-workflow.md +31 -22
  335. package/lib/oh-story/skills/story-short-write/scripts/author_memory_commit.py +871 -0
  336. package/lib/oh-story/skills/story-short-write/scripts/check-ai-patterns.js +64 -1
  337. package/lib/oh-story/skills/story-short-write/scripts/check-delivery-contract.js +212 -0
  338. package/lib/oh-story/skills/story-short-write/scripts/check-phase2-contract.js +363 -0
  339. package/lib/types/client/drama-production-view.d.ts +34 -0
  340. package/lib/types/client/drama-production-view.d.ts.map +1 -0
  341. package/lib/types/client/drama-production.d.ts +92 -0
  342. package/lib/types/client/drama-production.d.ts.map +1 -0
  343. package/lib/types/client/file-activity.d.ts +9 -2
  344. package/lib/types/client/file-activity.d.ts.map +1 -1
  345. package/lib/types/client/index.d.ts +1 -1
  346. package/lib/types/client/index.d.ts.map +1 -1
  347. package/lib/types/client/production-intents.d.ts +9 -0
  348. package/lib/types/client/production-intents.d.ts.map +1 -0
  349. package/lib/types/client/production-prompts.d.ts +9 -0
  350. package/lib/types/client/production-prompts.d.ts.map +1 -0
  351. package/lib/types/client/production-runtime.d.ts +58 -0
  352. package/lib/types/client/production-runtime.d.ts.map +1 -0
  353. package/lib/types/client/video-studio.d.ts +41 -0
  354. package/lib/types/client/video-studio.d.ts.map +1 -0
  355. package/lib/types/client/workbench-ui.d.ts +5 -0
  356. package/lib/types/client/workbench-ui.d.ts.map +1 -0
  357. package/lib/types/game-verification.d.ts +16 -0
  358. package/lib/types/game-verification.d.ts.map +1 -0
  359. package/lib/types/index.d.ts +5 -2
  360. package/lib/types/index.d.ts.map +1 -1
  361. package/lib/types/production-intent.d.ts +21 -0
  362. package/lib/types/production-intent.d.ts.map +1 -0
  363. package/lib/types/production-tool.d.ts +5 -0
  364. package/lib/types/production-tool.d.ts.map +1 -0
  365. package/lib/types/reference-tool.d.ts +6 -0
  366. package/lib/types/reference-tool.d.ts.map +1 -0
  367. package/lib/types/role-provider.d.ts.map +1 -1
  368. package/lib/types/role-tool.d.ts +3 -1
  369. package/lib/types/role-tool.d.ts.map +1 -1
  370. package/lib/types/skill-provider.d.ts +7 -0
  371. package/lib/types/skill-provider.d.ts.map +1 -1
  372. package/lib/types/video-project.d.ts +42 -0
  373. package/lib/types/video-project.d.ts.map +1 -0
  374. package/lib/types/workspace-request-trust.d.ts +6 -0
  375. package/lib/types/workspace-request-trust.d.ts.map +1 -1
  376. package/lib/types/workspace-route.d.ts +20 -0
  377. package/lib/types/workspace-route.d.ts.map +1 -1
  378. package/lib/video-recap/CHANGELOG.md +282 -0
  379. package/lib/video-recap/LICENSE +21 -0
  380. package/lib/video-recap/README.en.md +257 -0
  381. package/lib/video-recap/README.md +255 -0
  382. package/lib/video-recap/manifest.json +684 -0
  383. package/lib/video-recap/skills/video-assemble/SKILL.md +97 -0
  384. package/lib/video-recap/skills/video-assemble/references/jianying/LICENSE.duo-video +21 -0
  385. package/lib/video-recap/skills/video-assemble/references/jianying/SOURCE.md +15 -0
  386. package/lib/video-recap/skills/video-assemble/references/jianying/empty_draft_meta_info.json +69 -0
  387. package/lib/video-recap/skills/video-assemble/references/jianying/empty_jy_combination_segment.json +84 -0
  388. package/lib/video-recap/skills/video-assemble/references/jianying/empty_jy_combination_video_material.json +98 -0
  389. package/lib/video-recap/skills/video-assemble/references/jianying/empty_jy_draft.json +204 -0
  390. package/lib/video-recap/skills/video-assemble/references/jianying/empty_jy_material_video.json +83 -0
  391. package/lib/video-recap/skills/video-assemble/references/jianying/empty_jy_meta_material_value.json +23 -0
  392. package/lib/video-recap/skills/video-assemble/references/jianying/empty_jy_project_info.json +133 -0
  393. package/lib/video-recap/skills/video-assemble/references/jianying/empty_jy_segment.json +70 -0
  394. package/lib/video-recap/skills/video-assemble/references/jianying/empty_jy_text_styles.json +30 -0
  395. package/lib/video-recap/skills/video-assemble/references/jianying/empty_yj_material_audio.json +41 -0
  396. package/lib/video-recap/skills/video-assemble/references/jianying/empty_yj_material_text.json +109 -0
  397. package/lib/video-recap/skills/video-assemble/scripts/artifacts.py +88 -0
  398. package/lib/video-recap/skills/video-assemble/scripts/assemble.py +345 -0
  399. package/lib/video-recap/skills/video-assemble/scripts/assemble_constants.py +34 -0
  400. package/lib/video-recap/skills/video-assemble/scripts/assembly_contract.py +305 -0
  401. package/lib/video-recap/skills/video-assemble/scripts/assembly_settings.py +94 -0
  402. package/lib/video-recap/skills/video-assemble/scripts/audio_automation.py +205 -0
  403. package/lib/video-recap/skills/video-assemble/scripts/audio_mix.py +555 -0
  404. package/lib/video-recap/skills/video-assemble/scripts/export_jianying.py +261 -0
  405. package/lib/video-recap/skills/video-assemble/scripts/jianying_builders.py +767 -0
  406. package/lib/video-recap/skills/video-assemble/scripts/jianying_model.py +111 -0
  407. package/lib/video-recap/skills/video-assemble/scripts/jianying_optional.py +24 -0
  408. package/lib/video-recap/skills/video-assemble/scripts/jianying_schema.py +109 -0
  409. package/lib/video-recap/skills/video-assemble/scripts/jianying_templates.py +37 -0
  410. package/lib/video-recap/skills/video-assemble/scripts/jianying_timeline_contract.py +191 -0
  411. package/lib/video-recap/skills/video-assemble/scripts/jianying_tracks.py +75 -0
  412. package/lib/video-recap/skills/video-assemble/scripts/jianying_writer.py +394 -0
  413. package/lib/video-recap/skills/video-assemble/scripts/lib.py +239 -0
  414. package/lib/video-recap/skills/video-assemble/scripts/media.py +243 -0
  415. package/lib/video-recap/skills/video-assemble/scripts/narration_audio.py +477 -0
  416. package/lib/video-recap/skills/video-assemble/scripts/render_preflight.py +46 -0
  417. package/lib/video-recap/skills/video-assemble/scripts/source_subtitles.py +486 -0
  418. package/lib/video-recap/skills/video-assemble/scripts/subtitle_core.py +376 -0
  419. package/lib/video-recap/skills/video-assemble/scripts/subtitle_render.py +88 -0
  420. package/lib/video-recap/skills/video-assemble/scripts/timeline.py +248 -0
  421. package/lib/video-recap/skills/video-assemble/scripts/timeline_emit.py +89 -0
  422. package/lib/video-recap/skills/video-assemble/scripts/visual_render.py +512 -0
  423. package/lib/video-recap/skills/video-cut/SKILL.md +90 -0
  424. package/lib/video-recap/skills/video-cut/scripts/cut.py +67 -0
  425. package/lib/video-recap/skills/video-cut/scripts/cut_cli.py +320 -0
  426. package/lib/video-recap/skills/video-cut/scripts/cut_contract.py +545 -0
  427. package/lib/video-recap/skills/video-cut/scripts/cut_render.py +348 -0
  428. package/lib/video-recap/skills/video-cut/scripts/lib.py +77 -0
  429. package/lib/video-recap/skills/video-cut/scripts/media_geometry.py +341 -0
  430. package/lib/video-recap/skills/video-cut/scripts/narration_mapping.py +249 -0
  431. package/lib/video-recap/skills/video-cut/scripts/sentence_boundaries.py +745 -0
  432. package/lib/video-recap/skills/video-recap/SKILL.md +216 -0
  433. package/lib/video-recap/skills/video-recap/references/config-playbook.md +61 -0
  434. package/lib/video-recap/skills/video-recap/references/creative-editing-playbook.md +225 -0
  435. package/lib/video-recap/skills/video-recap/references/data-schema.md +534 -0
  436. package/lib/video-recap/skills/video-recap/references/research-guide.md +74 -0
  437. package/lib/video-recap/skills/video-recap/references/shift-left-qc-schema.md +23 -0
  438. package/lib/video-recap/skills/video-recap/references/timeline-and-jianying.md +251 -0
  439. package/lib/video-recap/skills/video-recap/scripts/doctor.py +483 -0
  440. package/lib/video-recap/skills/video-recap/scripts/final_qc.py +737 -0
  441. package/lib/video-recap/skills/video-recap/scripts/lib.py +242 -0
  442. package/lib/video-recap/skills/video-recap/scripts/materials.py +457 -0
  443. package/lib/video-recap/skills/video-recap/scripts/mimo_qc.py +95 -0
  444. package/lib/video-recap/skills/video-recap/scripts/mimo_qc_client.py +18 -0
  445. package/lib/video-recap/skills/video-recap/scripts/mimo_qc_contract.py +9 -0
  446. package/lib/video-recap/skills/video-recap/scripts/mimo_qc_evidence.py +371 -0
  447. package/lib/video-recap/skills/video-recap/scripts/mimo_qc_observations.py +201 -0
  448. package/lib/video-recap/skills/video-recap/scripts/mimo_qc_payload.py +227 -0
  449. package/lib/video-recap/skills/video-recap/scripts/mimo_qc_report.py +362 -0
  450. package/lib/video-recap/skills/video-recap/scripts/mimo_qc_runner.py +129 -0
  451. package/lib/video-recap/skills/video-recap/scripts/qc_contract.py +338 -0
  452. package/lib/video-recap/skills/video-recap/scripts/recap.py +9 -0
  453. package/lib/video-recap/skills/video-recap/scripts/recap_cli.py +140 -0
  454. package/lib/video-recap/skills/video-recap/scripts/recap_inspect.py +550 -0
  455. package/lib/video-recap/skills/video-recap/scripts/recap_review.py +77 -0
  456. package/lib/video-recap/skills/video-recap/scripts/recap_runner.py +654 -0
  457. package/lib/video-recap/skills/video-recap/scripts/recap_runtime.py +335 -0
  458. package/lib/video-recap/skills/video-recap/scripts/recap_stage_qc.py +217 -0
  459. package/lib/video-recap/skills/video-recap/scripts/recap_timeline.py +795 -0
  460. package/lib/video-recap/skills/video-script/SKILL.md +248 -0
  461. package/lib/video-recap/skills/video-script/references/creative-editing-playbook.md +225 -0
  462. package/lib/video-recap/skills/video-script/references/research-guide.md +75 -0
  463. package/lib/video-recap/skills/video-script/scripts/agent_brief.py +399 -0
  464. package/lib/video-recap/skills/video-script/scripts/agent_text.py +410 -0
  465. package/lib/video-recap/skills/video-script/scripts/brief_context.py +403 -0
  466. package/lib/video-recap/skills/video-script/scripts/brief_inputs.py +332 -0
  467. package/lib/video-recap/skills/video-script/scripts/brief_timeline.py +442 -0
  468. package/lib/video-recap/skills/video-script/scripts/deslop_qc.py +237 -0
  469. package/lib/video-recap/skills/video-script/scripts/evidence_bundle.py +492 -0
  470. package/lib/video-recap/skills/video-script/scripts/lib.py +327 -0
  471. package/lib/video-recap/skills/video-script/scripts/narration.py +12 -0
  472. package/lib/video-recap/skills/video-script/scripts/narration_lint.py +678 -0
  473. package/lib/video-recap/skills/video-script/scripts/review.py +42 -0
  474. package/lib/video-recap/skills/video-script/scripts/review_grounding.py +262 -0
  475. package/lib/video-recap/skills/video-script/scripts/review_response.py +761 -0
  476. package/lib/video-recap/skills/video-script/scripts/review_runner.py +200 -0
  477. package/lib/video-recap/skills/video-script/scripts/speech_ownership.py +204 -0
  478. package/lib/video-recap/skills/video-script/scripts/timeline_fusion.py +199 -0
  479. package/lib/video-recap/skills/video-script/scripts/validate.py +164 -0
  480. package/lib/video-recap/skills/video-understanding/SKILL.md +75 -0
  481. package/lib/video-recap/skills/video-understanding/references/data-schema.md +299 -0
  482. package/lib/video-recap/skills/video-understanding/references/prompt-templates.md +37 -0
  483. package/lib/video-recap/skills/video-understanding/references/research-guide.md +74 -0
  484. package/lib/video-recap/skills/video-understanding/scripts/agent_brief.py +399 -0
  485. package/lib/video-recap/skills/video-understanding/scripts/agent_text.py +410 -0
  486. package/lib/video-recap/skills/video-understanding/scripts/asr.py +260 -0
  487. package/lib/video-recap/skills/video-understanding/scripts/brief.py +12 -0
  488. package/lib/video-recap/skills/video-understanding/scripts/brief_context.py +403 -0
  489. package/lib/video-recap/skills/video-understanding/scripts/brief_inputs.py +332 -0
  490. package/lib/video-recap/skills/video-understanding/scripts/brief_timeline.py +442 -0
  491. package/lib/video-recap/skills/video-understanding/scripts/consolidate.py +647 -0
  492. package/lib/video-recap/skills/video-understanding/scripts/deslop_qc.py +237 -0
  493. package/lib/video-recap/skills/video-understanding/scripts/detect.py +513 -0
  494. package/lib/video-recap/skills/video-understanding/scripts/extract.py +62 -0
  495. package/lib/video-recap/skills/video-understanding/scripts/lib.py +470 -0
  496. package/lib/video-recap/skills/video-understanding/scripts/narration_lint.py +678 -0
  497. package/lib/video-recap/skills/video-understanding/scripts/speech_ownership.py +204 -0
  498. package/lib/video-recap/skills/video-understanding/scripts/storyboard.py +507 -0
  499. package/lib/video-recap/skills/video-understanding/scripts/timeline_fusion.py +199 -0
  500. package/lib/video-recap/skills/video-understanding/scripts/understand.py +9 -0
  501. package/lib/video-recap/skills/video-understanding/scripts/understanding_brief.py +216 -0
  502. package/lib/video-recap/skills/video-understanding/scripts/understanding_cache.py +327 -0
  503. package/lib/video-recap/skills/video-understanding/scripts/understanding_runner.py +367 -0
  504. package/lib/video-recap/skills/video-understanding/scripts/understanding_storyboard.py +162 -0
  505. package/lib/video-recap/skills/video-understanding/scripts/vlm.py +705 -0
  506. package/lib/video-recap/skills/video-voiceover/SKILL.md +81 -0
  507. package/lib/video-recap/skills/video-voiceover/scripts/dub.py +637 -0
  508. package/lib/video-recap/skills/video-voiceover/scripts/fish_audio.py +109 -0
  509. package/lib/video-recap/skills/video-voiceover/scripts/lib.py +421 -0
  510. package/lib/video-recap/skills/video-voiceover/scripts/tts_audio.py +113 -0
  511. package/lib/video-recap/skills/video-voiceover/scripts/voiceover.py +782 -0
  512. package/package.json +57 -41
  513. package/lib/drama/skills/short-drama/references/lifecycle-commands.md +0 -130
  514. package/lib/oh-story/skills/story-deslop/scripts/check-outline-copy.js +0 -241
  515. package/lib/oh-story/skills/story-long-write/references/format-and-structure.md +0 -169
  516. package/lib/oh-story/skills/story-setup/references/agent-references/genre-writing-formulas.md +0 -444
  517. package/lib/oh-story/skills/story-setup/references/agent-references/quality-checklist.md +0 -247
  518. package/lib/oh-story/skills/story-short-analyze/references/anti-ai-writing.md +0 -582
  519. package/lib/oh-story/skills/story-short-analyze/references/banned-words.md +0 -147
  520. package/lib/oh-story/skills/story-short-analyze/references/genre-catalog.md +0 -490
  521. package/lib/oh-story/skills/story-short-analyze/references/genre-core-mechanics.md +0 -425
  522. package/lib/oh-story/skills/story-short-analyze/references/genre-writing-formulas.md +0 -453
  523. /package/lib/oh-story/skills/{story-long-write/references/hooks-chapter.md → story-setup/references/agent-references/short-chapter-hooks.md} +0 -0
  524. /package/lib/oh-story/skills/{story-long-write/references/hooks-paragraph.md → story-setup/references/agent-references/short-paragraph-hooks.md} +0 -0
@@ -1 +1 @@
1
- {"version":3,"file":"workspace-route.d.ts","sourceRoot":"","sources":["../../src/workspace-route.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAgBnD,UAAU,qBAAqB;IAC7B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,YAAY,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC3C;AAkOD,+EAA+E;AAC/E,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,qBAAqB,GAAG,IAAI,CAM7F"}
1
+ {"version":3,"file":"workspace-route.d.ts","sourceRoot":"","sources":["../../src/workspace-route.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAmCnD,UAAU,qBAAqB;IAC7B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,YAAY,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC3C;AAiHD,MAAM,WAAW,SAAS;IAAG,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;CAAE;AAE3E;;;GAGG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,EAAE,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS,GAAG,IAAI,CAcpG;AAwGD,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,GAAG,IAAI,CAW7E;AAED,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAErE;AAoHD,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAQ9C;AAmMD;;;;;;GAMG;AACH,wBAAgB,4BAA4B,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAiBnE;AAuJD,+EAA+E;AAC/E,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,qBAAqB,GAAG,IAAI,CAM7F"}
@@ -0,0 +1,282 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project are documented here.
4
+
5
+ 格式参考 [Keep a Changelog](https://keepachangelog.com/zh-CN/1.1.0/),
6
+ 版本号遵循 [Semantic Versioning](https://semver.org/lang/zh-CN/)。
7
+
8
+ 小节名统一使用 Keep a Changelog 的六个英文类别(`Added` / `Changed` / `Deprecated` /
9
+ `Removed` / `Fixed` / `Security`),正文为中文。收紧到会拒绝旧输入的改动记入 `Changed`。
10
+
11
+ ## [Unreleased]
12
+
13
+ ## [0.4.0] - 2026-07-27
14
+
15
+ 汇总 `v0.3.3` 之后的全部工作:多源剪辑、QC、字幕与配音改进,可携带剪映草稿能力,内容驱动的创作流程,以及一轮深度审查带来的正确性、性能与配置面修复。
16
+
17
+ ### 新增
18
+
19
+ - **贴合原片字幕带。** `tools/measure_subtitle.py` 用 stdlib + ffmpeg 抽帧、检测并输出红框预览;`--subtitle-y-top/--subtitle-y-bot` 把新字幕基线与字号适配到测得坐标,并显式启用该区域遮罩。
20
+ - **半透明、解说时段遮罩。** 显式启用原字幕遮罩后,默认改为 `SUBTITLE_MASK_OPACITY=0.6`、`SOURCE_SUBTITLE_MASK_TIMING=narration`,原声留白不再常驻黑条;仍可设为 `1` / `all` 恢复全黑全时段效果。
21
+ - **参考音色解说。** recap / voiceover 新增 `--voice-ref`,通过 `mimo-v2.5-tts-voiceclone` 给普通解说克隆音色;新生成时参考音频惰性转码一次、最长取 30 秒,内容与转码版本指纹参与 TTS 缓存校验。
22
+ - **正式的建议性 MiMo QC。** `--mimo-qc pre-assemble|post-render|both` 在单源/多源流水线的组装前、成片后各最多发起一次 MiMo 请求,把语义/审美观察聚合进 `mimo_qc.json`;内容缓存、`--mimo-qc-refresh`、最多 6 张/768px 临时抽帧、密钥/base64 不落盘均有回归覆盖。缺 key、401/429、超时、畸形响应和本地异常全部 fail-open,只提示 Agent/用户,永远不生成 blocker。
23
+ - **可携带剪映草稿。** video/audio/image 默认打包到 `Resources/local`;timeline v2 新增恒定变速、倒放、transform、富文本/逐字样式、转场/mask/LUT、绿幕复合和离线资源轨道。
24
+
25
+ ### 改进
26
+
27
+ - **内容驱动的创作流程。** Agent 在剪辑或写稿前先比较剪辑假设,记录 POV、戏剧问题、change-based beats、具体画面/反应、`audio_owner` 与 `narration_job`;`recap_story_plan.json` / `visual_audio_board.json` 同时覆盖单视频与多视频 cut。旁白比例改为素材决定,`7:3` 只保留为粗略回退而非配额。
28
+ - **阶段技能完全自包含。** 阶段说明与本地参考不再引用兄弟技能的路径或名称;写稿阶段拥有独立的补充调研指南与 `deslop_qc.py`,不会假装新调研已被既有 VLM 消费。
29
+ - **多视频证据更可用。** 项目 brief 优先摘取逐来源的背景、索引、ASR 与场景证据,不再只截取通用写作说明。
30
+
31
+ ### 变更
32
+
33
+ - **每个配置旋钮只声明在读它的技能里。** 六份 `lib.py` 中有五份此前携带所有技能配置的并集(各 155–173 个键,其中 95–132 个该技能从不读取);`video-cut` 一直是反例(8 个键,全部使用)。现在各技能只声明自己读取的键,删除 583 条无效声明。保留集由运行时插桩实测得出(按调用栈把 parity 测试的读取与生产代码的读取区分开),而非静态匹配——这也是发现下列两处问题的方式。
34
+ - `zone_fade_seconds` 在五份副本中均有声明,但**全仓库无任何读取点**,此前仅靠「副本之间取值一致」的断言存活。
35
+ - `CLIP_PADDING` 在 `video-cut` 中依然无效:该技能的 `lib.py` 从未声明此键,查表始终落到内联默认值。
36
+ - **音频策略一致性断言改为按实际声明范围校验。** 此前断言五份副本对约 30 个音频键取值一致,而多数技能并不读取它们——这种一致性是复制行为自身造成的循环要求。新增不变量:**任何技能不得声明自身从不读取的配置**,从结构上杜绝上述两类问题复现。
37
+
38
+ ### 修复
39
+
40
+ - **画面锚点整体偏移 1/fps 秒。** ffmpeg 的 `fps` 滤镜首帧在源时间 0,而文件编号从 1 起,所以 `frame_00001.jpg` 是 `t=0`、第 n 帧是 `(n-1)/fps`;此前按 `n/fps` 计算,把 `frame_facts`、场景归属与 storyboard 标签整体推后 1/fps 秒(>5min 视频默认 fps=1,即整整 1 秒)。这些时间戳会写进 VLM prompt 并作为写稿 Agent 的权威画面锚点。换算规则收敛到 `extract.py` 独家定义,帧/VLM 缓存带约定版本号,旧产物强制重算。
41
+ - **带封面图的素材渲染直接失败。** 组装映射 `0:v` 会匹配到 attached_pic 那一路视频流,而 `-vf` 只作用于第一路,ffmpeg 报 `Could not write header` 并留下损坏文件——发生在整条流程的最后一步。改为 `0:v:0`。
42
+ - **`--clip-padding` 非零时相邻片段被误判为重复素材。** 重叠检测此前基于加过 padding 的区间,任意两个背靠背片段都会硬失败;现按 Agent 实际写入的入出点判断。
43
+ - **`CLIP_PADDING` 环境变量此前完全无效。** 六份 CONFIG 都声明了该键并通过 `clip_padding_source` 汇报为生效,但唯一实现 padding 的 video-cut 只读 CLI 参数。
44
+ - 多视频输出时间线的 speech 证据改为与 `audio_mix` / `sentence_boundaries` 一致优先读 `asr_clean.json`;`narration_coverage_max` 等三个只读不声明的 CONFIG 键补齐;`silencedetect` 超时改为与该函数其余失败路径一致地 fail-open;多源剪辑的句子截断阻断项不再挂在无关条件下。
45
+ - 亮色画面不再把整片背景误并为字幕候选;测量结果按源隔离,失败时保留上一轮成功产物。
46
+ - 校订版原声字幕使用逐窗口全不透明遮罩,避免与原片硬字幕重影;测量坐标拒绝不兼容的非底部 ASS 对齐。
47
+ - voice reference 使用同一不可变快照完成转码和缓存标识,进程内重复调用不再继承上一次音色;CLI 与环境变量统一提前校验。
48
+ - 长视频的遮罩滤镜超过安全命令长度时改用 ffmpeg filter script,避免 Windows `CreateProcess` 上限;measured band 统一为 `[top, bot)` 并成为视觉 QC 的真实安全区。
49
+ - 测量产物提交失败会回滚整组旧产物;recap 通过显式 assemble 参数传递字幕坐标,不再污染进程环境。
50
+ - 删除测试专用/生产不可达的 assemble、review、audio automation、QC rule-loader 兼容层;MiMo/其他 non-deterministic finding 不再有 allow-list 升级 blocker 的逃生口。每个 skill 的 `lib.py` / `brief.py` / `narration.py` 复制仍刻意保留,确保单独 clone/安装即可运行。
51
+
52
+ ### 性能
53
+
54
+ - **不再重复哈希/解码/探测同一批字节。** `file_fingerprint` 按进程记忆化(内容寻址不变,仅用 dev/inode/size/mtime_ns 作记忆键):一次理解流程原本要对源视频做 8–10 次全量 sha256、对整套抽帧做 2–3 遍,40 分钟视频约 2400 张全分辨率 JPEG。VLM 的逐帧 base64 缓存由无上界字典改为 LRU;续传缓存由每个场景整份重写改为按批落盘;TTS 响度归一从三遍纯 Python 遍历改为 `array('h')` 单遍(输出字节与元数据完全一致);命中缓存的 TTS 段不再逐段 ffprobe;黑/白帧场景过滤按场景并行。
55
+
56
+ ### 构建
57
+
58
+ - `pyproject.toml` 显式声明 ruff 规则集。CI 不固定 ruff 版本,而 0.16 起默认规则集被大幅扩展,会让无关 PR 的 lint 步骤失败。
59
+ - `scripts/test.py` 将「未安装 pytest」与真实测试失败区分开。
60
+
61
+ ### 测试
62
+
63
+ - 测试入口统一到跨平台 `scripts/test.py`;CI 中 frontmatter、manifest、prompt anchor 与隔离导入契约全部改为 pytest 行为/结构测试。
64
+ - 合并重复测试并增加动态 skill 发现、精确重复测试体检测、测试组注册、自包含边界、创作 JSON 结构与 multi-source brief 回归覆盖。
65
+
66
+ ### 验证
67
+
68
+ - 全套 `python3 scripts/test.py` 通过(801 tests);`ruff`、`compileall`、修改模块 `mypy` clean;其中 assemble 275 tests 覆盖剪映草稿协议、timeline 迁移和便携资源写入。
69
+ - 真实 ffmpeg 合成字幕样片验证:测量工具识别 `y=[613,637)`;遮罩像素在留白帧为 `128`、解说帧为 `51`。
70
+ - 剪映专业版 `10.8.7-beta1` 实测:视频/解说/BGM/字幕/图片轨在线,预览、保存、关闭与重开正常。
71
+
72
+ ## [0.3.3] - 2026-06-28
73
+
74
+ 多源视频剪辑解说 + 文件系统素材库复用为主线,并合入跨 harness 支持、成片兼容性与竖屏字幕修复、解说评审硬闸等改进。
75
+
76
+ ### 新增
77
+
78
+ - **多视频剪辑解说(cut 模式)。** 一次传入多个源视频,按 `source_id` 选取片段,剪成一个成片;项目级 `multi_source_manifest.json` 作为 recap / cut / assemble 的来源契约,`clip_plan.json` 每个片段带 `source_id`,重叠检测按源隔离。多视频 MVP 仅开放 `--edit-mode cut`。
79
+ - **文件系统素材库复用。** `--material-library-dir` 搭配 `--save-materials` / `--use-materials`,把每个源视频的分析产物沉淀为 grep 友好的 `material.json` / `material.md` / 追加式 `materials_index.jsonl`,不复制原始媒体;按源指纹 + 设置指纹门控恢复,复用前清理旧 work dir 的残留产物。无 DB / embedding / 语义检索,纯文件系统 + `grep`。
80
+ - **多源 provenance 透出。** `video-assemble` / `recap_inspect` 在时间线与剪映草稿中保留 `source_id` / `source_path`;个别源缺失时按片段降级并显式标记,保留其余在场源的来源,而非丢弃整条时间线。
81
+ - **`video-understanding --brief-only`。** 从已恢复 / 缓存的分析产物重建 OUTPUT 时间轴 brief,不重跑抽帧 / ASR / VLM / 外部 API。
82
+ - **跨 harness 支持 + Claude Code marketplace。** Codex 与 OpenClaw 直接读取 `.claude-plugin` 包,无需每 harness 文件;marketplace 命名为 `video-recap`。(#50)
83
+ - **解说评审 scorecard + dub-lint 硬闸 + partial-TTS 可见性。** (#49)
84
+
85
+ ### 改进
86
+
87
+ - **单视频 full / cut / dub 行为保持兼容。** 多视频仅在 cut 模式开放;单源剪辑滤镜图保持不变(字节级一致)。
88
+
89
+ ### 修复
90
+
91
+ - **异源 concat 几何归一化。** 多源片段先归一到统一画布(scale / pad / setsar / fps / yuv420p)再 concat,分辨率 / SAR / 帧率不同的源视频不再让 ffmpeg 报错;不同分辨率的多视频可正常合成一个成片。
92
+ - **多源音轨按源处理。** 个别无声源不再导致整段成片静音;每个片段都有音频(原声或合成静音)。
93
+ - **密钥脱敏更精确。** 只脱敏凭证形态(`tp-` / `sk-` / `gh*_` / `AKIA` / JWT 与 `KEY=VALUE`)与凭证命名的 JSON key,不再误伤 transcript / summary 里的 `secret` / `token` 等普通词,也不再把多个 key 合并丢值。
94
+ - **出片强制 `yuv420p` + faststart。** 微信 / 手机可播、边下边播。(#51)
95
+ - **字幕样式按探测画布缩放。** 修复竖屏 (9:16) 字幕被拉伸。(#53)
96
+
97
+ ### 验证
98
+
99
+ - 全套 `python3 scripts/test.py` 全部 skill groups passed(551 tests),`ruff` / `compileall` clean。
100
+ - 新增真实 ffmpeg 多分辨率 + 混合音频渲染测试(验证异源 concat 与音轨归一化);密钥脱敏保留正常词 / 不合并 key / 凭证形态测试;assemble 按片段降级(保留在场源 provenance)测试。
101
+
102
+ ## [0.3.2] - 2026-06-22
103
+
104
+ 让剪映草稿导出跟上新版工程结构,方便在剪映专业版里继续精修。
105
+
106
+ ### 新增
107
+
108
+ - **新版剪映 schema-driven 草稿导出。** 剪映导出从单文件 JSON 拼装拆成 schema / model / builder / track / writer 分层,草稿基线升级到 `version: 360000`、`new_version: 111.0.0`、`app_version: 5.9.5-beta1`,并补齐包含 `common_mask` 在内的新版 `materials` skeleton。
109
+ - **素材类型注册表与能力清单。** 明确区分已支持的 `video` / `audio` / `text` / `subtitle` / `speed`,以及预留但暂不写出的 image/sticker/effect/mask 等类别;未知或暂不支持类别会输出 note 并跳过,避免生成畸形草稿。
110
+
111
+ ### 改进
112
+
113
+ - **剪映导出仍保持可选、懒加载、stdlib-only。** `export_jianying.py` 现在只是薄 facade,核心 ffmpeg 渲染路径不会导入任何 `jianying_*` 模块;`timeline.json` 仍是后端无关的 canonical input,ffmpeg 仍是最终成片判定标准。
114
+ - **草稿写入更安全。** 写入器继续保留非空目录避让、媒体打包、路径重写、临时目录原子替换;并新增 `draft_name` 校验,拒绝空名、绝对路径、`..`、以及路径分隔符,防止错误名称逃逸草稿父目录。
115
+ - **BGM 循环与音量自动化覆盖更完整。** 循环 BGM 会拆成多段铺满时间线,并把窗口内 `KFTypeVolume` 音量关键帧放到对应片段。
116
+
117
+ ### 验证
118
+
119
+ - `ruff` / `py_compile` / `mypy --ignore-missing-imports` 覆盖剪映导出模块;相关 assemble/timeline 测试 84 passed,全项目 `scripts/test.py` 全部 skill groups passed。
120
+ - 本机剪映专业版 `10.8.7` 实测:生成并打开 schema E2E 草稿;又把历史 `longvacation_2min_work/timeline.json` 转成 `recap_tmp_convert_longvacation_2min_20260623_003900`,剪映已登记并可打开。
121
+
122
+ ## [0.3.0] - 2026-06-20
123
+
124
+ 长视频更稳、跨语言更干净、剪辑更顺眼,并新增解说导航与成片压缩工具。
125
+
126
+ ### 新增
127
+
128
+ - **VLM 场景分析可断点续传 + 限流自愈。** 长视频(数百场景)过去偶发 HTTP 429 会让整轮画面理解失败、再跑得从头重来。现在每个场景分析完即落盘(`vlm_scene_cache.json`,原子写),失败只重试缺失/失败的场景;遇到限流(429)的场景自动降到 ¼ 并发重试一次,持久性错误(空响应/解析失败)不重试。默认 8 并发不再拖垮长视频。
129
+ - **跨语言解说降噪 `FOREIGN_SOURCE_AUDIO`。** 当原片语言与解说不同(如日剧配中文解说)时,解说下方被压低的原声本就听不懂、还会被当成「怪音」。该开关把解说下的原声压到近静音(0.05),而原声留白块仍保持满音量;显式 `SPEECH_DUCKING_VOLUME`/`ZONE_DUCKING_VOLUME` 仍可覆盖。
130
+ - **剪辑边界吸附原片切镜头 `SCENE_CUT_SNAP`。** 片段边界若落在原片硬切点附近,会先闪一下相邻镜头再切,形成可见闪烁。新增一道吸附(在自然停顿吸附之后):用 ffmpeg 在窄窗口里探测原片硬切并把边界移上去(每片段约 2 次轻量探测,复用现有缓存);已对齐或附近无切点的边界不动,会把片段压到 ~0.5s 以下的吸附跳过。
131
+ - **成片压缩参数 `OUTPUT_CRF` / `OUTPUT_PRESET` / `OUTPUT_MAX_HEIGHT`。** 最终混流过去硬编码 `-crf 18 -preset veryfast` 且从不缩放,成片体积偏大。现可调 CRF/preset/高度上限(缩放放在最后,遮挡与字幕先在原分辨率渲染再随帧缩小,更清晰);默认仍是 18/veryfast/不缩放。demo:长假 2 分钟成片由 119MB 降到 16.9MB。
132
+ - **解说导航工具(咨询性,不影响成片)。** 新增只读的 `inspect`(`state` 看流程进度/源视频指纹/下一处暂停;`clip-map` 在成片↔原片时间轴间精确换算,回答「成片 30–60s = 原片哪段」)与视频故事板(源时间轴 + 剪辑成片时间轴的缩略图总览,写作时扫一张图就能定位转场/反转,复用已抽帧不重抽)。任一缺失或异常都只降级提示、绝不阻断流程。
133
+
134
+ ### 变更
135
+
136
+ - **手动评审自动按成片时间轴。** `review.py` 的 `--timeline` 默认改为 `auto`:检测到已验证的剪辑成片(`clip_plan_validated.json` + `edited_source.mp4`)就按成片时间轴评审,否则按原片。消除了 cut 模式下手动评审把原片时间当成成片、误报一堆「幻觉」的问题(demo 上 4 个假阳性 → 1 个真问题)。编排器显式传入的 `cut_output` 仍优先。
137
+ - **ASR 默认分段 30→15s。** 时间戳最坏误差大致减半,并重新启用静音/ASR 交叉校验;代价是每个视频约 2× 顺序 ASR 调用(`ASR_SEGMENT_SECONDS` 可调)。
138
+ - **自带字幕在不遮挡时也显示。** 原声留白字幕过去被绑在「遮挡原字幕(mask)」开关上,干净/外语片源(无烧录字幕、mask 关)会连同自带 `user_subtitles.*` 一起被丢掉。现解耦:有自带字幕文件即视为明确意图、在留白处照常显示(干净片源无重影风险)。与 `FOREIGN_SOURCE_AUDIO` 搭配适配「外语剧 + 自带中文字幕」。
139
+
140
+ ### 修复
141
+
142
+ - **cut 模式 pass2 简报崩溃。** 被拆分的场景拿到字符串 id(如 `"5.0"`)、未拆分的仍是 int,`sorted(scene_ids)` 因 int/str 混排崩溃。改为类型安全排序键(int 在前、拆分串在后),并对字节孪生的 `brief.py`/`narration.py` 同步修改(md5 保持一致)。
143
+ - **原声留白字幕滞后。** 粗粒度 ASR(按时钟分箱、按字符位置估时)会让某句晚显示约 6–8s。现「精确来源」与 ASR 兜底都改为按整句、从留白起点顺序排布,多句不再重叠或散到字符比例尾槽。
144
+ - **成片压缩两处健壮性(发布前评审发现)。** 奇数 `OUTPUT_MAX_HEIGHT`(如 721)过去会产生奇数高度、被 libx264/yuv420p 拒绝 → 空成片 + 笼统报错;现强制宽高都为偶数。`OUTPUT_CRF=0`(无损,合法值)过去被当假值改成 18;现原样保留。
145
+ - **inspect 测试接入 CI。** 新增的 inspect 测试组此前只写进 `scripts/test.sh`,而 CI 实际跑的是 `scripts/test.py`,导致这 22 个测试从未在 CI 运行;现已补进运行器。
146
+
147
+ ### 其他
148
+
149
+ - demo 换成《悠长假日》第一集 2 分钟 cut 模式解说,集中展示本轮能力(无闪烁边界、跨语言降噪、自带中文字幕留白、CRF24/720p 压缩);并更新 README 中的 demo 链接。
150
+
151
+ ## [0.2.3] - 2026-06-19
152
+
153
+ 一轮成片质量打磨:原声留白字幕更准(可自带字幕)、画面理解更密、解说去掉破折号、评审更稳。
154
+
155
+ ### 新增
156
+
157
+ - **自带原声字幕(更准)。** 解说留白处的原声字幕,除了 Agent 校对、ASR 兜底之外,现在可以直接放一份准确的字幕文件作为**首选来源**:`work_dir/user_subtitles.json`(`[{start,end,text}]`,默认按成片时间轴;或写成 `{"timeline":"source","lines":[...]}` 用原片时间轴,按剪辑计划自动映射到成片)或 `user_subtitles.srt` / `.ass`(默认按原片时间轴映射)。优先级:自带字幕 › Agent 校对的 `original_subtitles.json` › ASR 兜底。
158
+ - **逐帧采样随场景时长伸缩。** VLM 每个场景的取帧数过去硬上限 6 帧,长场景(合并后可达上百秒)只能 1 帧/约 20 秒,`frame_facts` 严重稀疏。现按场景时长伸缩(约每 `VLM_SECONDS_PER_FRAME`=4 秒一帧,下限 3、上限 `VLM_MAX_FRAMES`=16),长场景的画面理解不再被饿死;VLM `max_tokens` 800→1500(`VLM_MAX_TOKENS`)。
159
+ - **MiMo 视频概览可作主理解来源。** 开启视频概览(`--mimo-video-overview` / `MIMO_VIDEO_OVERVIEW=1`)时,它会成为每个场景的**主要描述**(带动态、读得懂剧情),逐帧 `frame_facts` 仍保留作锚点与兜底;因为不动 `frame_facts`,substrate 评级不会因此回退。概览仍是可选项(默认关闭)。
160
+
161
+ ### 变更
162
+
163
+ - **解说不再用破折号。** 破折号烧进字幕里很突兀:写作规则禁止在解说与 `original_subtitles.json` 里用破折号(——/—),渲染时再做一道归一化(替换为逗号)兜底;只改字幕显示,不动 TTS 朗读文本。
164
+ - **解说评审更确定、只对硬伤拦。** 评委固定 `temperature=0`+种子,复跑结论一致;只有 `hallucination`/`incomplete`(事实类)能在严格模式拦截,文笔类意见(钩子弱、念画面、套话等)一律降为提示;评审规则承认 `background_research` 与画面、对白并列为有效依据,不再把有据可查的设定误判成幻觉。
165
+ - **覆盖率指标按写作预算同速率计。** 解说覆盖率过去用 4.55 字/秒打分、却用 3.87 字/秒给 Agent 配额,比自己的预算还严约 18%,容易误报「讲得太少」。现统一用 3.87(含 `speech_safety_margin`);并把几个覆盖率阈值提升为真正的 CONFIG 项。
166
+ - **ASR 人名按背景资料纠错。** 转写后用 `background_research.json` 里的人名修正单字同音错误(如 叶青眉→叶轻眉),严格限定「恰好一字之差、且窗口本身不是已知人名」,避免误改。
167
+ - **视频概览部分被审核拦截时降级。** 概览分片若部分被内容审核拦截,不再整体中止理解,而是用可用分片降级产出、未覆盖场景回退到逐帧描述;概览取帧帧率 `mimo_video_fps` 2→3。
168
+
169
+ ### 修复
170
+
171
+ - **原声留白字幕与原声对不上。** 字幕时间过去依赖粗粒度 ASR(按块时间戳、中点估时),偶尔和原声对不上。现在「精确来源」(自带字幕/Agent 校对稿)按句**区间裁剪**精确落到所覆盖的留白:跨解说块的句子按时间比例切成各段、不再整句重复出现;过密的行截断显示而非直接丢成空白。
172
+
173
+ ## [0.2.2] - 2026-06-18
174
+
175
+ 让分块解说的成片更连贯、更好看:给原声留白补上**校对过**的字幕、解说与原声自然衔接、剪辑不再切断台词;并把会到最后才炸的失败提前暴露。
176
+
177
+ ### 新增
178
+
179
+ - **原声留白也烧字幕了。** 解说块之间留给原声的留白,过去字幕是空的(解说字幕只写解说,原片自带字幕又被遮挡)。现在这些留白会烧上**原声台词字幕**,并用 `「」` 与解说区分开。优先采用 Agent 校对过的 `original_subtitles.json`(OUTPUT 时间轴 `[{start,end,text}]`:订正 ASR 错字与人名、只保留留白里真正出声的台词);没有该文件时退回保守的 ASR 兜底——按句归到它所在的那一段留白、跳过太密读不完的行(`SUBTITLE_ORIGINAL_IN_GAPS`,默认开;cut 模式按剪辑计划把 ASR 从源时间映射到成片时间)。
180
+ - **剪辑不再切断一句台词(cut 模式)。** `video-cut` 会把每个片段的结尾向后吸附到最近的自然停顿(依据 `silence_periods.json`,上限 `CLIP_SNAP_MAX_EXTEND`,默认 2 秒;`SNAP_CLIP_LINE_END` 可开关),让原声把话说完;选片 brief 也提示 Agent 在完整句尾收口。
181
+ - **字幕烧录预检(快速失败)。** 烧字幕需要带 libass(`subtitles` 滤镜)的 ffmpeg。编排器在整条流程开跑前就检查,缺失即报错并给出处置(装一个带 libass 的 ffmpeg,或加 `--no-burn-subtitles`),不再跑完理解 / VLM / ASR / TTS、到最后渲染才失败;`video-assemble` 单独运行时同样有此预检。
182
+ - **成片时直接给出解说评审入口。** 存在 `narration_review.md` 时,编排器收尾会打印它的结论与路径,把内容风险(钩子弱 / 没主线 / 节奏)摆到眼前——仍是建议性,硬门禁只有 `validate.py`。
183
+
184
+ ### 变更
185
+
186
+ - **解说块与原声自然衔接。** brief、写作规则和评审一起教会 Agent:原声留白前的那一块要把原声**引出来**,留白后的那一块要**接住**原声刚呈现的内容,让解说和它包裹的原声读成一个连贯的 beat,而不是各说各的(评审新增 `disjoint_handoff` 类别)。
187
+
188
+ ### 修复
189
+
190
+ - **原声字幕过度渲染 / 与解说混在一起。** 早先的实现会把一整段(多句)ASR 文本塞进一小段留白、还在多段留白里重复出现,渲染出根本没说出口的台词。现在按句归属到单段留白、跳过过密的行、并用 `「」` 与解说分隔;最佳效果由 Agent 校对的 `original_subtitles.json` 提供。
191
+ - **文档:字幕烧录默认开启。** 两份 README 与 SKILL.md 原先把烧字幕写成需要 `--burn-subtitles` 才开,实际是默认开(用 `--no-burn-subtitles` 关闭);已更正措辞。
192
+
193
+ ## [0.2.1] - 2026-06-17
194
+
195
+ A delivery-quality release: narration now plays in blocks with the original audio breathing
196
+ between them at full volume, and the burned-in subtitle band no longer compresses the picture.
197
+
198
+ ### Changed
199
+
200
+ - **Narration is delivered in BLOCKS, ~7:3.** Each beat is a few sentences written as one
201
+ continuous thought and synthesized as a single fluent TTS utterance — fixing the choppy,
202
+ sentence-by-sentence delivery. Between blocks the recap leaves deliberate original-audio
203
+ blocks (~30% of the timeline) where the original scene plays at FULL volume.
204
+ - **Original-audio blocks play at full volume.** `idle_orig_volume` now defaults to `1.0` and
205
+ `duck_bridge_seconds` to `1.5` (was `12`), so the original is ducked only under a narration
206
+ block and swells back to full in the gaps, instead of sitting under one permanent low bed.
207
+ This reverses the 0.2.0 "continuous bed" default. Tune with `IDLE_ORIG_VOLUME` /
208
+ `DUCK_BRIDGE_SECONDS`.
209
+ - **Burned-in subtitles are split into short one-line chunks** timed karaoke-style across each
210
+ block, and the source-subtitle masking band is sized for ONE line (~14% of height) instead of
211
+ two (~23%) — the black band no longer compresses the picture.
212
+ - **The brief and lint steer block authoring.** The agent is told to write blocks and leave
213
+ ~30% original-audio gaps; the per-sentence density lint is replaced by a block-coverage lint
214
+ (`no_original_blocks` / `under_narrated` / `no_original_breaks` / `fragmented_beats`), and the
215
+ block count is derived from coverage instead of beats-per-minute.
216
+
217
+ ### Fixed
218
+
219
+ - **Blocks are no longer truncated by the speed-up.** `voiceover` sized a segment's text against
220
+ the raw TTS duration, ignoring the `narration_speed` (1.3×) atempo that assemble applies before
221
+ placement — so a correctly-budgeted block was clipped into a fragment. The truncation budget now
222
+ accounts for `narration_speed`.
223
+
224
+ ## [0.2.0] - 2026-06-16
225
+
226
+ A quality-focused release that re-architects cut mode and the narration mix so the
227
+ recap feels like a recap, not captions over a clip.
228
+
229
+ ### Changed
230
+
231
+ - **Cut mode is now cut-first / narrate-second (two pauses).** The orchestrator renders
232
+ `edited_source.mp4` from `clip_plan.json` first, then asks the agent to write
233
+ `narration.json` against that real output timeline. Narration and picture stay in sync
234
+ by construction — the old source→output remap that could silently drop or clamp beats is
235
+ gone. Full mode is unchanged (single pause).
236
+ - **Continuous original-audio bed.** The original is ducked into one continuous low bed
237
+ under the narration instead of swelling back up between sentences. Inter-beat gaps shorter
238
+ than `duck_bridge_seconds` (default 12s, just above the max narration gap) stay ducked;
239
+ only the lead-in and lead-out return to full volume. Tune with `DUCK_BRIDGE_SECONDS`.
240
+ - **Narration density is a guide, not a quota.** The brief frames beats/min as a target to
241
+ aim for, explicitly telling the agent never to pad with filler or pixel-description to hit
242
+ a number — fewer "cold", caption-like recaps.
243
+ - **`--consolidate` story index is on by default**, with a backward-compatible manifest shim
244
+ so existing `work_dir`s still resume. Use `--no-consolidate` to opt out.
245
+ - **Research directive only fires when the substrate is thin/empty** (not on every titled
246
+ run), and the orchestrator surfaces a research hint in the pause banner.
247
+
248
+ ### Added
249
+
250
+ - **Cut-desync floor:** narration is linted against the normalized clip plan, with a blocking
251
+ preflight that fails before TTS on heavy drop / too-sparse / long-gap output; `--allow-sparse-cut`
252
+ ships an intentional montage anyway.
253
+ - **Phase ledger (`recap_phase.json`)** for deterministic cut-mode resume; a stale narration
254
+ from a changed `clip_plan` can no longer resume into TTS.
255
+ - **`duck_bridge_seconds`** config knob (env `DUCK_BRIDGE_SECONDS`).
256
+
257
+ ### Fixed
258
+
259
+ - **Long-video understanding rides out MiMo cluster rate limits.** A full episode fans out
260
+ into ~90 ASR + ~185 VLM calls; the MiMo endpoints now retry up to 10× with a 60s backoff
261
+ cap (plus a 10s floor when the server sends no `Retry-After`), and an optional
262
+ `ASR_THROTTLE_SECONDS` spaces sequential ASR — so a transient 429 no longer aborts the run.
263
+ - **Resume cannot reuse stale artifacts.** Cached-artifact reuse now proves it matches the
264
+ current source bytes / settings and rejects stale provenance, so a changed input or config
265
+ can no longer silently resume on an out-of-date intermediate.
266
+
267
+ ## [0.1.0]
268
+
269
+ - Initial release: turn any video into a Chinese-narration recap on `ffmpeg` + one Xiaomi
270
+ MiMo API key. Five independent skills (understanding, script, cut, voiceover, assemble)
271
+ plus a thin orchestrator; optional 剪映 draft export.
272
+
273
+ [Unreleased]: https://github.com/zenstory-ai/video-recap-skills/compare/v0.4.0...HEAD
274
+ [0.4.0]: https://github.com/zenstory-ai/video-recap-skills/compare/v0.3.3...v0.4.0
275
+ [0.3.3]: https://github.com/zenstory-ai/video-recap-skills/compare/v0.3.2...v0.3.3
276
+ [0.3.2]: https://github.com/zenstory-ai/video-recap-skills/compare/v0.3.1...v0.3.2
277
+ [0.3.0]: https://github.com/zenstory-ai/video-recap-skills/compare/v0.2.3...v0.3.0
278
+ [0.2.3]: https://github.com/zenstory-ai/video-recap-skills/compare/v0.2.2...v0.2.3
279
+ [0.2.2]: https://github.com/zenstory-ai/video-recap-skills/compare/v0.2.1...v0.2.2
280
+ [0.2.1]: https://github.com/zenstory-ai/video-recap-skills/compare/v0.2.0...v0.2.1
281
+ [0.2.0]: https://github.com/zenstory-ai/video-recap-skills/compare/v0.1.0...v0.2.0
282
+ [0.1.0]: https://github.com/zenstory-ai/video-recap-skills/releases/tag/v0.1.0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 PiteChen
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,257 @@
1
+ # video-recap-skills
2
+
3
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
4
+ ![Claude Code Plugin](https://img.shields.io/badge/Claude%20Code-Plugin-purple)
5
+ ![Powered by Xiaomi MiMo](https://img.shields.io/badge/AI-Xiaomi%20MiMo-green)
6
+ ![Fish Audio TTS](https://img.shields.io/badge/TTS-Fish%20Audio-blue)
7
+
8
+ [中文](README.md) · English
9
+
10
+ **In Claude Code, Codex CLI, OpenCode, or OpenClaw, one natural-language request turns a video into a Chinese-narration recap.** It needs only Python, `ffmpeg`, and one Xiaomi MiMo API key locally; TTS can optionally use Fish Audio. No GPU or model downloads are required, and it runs on macOS / Linux / Windows.
11
+
12
+ ## Demo
13
+
14
+ <video src="https://github.com/user-attachments/assets/f3c2df0c-6869-4f5b-8f4c-cce70b58b667" width="640" controls></video>
15
+
16
+ [Explore the complete 60-second *Guohuo (这一秒过火)* Skill project, Remotion overlay source, and content audit](examples/guohuo-60s/)
17
+
18
+ The case study covers the core cut, picture/audio lock, packaging exploration, viewing feedback, scoped conform/re-cut, and frozen-set verification. It also demonstrates multi-episode selects, source-audio/narration ownership, Fish Audio voiceover with TTS-aligned captions, and repairing distracting joins by restoring continuous source motion. No copyrighted episode footage, audio, or rendered video is stored in the repository.
19
+
20
+ Beyond the rendered MP4, you can export a **剪映/JianYing draft** to keep editing by hand, with original clips, narration, BGM, and subtitles:
21
+
22
+ <img alt="Exported 剪映 draft: original clips, narration, BGM, and subtitles" src="docs/jianying-export.png" width="100%">
23
+
24
+ ## What it is
25
+
26
+ ```mermaid
27
+ flowchart LR
28
+ video(["Video"]) --> understand["① Understand<br/>scenes · ASR · VLM"]
29
+ research["Story research · optional"] -.-> understand
30
+ understand --> script["② Direct · Edit · Script<br/>agent"] --> voiceover["③ Voiceover<br/>MiMo / Fish Audio"] --> assemble["④ Assemble<br/>mux · subtitles"] --> output(["Recap"])
31
+ understand -. cut mode · cut first .-> cut["Cut<br/>render first"] -.-> script
32
+ classDef io fill:#4f86c6,stroke:#3a6298,color:#fff;
33
+ classDef stage fill:#eef6ff,stroke:#4f86c6,color:#1f2937;
34
+ classDef opt fill:#f3f4f6,stroke:#9ca3af,color:#475569;
35
+ class video,output io;
36
+ class understand,script,voiceover,assemble stage;
37
+ class research,cut opt;
38
+ ```
39
+
40
+ ## Why use it
41
+
42
+ - **One key, runs anywhere.** ASR, VLM, and TTS all go through [Xiaomi MiMo](https://platform.xiaomimimo.com); the local runtime uses only Python's standard library and `ffmpeg`, with no `pip install`.
43
+ - **Optional Fish Audio TTS.** Select `--tts-provider fish-audio` to use Fish Audio. Its current `s2.1-pro-free` model is useful for development, evaluation, and non-SLA workloads while the existing MiMo path remains the default.
44
+ - **Research when it matters.** When the title/story context is known or the brief notes the material is thin, put character relationships and plot background in `background_research.json` so the VLM knows who's who.
45
+ - **Make the editorial decision before allocating sound.** The agent first compares edit hypotheses and locks the POV, story spine, exact picture moments, and original-audio anchors. Narration is voiced as a block only when it has a defined job; strong dialogue, action sound, or silence may own an entire beat. A 7:3 split is only a rough fallback, never a quota.
46
+ - **Cut first, frames aligned.** Cut mode renders the shortened video first, then writes narration against that output timeline, so picture and voice stay in sync.
47
+ - **Multi-video cut, reusable analysis.** Feed several videos at once, pick ranges by `source_id`, and render one recap; each video's analysis is saved to a filesystem material library you can `grep` and reuse next time.
48
+ - **Keep editing in 剪映.** Optionally export a schema-driven draft with editable original clips, narration, BGM, subtitles, and local image overlays. Video/audio/images are bundled under `Resources/local` with a material index, so a clone or moved draft stays usable. ffmpeg remains the canonical render.
49
+ - **Optional MiMo adviser, never a gatekeeper.** On request, MiMo can review the project before assembly or after rendering. Missing keys, rate limits, timeouts, and malformed model output are warnings only, never blockers or automatic edits.
50
+
51
+ ## Installation
52
+
53
+ ### 1. Shared prerequisites
54
+
55
+ - Python 3.10+
56
+ - `ffmpeg` on `PATH`; subtitle burn-in is enabled by default and requires libass / the `subtitles` filter
57
+ - One [Xiaomi MiMo](https://platform.xiaomimimo.com) API key for ASR, VLM, and the default TTS path
58
+
59
+ ```bash
60
+ brew install ffmpeg # macOS
61
+ sudo apt install ffmpeg # Debian / Ubuntu
62
+ choco install ffmpeg # Windows; scoop or winget also work
63
+
64
+ export MIMO_API_KEY=your-mimo-key # macOS / Linux
65
+ export MIMO_TOKEN_PLAN_CLUSTER=cn # optional for tp-* keys: cn | sgp | ams
66
+ ```
67
+
68
+ In Windows PowerShell, use `$env:MIMO_API_KEY="your-mimo-key"`. MiMo does not require a subscription: `sk-*` keys can use pay-as-you-go billing. In one complete-video run measured for this project, usage cost about CNY 1.3; actual cost varies with video length and request volume. Pay-as-you-go keys default to `https://api.xiaomimimo.com/v1`.
69
+
70
+ To use the currently free Fish Audio TTS path:
71
+
72
+ ```bash
73
+ export TTS_PROVIDER=fish-audio
74
+ export FISH_API_KEY=your-fish-key
75
+ export FISH_TTS_REFERENCE_ID=your-voice-model-id # optional; overrides the built-in “娱乐扒妹” voice
76
+ ```
77
+
78
+ The default Fish model is `s2.1-pro-free`, with the built-in “娱乐扒妹” narration voice (reference ID `5653cea4ac83480aaf2bf45406556185`). Set `FISH_TTS_REFERENCE_ID` to override it. [Fish Audio currently states](https://fish.audio/blog/s2-1-pro-free-api/?articleLocale=en) that free access runs through **2026-08-31**, subject to its Fair Use Policy and without an SLA; check its current policy after that date. See the [config playbook](skills/video-recap/references/config-playbook.md) for model, voice, loudness, subtitle, and per-capability settings.
79
+
80
+ ### 2. Choose an agent host
81
+
82
+ #### Claude Code
83
+
84
+ Run inside Claude Code:
85
+
86
+ ```text
87
+ /plugin marketplace add zenstory-ai/video-recap-skills
88
+ /plugin install video-recap-skills@video-recap
89
+ ```
90
+
91
+ Or simply ask:
92
+
93
+ ```text
94
+ Install this plugin: https://github.com/zenstory-ai/video-recap-skills
95
+ ```
96
+
97
+ #### Codex CLI
98
+
99
+ ```bash
100
+ codex plugin marketplace add zenstory-ai/video-recap-skills
101
+ codex plugin add video-recap-skills@video-recap
102
+ ```
103
+
104
+ For a local checkout, replace the marketplace source in the first command with its directory. This flow was smoke-tested with an isolated `CODEX_HOME` on Codex CLI `0.144.1`.
105
+
106
+ #### OpenCode
107
+
108
+ The official [OpenCode Agent Skills documentation](https://opencode.ai/docs/skills/) defines project skills under `.opencode/skills/<name>/SKILL.md`. Clone the repository and start OpenCode from that directory:
109
+
110
+ ```bash
111
+ git clone https://github.com/zenstory-ai/video-recap-skills.git
112
+ cd video-recap-skills
113
+ mkdir -p .opencode
114
+ ln -s ../skills .opencode/skills # macOS / Linux
115
+ opencode debug skill
116
+ ```
117
+
118
+ On Windows, copy `skills\*` into `.opencode\skills\`. This PR was run-verified on OpenCode `1.14.32`: `opencode debug skill` discovered all 6 skills. Use `video-recap` for normal end-to-end production, `video-script` for planning or writing only, and the other four skills as tool stages.
119
+
120
+ #### OpenClaw
121
+
122
+ After cloning, import the Claude plugin bundle and check the discovered skills:
123
+
124
+ ```bash
125
+ openclaw plugins install ./video-recap-skills
126
+ openclaw skills list
127
+ ```
128
+
129
+ Do not register the same checkout through multiple discovery paths; duplicate registration can cause name collisions or repeated triggers.
130
+
131
+ After installation, ask the agent to check the environment:
132
+
133
+ ```text
134
+ Check the video-recap environment and tell me whether Python, ffmpeg/libass, and MiMo are ready.
135
+ ```
136
+
137
+ ## Usage
138
+
139
+ Give the agent the video paths, desired result, and any useful story context. Users do not need to run the repository's Python scripts directly.
140
+
141
+ **Full-video recap:**
142
+
143
+ ```text
144
+ Make a Chinese-narration recap of /path/to/video.mp4. It is episode 1 of 庆余年, the lead is 范闲, and subtitles should be burned in.
145
+ ```
146
+
147
+ **Cut a long video into a shorter recap:**
148
+
149
+ ```text
150
+ Turn /path/to/long.mp4 into a roughly ten-minute recap while preserving key original dialogue and character reactions.
151
+ ```
152
+
153
+ **Build one story from multiple videos:**
154
+
155
+ ```text
156
+ Use /path/to/ep1.mp4 and /path/to/ep2.mp4 to make one ten-minute recap with a shared story spine, not two separate summaries.
157
+ ```
158
+
159
+ The agent handles understanding, story and audiovisual planning, editing, narration, voiceover, and assembly. In cut mode it first chooses footage, renders the shortened video, and only then writes narration on the output timeline; the agent also handles the internal pauses and resume steps.
160
+
161
+ ## Common advanced requests
162
+
163
+ **Reuse previously analyzed material:**
164
+
165
+ ```text
166
+ Analyze /path/to/ep1.mp4 and save reusable understanding artifacts under /path/to/.video-materials. Prefer that material library in later projects.
167
+ ```
168
+
169
+ The library contains JSON, Markdown, and an index only. It does not copy raw media, create a database, or use embeddings; the agent searches it directly on the filesystem.
170
+
171
+ **Add advisory quality review and export a JianYing draft:**
172
+
173
+ ```text
174
+ Make a recap of /path/to/video.mp4, run MiMo quality review before assembly and after rendering, and export an editable JianYing draft.
175
+ ```
176
+
177
+ MiMo review is always advisory: at most one request per selected stage, fail-open, and never an automatic edit or render blocker.
178
+
179
+ **Align new subtitles with the source's burned-in subtitle band:**
180
+
181
+ ```text
182
+ Detect the source subtitle band in /path/to/video.mp4 and let me confirm the preview before rendering recap subtitles in the same region.
183
+ ```
184
+
185
+ The measurement preview is stored under `.subtitle_measure/`. It currently requires square-pixel video and bottom-aligned source subtitles. This capability is adapted from [ops120/video-recap-skills-plus](https://github.com/ops120/video-recap-skills-plus).
186
+
187
+ **Clone an authorized reference voice:**
188
+
189
+ ```text
190
+ Use the voice from /path/to/voice-ref.wav for the recap of /path/to/video.mp4. I have the voice owner's authorization.
191
+ ```
192
+
193
+ The reference audio is sent to MiMo for synthesis and its content fingerprint participates in cache validation. Use voice cloning only with the voice owner's authorization.
194
+
195
+ **Use the currently free Fish Audio voiceover path:**
196
+
197
+ ```text
198
+ Use Fish Audio for the Chinese narration of /path/to/video.mp4 with the built-in “娱乐扒妹” voice.
199
+ ```
200
+
201
+ The agent passes `--tts-provider fish-audio` to the orchestrator. `FISH_API_KEY` is required; the built-in “娱乐扒妹” voice is used unless `FISH_TTS_REFERENCE_ID` overrides it. Local `--voice-ref` cloning remains specific to MiMo.
202
+
203
+ **Dub an English video into Chinese while preserving the voice:**
204
+
205
+ ```text
206
+ Dub /path/to/english.mp4 into Chinese, keeping the original speaker's voice.
207
+ ```
208
+
209
+ This replaces the original speech instead of overlaying commentary. The current version supports one speaker and full-track replacement without background-music separation.
210
+
211
+ ## Architecture
212
+
213
+ | Skill | Does | In → Out (the `work_dir` contract) |
214
+ |---|---|---|
215
+ | **video-understanding** | scene detect · frame extract · ASR (`mimo-v2.5-asr`) · VLM (`mimo-v2.5`) · fuse timeline · build brief | `video` → `scenes / asr_result / vlm_analysis / silence_periods / timeline_fusion / agent_narration_brief.md` |
216
+ | **video-script** | directing/story/picture/audio plan + narration + advisory review + lint/validate | `brief + index` → `recap_story_plan.json + visual_audio_board.json + [clip_plan.json] + narration.json` |
217
+ | **video-cut** | clip plan → render the cut (cut-first/narrate-second; narration is written on the output timeline, no remap) | `clip_plan.json + video` → `edited_source.mp4` |
218
+ | **video-voiceover** | synthesize narration audio (MiMo `mimo-v2.5-tts` / Fish Audio `s2.1-pro-free`) | `narration.json` → `tts_segments/ + tts_meta.json` |
219
+ | **video-assemble** | mux · duck original audio · render subtitles · multi-track timeline (optional 剪映 export) | `video + tts_meta` → `recap_<name>.mp4 + subtitles.srt/.ass + timeline.json` |
220
+ | **video-recap** | orchestration and environment diagnostics | `video` → `recap_<name>.mp4` |
221
+
222
+ ## Output
223
+
224
+ - `recap_<name>.mp4`: the final recap, written to a stable name; subtitles are burned in by default and also written as `subtitles.srt` and `subtitles.ass`
225
+ - `work_dir/narration.json`: the narration script (`narration_lint.json` timing diagnostics, `narration_review.md` review notes)
226
+ - `work_dir/recap_story_plan.json` · `visual_audio_board.json`: agent-authored story, picture, and audio decisions for resume/advisory review; not a render gate
227
+ - `work_dir/agent_narration_brief.md`: timing and scene brief for the agent
228
+ - `work_dir/vlm_analysis.json` · `asr_result.json` · `silence_periods.json` · `timeline_fusion.json`: understanding artifacts
229
+ - `work_dir/clip_plan.json` · `edited_source.mp4` · `recap_phase.json`: cut-mode artifacts (narration is written on the output timeline; `recap_phase.json` records cut/narrate progress for deterministic resume)
230
+ - `work_dir/multi_source_manifest.json` · `work_dir/sources/<source_id>/`: multi-video cut source manifest and per-source analysis artifacts
231
+ - `<material-library-dir>/materials/<material_id>/material.json|material.md` · `materials_index.jsonl`: optional grep-friendly material library for reusing analyzed sources
232
+ - `work_dir/timeline.json` · `work_dir/assembly_manifest.json` · `tts_segments/` · `tts_meta.json`: multi-track timeline, slim render record, and TTS audio
233
+ - `work_dir/mimo_qc.json`: optional aggregated pre-assemble/post-render MiMo advice; never a gate
234
+
235
+ ## Bring your own original-dialogue subtitles (optional, more accurate)
236
+
237
+ During the original-audio gaps between narration blocks, the original dialogue is burned as a subtitle (wrapped in `「」` to set it apart from narration). By default that text is agent-proofread with an ASR fallback — but ASR timing is coarse and can drift from the audio. For accurate timing, drop a subtitle file into `work_dir`; it becomes the **preferred source**:
238
+
239
+ - `work_dir/user_subtitles.json`: `[{"start": s, "end": s, "text": "line"}]` on the **output** timeline, used as-is; or wrap it as `{"timeline": "source", "lines": [...]}` to give **source**-timeline subs that are auto-mapped onto the cut via the clip plan.
240
+ - `work_dir/user_subtitles.srt` / `.ass`: parsed as **source**-timeline by default and mapped onto the cut.
241
+
242
+ Priority: **your file › the agent-proofread `original_subtitles.json` › ASR fallback**. When the source is accurate, each line is clipped precisely into its gap instead of being placed by a coarse midpoint estimate.
243
+
244
+ ## References
245
+
246
+ - Per-skill contracts: each `skills/<skill>/SKILL.md` (the writing rules are in video-script's SKILL.md)
247
+ - [Data schema](skills/video-recap/references/data-schema.md) · [Config playbook](skills/video-recap/references/config-playbook.md) · [Multi-track timeline / 剪映 export](skills/video-recap/references/timeline-and-jianying.md)
248
+ - [Background research guide](skills/video-recap/references/research-guide.md) · [VLM prompt templates](skills/video-understanding/references/prompt-templates.md)
249
+
250
+ ## Acknowledgements
251
+
252
+ - [linux.do](https://linux.do)
253
+ - The 剪映 draft protocol references [pyJianYingDraft](https://github.com/GuanYixuan/pyJianYingDraft), [capcut-mate](https://github.com/Hommy-master/capcut-mate), and [duo-video](https://github.com/duoec/duo-video).
254
+
255
+ ## License
256
+
257
+ MIT, see [LICENSE](LICENSE).