@oh-story/dsh 0.1.9 → 0.1.11

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 (529) hide show
  1. package/README.md +14 -14
  2. package/lib/client.js +209 -73
  3. package/lib/client.js.map +3 -3
  4. package/lib/drama/manifest.json +248 -168
  5. package/lib/drama/skills/short-drama/SKILL.md +16 -4
  6. package/lib/drama/skills/short-drama/assets/project-template/short-drama.json +3 -0
  7. package/lib/drama/skills/short-drama/references/creator-documents.md +3 -0
  8. package/lib/drama/skills/short-drama/references/knowhow-index.md +15 -0
  9. package/lib/drama/skills/short-drama/scripts/creator_markdown_check.py +14 -0
  10. package/lib/drama/skills/short-drama/scripts/project_tool.py +131 -0
  11. package/lib/drama/skills/short-drama-assets/SKILL.md +2 -1
  12. package/lib/drama/skills/short-drama-assets/references/asset-review-checklist.md +2 -0
  13. package/lib/drama/skills/short-drama-assets/references/character-and-look.md +10 -0
  14. package/lib/drama/skills/short-drama-assets/references/continuity-lock.md +6 -9
  15. package/lib/drama/skills/short-drama-assets/references/era-anchors.md +37 -0
  16. package/lib/drama/skills/short-drama-assets/references/stage-contract.md +2 -0
  17. package/lib/drama/skills/short-drama-assets/references/voice-direction.md +28 -0
  18. package/lib/drama/skills/short-drama-develop/SKILL.md +10 -4
  19. package/lib/drama/skills/short-drama-develop/assets/adaptation-map.example.jsonl +1 -1
  20. package/lib/drama/skills/short-drama-develop/assets/creative-brief.md +8 -0
  21. package/lib/drama/skills/short-drama-develop/references/adaptation-craft.md +80 -13
  22. package/lib/drama/skills/short-drama-develop/references/episode-design.md +95 -12
  23. package/lib/drama/skills/short-drama-develop/references/genre-and-hook-playbook.md +9 -5
  24. package/lib/drama/skills/short-drama-develop/references/genre-cards//345/244/215/344/273/207/346/211/223/350/204/270.md +1 -1
  25. package/lib/drama/skills/short-drama-develop/references/genre-cards//347/263/273/347/273/237/346/265/201.md +51 -0
  26. package/lib/drama/skills/short-drama-develop/references/genre-cards//351/200/206/350/242/255.md +51 -0
  27. package/lib/drama/skills/short-drama-develop/references/genre-cards//351/207/215/347/224/237/347/251/277/350/266/212.md +51 -0
  28. package/lib/drama/skills/short-drama-develop/references/genre-cards.md +10 -7
  29. package/lib/drama/skills/short-drama-develop/references/premise-devices.md +15 -9
  30. package/lib/drama/skills/short-drama-develop/references/serial-character-and-memory.md +3 -2
  31. package/lib/drama/skills/short-drama-develop/references/stage-contract.md +14 -7
  32. package/lib/drama/skills/short-drama-develop/references/story-craft.md +7 -3
  33. package/lib/drama/skills/short-drama-edit/SKILL.md +65 -44
  34. package/lib/drama/skills/short-drama-edit/assets/remotion/README.md +49 -13
  35. package/lib/drama/skills/short-drama-edit/assets/remotion/package.json +4 -2
  36. package/lib/drama/skills/short-drama-edit/assets/remotion/src/Overlay.tsx +31 -0
  37. package/lib/drama/skills/short-drama-edit/assets/remotion/src/Root.tsx +5 -5
  38. package/lib/drama/skills/short-drama-edit/assets/remotion/src/Subtitles.tsx +68 -69
  39. package/lib/drama/skills/short-drama-edit/assets/remotion/src/font.ts +39 -29
  40. package/lib/drama/skills/short-drama-edit/assets/remotion/src/rules.mjs +188 -0
  41. package/lib/drama/skills/short-drama-edit/assets/remotion/src/schema.ts +26 -13
  42. package/lib/drama/skills/short-drama-edit/assets/remotion/src/screen/Card.tsx +72 -0
  43. package/lib/drama/skills/short-drama-edit/assets/remotion/src/screen/CornerChip.tsx +39 -0
  44. package/lib/drama/skills/short-drama-edit/assets/remotion/src/screen/ScreenText.tsx +36 -0
  45. package/lib/drama/skills/short-drama-edit/assets/remotion/src/screen/SystemPanel.tsx +44 -0
  46. package/lib/drama/skills/short-drama-edit/assets/remotion/src/screen/TaskPanel.tsx +100 -0
  47. package/lib/drama/skills/short-drama-edit/assets/remotion/src/screen/chrome.tsx +197 -0
  48. package/lib/drama/skills/short-drama-edit/assets/remotion/src/screen/tokens.ts +62 -0
  49. package/lib/drama/skills/short-drama-edit/assets/remotion/tsconfig.json +1 -0
  50. package/lib/drama/skills/short-drama-edit/assets//345/211/252/350/276/221/345/215/225.md +6 -4
  51. package/lib/drama/skills/short-drama-edit/references/cut-craft.md +26 -67
  52. package/lib/drama/skills/short-drama-edit/references/delivery-verify.md +31 -56
  53. package/lib/drama/skills/short-drama-edit/references/generated-footage.md +42 -78
  54. package/lib/drama/skills/short-drama-edit/references/sound-and-subtitles.md +44 -92
  55. package/lib/drama/skills/short-drama-edit/references/stage-contract.md +14 -16
  56. package/lib/drama/skills/short-drama-edit/scripts/edit_tool.py +1272 -125
  57. package/lib/drama/skills/short-drama-edit/scripts/selftest.py +113 -9
  58. package/lib/drama/skills/short-drama-image-prompts/SKILL.md +2 -0
  59. package/lib/drama/skills/short-drama-image-prompts/references/common-recipe.md +11 -0
  60. package/lib/drama/skills/short-drama-novel-analyze/SKILL.md +3 -3
  61. package/lib/drama/skills/short-drama-novel-analyze/assets/episode-candidate.example.jsonl +2 -2
  62. package/lib/drama/skills/short-drama-novel-analyze/references/adaptation-triage.md +8 -4
  63. package/lib/drama/skills/short-drama-novel-analyze/references/adaptation-value.md +10 -3
  64. package/lib/drama/skills/short-drama-novel-analyze/references/aggregation-and-entities.md +25 -1
  65. package/lib/drama/skills/short-drama-novel-analyze/references/stage-contract.md +1 -0
  66. package/lib/drama/skills/short-drama-produce/SKILL.md +5 -1
  67. package/lib/drama/skills/short-drama-produce/references/adapter-contract.md +14 -20
  68. package/lib/drama/skills/short-drama-produce/references/providers/minimax-h3-video.md +8 -26
  69. package/lib/drama/skills/short-drama-produce/references/providers/minimax-speech.md +41 -0
  70. package/lib/drama/skills/short-drama-produce/scripts/provider_adapters.py +142 -1
  71. package/lib/drama/skills/short-drama-review/SKILL.md +4 -5
  72. package/lib/drama/skills/short-drama-review/references/production-quality-gates.md +6 -19
  73. package/lib/drama/skills/short-drama-review/references/review-method.md +6 -1
  74. package/lib/drama/skills/short-drama-review/references/rubric-assets-prompts.md +11 -0
  75. package/lib/drama/skills/short-drama-review/references/rubric-story-script.md +77 -3
  76. package/lib/drama/skills/short-drama-review/references/rubric-visual-motion.md +24 -35
  77. package/lib/drama/skills/short-drama-review/references/stage-contract.md +3 -0
  78. package/lib/drama/skills/short-drama-storyboard/SKILL.md +23 -11
  79. package/lib/drama/skills/short-drama-storyboard/references/blocking-playbooks.md +1 -1
  80. package/lib/drama/skills/short-drama-storyboard/references/lighting-craft.md +39 -0
  81. package/lib/drama/skills/short-drama-storyboard/references/production-shot-grammar.md +2 -2
  82. package/lib/drama/skills/short-drama-storyboard/references/shot-craft.md +139 -34
  83. package/lib/drama/skills/short-drama-storyboard/references/stage-contract.md +5 -3
  84. package/lib/drama/skills/short-drama-video-prompts/SKILL.md +15 -12
  85. package/lib/drama/skills/short-drama-video-prompts/references/camera-audio-continuity.md +29 -0
  86. package/lib/drama/skills/short-drama-video-prompts/references/delivery-profile.md +4 -5
  87. package/lib/drama/skills/short-drama-video-prompts/references/generability.md +4 -2
  88. package/lib/drama/skills/short-drama-video-prompts/references/minimax-h3.md +52 -39
  89. package/lib/drama/skills/short-drama-video-prompts/references/motion-recipe.md +24 -21
  90. package/lib/drama/skills/short-drama-video-prompts/references/performance-action-timing.md +9 -23
  91. package/lib/drama/skills/short-drama-video-prompts/references/production-prompt-grammar.md +14 -26
  92. package/lib/drama/skills/short-drama-video-prompts/references/review-and-fixtures.md +1 -1
  93. package/lib/drama/skills/short-drama-video-prompts/references/seedance-2.0.md +2 -3
  94. package/lib/drama/skills/short-drama-video-prompts/references/seedance-2.5.md +34 -9
  95. package/lib/drama/skills/short-drama-video-prompts/references/stage-contract.md +3 -2
  96. package/lib/drama/skills/short-drama-video-prompts/references/target-model-profile.md +8 -1
  97. package/lib/drama/skills/short-drama-video-prompts/references/wan-3.0.md +103 -0
  98. package/lib/drama/skills/short-drama-video-prompts/scripts/motion_timing_check.py +8 -7
  99. package/lib/drama/skills/short-drama-write/SKILL.md +10 -7
  100. package/lib/drama/skills/short-drama-write/references/dialogue-craft.md +1 -1
  101. package/lib/drama/skills/short-drama-write/references/script-craft.md +56 -3
  102. package/lib/drama/skills/short-drama-write/references/stage-contract.md +4 -0
  103. package/lib/drama/skills/short-drama-write/scripts/duration_estimate.py +48 -2
  104. package/lib/index.js +346 -98
  105. package/lib/index.js.map +4 -4
  106. package/lib/novel-to-game/README.md +299 -59
  107. package/lib/novel-to-game/README_ZH.md +299 -56
  108. package/lib/novel-to-game/VERSION +1 -1
  109. package/lib/novel-to-game/examples/jin-ping-mei/build/BUILD_BRIEF.md +3 -1
  110. package/lib/novel-to-game/examples/jin-ping-mei/build/app/RUN.md +11 -3
  111. package/lib/novel-to-game/examples/jin-ping-mei/build/app/css/new-guofeng.css +397 -8
  112. package/lib/novel-to-game/examples/jin-ping-mei/build/app/css/style.css +0 -31
  113. package/lib/novel-to-game/examples/jin-ping-mei/build/app/js/data.js +71 -73
  114. package/lib/novel-to-game/examples/jin-ping-mei/build/app/js/engine.js +78 -89
  115. package/lib/novel-to-game/examples/jin-ping-mei/build/app/js/main.js +37 -14
  116. package/lib/novel-to-game/examples/jin-ping-mei/build/app/js/text.js +5 -5
  117. package/lib/novel-to-game/examples/jin-ping-mei/build/app/package.json +2 -1
  118. package/lib/novel-to-game/examples/jin-ping-mei/qa/README.md +11 -16
  119. package/lib/novel-to-game/examples/jin-ping-mei/qa/verification.json +11 -11
  120. package/lib/novel-to-game/examples/jin-ping-mei/qa/verify_playable_model.mjs +23 -0
  121. package/lib/novel-to-game/manifest.json +77 -87
  122. package/lib/novel-to-game/skills/game-art-direction/SKILL.md +7 -12
  123. package/lib/novel-to-game/skills/game-art-direction/references/art-direction-method.md +27 -106
  124. package/lib/novel-to-game/skills/game-build/SKILL.md +13 -14
  125. package/lib/novel-to-game/skills/game-build/references/blender-asset-workflow.md +24 -0
  126. package/lib/novel-to-game/skills/game-build/references/build-brief-contract.md +45 -82
  127. package/lib/novel-to-game/skills/game-build/references/generative-media-pipeline.md +14 -45
  128. package/lib/novel-to-game/skills/game-build/references/playable-model-contract.md +30 -65
  129. package/lib/novel-to-game/skills/game-build/references/tts-production-contract.md +13 -27
  130. package/lib/novel-to-game/skills/game-concept/SKILL.md +13 -15
  131. package/lib/novel-to-game/skills/game-concept/references/concept-method.md +28 -75
  132. package/lib/novel-to-game/skills/game-qa/SKILL.md +6 -7
  133. package/lib/novel-to-game/skills/game-qa/references/test-design-method.md +9 -5
  134. package/lib/novel-to-game/skills/game-world-design/SKILL.md +12 -16
  135. package/lib/novel-to-game/skills/game-world-design/references/narrative-design-method.md +23 -72
  136. package/lib/novel-to-game/skills/game-world-design/references/numeric-design-method.md +14 -48
  137. package/lib/novel-to-game/skills/game-world-design/references/world-design-method.md +36 -103
  138. package/lib/novel-to-game/skills/novel-game-analyze/SKILL.md +4 -10
  139. package/lib/novel-to-game/skills/novel-game-analyze/references/gameability-protocol.md +4 -4
  140. package/lib/novel-to-game/skills/novel-to-game/SKILL.md +9 -21
  141. package/lib/novel-to-game/skills/novel-to-game/references/intake-method.md +5 -4
  142. package/lib/novel-to-game/skills/novel-to-game/references/pipeline-contract.md +5 -8
  143. package/lib/oh-story/manifest.json +607 -327
  144. package/lib/oh-story/roles/chapter-extractor.md +177 -237
  145. package/lib/oh-story/roles/character-designer.md +1 -2
  146. package/lib/oh-story/roles/consistency-checker.md +15 -13
  147. package/lib/oh-story/roles/narrative-writer.md +36 -38
  148. package/lib/oh-story/roles/story-architect.md +9 -61
  149. package/lib/oh-story/roles/story-explorer.md +20 -125
  150. package/lib/oh-story/roles/story-researcher.md +0 -1
  151. package/lib/oh-story/skills/story/SKILL.md +15 -9
  152. package/lib/oh-story/skills/story/VERSION +1 -1
  153. package/lib/oh-story/skills/story/references/author-memory-maintenance.md +75 -0
  154. package/lib/oh-story/skills/story/references/author-memory.md +46 -94
  155. package/lib/oh-story/skills/story/scripts/author_memory_commit.py +934 -170
  156. package/lib/oh-story/skills/story-cover/SKILL.md +10 -1
  157. package/lib/oh-story/skills/story-deslop/SKILL.md +59 -73
  158. package/lib/oh-story/skills/story-deslop/references/agent-calls.md +5 -0
  159. package/lib/oh-story/skills/story-deslop/references/anti-ai-writing.md +12 -11
  160. package/lib/oh-story/skills/story-deslop/references/author-memory-maintenance.md +75 -0
  161. package/lib/oh-story/skills/story-deslop/references/author-memory.md +46 -94
  162. package/lib/oh-story/skills/story-deslop/references/banned-words.md +2 -2
  163. package/lib/oh-story/skills/story-deslop/references/deslop-gates.md +22 -5
  164. package/lib/oh-story/skills/story-deslop/references/style-resolution.md +4 -4
  165. package/lib/oh-story/skills/story-deslop/scripts/author_memory_commit.py +934 -170
  166. package/lib/oh-story/skills/story-deslop/scripts/check-ai-patterns.js +155 -8
  167. package/lib/oh-story/skills/story-import/SKILL.md +64 -584
  168. package/lib/oh-story/skills/story-import/references/character-state-reverse.md +1 -1
  169. package/lib/oh-story/skills/story-import/references/deep-analysis.md +47 -0
  170. package/lib/oh-story/skills/story-import/references/format-and-structure.md +1 -1
  171. package/lib/oh-story/skills/story-import/references/import-report.md +64 -0
  172. package/lib/oh-story/skills/story-import/references/import-special-cases.md +34 -0
  173. package/lib/oh-story/skills/story-import/references/import-tracking.md +95 -0
  174. package/lib/oh-story/skills/story-import/references/length-routing.md +1 -1
  175. package/lib/oh-story/skills/story-import/references/outline-reverse-rules.md +79 -0
  176. package/lib/oh-story/skills/story-import/references/outline-reverse.md +24 -0
  177. package/lib/oh-story/skills/story-import/references/state-tracking.md +4 -69
  178. package/lib/oh-story/skills/story-import/references/structure-mapping-long.md +98 -92
  179. package/lib/oh-story/skills/story-import/references/structure-mapping-short.md +24 -12
  180. package/lib/oh-story/skills/story-import/references/tracking-initialization.md +1 -1
  181. package/lib/oh-story/skills/story-import/references/tracking-transaction.md +15 -11
  182. package/lib/oh-story/skills/story-import/scripts/build_outline_brief.py +332 -0
  183. package/lib/oh-story/skills/story-import/scripts/check-outline-contract.js +132 -27
  184. package/lib/oh-story/skills/story-import/scripts/tracking_commit.py +478 -15
  185. package/lib/oh-story/skills/story-import/scripts/wordcount_core.py +182 -23
  186. package/lib/oh-story/skills/story-long-analyze/SKILL.md +81 -270
  187. package/lib/oh-story/skills/story-long-analyze/references/author-facing.md +252 -0
  188. package/lib/oh-story/skills/story-long-analyze/references/deconstruction-notes.md +3 -3
  189. package/lib/oh-story/skills/story-long-analyze/references/final-checks.md +19 -0
  190. package/lib/oh-story/skills/story-long-analyze/references/index-rebuild.md +11 -0
  191. package/lib/oh-story/skills/story-long-analyze/references/inspiration-library.md +105 -0
  192. package/lib/oh-story/skills/story-long-analyze/references/pipeline-ops.md +138 -64
  193. package/lib/oh-story/skills/story-long-analyze/references/semantic-acceptance-fixtures.md +84 -0
  194. package/lib/oh-story/skills/story-long-analyze/references/stage1-golden-chapters.md +128 -0
  195. package/lib/oh-story/skills/story-long-analyze/references/stage2-extraction.md +229 -0
  196. package/lib/oh-story/skills/story-long-analyze/references/stage3-plot-rhythm.md +480 -0
  197. package/lib/oh-story/skills/story-long-analyze/references/stage4-characters-settings.md +195 -0
  198. package/lib/oh-story/skills/story-long-analyze/references/stage5-report.md +33 -0
  199. package/lib/oh-story/skills/story-long-analyze/references/style-profile-generator.md +55 -128
  200. package/lib/oh-story/skills/story-long-analyze/references/style-profile-protocol.md +6 -6
  201. package/lib/oh-story/skills/story-long-analyze/references/synthesis-inputs.md +39 -0
  202. package/lib/oh-story/skills/story-long-analyze/scripts/build_chapter_index.py +466 -0
  203. package/lib/oh-story/skills/story-long-analyze/scripts/inspect_existing_assets.py +702 -0
  204. package/lib/oh-story/skills/story-long-analyze/scripts/inspiration_index.py +864 -0
  205. package/lib/oh-story/skills/story-long-analyze/scripts/manage_analysis_run.py +1145 -0
  206. package/lib/oh-story/skills/story-long-analyze/scripts/render_relation_chart.py +425 -0
  207. package/lib/oh-story/skills/story-long-scan/SKILL.md +45 -194
  208. package/lib/oh-story/skills/story-long-scan/references/platform-ciweimao.md +19 -0
  209. package/lib/oh-story/skills/story-long-scan/references/platform-fanqie.md +45 -0
  210. package/lib/oh-story/skills/story-long-scan/references/platform-jjwxc.md +28 -0
  211. package/lib/oh-story/skills/story-long-scan/references/platform-qidian.md +35 -0
  212. package/lib/oh-story/skills/story-long-scan/references/platform-qimao.md +27 -0
  213. package/lib/oh-story/skills/story-long-scan/references/topic-decision.md +6 -2
  214. package/lib/oh-story/skills/story-long-write/SKILL.md +49 -81
  215. package/lib/oh-story/skills/story-long-write/references/agent-calls.md +47 -0
  216. package/lib/oh-story/skills/story-long-write/references/anti-ai-writing.md +12 -11
  217. package/lib/oh-story/skills/story-long-write/references/artifact-protocols.md +24 -202
  218. package/lib/oh-story/skills/story-long-write/references/author-memory-maintenance.md +75 -0
  219. package/lib/oh-story/skills/story-long-write/references/author-memory.md +46 -94
  220. package/lib/oh-story/skills/story-long-write/references/banned-words.md +2 -2
  221. package/lib/oh-story/skills/story-long-write/references/benchmark-recall.md +7 -11
  222. package/lib/oh-story/skills/story-long-write/references/character-relations.md +49 -1
  223. package/lib/oh-story/skills/story-long-write/references/cross-book-recall.md +26 -0
  224. package/lib/oh-story/skills/story-long-write/references/deslop-gates.md +171 -0
  225. package/lib/oh-story/skills/story-long-write/references/dialogue-mastery.md +4 -0
  226. package/lib/oh-story/skills/story-long-write/references/emotion-on-page.md +116 -0
  227. package/lib/oh-story/skills/story-long-write/references/emotional-arc-design.md +1 -114
  228. package/lib/oh-story/skills/story-long-write/references/emotional-methods.md +2 -2
  229. package/lib/oh-story/skills/story-long-write/references/genre-prose-cards.md +1 -1
  230. package/lib/oh-story/skills/story-long-write/references/long-chapter-quality.md +7 -15
  231. package/lib/oh-story/skills/story-long-write/references/long-format.md +0 -8
  232. package/lib/oh-story/skills/story-long-write/references/long-genre-catalog.md +1 -1
  233. package/lib/oh-story/skills/story-long-write/references/long-genre-mechanics.md +3 -3
  234. package/lib/oh-story/skills/story-long-write/references/opening-design.md +2 -2
  235. package/lib/oh-story/skills/story-long-write/references/outline-conflict.md +4 -4
  236. package/lib/oh-story/skills/story-long-write/references/outline-methods.md +7 -7
  237. package/lib/oh-story/skills/story-long-write/references/outline-rhythm.md +3 -3
  238. package/lib/oh-story/skills/story-long-write/references/outline-structure-theory.md +14 -69
  239. package/lib/oh-story/skills/story-long-write/references/plot-frameworks.md +1 -1
  240. package/lib/oh-story/skills/story-long-write/references/plot-special-topics.md +2 -2
  241. package/lib/oh-story/skills/story-long-write/references/project-files.md +19 -13
  242. package/lib/oh-story/skills/story-long-write/references/reader-contract-and-progression.md +13 -5
  243. package/lib/oh-story/skills/story-long-write/references/reference-index.md +5 -6
  244. package/lib/oh-story/skills/story-long-write/references/stop-and-fix.md +9 -0
  245. package/lib/oh-story/skills/story-long-write/references/style-combat-face.md +1 -58
  246. package/lib/oh-story/skills/story-long-write/references/style-genre-modules.md +1 -1
  247. package/lib/oh-story/skills/story-long-write/references/style-resolution.md +4 -4
  248. package/lib/oh-story/skills/story-long-write/references/tracking-initialization.md +1 -1
  249. package/lib/oh-story/skills/story-long-write/references/tracking-transaction.md +15 -11
  250. package/lib/oh-story/skills/story-long-write/references/workflow-chapter.md +81 -121
  251. package/lib/oh-story/skills/story-long-write/references/workflow-daily.md +41 -139
  252. package/lib/oh-story/skills/story-long-write/references/workflow-outline.md +157 -0
  253. package/lib/oh-story/skills/story-long-write/references/workflow-revision.md +57 -67
  254. package/lib/oh-story/skills/story-long-write/references/workflow-setup.md +112 -253
  255. package/lib/oh-story/skills/story-long-write/references/workflow-volume.md +142 -0
  256. package/lib/oh-story/skills/story-long-write/references/writer-prompt-fallback.md +6 -4
  257. package/lib/oh-story/skills/story-long-write/references/writing-craft.md +19 -65
  258. package/lib/oh-story/skills/story-long-write/scripts/author_memory_commit.py +934 -170
  259. package/lib/oh-story/skills/story-long-write/scripts/build_architect_brief.py +260 -0
  260. package/lib/oh-story/skills/story-long-write/scripts/build_writer_prompt.py +226 -25
  261. package/lib/oh-story/skills/story-long-write/scripts/check-ai-patterns.js +155 -8
  262. package/lib/oh-story/skills/story-long-write/scripts/check-outline-contract.js +132 -27
  263. package/lib/oh-story/skills/story-long-write/scripts/check-outline-copy.js +7 -2
  264. package/lib/oh-story/skills/story-long-write/scripts/outline_view.py +7 -4
  265. package/lib/oh-story/skills/story-long-write/scripts/storyctl.py +304 -46
  266. package/lib/oh-story/skills/story-long-write/scripts/tracking_commit.py +478 -15
  267. package/lib/oh-story/skills/story-long-write/scripts/wordcount_core.py +182 -23
  268. package/lib/oh-story/skills/story-review/SKILL.md +31 -302
  269. package/lib/oh-story/skills/story-review/references/agent-prompts.md +184 -0
  270. package/lib/oh-story/skills/story-review/references/anti-ai-writing.md +12 -11
  271. package/lib/oh-story/skills/story-review/references/author-memory-maintenance.md +75 -0
  272. package/lib/oh-story/skills/story-review/references/author-memory.md +46 -94
  273. package/lib/oh-story/skills/story-review/references/banned-words.md +2 -2
  274. package/lib/oh-story/skills/story-review/references/batch-review.md +19 -0
  275. package/lib/oh-story/skills/story-review/references/character-relations.md +49 -1
  276. package/lib/oh-story/skills/story-review/references/dialogue-mastery.md +4 -0
  277. package/lib/oh-story/skills/story-review/references/review-quality.md +6 -11
  278. package/lib/oh-story/skills/story-review/references/review-tracking.md +10 -0
  279. package/lib/oh-story/skills/story-review/references/solo.md +52 -0
  280. package/lib/oh-story/skills/story-review/references/style-resolution.md +4 -4
  281. package/lib/oh-story/skills/story-review/references/tracking-initialization.md +1 -1
  282. package/lib/oh-story/skills/story-review/references/tracking-transaction.md +15 -11
  283. package/lib/oh-story/skills/story-review/scripts/author_memory_commit.py +934 -170
  284. package/lib/oh-story/skills/story-review/scripts/check-ai-patterns.js +155 -8
  285. package/lib/oh-story/skills/story-review/scripts/tracking_commit.py +478 -15
  286. package/lib/oh-story/skills/story-review/scripts/wordcount_core.py +182 -23
  287. package/lib/oh-story/skills/story-setup/SKILL.md +71 -452
  288. package/lib/oh-story/skills/story-setup/references/agent-references/agent-quality.md +4 -4
  289. package/lib/oh-story/skills/story-setup/references/agent-references/anti-ai-writing.md +12 -11
  290. package/lib/oh-story/skills/story-setup/references/agent-references/banned-words.md +2 -2
  291. package/lib/oh-story/skills/story-setup/references/agent-references/benchmark-style-load.md +107 -0
  292. package/lib/oh-story/skills/story-setup/references/agent-references/character-relations.md +49 -1
  293. package/lib/oh-story/skills/story-setup/references/agent-references/deslop-gates.md +22 -5
  294. package/lib/oh-story/skills/story-setup/references/agent-references/dialogue-mastery.md +4 -0
  295. package/lib/oh-story/skills/story-setup/references/agent-references/emotion-on-page.md +116 -0
  296. package/lib/oh-story/skills/story-setup/references/agent-references/emotional-arc-design.md +1 -114
  297. package/lib/oh-story/skills/story-setup/references/agent-references/format-and-structure.md +1 -1
  298. package/lib/oh-story/skills/story-setup/references/agent-references/genre-prose-cards.md +1 -1
  299. package/lib/oh-story/skills/story-setup/references/agent-references/long-emotional-methods.md +2 -2
  300. package/lib/oh-story/skills/story-setup/references/agent-references/long-genre-catalog.md +1 -1
  301. package/lib/oh-story/skills/story-setup/references/agent-references/long-genre-mechanics.md +3 -3
  302. package/lib/oh-story/skills/story-setup/references/agent-references/long-quality.md +7 -5
  303. package/lib/oh-story/skills/story-setup/references/agent-references/opening-design.md +2 -2
  304. package/lib/oh-story/skills/story-setup/references/agent-references/outline-conflict.md +4 -4
  305. package/lib/oh-story/skills/story-setup/references/agent-references/outline-methods.md +7 -7
  306. package/lib/oh-story/skills/story-setup/references/agent-references/outline-rhythm.md +3 -3
  307. package/lib/oh-story/skills/story-setup/references/agent-references/short-emotional-methods.md +1 -1
  308. package/lib/oh-story/skills/story-setup/references/agent-references/short-genre-formulas.md +0 -15
  309. package/lib/oh-story/skills/story-setup/references/agent-references/short-reversal.md +1 -1
  310. package/lib/oh-story/skills/story-setup/references/agent-references/style-combat-face.md +1 -58
  311. package/lib/oh-story/skills/story-setup/references/agent-references/style-genre-modules.md +1 -1
  312. package/lib/oh-story/skills/story-setup/references/agent-references/style-resolution.md +4 -4
  313. package/lib/oh-story/skills/story-setup/references/agent-references/writing-craft.md +19 -65
  314. package/lib/oh-story/skills/story-setup/references/diagnostics.md +4 -4
  315. package/lib/oh-story/skills/story-short-analyze/SKILL.md +56 -110
  316. package/lib/oh-story/skills/story-short-analyze/references/analysis-character-relations.md +1 -1
  317. package/lib/oh-story/skills/story-short-analyze/references/analysis-method.md +42 -0
  318. package/lib/oh-story/skills/story-short-analyze/references/optional-modules.md +97 -0
  319. package/lib/oh-story/skills/story-short-analyze/references/output-contract.md +9 -47
  320. package/lib/oh-story/skills/story-short-analyze/references/quality-checklist.md +80 -0
  321. package/lib/oh-story/skills/story-short-analyze/references/source-story-quality.md +4 -4
  322. package/lib/oh-story/skills/story-short-analyze/references/stage2-3-structure-emotion.md +308 -0
  323. package/lib/oh-story/skills/story-short-analyze/references/stage4-6-reversal-summary.md +611 -0
  324. package/lib/oh-story/skills/story-short-scan/SKILL.md +35 -65
  325. package/lib/oh-story/skills/story-short-scan/references/manual-rank-input.md +36 -0
  326. package/lib/oh-story/skills/story-short-scan/references/platform-dianzhong.md +24 -0
  327. package/lib/oh-story/skills/story-short-scan/references/platform-heiyan.md +21 -0
  328. package/lib/oh-story/skills/story-short-scan/references/topic-match.md +38 -0
  329. package/lib/oh-story/skills/story-short-write/SKILL.md +23 -175
  330. package/lib/oh-story/skills/story-short-write/references/agent-calls.md +13 -0
  331. package/lib/oh-story/skills/story-short-write/references/author-memory-maintenance.md +75 -0
  332. package/lib/oh-story/skills/story-short-write/references/author-memory.md +46 -94
  333. package/lib/oh-story/skills/story-short-write/references/banned-words.md +2 -2
  334. package/lib/oh-story/skills/story-short-write/references/benchmark-recall.md +1 -21
  335. package/lib/oh-story/skills/story-short-write/references/dialogue-mastery.md +4 -0
  336. package/lib/oh-story/skills/story-short-write/references/emotional-methods.md +1 -1
  337. package/lib/oh-story/skills/story-short-write/references/genre-writing-formulas.md +0 -15
  338. package/lib/oh-story/skills/story-short-write/references/output-contract.md +9 -47
  339. package/lib/oh-story/skills/story-short-write/references/reference-index.md +17 -47
  340. package/lib/oh-story/skills/story-short-write/references/scene-craft.md +40 -0
  341. package/lib/oh-story/skills/story-short-write/references/short-craft.md +7 -43
  342. package/lib/oh-story/skills/story-short-write/references/short-format.md +3 -3
  343. package/lib/oh-story/skills/story-short-write/references/short-prose-quality.md +2 -1
  344. package/lib/oh-story/skills/story-short-write/references/short-reversal.md +1 -1
  345. package/lib/oh-story/skills/story-short-write/references/style-resolution.md +4 -4
  346. package/lib/oh-story/skills/story-short-write/references/submission-craft.md +1 -1
  347. package/lib/oh-story/skills/story-short-write/references/villain-and-reveal.md +5 -10
  348. package/lib/oh-story/skills/story-short-write/references/workflow-design.md +21 -13
  349. package/lib/oh-story/skills/story-short-write/references/workflow-draft.md +116 -0
  350. package/lib/oh-story/skills/story-short-write/references/workflow-revision.md +99 -0
  351. package/lib/oh-story/skills/story-short-write/references/writing-workflow.md +7 -119
  352. package/lib/oh-story/skills/story-short-write/scripts/author_memory_commit.py +934 -170
  353. package/lib/oh-story/skills/story-short-write/scripts/check-ai-patterns.js +155 -8
  354. package/lib/oh-story/skills/story-short-write/scripts/check-outline-copy.js +7 -2
  355. package/lib/types/client/drama-production-view.d.ts.map +1 -1
  356. package/lib/types/client/file-activity.d.ts +19 -1
  357. package/lib/types/client/file-activity.d.ts.map +1 -1
  358. package/lib/types/client/index.d.ts.map +1 -1
  359. package/lib/types/client/production-prompts.d.ts +7 -0
  360. package/lib/types/client/production-prompts.d.ts.map +1 -1
  361. package/lib/types/client/production-runtime.d.ts +16 -0
  362. package/lib/types/client/production-runtime.d.ts.map +1 -1
  363. package/lib/types/client/video-studio.d.ts.map +1 -1
  364. package/lib/types/drama-adapters.d.ts +5 -3
  365. package/lib/types/drama-adapters.d.ts.map +1 -1
  366. package/lib/types/native-hooks.d.ts +53 -1
  367. package/lib/types/native-hooks.d.ts.map +1 -1
  368. package/lib/types/role-identity.d.ts +17 -0
  369. package/lib/types/role-identity.d.ts.map +1 -0
  370. package/lib/types/role-tool.d.ts.map +1 -1
  371. package/lib/types/skill-provider.d.ts.map +1 -1
  372. package/lib/types/video-project.d.ts.map +1 -1
  373. package/lib/types/workspace-route.d.ts.map +1 -1
  374. package/lib/video-recap/CHANGELOG.md +60 -1
  375. package/lib/video-recap/README.en.md +348 -137
  376. package/lib/video-recap/README.md +340 -136
  377. package/lib/video-recap/manifest.json +406 -251
  378. package/lib/video-recap/skills/video-assemble/SKILL.md +30 -15
  379. package/lib/video-recap/skills/video-assemble/references/audio-modes.md +63 -0
  380. package/lib/video-recap/skills/video-assemble/references/explicit-audio-mix.md +75 -0
  381. package/lib/video-recap/skills/video-assemble/references/foreground-compose.md +118 -0
  382. package/lib/video-recap/skills/video-assemble/references/narration-adoption.md +103 -0
  383. package/lib/video-recap/skills/video-assemble/references/packaging.md +45 -0
  384. package/lib/video-recap/skills/video-assemble/references/pair-media.md +74 -0
  385. package/lib/video-recap/skills/video-assemble/references/source-score.md +147 -0
  386. package/lib/video-recap/skills/video-assemble/references/subtitle-track.md +202 -0
  387. package/lib/video-recap/skills/video-assemble/scripts/adoption/__init__.py +1 -0
  388. package/lib/video-recap/skills/video-assemble/scripts/adoption/audio_mix_binding.py +279 -0
  389. package/lib/video-recap/skills/video-assemble/scripts/adoption/frozen_audio.py +187 -0
  390. package/lib/video-recap/skills/video-assemble/scripts/adoption/narration_binding.py +323 -0
  391. package/lib/video-recap/skills/video-assemble/scripts/adoption/strict_inputs.py +109 -0
  392. package/lib/video-recap/skills/video-assemble/scripts/adoption/strict_publish.py +130 -0
  393. package/lib/video-recap/skills/video-assemble/scripts/artifacts.py +10 -46
  394. package/lib/video-recap/skills/video-assemble/scripts/assemble.py +378 -119
  395. package/lib/video-recap/skills/video-assemble/scripts/assemble_constants.py +29 -12
  396. package/lib/video-recap/skills/video-assemble/scripts/assembly_contract.py +95 -44
  397. package/lib/video-recap/skills/video-assemble/scripts/assembly_settings.py +75 -32
  398. package/lib/video-recap/skills/video-assemble/scripts/audio_mix.py +11 -11
  399. package/lib/video-recap/skills/video-assemble/scripts/compose_foreground.py +293 -0
  400. package/lib/video-recap/skills/video-assemble/scripts/export_jianying.py +71 -78
  401. package/lib/video-recap/skills/video-assemble/scripts/jianying/__init__.py +1 -0
  402. package/lib/video-recap/skills/video-assemble/scripts/{jianying_builders.py → jianying/builders.py} +39 -67
  403. package/lib/video-recap/skills/video-assemble/scripts/{jianying_model.py → jianying/model.py} +3 -11
  404. package/lib/video-recap/skills/video-assemble/scripts/{jianying_optional.py → jianying/optional.py} +1 -1
  405. package/lib/video-recap/skills/video-assemble/scripts/jianying/schema.py +53 -0
  406. package/lib/video-recap/skills/video-assemble/scripts/{jianying_templates.py → jianying/templates.py} +1 -1
  407. package/lib/video-recap/skills/video-assemble/scripts/{jianying_timeline_contract.py → jianying/timeline_contract.py} +34 -13
  408. package/lib/video-recap/skills/video-assemble/scripts/{jianying_writer.py → jianying/writer.py} +7 -17
  409. package/lib/video-recap/skills/video-assemble/scripts/lib.py +37 -4
  410. package/lib/video-recap/skills/video-assemble/scripts/media.py +12 -21
  411. package/lib/video-recap/skills/video-assemble/scripts/narration_audio.py +64 -34
  412. package/lib/video-recap/skills/video-assemble/scripts/packaging.py +122 -0
  413. package/lib/video-recap/skills/video-assemble/scripts/pair_media.py +216 -0
  414. package/lib/video-recap/skills/video-assemble/scripts/render_preflight.py +1 -3
  415. package/lib/video-recap/skills/video-assemble/scripts/source_score.py +469 -0
  416. package/lib/video-recap/skills/video-assemble/scripts/source_subtitles.py +25 -9
  417. package/lib/video-recap/skills/video-assemble/scripts/subtitles/__init__.py +1 -0
  418. package/lib/video-recap/skills/video-assemble/scripts/{subtitle_core.py → subtitles/core.py} +13 -6
  419. package/lib/video-recap/skills/video-assemble/scripts/{subtitle_render.py → subtitles/render.py} +5 -4
  420. package/lib/video-recap/skills/video-assemble/scripts/subtitles/track.py +324 -0
  421. package/lib/video-recap/skills/video-assemble/scripts/subtitles/track_binding.py +200 -0
  422. package/lib/video-recap/skills/video-assemble/scripts/timeline.py +30 -46
  423. package/lib/video-recap/skills/video-assemble/scripts/timeline_emit.py +91 -7
  424. package/lib/video-recap/skills/video-assemble/scripts/visual_render.py +22 -8
  425. package/lib/video-recap/skills/video-cut/SKILL.md +34 -16
  426. package/lib/video-recap/skills/video-cut/references/shot-review.md +50 -0
  427. package/lib/video-recap/skills/video-cut/scripts/cut.py +2 -28
  428. package/lib/video-recap/skills/video-cut/scripts/cut_cli.py +58 -62
  429. package/lib/video-recap/skills/video-cut/scripts/cut_contract.py +21 -106
  430. package/lib/video-recap/skills/video-cut/scripts/cut_render.py +14 -9
  431. package/lib/video-recap/skills/video-cut/scripts/lib.py +39 -0
  432. package/lib/video-recap/skills/video-cut/scripts/narration_mapping.py +2 -155
  433. package/lib/video-recap/skills/video-cut/scripts/narrative_selection.py +244 -0
  434. package/lib/video-recap/skills/video-cut/scripts/shot_review.py +357 -0
  435. package/lib/video-recap/skills/video-recap/SKILL.md +86 -42
  436. package/lib/video-recap/skills/video-recap/references/audio-routing.md +126 -0
  437. package/lib/video-recap/skills/video-recap/references/config-playbook.md +12 -8
  438. package/lib/video-recap/skills/video-recap/references/data-schema.md +44 -33
  439. package/lib/video-recap/skills/video-recap/references/resource-library.md +151 -0
  440. package/lib/video-recap/skills/video-recap/references/shift-left-qc-schema.md +1 -1
  441. package/lib/video-recap/skills/video-recap/scripts/doctor.py +123 -30
  442. package/lib/video-recap/skills/video-recap/scripts/final_qc.py +22 -75
  443. package/lib/video-recap/skills/video-recap/scripts/lib.py +3 -3
  444. package/lib/video-recap/skills/video-recap/scripts/library.py +509 -0
  445. package/lib/video-recap/skills/video-recap/scripts/materials.py +63 -91
  446. package/lib/video-recap/skills/video-recap/scripts/mimo_qc.py +8 -70
  447. package/lib/video-recap/skills/video-recap/scripts/project_binding.py +286 -0
  448. package/lib/video-recap/skills/video-recap/scripts/qc/__init__.py +1 -0
  449. package/lib/video-recap/skills/video-recap/scripts/{mimo_qc_client.py → qc/mimo_client.py} +1 -1
  450. package/lib/video-recap/skills/video-recap/scripts/{mimo_qc_evidence.py → qc/mimo_evidence.py} +33 -66
  451. package/lib/video-recap/skills/video-recap/scripts/{mimo_qc_observations.py → qc/mimo_observations.py} +3 -11
  452. package/lib/video-recap/skills/video-recap/scripts/{mimo_qc_payload.py → qc/mimo_payload.py} +4 -7
  453. package/lib/video-recap/skills/video-recap/scripts/{mimo_qc_report.py → qc/mimo_report.py} +17 -28
  454. package/lib/video-recap/skills/video-recap/scripts/{mimo_qc_runner.py → qc/mimo_runner.py} +2 -2
  455. package/lib/video-recap/skills/video-recap/scripts/qc_contract.py +0 -19
  456. package/lib/video-recap/skills/video-recap/scripts/recap_cli.py +119 -50
  457. package/lib/video-recap/skills/video-recap/scripts/recap_inspect.py +32 -114
  458. package/lib/video-recap/skills/video-recap/scripts/recap_review.py +9 -23
  459. package/lib/video-recap/skills/video-recap/scripts/recap_runner.py +387 -334
  460. package/lib/video-recap/skills/video-recap/scripts/recap_runtime.py +23 -23
  461. package/lib/video-recap/skills/video-recap/scripts/recap_source.py +278 -0
  462. package/lib/video-recap/skills/video-recap/scripts/recap_stage_qc.py +25 -12
  463. package/lib/video-recap/skills/video-recap/scripts/recap_timeline.py +59 -52
  464. package/lib/video-recap/skills/video-recap/scripts/resource_lock.py +162 -0
  465. package/lib/video-recap/skills/video-script/SKILL.md +16 -13
  466. package/lib/video-recap/skills/video-script/references/creative-editing-playbook.md +9 -5
  467. package/lib/video-recap/skills/video-script/references/promotional-copy.md +68 -0
  468. package/lib/video-recap/skills/video-script/references/research-guide.md +1 -1
  469. package/lib/video-recap/skills/video-script/scripts/evidence_bundle.py +24 -76
  470. package/lib/video-recap/skills/video-script/scripts/lib.py +10 -87
  471. package/lib/video-recap/skills/video-script/scripts/narration_lint.py +63 -39
  472. package/lib/video-recap/skills/video-script/scripts/review.py +0 -2
  473. package/lib/video-recap/skills/video-script/scripts/review_grounding.py +35 -59
  474. package/lib/video-recap/skills/video-script/scripts/review_response.py +66 -128
  475. package/lib/video-recap/skills/video-script/scripts/review_runner.py +12 -20
  476. package/lib/video-recap/skills/video-script/scripts/speech_ownership.py +4 -4
  477. package/lib/video-recap/skills/video-script/scripts/validate.py +53 -42
  478. package/lib/video-recap/skills/video-understanding/SKILL.md +6 -4
  479. package/lib/video-recap/skills/video-understanding/references/data-schema.md +50 -156
  480. package/lib/video-recap/skills/video-understanding/references/research-guide.md +4 -4
  481. package/lib/video-recap/skills/video-understanding/scripts/asr.py +85 -65
  482. package/lib/video-recap/skills/video-understanding/scripts/asr_timing_evidence.py +270 -0
  483. package/lib/video-recap/skills/video-understanding/scripts/brief.py +2 -5
  484. package/lib/video-recap/skills/video-understanding/scripts/briefing/__init__.py +1 -0
  485. package/lib/video-recap/skills/{video-script/scripts/agent_brief.py → video-understanding/scripts/briefing/builder.py} +38 -35
  486. package/lib/video-recap/skills/video-understanding/scripts/{brief_context.py → briefing/context.py} +4 -35
  487. package/lib/video-recap/skills/{video-script/scripts/brief_inputs.py → video-understanding/scripts/briefing/inputs.py} +9 -31
  488. package/lib/video-recap/skills/{video-script/scripts/brief_timeline.py → video-understanding/scripts/briefing/timeline.py} +5 -6
  489. package/lib/video-recap/skills/video-understanding/scripts/consolidate.py +65 -116
  490. package/lib/video-recap/skills/video-understanding/scripts/detect.py +31 -40
  491. package/lib/video-recap/skills/video-understanding/scripts/lib.py +30 -86
  492. package/lib/video-recap/skills/video-understanding/scripts/narration_lint.py +63 -39
  493. package/lib/video-recap/skills/video-understanding/scripts/speech_ownership.py +4 -4
  494. package/lib/video-recap/skills/video-understanding/scripts/storyboard.py +17 -79
  495. package/lib/video-recap/skills/video-understanding/scripts/understanding_brief.py +14 -40
  496. package/lib/video-recap/skills/video-understanding/scripts/understanding_cache.py +64 -46
  497. package/lib/video-recap/skills/video-understanding/scripts/understanding_runner.py +31 -11
  498. package/lib/video-recap/skills/video-understanding/scripts/understanding_storyboard.py +19 -14
  499. package/lib/video-recap/skills/video-understanding/scripts/vlm.py +80 -108
  500. package/lib/video-recap/skills/video-voiceover/SKILL.md +29 -19
  501. package/lib/video-recap/skills/video-voiceover/references/index-tts.md +31 -0
  502. package/lib/video-recap/skills/video-voiceover/scripts/approved_text_policy.py +123 -0
  503. package/lib/video-recap/skills/video-voiceover/scripts/dub.py +51 -59
  504. package/lib/video-recap/skills/video-voiceover/scripts/lib.py +8 -44
  505. package/lib/video-recap/skills/video-voiceover/scripts/providers/__init__.py +1 -0
  506. package/lib/video-recap/skills/video-voiceover/scripts/providers/index_tts.py +184 -0
  507. package/lib/video-recap/skills/video-voiceover/scripts/voiceover.py +212 -134
  508. package/package.json +45 -45
  509. package/lib/novel-to-game/skills/game-world-design/references/dialogue-design-method.md +0 -58
  510. package/lib/novel-to-game/skills/game-world-design/references/game-writing-craft.md +0 -53
  511. package/lib/novel-to-game/skills/novel-to-game/references/intake-benchmark-reference.md +0 -38
  512. package/lib/oh-story/skills/story-long-analyze/references/material-decomposition.md +0 -530
  513. package/lib/oh-story/skills/story-long-analyze/references/output-templates.md +0 -559
  514. package/lib/oh-story/skills/story-long-scan/references/scan-output-format.md +0 -207
  515. package/lib/oh-story/skills/story-long-write/references/state-tracking.md +0 -108
  516. package/lib/oh-story/skills/story-short-analyze/references/material-decomposition.md +0 -678
  517. package/lib/oh-story/skills/story-short-analyze/references/output-templates.md +0 -561
  518. package/lib/video-recap/skills/video-assemble/scripts/jianying_schema.py +0 -98
  519. package/lib/video-recap/skills/video-recap/references/creative-editing-playbook.md +0 -225
  520. package/lib/video-recap/skills/video-recap/references/research-guide.md +0 -74
  521. package/lib/video-recap/skills/video-recap/references/timeline-and-jianying.md +0 -250
  522. package/lib/video-recap/skills/video-script/scripts/brief_context.py +0 -348
  523. package/lib/video-recap/skills/video-script/scripts/narration.py +0 -12
  524. package/lib/video-recap/skills/video-understanding/scripts/agent_brief.py +0 -399
  525. package/lib/video-recap/skills/video-understanding/scripts/brief_inputs.py +0 -290
  526. package/lib/video-recap/skills/video-understanding/scripts/brief_timeline.py +0 -327
  527. /package/lib/video-recap/skills/video-assemble/scripts/{jianying_tracks.py → jianying/tracks.py} +0 -0
  528. /package/lib/video-recap/skills/video-recap/scripts/{mimo_qc_contract.py → qc/mimo_contract.py} +0 -0
  529. /package/lib/video-recap/skills/video-voiceover/scripts/{fish_audio.py → providers/fish_audio.py} +0 -0
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: video-recap
3
3
  description: >
4
- 从输入视频端到端生成中文解说成片。用户提供 .mp4 / .mov / .mkv / .webm,并要求添加旁白、
4
+ 从输入视频生成中文解说成片或原声剧情短片。用户提供 .mp4 / .mov / .mkv / .webm,并要求剪辑、添加旁白、
5
5
  配音、总结、短剧/电视剧/电影/纪录片/科普解说时使用。负责编排 video-* 技能链:视频理解 →
6
6
  Agent 制定故事与视听方案 → 剪辑 → 配音 → 合成。触发词:视频解说、视频旁白、生成解说、
7
7
  视频 recap、video recap、voiceover、narration、auto-dub、recap。
@@ -15,34 +15,55 @@ description: >
15
15
  video-understanding ─▶ Agent 按 video-script 制定方案并写稿 ─▶ [video-cut] ─▶ video-voiceover ─▶ video-assemble
16
16
  ```
17
17
 
18
- 流程支持断点续跑:写好 `narration.json` 后重复同一条命令即可继续。第二阶段会校验
19
- `recap_run_manifest.json`,拒绝复用来自其他源视频或其他运行参数的旧工作目录;视频理解产物也只在来源一致时复用。
18
+ 流程支持断点续跑:写好 `narration.json` 后重复同一条命令即可继续。第二阶段会比对
19
+ `recap_run_manifest.json` 记录的源视频路径、文件大小/修改时间与运行参数,拒绝复用来自其他源视频或其他参数的旧工作目录;视频理解产物也只在来源一致时复用。
20
20
 
21
- ## 2. 创作职责
21
+ 画面流程 `--edit-mode full|cut|dub` 与声音策略 `--audio-mode` 是两个独立开关;
22
+ `narration` 保留上述解说流程,`source-mix` 不做配音,`adopted-packet-copy` 冻结当前输入的已采用 AAC 音轨。
23
+ 组合只有下面几条路径,其余组合在启动时直接报错:
24
+
25
+ | 输入 | `--edit-mode` | `--audio-mode` | Agent 暂停点 | 流程 | 详见 |
26
+ |---|---|---|---|---|---|
27
+ | 单视频 | full | narration | 1:`narration.json` | 理解 → 写稿 → 校验 → 配音 → 合成 | §4 |
28
+ | 单视频 | cut | narration | 2:`clip_plan.json`,再对着成片写 `narration.json` | 理解 → 剪辑 → 重建输出时间 brief → 写稿 → 配音 → 合成 | §4 |
29
+ | 多视频 | cut | narration | 2:同上,clip 必须带 `source_id` | 逐源理解 → 剪辑 → 写稿 → 配音 → 合成 | §4.3 |
30
+ | 单视频 | full | source-mix / adopted-packet-copy | 无 | 直接合成当前整段 | §4.7 |
31
+ | 单 / 多视频 | cut | source-mix / adopted-packet-copy | 1:`clip_plan.json` | 理解 → 剪辑 → 合成,不写稿 | §4.7 |
32
+ | 单视频 | dub | narration | 1:`dub_script.json` | 英文转写 → 译稿 → 克隆音色整轨替换 | §5 |
33
+ | 已剪好的母版 | full | narration + 三个采用 JSON | 无 | 只做严格合成 | 下文 |
34
+
35
+ 所有 full/cut 路径共用同一段收尾:(有旁白时)评审 → TTS → 合成 → 成片 QC。使用原声模式时读
36
+ `references/audio-routing.md`。
22
37
 
23
- 这不是单纯的 JSON / 渲染流水线。Agent 是本次内容的创作负责人。先判断本轮的**创作控制模式**;它与 `--edit-mode full|cut|dub` 是两个维度:
38
+ 已有预制画面和本地采用的完整声音三件套时,可走严格 assembly-only 路径:
24
39
 
25
- - **CREATE**:从素材创作新成片。比较真正可行的故事/剪辑假设,再选择主线。
26
- - **DIRECTED**:用户已经指定结构、镜头、台词或包装方向。把这些决定当作基线落实,不为满足模板而另起方案。
27
- - **REVISION**:用户针对已有版本看片修改。最新反馈覆盖旧决定;本轮未点名的故事、镜头、声音和包装默认冻结,不重新发散创作。
40
+ ```bash
41
+ python3 scripts/recap.py picture.mp4 --edit-mode full --work-dir NEW_WORK \
42
+ --output-dir DELIVERY \
43
+ --tts-meta tts_meta.json \
44
+ --narration-adoption narration_adoption.json \
45
+ --audio-mix-adoption audio_mix_adoption.json
46
+ ```
28
47
 
29
- REVISION 开始前先明确“本轮修改项”和“冻结项”。表达、节奏、字幕反馈写回 `style_card.json`,镜头、入出点和声音分工写回 `visual_audio_board.json`;只有观众承诺、POV、主线或故事 beat 改变时才更新 `recap_story_plan.json`。删除成片内容时同步删除计划中的旧描述,不能让工作产物继续指导已不存在的镜头。
48
+ 三个 JSON 参数必须同时出现。该入口只接受单视频、full、narration、音轨 0、新工作目录和未存在的
49
+ 交付文件;不运行理解、写稿、解说评审、TTS、cut、MiMo QC 或剪映导出。语义与媒体形状仍由
50
+ video-assemble 严格验证,recap 只核对子技能绑定记录引用的是同一批采用文件与母版路径,不把调用方
51
+ 采用的声音或混音声明成自动创作或发布批准。详见 `references/audio-routing.md`。
30
52
 
31
- 确定模式后,在进入昂贵的下游处理前完成五次判断:
53
+ 这里的单视频是**已经剪好的母版**。重剪后可以复用未改动的 WAV 与 `tts_meta.json`,但必须按新母版
54
+ 重新写混音采用文件里的落点与准备好的音床;衔接步骤见 `references/audio-routing.md` 的 “Keep adopted voice after a cut”。
32
55
 
33
- 1. **导演判断**:确定观众承诺、POV、戏剧问题、情绪终点,以及哪些信息要保留到后面揭示。
34
- 2. **故事编辑**:CREATE 比较至少两个可行的剪辑假设;DIRECTED / REVISION 继承用户指定或已确认的主线。beat 始终定义为“发生了什么变化”,而不是场景摘要。
35
- 3. **画面剪辑**:选择真正值得保留的具体时刻、人物反应、入点与出点。
36
- 4. **声音/旁白**:先分配画面、原声、沉默和旁白的任务,再写解说词。
37
- 5. **观众复核**:分别检查无旁白、只听声音和第一次观看时的体验,优先修改回报最高的问题。
56
+ ## 2. 创作职责
38
57
 
39
- 执行前阅读本技能的 `references/creative-editing-playbook.md`,并把简洁的创作决定写入:
58
+ 这不是单纯的 JSON / 渲染流水线。Agent 是本次内容的创作负责人。先判断本轮的**创作控制模式**(CREATE / DIRECTED / REVISION,与 `--edit-mode` 无关),再在进入昂贵的下游处理前完成五次判断:
40
59
 
41
- - `recap_story_plan.json`:导演意图、适用时的备选假设、选定主线和基于变化的 beat 图。
42
- - `visual_audio_board.json`:每拍的画面任务、表演/反应选择、原声锚点、`audio_owner` 与 `narration_job`。
43
- - `style_card.json`(有表达要求或表达反馈时):当前声音、口语节奏、字幕阅读姿态与明确禁忌。
60
+ 1. **导演判断**:观众承诺、POV、戏剧问题、情绪终点与揭示节奏。
61
+ 2. **故事编辑**:beat 定义为“发生了什么变化”,不是场景摘要。
62
+ 3. **画面剪辑**:选择真正值得保留的具体时刻、反应、入点与出点。
63
+ 4. **声音/旁白**:先分配画面、原声、沉默和旁白的任务,再写解说词。
64
+ 5. **观众复核**:分别检查无旁白、只听声音和第一次观看的体验。
44
65
 
45
- 这些文件只记录可审计的当前决定,不记录冗长思维过程;它们不会增加服务或渲染依赖。现有工具可以忽略它们,Agent 与建议型解说评审会用它们保持创作一致。建立这条内容基线不需要平台数据。
66
+ 三种控制模式的定义、REVISION 的修改/冻结规则、创作方法以及 `recap_story_plan.json` / `visual_audio_board.json` / `style_card.json` 的写法,全部按 `video-script` 执行;它会要求先读创作手册。这些文件只记录可审计的当前决定,不增加服务或渲染依赖。
46
67
 
47
68
  ## 3. 环境与脚本路径
48
69
 
@@ -57,7 +78,7 @@ export MIMO_API_KEY=***
57
78
  - VLM:`mimo-v2.5`
58
79
  - TTS:`mimo-v2.5-tts`
59
80
 
60
- TTS 可通过 `--tts-provider fish-audio` / `TTS_PROVIDER=fish-audio` 改用 Fish Audio;此时另需 `FISH_API_KEY`,默认模型为 `s2.1-pro-free`,默认使用“娱乐扒妹”音色(`5653cea4ac83480aaf2bf45406556185`),可用 `FISH_TTS_REFERENCE_ID` 覆盖。ASR/VLM 仍使用 MiMo。
81
+ TTS 供应商由 `--tts-provider mimo-tts|fish-audio|index-tts`(或 `TTS_PROVIDER`)透传给配音技能;Fish Audio 与自托管 index-tts 各自的环境变量、默认音色和能力限制见该技能。ASR/VLM 始终使用 MiMo。`--doctor` 只做离线配置检查。
61
82
 
62
83
  `tp-*` Token Plan 密钥默认使用中国区集群,可用 `MIMO_TOKEN_PLAN_CLUSTER` 覆盖。
63
84
 
@@ -66,15 +87,15 @@ TTS 可通过 `--tts-provider fish-audio` / `TTS_PROVIDER=fish-audio` 改用 Fis
66
87
  - `--mimo-video-overview`:按场景块补充 MiMo 视频理解。
67
88
  - `--mimo-qc pre-assemble|post-render|both`:在合成前、成片后或两个阶段给出建议型复核。
68
89
 
69
- MiMo QC 默认关闭;每个选定阶段最多请求一次,写入 `mimo_qc.json`。任何凭证缺失、限流、超时、格式错误或采样失败都只记录状态,不阻断流程。详细可覆盖配置见 `references/config-playbook.md`。
90
+ MiMo QC 默认关闭;每个选定阶段最多请求一次,写入 `mimo_qc.json`。任何凭证缺失、限流、超时、格式错误或采样失败都只记录状态,不阻断流程。可覆盖配置见 `references/config-playbook.md`,QC 报告的最小契约见 `references/shift-left-qc-schema.md`。
70
91
 
71
92
  下面的 `scripts/...` 均相对于本技能目录。若执行器从仓库根目录启动,请给脚本路径加上本技能的绝对目录。脚本启动后会自行定位兄弟技能和资源。
72
93
 
73
- ## 4. 标准解说流程
94
+ ## 4. 标准解说流程(audio-mode narration)
74
95
 
75
96
  ### 4.1 背景调研
76
97
 
77
- 若能识别影片、剧集或主题,先按本技能的 `references/research-guide.md` 调研并写入
98
+ 若能识别影片、剧集或主题,先按 video-understanding 技能的调研指南 `research-guide.md` 调研并写入
78
99
  `work_dir/background_research.json`。视频理解会把人物名和剧情背景折入 VLM 上下文,避免只得到“黑衣男子”一类模糊描述。无法识别来源时可跳过。
79
100
 
80
101
  ### 4.2 分析并暂停创作
@@ -114,6 +135,10 @@ python3 scripts/recap.py ep1.mp4 ep2.mp4 --edit-mode cut --material-library-dir
114
135
 
115
136
  素材检索只是对 JSON / MD / JSONL 做 grep,例如 `grep -R "keyword" .video-materials`。当前版本不复制原始媒体,也不提供数据库、向量或语义搜索。
116
137
 
138
+ 同一根目录还可以登记可复用的资源(BGM、音效、音色、字体、图片)、带版本与采用记录的模板(字幕样式、包装图层)和样片。
139
+ 格式与 `scripts/library.py check|list|show` 只读工具见 `references/resource-library.md`。用 `--project recap_project.json` 把已采用的字幕样式、音色与 BGM 绑定到这次运行;
140
+ 每次 full / cut 合成后 `work_dir/resource_lock.json` 记下实际用到的资源与授权状态。
141
+
117
142
  ### 4.4 继续生成成片
118
143
 
119
144
  写好所需产物后,重复同一条命令:
@@ -130,7 +155,9 @@ python3 scripts/recap.py <video> --work-dir <work_dir> # 可追加 --edit-mode
130
155
  python3 scripts/recap.py <video> --work-dir <work_dir> --mimo-qc both
131
156
  ```
132
157
 
133
- 合成前复核会读取脚本、计划和 TTS 元数据;成片后还会读取最多六张临时 JPEG。相同输入命中内容缓存,`--mimo-qc-refresh` 可强制刷新。帧的 base64 与凭证不会写入磁盘。
158
+ 合成前复核会读取脚本、计划和 TTS 元数据;成片后还会读取最多六张临时 JPEG。输入文件的大小/修改时间、模型与提示都未变时直接复用上次报告,`--mimo-qc-refresh` 可强制刷新。帧的 base64 与凭证不会写入磁盘。
159
+
160
+ 已有批准解说稿时加 `--preserve-approved-text`:校验与 TTS 原样保留批准稿(只更新 `overlaps_speech`),装不下时间窗即失败,不缩稿、不降级为部分成功。
134
161
 
135
162
  ### 4.5 字幕与克隆旁白
136
163
 
@@ -154,7 +181,27 @@ python3 tools/measure_subtitle.py <video>
154
181
  4. 单独复看开头、核心情绪/表演点和结尾,确认进入时机、回报停留和收束都成立。
155
182
  5. REVISION 分别验证本轮修改项已经改变、冻结项没有意外变化;然后再做解码、时长、音画规格等机械检查。
156
183
 
157
- scene score、亮度统计、contact sheet 与自动 QC 只负责定位候选问题;最终判断以真实播放为准。短时间内出现密集候选时,必须判断每个切点来自原片还是本次拼接:原片无关短镜头整段删,相关短镜头扩展到完整动作/反应;人工拼接点优先移动边界、恢复同源连续运动或合并片段,能消除就不保留。修复失败时回到剪点、声音或文案层,不用更多包装掩盖。
184
+ scene score、亮度统计、contact sheet 与自动 QC 只负责定位候选问题;最终判断以真实播放为准。密集切点的来源判断与处理规则按剪辑技能执行。修复失败时回到剪点、声音或文案层,不用更多包装掩盖。
185
+
186
+ full/cut 交付如需让确定性的最终检查影响命令退出状态,显式传
187
+ `--require-final-qc`。只有 `final_qc.json` 与 `golden_eval.json` 的摘要均为
188
+ `ok: true` 且整数 `blocker_count: 0` 才打印完成并返回成功;缺失、畸形或 blocker
189
+ 会保留报告和已渲染诊断媒体,但命令非零退出且不打印完成。默认仍是仅报告、不阻断。
190
+ 该参数不支持 `--edit-mode dub`;dub 未传该参数时的准备和渲染行为不变。
191
+
192
+ ### 4.7 不需要解说的片子
193
+
194
+ ```bash
195
+ # 对当前整段输入直接合成;不隐式跑理解/ASR/TTS
196
+ python3 scripts/recap.py locked_picture.mp4 --work-dir source_work --audio-mode source-mix
197
+ # 剪辑计划仍按 cut 流程产生,剪完不再暂停等待 narration.json
198
+ python3 scripts/recap.py ep1.mp4 ep2.mp4 --edit-mode cut --work-dir cut_work --audio-mode source-mix
199
+ # 只换包装时冻结当前整片 AAC;不允许同时加 BGM/TTS
200
+ python3 scripts/recap.py adopted.mp4 --work-dir packaging_work --audio-mode adopted-packet-copy
201
+ ```
202
+
203
+ `source-mix` 仍会混音和重编码;`cut + adopted-packet-copy` 冻结的是剪后中间片的声音,不是原片的 AAC 包。
204
+ 当前严格字幕轨只支持 adopted 模式;其他字幕来源没有因此变成精确对齐。切换声音模式须新工作目录,不得把旧 TTS、QC 或自动生成的解说花字混入本轮原声生产。细节见 `references/audio-routing.md`。
158
205
 
159
206
  ## 5. 英译中原声复刻模式
160
207
 
@@ -178,12 +225,22 @@ python3 scripts/recap.py <video> --edit-mode dub --work-dir <work_dir>
178
225
 
179
226
  重复同一命令后输出 `dub_<name>.mp4`。每句单独克隆并贴回原时间线;只有即将覆盖下一句时才局部加速。当前版本只支持单说话者、整轨替换,不分离背景音乐。
180
227
 
181
- ## 6. 自检命令
228
+ ## 6. 自检与只读 dashboard
182
229
 
183
230
  ```bash
184
231
  python3 scripts/recap.py --doctor
185
232
  ```
186
233
 
234
+ ### 6.1 只读 dashboard
235
+
236
+ ```bash
237
+ python3 scripts/dashboard_server.py --root <目录> [--port 0] [--open]
238
+ ```
239
+
240
+ 前台运行并打印本机地址(只绑定 127.0.0.1,Agent 启动时放到后台)。它在 `--root` 下按 `library.json`、`recap_project.json`、
241
+ `recap_run_manifest.json` 发现资源库、项目与运行,按阶段显示剪辑节奏、旁白、成片与时间线、QC 和 `resource_lock.json`。
242
+ 严格只读:只接受 GET / HEAD,不写任何文件;页面上的「复制给助手」只复制一句请求,改动回到对话里做。
243
+
187
244
  ## 7. 输出与参数
188
245
 
189
246
  主要输出:
@@ -194,23 +251,10 @@ python3 scripts/recap.py --doctor
194
251
  - `work_dir/recap_story_plan.json` / `visual_audio_board.json`:Agent 创作意图与剪辑决定。
195
252
  - `work_dir/mimo_qc.json`:可选的建议型复核,不作为发布门禁。
196
253
 
197
- 可透传参数:
198
-
199
- `--context`、`--scene-threshold`、`--style`、`--edit-mode {full,cut,dub}`、`--target-duration`、
200
- `--skip-asr`、`--mimo-video-overview`、`--mimo-qc {off,pre-assemble,post-render,both}`、
201
- `--mimo-qc-refresh`、`--consolidate`、`--consolidate-asr`、`--tts-provider`、`--mimo-tts-voice`、`--voice-ref`、
202
- `--allow-partial-tts`、`--review-narration`、`--no-review-narration`、`--require-narration-review`、
203
- `--subtitle-y-top`、`--subtitle-y-bot`、`--no-burn-subtitles`、`--output-dir`、
204
- `--export-jianying`、`--jianying-bundle-media`、`--jianying-no-bundle-media`、
205
- `--material-library-dir`、`--use-materials`、`--save-materials`。
206
-
207
- `--style` 是原样传给 Agent 的自由文本指导,不是 preset、枚举、开关或有限风格分类。
254
+ 完整参数列表以 `python3 scripts/recap.py --help` 为准。`--style` 是原样传给 Agent 的自由文本指导,不是 preset、枚举、开关或有限风格分类。
208
255
 
209
256
  ## 8. 能力边界
210
257
 
211
- - 编排器不代替 Agent 写 `narration.json` / `clip_plan.json`;具体写作遵循创作 brief 与写作阶段契约。
212
258
  - 语义评审默认建议型、失败开放;只有调用方显式启用严格解说评审时,事实矛盾、残句或评审不可用才会在 TTS 前阻断。确定性校验阶段始终负责硬校验。
213
259
  - MiMo QC 不能阻断、自动修复或改变退出状态,只提供定位建议。
214
- - 建立内容质量基线不依赖平台分析、留存遥测或发布接入。
215
- - 本技能不是无人值守调度器,不会向任何平台发布内容。
216
- - 各阶段技能不共享代码,只通过 `work_dir` 产物通信。
260
+ - 宣发标题、花字或外部文案回填见 `video-script` 的 references/promotional-copy.md。
@@ -0,0 +1,126 @@
1
+ # Recap audio routing
2
+
3
+ `--edit-mode` selects the picture workflow; `--audio-mode` independently
4
+ selects the final audio workflow:
5
+
6
+ | Audio mode | Narration validation/review | TTS | Assemble input |
7
+ | --- | --- | --- | --- |
8
+ | `narration` (default) | Runs as before | Runs as before | source or rendered cut |
9
+ | `source-mix` | Not applicable | Not run | current source or rendered cut |
10
+ | `adopted-packet-copy` | Not applicable | Not run | current source or rendered cut |
11
+
12
+ `full` with either non-narration mode goes directly to assemble and does not
13
+ implicitly run understanding. `cut` still requires the existing `clip_plan`:
14
+ the first run analyzes and pauses for that plan, then later runs the established
15
+ single- or multi-source cut renderer. It does not pause for `narration.json`.
16
+
17
+ ## Local adopted full-sound assembly
18
+
19
+ The strict local-adoption route accepts one prebuilt picture in `full` mode and
20
+ exactly this all-or-none bundle:
21
+
22
+ ```text
23
+ --tts-meta PATH --narration-adoption PATH --audio-mix-adoption PATH
24
+ ```
25
+
26
+ It requires narration mode, stream 0, a new explicit `--work-dir`, and a delivery path
27
+ that does not already exist. `--output-dir` is optional; when omitted, delivery uses the
28
+ new work directory's parent. The route calls only the video-assemble CLI; it does
29
+ not run understanding, script validation, narration review, voiceover, MiMo QC, cut,
30
+ continuation, editor export, or material-cache reuse. Ambient TTS provider and voice
31
+ configuration are inert. Explicit TTS/voice/review/MiMo/editor flags are rejected rather
32
+ than silently ignored.
33
+
34
+ `recap_run_manifest.json` records the resolved path of all three local artifacts under
35
+ `audio.local_adoption`, and the picture's path plus `{size, mtime_ns}` as
36
+ `source_video_identity`. Analysis settings remain separate and unchanged. Recap validates
37
+ routing and, after the child run, checks that the assembler's binding records reference
38
+ the same adoption files and picture; video-assemble remains authoritative for the adoption
39
+ schemas, PCM shapes, frame clock, mix, bindings, and final media transaction. This path
40
+ executes caller-adopted assets and does not claim that recap authored or approved their
41
+ story, voice, or mix.
42
+
43
+ ## Keep adopted voice after a cut
44
+
45
+ The single input above is the **finished picture**, which may contain one or many source
46
+ episodes. Use two existing stages rather than sending an old mix binding into a new cut:
47
+
48
+ 1. Finish the selected cut with `video-cut`: either run `recap.py ... --edit-mode cut`,
49
+ or call that skill's own `scripts/cut.py` from its installed directory, with an
50
+ existing clip plan and source manifest:
51
+
52
+ ```bash
53
+ python3 <video-cut>/scripts/cut.py ep1.mp4 --work-dir CUT_WORK \
54
+ --sources-manifest SOURCES_JSON
55
+ ```
56
+
57
+ A single-source cut omits `--sources-manifest`. For already locked frame decisions,
58
+ use the picture-plan path instead. Read `clip_plan_validated.json` (or the locked path's
59
+ `picture_map.json`) before placing sound.
60
+ 2. Keep the selected WAVs, `tts_meta.json`, and `narration_adoption.json` when the words,
61
+ WAV bytes, and selected voice are unchanged. Do not run voiceover just to move a line.
62
+ In this explicit mix, new `output_start_sample` values own placement; old generation
63
+ windows in `tts_meta.json` are not the revised output timeline.
64
+ 3. Match source dialogue, ambience and music to the new picture. Reuse the prepared bed
65
+ only if that sound and its complete sample clock remain appropriate; otherwise rebuild
66
+ it with the existing `video-assemble` source/score producer. Write a **new** mix adoption
67
+ with the prepared receipt path, total samples and complete WAV placements for the new
68
+ picture. Reordering shots can require moving dialogue too; a mix adoption written for
69
+ the old picture cannot simply be pointed at the new one.
70
+ 4. Run the local adopted `full` command in `SKILL.md` with `CUT_WORK/edited_source.mp4` and a new
71
+ assembly work/delivery directory. Inspect the emitted narration placements and subtitles
72
+ against that mixed output. Rebind any precise subtitle track to the new finished audio.
73
+
74
+ The same steps handle a later revision: keep unchanged picture/voice assets, rebuild only
75
+ the affected bed and placement decisions, then assemble into a new directory. The local
76
+ assembly command still does not resume an old work directory or decide new placements.
77
+
78
+ ## Identity and resume
79
+
80
+ `recap_run_manifest.json` binds `{mode, selected_stream_index}` separately from
81
+ understanding/material settings. Changing audio mode or stream requires a new
82
+ work directory; it never reuses narrated TTS accidentally. Legacy manifests
83
+ without the audio field are interpreted as `narration`, stream 0, preserving
84
+ old in-flight narration runs. Continuation commands retain the audio selection.
85
+
86
+ An unbound work directory containing `narration.json` is ambiguous and cannot
87
+ be adopted by a source mode. Existing run-local QC stages are reset after the
88
+ work-directory policy is validated. Source runs record TTS, narration
89
+ validation, and narration review as `not_applicable`; old `tts_meta.json` and
90
+ narration review files are not read as evidence for the current run.
91
+
92
+ ## Fail-closed combinations
93
+
94
+ - `dub` cannot be combined with a non-narration audio mode.
95
+ - Explicit TTS/text-policy options are rejected in source modes rather than
96
+ ignored. Ambient TTS provider/voice configuration is inert because TTS does
97
+ not run, and continuation commands do not promote it into explicit flags.
98
+ - Cut audio modes support selected stream 0 only. Full mode may pass
99
+ another stream to assemble, subject to assemble/export support.
100
+ - Source modes do not support advisory MiMo QC; use `off`.
101
+ - Local adopted full-sound assembly consumes a prebuilt picture in `full` mode; use the
102
+ two-stage workflow above for single- or multi-source cuts. That assembly invocation
103
+ does not resume an old work directory or export an editor draft.
104
+ - `source-mix` rejects an explicit `subtitle_track.json` before analysis or cut,
105
+ because the precise-track contract only binds adopted packet audio.
106
+
107
+ `--preserve-approved-text` remains opt-in and is forwarded unchanged to
108
+ voiceover and continuation only in narration mode.
109
+
110
+ Narration may explicitly select `--tts-provider index-tts`; `auto` does not
111
+ select Index TTS. Index TTS cannot be combined with MiMo voice selection,
112
+ `--voice-ref`, or `dub`. Its endpoint and voice remain backend configuration,
113
+ not recap defaults.
114
+
115
+ ## Packaging and frozen-audio boundary
116
+
117
+ Source modes never regenerate `visual_overlays.json`. A work directory already
118
+ bound to narration is rejected, preventing narration-derived overlays from
119
+ silently becoming source-mode author input. Otherwise existing overlays are
120
+ treated as caller-authored packaging and preserved.
121
+
122
+ `adopted-packet-copy` freezes only the selected audio stream on the actual file
123
+ passed to assemble. In `full`, that is the input video. In `cut`, the cut stage
124
+ has already rendered `edited_source.mp4`; packet-copy verification therefore
125
+ applies to that file's audio, **not** to AAC packets from any original source.
126
+ This routing does not prove listening quality or publication approval.
@@ -2,8 +2,10 @@
2
2
 
3
3
  The bundle runs **zero-config** with sensible defaults. To change behavior, set the
4
4
  environment variables below (or pass the noted CLI flags) — they **override** the defaults.
5
- Nothing here is required; this is documentation only. No tool reads a config file, and the
6
- bundle ships no root `CLAUDE.md` (so it never collides with your project/global instructions).
5
+ Nothing here is required; this is documentation only. The only config file any tool reads is an
6
+ optional `recap_project.json` passed with `--project` (see `resource-library.md`): it resolves to the same
7
+ variables below, and a variable you set that disagrees with the project stops the run. The bundle ships no
8
+ root `CLAUDE.md` (so it never collides with your project/global instructions).
7
9
  Defaults below are bundle-level defaults unless a note scopes them to a specific stage.
8
10
 
9
11
  | Concern | Env var / flag | Default | Notes |
@@ -14,18 +16,19 @@ Defaults below are bundle-level defaults unless a note scopes them to a specific
14
16
  | ASR model | `MIMO_ASR_MODEL` | `mimo-v2.5-asr` | speech-to-text |
15
17
  | ASR language | `MIMO_ASR_LANGUAGE` | `auto` | `auto` / `zh` / `en` |
16
18
  | ASR window | `ASR_SEGMENT_SECONDS` | `15` | smaller → finer dialogue timestamps (stays under MiMo's 10MB base64 cap) |
17
- | TTS provider | `TTS_PROVIDER` / `--tts-provider {auto,mimo-tts,fish-audio}` | `auto` | `auto` prefers configured MiMo, then Fish Audio; explicit selection is recommended for repeatable runs |
19
+ | TTS provider | `TTS_PROVIDER` / `--tts-provider {auto,mimo-tts,fish-audio,index-tts}` | `auto` | `auto` prefers configured MiMo, then Fish Audio, and never picks index-tts; explicit selection is recommended for repeatable runs |
18
20
  | MiMo TTS model | `MIMO_TTS_MODEL` | `mimo-v2.5-tts` | MiMo provider only |
19
21
  | MiMo voice | `MIMO_TTS_VOICE` / `--mimo-tts-voice` | `冰糖` | |
20
22
  | Cloned narration voice | `VOICE_REF` / `--voice-ref` | off | MiMo full/cut only; lazily normalize once, then use `mimo-v2.5-tts-voiceclone`; mutually exclusive with `--mimo-tts-voice`; requires authorization and sends the reference to MiMo |
21
23
  | Fish Audio key | `FISH_API_KEY` | — | required when Fish Audio is selected; never written to artifacts or cache metadata |
22
- | Fish Audio model | `FISH_TTS_MODEL` | `s2.1-pro-free` | current free model; Fair Use/no SLA and free availability is currently announced through 2026-08-31 |
23
- | Fish Audio voice | `FISH_TTS_REFERENCE_ID` | `5653cea4ac83480aaf2bf45406556185`(娱乐扒妹) | optional override for the built-in narration voice; participates in segment cache identity |
24
+ | Fish Audio model | `FISH_TTS_MODEL` | `s2.1-pro-free` | free model under Fair Use, no SLA; check Fish Audio's current policy |
25
+ | Fish Audio voice | `FISH_TTS_REFERENCE_ID` | `5653cea4ac83480aaf2bf45406556185`(娱乐扒妹) | optional override for the built-in narration voice; part of the per-segment cache settings |
24
26
  | Fish Audio endpoint | `FISH_TTS_API_URL` | `https://api.fish.audio/v1/tts` | returns WAV directly to the existing voiceover pipeline |
25
- | TTS transport | `TTS_TIMEOUT` / `TTS_WORKERS` / `TTS_RETRIES` | `300` / `4` / `3` | request timeout, parallel segments, and per-segment retries for both providers |
27
+ | Self-hosted TTS | `INDEX_TTS_ENDPOINT` / `INDEX_TTS_VOICE` | — | explicit `--tts-provider index-tts` only; the endpoint is never written to disk, and segment `emotion`/style is rejected |
28
+ | TTS transport | `TTS_TIMEOUT` / `TTS_WORKERS` / `TTS_RETRIES` | `300` / `4` / `3` | request timeout, parallel segments, and per-segment retries for all providers |
26
29
  | Advisory MiMo QC | `MIMO_QC` / `--mimo-qc {off,pre-assemble,post-render,both}` | `off` | optional subjective review at the selected stage(s), one request per stage. Always fail-open: results only point the agent/user to `mimo_qc.json`, never block or auto-repair |
27
- | MiMo QC refresh/model | `MIMO_QC_REFRESH` / `--mimo-qc-refresh`; `MIMO_QC_MODEL` | cache on / VLM fallback | content-keyed cache excludes absolute paths. Post-render temporarily samples at most 6 JPEGs (≤768px); base64 is never persisted. The standalone adapter requires explicit `mimo_qc.py --live` for network access |
28
- | Narration block coverage | `NARRATION_COVERAGE_TARGET` / `NARRATION_BLOCK_SECONDS` | `0.7` / `9.0` | current block-recap density controls; old `TARGET_SEGMENTS_PER_MINUTE` applies only to legacy single-pass cut mapping reports |
30
+ | MiMo QC refresh/model | `MIMO_QC_REFRESH` / `--mimo-qc-refresh`; `MIMO_QC_MODEL` | cache on / VLM fallback | the reuse check compares evidence file sizes/mtimes, model and prompt, never absolute paths. Post-render temporarily samples at most 6 JPEGs (≤768px); base64 is never persisted. The standalone adapter requires explicit `mimo_qc.py --live` for network access |
31
+ | Narration block coverage | `NARRATION_COVERAGE_TARGET` / `NARRATION_BLOCK_SECONDS` | `0.7` / `9.0` | current block-recap density controls |
29
32
  | Narration speed | `NARRATION_SPEED` | `1.15` | global atempo on the voiceover; set `1.0` for long-form/documentary |
30
33
  | Narration authored start | `NARRATION_DELAY_SECONDS` | `0` | the renderer uses the Agent-authored `start` exactly. Set a non-zero value only for legacy drafts; hidden delay can move a validated sentence-boundary entry back into source speech |
31
34
  | Source sentence boundary detector | `SOURCE_BOUNDARY_NOISE_THRESHOLD` / `SOURCE_BOUNDARY_MIN_PAUSE` / `SOURCE_BOUNDARY_MAX_ALIGNMENT_ERROR` | `-18dB` / `0.12` / `2.1` | aligns ASR terminal punctuation to short acoustic pauses and writes `speech_boundary_anchors.json`; unsafe narration entries and cut in/out points are blocked. There is no intentional-interrupt override |
@@ -47,6 +50,7 @@ Defaults below are bundle-level defaults unless a note scopes them to a specific
47
50
  | Shot-change-aware cut | `SCENE_CUT_SNAP` / `SCENE_CUT_SNAP_MARGIN` / `SCENE_CUT_DETECT_THRESHOLD` | on / `0.5` / `0.4` | cut mode: nudge each clip boundary off the original footage's hard cuts so the edit point doesn't flash a sliver of the adjacent shot (闪烁). source_start moves forward onto / source_end back onto any shot-change within the margin; boundaries already on a cut, or that would shrink a clip below ~0.5s, are left as-is. Set `SCENE_CUT_SNAP=0` to disable |
48
51
  | VLM workers | `VLM_WORKERS` | `8` | lower to 1 if a proxy/WAF rate-limits |
49
52
  | Subtitle size | `SUBTITLE_FONT_SIZE` / `SUBTITLE_MARGIN_V` | `42` / `48` | look & placement |
53
+ | Subtitle font | `SUBTITLE_FONT_NAME` / `SUBTITLE_FONT_FILE` | `Arial` / — | with a font file, burned ASS subtitles load fonts from its directory (`fontsdir`) and on-screen text overlays use it (`fontfile`); `SUBTITLE_FONT_NAME` must be that file's family name. A bound `subtitle_style` template sets both |
50
54
  | 整理 / index | `--no-consolidate` / `--consolidate-asr` | on | build the understanding index (and optionally clean ASR); use `--no-consolidate` to skip |
51
55
  | Advisory / strict narration review | `REVIEW_NARRATION` / `--review-narration` / `--no-review-narration`; strict: `REQUIRE_NARRATION_REVIEW` / `--require-narration-review` | advisory on, strict off | runs the narration review stage after validation and before TTS. Default advisory mode is fail-open; strict mode blocks TTS on review failure, parse error, or error-severity findings. In cut mode the reviewer uses `clip_plan_validated.json` to remap VLM/ASR grounding onto the output timeline |
52
56
  | 剪映 export (optional) | `--export-jianying` / `EXPORT_JIANYING` | off | after rendering, also write a 剪映/JianYing draft from `timeline.json`. Decoupled — the core render never needs it |
@@ -106,14 +106,13 @@
106
106
  {
107
107
  "schema_version": 2,
108
108
  "timeline": "cut_output",
109
- "clip_plan_fingerprint": "md5-of-canonical-clip-plan",
110
109
  "sentence_anchors": [{"time": 4.0, "pause_start": 3.8, "confidence": "high"}],
111
110
  "speech_spans": [{"start": 0.0, "end": 3.8}],
112
111
  "quiet_windows": [{"start": 3.8, "end": 4.1}]
113
112
  }
114
113
  ```
115
114
 
116
- `clip_plan_fingerprint` 必须与当前 `clip_plan_validated.json` 一致。缺失、过期或畸形的
115
+ 该文件必须不早于当前 `clip_plan_validated.json`(按修改时间判断)。缺失、过期或畸形的
117
116
  output 证据一律 fail closed,不能回退到原片时钟或信任 Agent 写入的
118
117
  `overlaps_speech=false`。多来源剪辑的每条映射记录还保留 `source_id` 和原片起止时间。
119
118
 
@@ -143,7 +142,7 @@ output 证据一律 fail closed,不能回退到原片时钟或信任 Agent 写
143
142
 
144
143
  ## narration.json
145
144
 
146
- Agent 撰写的解说词。full 模式下使用原视频时间;**orchestrated cut 模式(`video-recap --edit-mode cut`)下,第二次暂停时已经先剪出 `edited_source.mp4`,因此 `narration.json` 必须直接使用剪后成片的 OUTPUT 时间轴(0..成片总时长),不会再生成或消费 `narration_mapped.json`。只有 legacy direct `video-cut` 单 pass 路径才会把原视频时间的 narration remap 成 `narration_mapped.json`:
145
+ Agent 撰写的解说词。full 模式下使用原视频时间;**orchestrated cut 模式(`video-recap --edit-mode cut`)下,第二次暂停时已经先剪出 `edited_source.mp4`,因此 `narration.json` 必须直接使用剪后成片的 OUTPUT 时间轴(0..成片总时长);不存在原视频时间→输出时间的旁白映射产物:
147
146
 
148
147
  ```json
149
148
  [
@@ -181,7 +180,7 @@ Agent 撰写的解说词。full 模式下使用原视频时间;**orchestrated
181
180
 
182
181
  ## recap_story_plan.json / visual_audio_board.json(Agent 创作工作产物)
183
182
 
184
- 这两个 JSON 是 skill 层的创作决策记录:前者保存导演意图、备选剪辑假设、POV/主线和 change-based beats;后者保存每拍的画面/表演选择、入点/出点、原声锚点、`audio_owner` 与 `narration_job`。完整字段与工作流见本技能的 `creative-editing-playbook.md`。
183
+ 这两个 JSON 是 skill 层的创作决策记录:前者保存导演意图、备选剪辑假设、POV/主线和 change-based beats;后者保存每拍的画面/表演选择、入点/出点、原声锚点、`audio_owner` 与 `narration_job`。完整字段与工作流见 video-script 技能的 `creative-editing-playbook.md`。
185
184
 
186
185
  CLI 不以它们作为渲染硬门禁,也不新增解析服务;建议型解说评审在文件存在时读取它们,Agent 则用它们保证 cut、旁白和声音选择没有偏离同一个创作意图。
187
186
 
@@ -264,19 +263,19 @@ CLI 不以它们作为渲染硬门禁,也不新增解析服务;建议型解
264
263
 
265
264
  ## multi_source_manifest.json(多视频 cut)
266
265
 
267
- 多视频剪辑模式下,项目级 `work_dir/multi_source_manifest.json` 是编排、剪辑与合成阶段共用的来源契约。`source_id` 默认由源文件 SHA-256 派生为 `src_<fingerprint[:12]>`;同一项目里重复 fingerprint 的不同路径会追加短 path hash 后缀。
266
+ 多视频剪辑模式下,项目级 `work_dir/multi_source_manifest.json` 是编排、剪辑与合成阶段共用的来源契约。`source_id` 由源文件名主干与文件大小派生为 `src_<stem>_<size>`;同一项目里得到相同 id 的后续来源按输入顺序追加 `_2`、`_3` 后缀。`source_video_identity` 记录该文件的 `{size, mtime_ns}`,续跑时与当前输入逐项比对。
268
267
 
269
268
  ```json
270
269
  {
271
270
  "schema_version": 1,
272
271
  "sources": [
273
272
  {
274
- "source_id": "src_0123456789ab",
273
+ "source_id": "src_episode1_734003200",
275
274
  "source_path": "/abs/episode1.mp4",
276
275
  "source_name": "episode1.mp4",
277
- "source_video_fingerprint": "0123456789abcdef...",
278
- "source_work_dir": "sources/src_0123456789ab",
279
- "material_id": "episode1-0123456789ab"
276
+ "source_video_identity": {"size": 734003200, "mtime_ns": 1758326400000000000},
277
+ "source_work_dir": "sources/src_episode1_734003200",
278
+ "material_id": "episode1-734003200"
280
279
  }
281
280
  ]
282
281
  }
@@ -307,8 +306,8 @@ cut 模式下 Agent 选择要保留的原片片段,数组或 `{ "clips": [...]
307
306
  {
308
307
  "target_duration": "10m",
309
308
  "clips": [
310
- {"source_id": "src_0123456789ab", "start": 12.0, "end": 38.0, "reason": "b01 | setup | knowledge: unknown→clue | POV=主角 | 保留迟疑反应 | 入点=线索出现 | 出点=疑问成立"},
311
- {"source_id": "src_fedcba987654", "start": 4.0, "end": 22.0, "reason": "b02 | payoff | power: suspect→hero | POV=主角 | 保留最终选择 | 入点=证据落下 | 出点=代价显现"}
309
+ {"source_id": "src_episode1_734003200", "start": 12.0, "end": 38.0, "reason": "b01 | setup | knowledge: unknown→clue | POV=主角 | 保留迟疑反应 | 入点=线索出现 | 出点=疑问成立"},
310
+ {"source_id": "src_episode2_689110016", "start": 4.0, "end": 22.0, "reason": "b02 | payoff | power: suspect→hero | POV=主角 | 保留最终选择 | 入点=证据落下 | 出点=代价显现"}
312
311
  ]
313
312
  }
314
313
  ```
@@ -347,7 +346,7 @@ CLI 校验 `clip_plan.json` 后写出,额外包含输出时间轴:
347
346
  "clips": [
348
347
  {
349
348
  "clip_id": 0,
350
- "source_id": "src_0123456789ab",
349
+ "source_id": "src_episode1_734003200",
351
350
  "source_path": "/abs/episode1.mp4",
352
351
  "source_start": 12.0,
353
352
  "source_end": 38.0,
@@ -362,7 +361,7 @@ CLI 校验 `clip_plan.json` 后写出,额外包含输出时间轴:
362
361
 
363
362
  ## material library(可选,grep 复用)
364
363
 
365
- `--material-library-dir <dir> --save-materials` 会把每个源视频的已分析小文件复制到 `<dir>/materials/<material_id>/`,不复制原始媒体。`--use-materials` 会在 fingerprint 和 settings fingerprint 匹配时把这些 JSON/MD 产物恢复到当前 per-source `work_dir`。
364
+ `--material-library-dir <dir> --save-materials` 会把每个源视频的已分析小文件复制到 `<dir>/materials/<material_id>/`,不复制原始媒体。`--use-materials` 会在源文件路径、`source_video_identity`(`{size, mtime_ns}`)和分析 `settings` 都相等时把这些 JSON/MD 产物恢复到当前 per-source `work_dir`。
366
365
 
367
366
  ```text
368
367
  .video-materials/
@@ -377,27 +376,10 @@ CLI 校验 `clip_plan.json` 后写出,额外包含输出时间轴:
377
376
  artifacts/understanding_index.json
378
377
  ```
379
378
 
380
- `materials_index.jsonl` 每次保存追加一行,字段包括 `schema_version`, `event`, `material_id`, `source_name`, `source_path`, `source_video_fingerprint`, `settings_fingerprint`, `summary`, `tags`, `material_dir`, `updated_at`。当前权威状态始终以 `materials/<material_id>/material.json` 为准。MVP 只承诺 `grep -R "关键词" <library>` 这类文件检索;没有 DB、embedding 或语义搜索。
379
+ `materials_index.jsonl` 每次保存追加一行,字段包括 `schema_version`, `event`, `material_id`, `source_name`, `source_path`, `source_video_identity`, `summary`, `tags`, `material_dir`, `updated_at`;`material.json` 另外记录分析 `settings` 字典与每个产物的 `bytes`。当前权威状态始终以 `materials/<material_id>/material.json` 为准。MVP 只承诺 `grep -R "关键词" <library>` 这类文件检索;没有 DB、embedding 或语义搜索。
381
380
 
382
381
  保存时会对凭证形态(`tp-`/`sk-`/`gh*_`/`AKIA`/JWT 与 `KEY=VALUE` 赋值)和凭证命名的 JSON key 做脱敏,但这只是**尽力而为**的兜底,不是保证:陌生格式的密钥仍可能漏过。请从源头避免把密钥写进分析产物——key 从环境变量/`.env` 读取,不需要落进 scenes/ASR/VLM/summary 等 JSON。
383
382
 
384
- ## narration_mapped.json
385
-
386
- 仅 legacy direct `video-cut` 单 pass 路径会生成。orchestrated cut 模式不使用它:Agent 在 pass2 直接按剪后成片 OUTPUT 时间轴写 `narration.json`。当 legacy 路径启用时,`start/end` 已变成短视频输出时间,`source_start/source_end` 保留原视频时间:
387
-
388
- ```json
389
- [
390
- {
391
- "start": 2.0,
392
- "end": 7.0,
393
- "source_start": 14.0,
394
- "source_end": 19.0,
395
- "source_clip_id": 0,
396
- "narration": "解说文本"
397
- }
398
- ]
399
- ```
400
-
401
383
  ## original_subtitles.json / user_subtitles.{json,srt,ass}(可选,原声留白字幕)
402
384
 
403
385
  解说块之间的原声留白会把【原声台词】烧成字幕(assemble 阶段用 `「」` 包裹以区分解说)。来源优先级(高→低):
@@ -484,6 +466,35 @@ CLI 校验 `clip_plan.json` 后写出,额外包含输出时间轴:
484
466
 
485
467
  > 正常(无失败)运行也会带 `"partial": false, "failures": []`。partial 成片只适合预览,不建议直接发布。
486
468
 
469
+ `voice` 记录本次实际使用的音色:`{"provider": "mimo-tts", "model": "mimo-v2.5-tts", "voice_id": "冰糖", "reference": null}`。
470
+ 用参考音频克隆时 `voice_id` 为 `null`,`reference` 为 `{path, size, mtime_ns}`;Fish Audio 的 `voice_id` 是 reference id,
471
+ index-tts 的是 `INDEX_TTS_VOICE`。旧 `tts_meta.json` 没有这个字段时按只知道 `engine` 处理。
472
+
473
+ ## resource_lock.json(本次运行用到的资源)
474
+
475
+ full / cut 流程(含本地采用路径)合成完成后,video-recap 在 `work_dir` 写出 `resource_lock.json`,汇总运行清单、
476
+ `tts_meta.json.voice` 与 `assembly_manifest.json`(BGM 路径、字幕字体)里已有的事实;配置了资源库时,按解析后的路径
477
+ (音色按 provider + voice_id)把每项对上已登记的资源,带出授权与声音授权状态。dub 模式不写。
478
+
479
+ ```json
480
+ {
481
+ "schema": "video-recap.resource-lock.v1",
482
+ "work_dir": "/abs/work_dir",
483
+ "library": "/abs/library",
484
+ "project": null,
485
+ "templates": [],
486
+ "resources": [
487
+ {"role": "bgm", "path": "/abs/library/resources/bgm/pulse-demo/pulse-demo.wav", "size": 8044, "mtime_ns": 1,
488
+ "detail": {}, "library": {"id": "pulse-demo", "kind": "bgm", "license": "owned", "consent": null}}
489
+ ],
490
+ "attention": [{"code": "license_unknown", "role": "voice", "message": "…"}]
491
+ }
492
+ ```
493
+
494
+ `role` ∈ `source_video` / `voice` / `bgm` / `subtitle_font`(项目绑定后还会有模板引入的资源)。`attention` 列出需要人确认的项:
495
+ `license_unknown` / `license_restricted`、参考音频的 `consent_unknown` / `consent_denied`,以及配置了资源库但没有登记的
496
+ `unregistered`。它只提示、不阻断;`final_qc.json` 只承载阻断项,不包含这些提示。
497
+
487
498
  组装后,`assembly_manifest.json.audio_segments[]` 另外记录 `fit_status`、`truncated`、
488
499
  `truncate_reason`、`placed_audio_duration`、`placed_audio_path`、`source_duck_end`、
489
500
  `source_restore_at` 与 `source_handoff_status`。组装阶段从不按时间裁旁白尾音:放不下时用
@@ -496,7 +507,7 @@ CLI 校验 `clip_plan.json` 后写出,额外包含输出时间轴:
496
507
 
497
508
  Dub 模式下,`dub_script.json` 在 voiceclone **之前**先经过 deterministic lint,把明显不可发布的脚本挡在昂贵的克隆 TTS 之前。空译文、相邻行重叠、时间越界、`room < 0.4s` 等 **error** 会 `verdict=FAIL` 并阻断 render;`fast_speech`、`trim_risk` 等是 warning,不阻断。
498
509
 
499
- 每行 voiceclone 原始 WAV 会按模型、合成提示、中文台词和参考音频 SHA-256 写入相邻的 `*.wav.meta.json`。指纹完全匹配且 WAV 可读取时,dub render 直接复用并在 `dub_manifest.json.lines[].tts_cache` 记录 `hit`;台词、参考音频、模型或提示变化都会自动失效并重新合成。
510
+ 每行 voiceclone 原始 WAV 会把中文台词、模型/提示等合成设置和参考音频信息写入相邻的 `*.wav.meta.json`。台词与设置完全相等且 WAV 可读取时,dub render 直接复用并在 `dub_manifest.json.lines[].tts_cache` 记录 `hit`;台词、参考音频、模型或提示变化都会重新合成。
500
511
 
501
512
  ```json
502
513
  {
@@ -527,7 +538,7 @@ Dub 模式下,`dub_script.json` 在 voiceclone **之前**先经过 determinist
527
538
 
528
539
  `preflight_qc.json`、`final_qc.json`、`golden_eval.json`、`mimo_qc.json` 共用最小 QC 契约;stage 仅允许 `pre_cut` / `post_cut` / `pre_tts` / `post_tts` / `pre_assemble` / `post_render` / `golden`,其中 `mimo_qc.json` 是 artifact 而不是 stage。详见 `shift-left-qc-schema.md`。
529
540
 
530
- `recap.py` 可通过 `--mimo-qc pre-assemble|post-render|both`(默认 `off`)在组装前和/或成片后写 `mimo_qc.json`。每个 stage 最多一次 live request;相同素材/模型命中内容缓存,`--mimo-qc-refresh` 可刷新。`post_render` 最多临时抽取 6 张、最长边 768px 的 JPEG;base64 只进入请求,不写进 artifact。多 stage 报告聚合在 `metadata.stages`,状态为 `completed` / `cached` / `unavailable` / `failed`,任何状态都不阻断、也不自动修复。关闭功能会清理旧 `mimo_qc.json`,避免陈旧建议被误认为本轮结果。
541
+ `recap.py` 可通过 `--mimo-qc pre-assemble|post-render|both`(默认 `off`)在组装前和/或成片后写 `mimo_qc.json`。每个 stage 最多一次 live request;报告的 `metadata.cache_input`(证据文件的 kind/bytes/mtime_ns、模型、提示与抽帧元数据)与本次完全相等时复用上次结果,`--mimo-qc-refresh` 可刷新。`post_render` 最多临时抽取 6 张、最长边 768px 的 JPEG;base64 只进入请求,不写进 artifact。多 stage 报告聚合在 `metadata.stages`,状态为 `completed` / `cached` / `unavailable` / `failed`,任何状态都不阻断、也不自动修复。关闭功能会清理旧 `mimo_qc.json`,避免陈旧建议被误认为本轮结果。
531
542
 
532
543
  QC 证据把 `source_asr` 与 `generated_subtitles` 分开:前者只用于源事实/原声时序,后者是本轮旁白派生字幕,不能反过来充当事实证据。多视频项目从 `multi_source_manifest.json` 指向的逐源 work dir 汇集 ASR;`cut_output` 解说评审同样按 `source_id` 映射逐源 VLM/ASR,避免项目根目录没有单一 ASR 文件时产生空证据。
533
544