@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
@@ -15,7 +15,9 @@ from pathlib import Path
15
15
  sys.path.insert(0, str(Path(__file__).resolve().parent))
16
16
 
17
17
  from edit_tool import ( # noqa: E402
18
+ _unaccounted_shots,
18
19
  DEFAULT_REMOTION_CONCURRENCY,
20
+ DisplayCue,
19
21
  REMOTION_SOURCE,
20
22
  REMOTION_SOURCE_FILES,
21
23
  EditError,
@@ -101,7 +103,7 @@ def check_subtitle_geometry() -> None:
101
103
  """
102
104
 
103
105
  width, height = 768, 1344
104
- ass = _build_ass([(1.0, 2.0, "这条路我自己走")], width, height)
106
+ ass = _build_ass([DisplayCue(1.0, 2.0, "这条路我自己走")], width, height)
105
107
  require(f"PlayResX: {width}" in ass, "PlayResX 必须等于画面宽")
106
108
  require(f"PlayResY: {height}" in ass, "PlayResY 必须等于画面高")
107
109
  style = next(line for line in ass.splitlines() if line.startswith("Style:"))
@@ -112,7 +114,12 @@ def check_subtitle_geometry() -> None:
112
114
  f"字号 {font_size} 不在画面高度的 2%–6% 之间",
113
115
  )
114
116
  margin_v = float(fields[21])
115
- require(margin_v < height * 0.2, f"底边距 {margin_v} 会把字幕推离安全区")
117
+ # The baseline sits about a quarter up, above the platform's own bottom UI;
118
+ # much higher and the line lands on faces.
119
+ require(
120
+ height * 0.15 < margin_v < height * 0.3,
121
+ f"底边距 {margin_v} 不在画面高度的 15%–30% 之间",
122
+ )
116
123
  margin_h = float(fields[19])
117
124
  require(margin_h > 0, "左右边距为 0 时长句会顶到画面边缘")
118
125
  require("这条路我自己走" in ass, "台词原文必须原样进 ASS")
@@ -147,18 +154,17 @@ def check_subtitle_timing() -> None:
147
154
 
148
155
 
149
156
  def check_shot_match() -> None:
150
- """A declared correction is applied; an undeclared one never is.
157
+ """A stated correction becomes its own filter chain, within the tool's ranges.
151
158
 
152
- Generated shots drift a stop apart, so the join reads as a mistake. The
153
- correction has to be visible in the document — a tool that measured clips
154
- and adjusted them on its own would be changing pictures nobody could review.
159
+ Generated shots drift a stop apart, so the join reads as a mistake. What a
160
+ cut states in 「画面」 replaces the automatic within-scene match for that cut.
155
161
  """
156
162
 
157
163
  with tempfile.TemporaryDirectory() as scratch:
158
164
  root = Path(scratch)
159
165
  episode = build(root, CUT_LIST)
160
166
  _, cuts, _ = parse_cut_list(episode / "剪辑单.md")
161
- require(_shot_match_filter(cuts[0]) == "", "没写画面的段不得被改动")
167
+ require(_shot_match_filter(cuts[0]) == "", "没写画面的段没有自己的校正")
162
168
 
163
169
  listed = CUT_LIST.replace(
164
170
  "- 声音:保留原声\n- 字幕:无",
@@ -340,7 +346,7 @@ def check_ass_escaping() -> None:
340
346
  escaped = _ass_text(line)
341
347
  require("\\{" in escaped and "\\}" in escaped, f"花括号没有转义: {escaped}")
342
348
  require("姓名" in escaped, "转义把字弄丢了")
343
- ass = _build_ass([(1.0, 2.0, line)], 1080, 1920)
349
+ ass = _build_ass([DisplayCue(1.0, 2.0, line)], 1080, 1920)
344
350
  dialogue = [row for row in ass.splitlines() if row.startswith("Dialogue")][0]
345
351
  require(dialogue.endswith(escaped), f"Dialogue 行没有用转义后的正文: {dialogue}")
346
352
  require(
@@ -361,7 +367,7 @@ def check_remotion_sources_all_shipped() -> None:
361
367
  path.relative_to(REMOTION_SOURCE).as_posix()
362
368
  for path in REMOTION_SOURCE.rglob("*")
363
369
  if path.is_file()
364
- and path.suffix in {".ts", ".tsx", ".json"}
370
+ and path.suffix in {".ts", ".tsx", ".mjs", ".json"}
365
371
  and "node_modules" not in path.parts
366
372
  }
367
373
  listed = set(REMOTION_SOURCE_FILES)
@@ -377,6 +383,101 @@ def check_remotion_concurrency_is_capped() -> None:
377
383
  require("--concurrency=" in source, "render 必须显式传 --concurrency,不能用 Remotion 的默认值")
378
384
 
379
385
 
386
+ def check_grain_is_a_delivery_wide_decision() -> None:
387
+ """Grain is declared once for the film, and refused when it is not grain.
388
+
389
+ Per cut it would become one more thing that differs between segments, which
390
+ is the defect it exists to cover.
391
+ """
392
+
393
+ with tempfile.TemporaryDirectory() as scratch:
394
+ root = Path(scratch)
395
+ episode = build(root, CUT_LIST)
396
+ path = episode / "剪辑单.md"
397
+ baseline = path.read_text(encoding="utf-8")
398
+
399
+ delivery, _, _ = parse_cut_list(path)
400
+ require(delivery.grain is None, "没声明颗粒时应当是 None")
401
+
402
+ anchor = "- 交付响度:"
403
+ require(anchor in baseline, "夹具里应当有交付响度那一行")
404
+ path.write_text(baseline.replace(anchor, "- 颗粒:6\n" + anchor, 1), encoding="utf-8")
405
+ delivery, _, _ = parse_cut_list(path)
406
+ require(delivery.grain == 6.0, f"颗粒没有解析出来: {delivery.grain}")
407
+
408
+ path.write_text(baseline.replace(anchor, "- 颗粒:无\n" + anchor, 1), encoding="utf-8")
409
+ delivery, _, _ = parse_cut_list(path)
410
+ require(delivery.grain is None, "「无」应当解析成不加颗粒")
411
+
412
+ path.write_text(baseline.replace(anchor, "- 颗粒:80\n" + anchor, 1), encoding="utf-8")
413
+ try:
414
+ parse_cut_list(path)
415
+ except EditError as error:
416
+ require("超出" in str(error), f"越界报错没说清: {error}")
417
+ else:
418
+ raise AssertionError("颗粒 80 应当被拒绝")
419
+
420
+
421
+ def check_missing_shots_are_reported() -> None:
422
+ """A shot absent from the film must be absent on purpose.
423
+
424
+ Absence is invisible in a finished film — nobody watching can tell that an
425
+ episode's opening seven shots were never made. The only place it can be
426
+ caught is here, against the document that lists them.
427
+ """
428
+
429
+ known = {f"MOTION-EP006-{i:03d}" for i in range(1, 5)}
430
+
431
+ class Stub:
432
+ def __init__(self, motion): self.motion = motion
433
+
434
+ used = [Stub("MOTION-EP006-003"), Stub("MOTION-EP006-004")]
435
+ findings = _unaccounted_shots(known, used, [])
436
+ require(findings, "少了两镜却没有任何 finding")
437
+ require("001" in findings[0] and "002" in findings[0], f"没点名缺的镜头: {findings}")
438
+
439
+ excused = _unaccounted_shots(
440
+ known, used, ["MOTION-EP006-001(理由:质量不可用)", "MOTION-EP006-002(理由:文件缺失)"]
441
+ )
442
+ require(not excused, f"写进未采用的镜头不该再报: {excused}")
443
+
444
+ require(not _unaccounted_shots(known, [Stub(m) for m in known], []), "全采用时不该报")
445
+
446
+
447
+ def check_screen_text_and_effects() -> None:
448
+ """Screen text is traced to [画面文字] lines; effects are held to their cut."""
449
+
450
+ with tempfile.TemporaryDirectory() as scratch:
451
+ root = Path(scratch)
452
+ episode = build(root, CUT_LIST)
453
+ (episode / "剧本.md").write_text(
454
+ SCREENPLAY + "\n[画面文字] 剩余 4 天 23:59:58\n", encoding="utf-8"
455
+ )
456
+ (episode / "media" / "chime.wav").write_bytes(b"")
457
+ anchor = "- 字幕:这条路我自己走"
458
+ require(anchor in CUT_LIST, "夹具里应当有一条台词字幕")
459
+ lines = (
460
+ "- 画面文字 1:0.00-1.00 任务面板 剩余(倒计时:431998)\n"
461
+ "- 画面文字 2:1.00-2.00 角标 剩余(倒计时:接续)\n"
462
+ "- 音效:0.00-0.50 media/chime.wav(增益:-10)"
463
+ )
464
+ (episode / "剪辑单.md").write_text(
465
+ CUT_LIST.replace(anchor, anchor + "\n" + lines), encoding="utf-8"
466
+ )
467
+ _, cuts, _ = parse_cut_list(episode / "剪辑单.md")
468
+ require(len(cuts[1].screen_texts) == 2, "两条画面文字应全部解析")
469
+ require(len(cuts[1].sound_effects) == 1, "音效应当解析")
470
+ require(not check_cuts(episode, cuts, root, probe=False), "合法的画面文字与音效不该报错")
471
+
472
+ (episode / "剪辑单.md").write_text(
473
+ CUT_LIST.replace(anchor, anchor + "\n- 画面文字:0.00-1.00 卡片 剩余 5 天"),
474
+ encoding="utf-8",
475
+ )
476
+ _, cuts, _ = parse_cut_list(episode / "剪辑单.md")
477
+ findings = check_cuts(episode, cuts, root, probe=False)
478
+ require(any("[画面文字]" in item for item in findings), f"编造的画面文字没抓到: {findings}")
479
+
480
+
380
481
  def main() -> int:
381
482
  with tempfile.TemporaryDirectory() as scratch:
382
483
  root = Path(scratch)
@@ -445,7 +546,10 @@ def main() -> int:
445
546
  check_shot_match()
446
547
  check_ass_escaping()
447
548
  check_multi_subtitle()
549
+ check_screen_text_and_effects()
448
550
  check_stale_window()
551
+ check_missing_shots_are_reported()
552
+ check_grain_is_a_delivery_wide_decision()
449
553
  check_remotion_sources_all_shipped()
450
554
  check_remotion_concurrency_is_capped()
451
555
  print("short-drama-edit self-tests passed")
@@ -20,6 +20,8 @@ license: MIT
20
20
 
21
21
  有当前视觉设定即可直接开始;剧本只在提示词需要确认剧情状态时读取。Look Development 是可选分支。
22
22
  先确认用途:身份板、造型/状态变体、地点板、道具板、组合 production sheet 或比较风格帧。
23
+ 分镜需要生产尾帧时,可把已接受的「收尾关键帧提示词」落实为独立 `IMG-...` 状态图条目:
24
+ 说明来源 SHOT 与终点,沿用视觉事实和参考范围,不重新设计动作。实际生成以该 IMG 条目为来源。
23
25
 
24
26
  创作者可读说明跟随项目语言;可复制正文跟随 `short-drama.json#/format/prompt_language`。没有
25
27
  `short-drama.json` 时正文默认
@@ -203,6 +203,17 @@
203
203
  - **`taste_option`**:写实度、媒介、颗粒、色调和镜头感由视觉风格或创作者决定。
204
204
  - 禁止用固定词表或形容词比例阻断交付;描述是否空泛,由审查者指出具体缺了什么。
205
205
 
206
+ ### 光学与表面描述
207
+
208
+ **`craft_default`**:对需要明确透视或写实质感的画面,写明机位、取景距离和可见表面特征。
209
+ 焦段可辅助表达,但不能据此承诺模型会精确模拟光学。
210
+
211
+ 根据画面尺度选择毛孔、布料折痕或金属使用痕迹;「干净」不必等同于没有任何纹理和折痕。
212
+ 不要给每张图添加相同的相机参数、瑕疵清单或排除词。
213
+
214
+ **`taste_option`**:表面是否平滑、是否修饰,以及写实程度由已接受的视觉风格决定。
215
+ 结果用对照图检查;像素纹理指标只作辅助,不能代替人物与材质的视觉判断。
216
+
206
217
  ## 5. 输出、常见问题与检查
207
218
 
208
219
  ### 输出
@@ -170,7 +170,7 @@ python3 {技能目录}/scripts/novel_index.py coverage \
170
170
 
171
171
  - `story-units.md`:把情节点归成有始有终的单元,每个单元记录进入状态、冲突、代价与出去状态;
172
172
  - `rhythm-and-emotion.md`:关键信息如何逐章推进、情绪触动点的铺垫→释放→余波、
173
- 跨章伏笔与兑现。
173
+ 跨章伏笔与兑现,以及按观众收益排名的爽点表。
174
174
 
175
175
  聚合完成后跑同一文件里的三条阈值自检(归属置信、覆盖率、重叠率)与散落情节兜底。
176
176
  阈值不是评分,是**边界模糊的信号**:重叠率过高说明两个单元其实是一个。
@@ -192,8 +192,8 @@ python3 {技能目录}/scripts/novel_index.py coverage \
192
192
 
193
193
  - `adaptation-value.md`:哪些单元在竖屏短剧里能直接成立、哪些要换载体、哪些是纯文字快感
194
194
  (内心戏、叙述性诡计、长铺垫)在画面上无法兑现;制作负担落在哪里。
195
- - `episode-candidates.jsonl`:按**局部戏剧结果与精确交接**切出的候选集,不按章号或字数
196
- 平均切。每条带来源 span、承担的功能、以及未决项。
195
+ - `episode-candidates.jsonl`:按**爽点分布、局部戏剧结果与精确交接**切出的候选集,不按章号
196
+ 或字数平均切。每条带来源 span、承担的功能、承接的爽点以及未决项。
197
197
 
198
198
  同时**回填快评**:S1 的哪几条判断被全量结果推翻了,写进 `adaptation-value.md` 的开头。
199
199
  一个抽样结论被证伪,比它被悄悄忘掉有用得多——下一本书的快评会因此更准。
@@ -1,3 +1,3 @@
1
1
  {"record_type":"sources","schema_version":"1.0.0","sources":{"index":{"owner":"short-drama-novel-analyze","artifact":"项目开发/source-analysis/_index.json"},"original-source":{"owner":"creator","artifact":"输入/original-source.txt"}}}
2
- {"example_only":true,"destination":"项目开发/source-analysis/episode-candidates.jsonl","schema_version":"1.0.0-draft","record_type":"episode_candidate","candidate_id":"NVA-EPC-EXAMPLE-001","status":"candidate","source_ref":{"src":"original-source"},"index_ref":{"src":"index"},"story_units":["UNIT-EXAMPLE-03"],"chapter_range":{"sequence_start":14,"sequence_end":19},"screen_judgement":"needs_carrier","trope_tags":["信息差","反转打脸"],"entering_knowledge":"观众已知两人共用一份旧证据,但不知道其中一人已经改过它","promise_paid":"改动被第三方当场指出,怀疑从猜测变成具体指控","exit_pressure":"被指控者必须在下一次公开场合前决定认或不认","inherited_facts":["改动过的证据仍在对方手里","两人的合作关系尚未破裂"],"preserved_functions":["关系压力","信息不对称"],"carrier_change":{"original_carrier":"长段内心权衡","new_carrier":"第三方当众比对两份文件的可见动作","lost_or_changed":["读者原本先于角色知道改动,改编后观众与角色同时知道"]},"production_load":{"distinct_locations":2,"characters_in_frame":3,"readable_text_required":true,"notes":"证据文件的可读文字需与美术确认"},"unresolved":["第三方的立场在原文中前后不一致,待创作者裁定"],"creator_acceptance":{"status":"pending","decision_ref":null}}
3
- {"example_only":true,"destination":"项目开发/source-analysis/episode-candidates.jsonl","schema_version":"1.0.0-draft","record_type":"episode_candidate","candidate_id":"NVA-EPC-EXAMPLE-002","status":"candidate","source_ref":{"src":"original-source"},"index_ref":{"src":"index"},"story_units":["UNIT-EXAMPLE-04"],"chapter_range":{"sequence_start":20,"sequence_end":22},"screen_judgement":"screen_ready","trope_tags":["打脸"],"entering_knowledge":"观众已知指控成立,不知道被指控者手里还有一份未公开的记录","promise_paid":"记录被主动交出,代价是失去唯一的退路","exit_pressure":"退路没了,对手却仍未出手","inherited_facts":["记录已进入公开视野"],"preserved_functions":["代价","权力转移"],"carrier_change":null,"production_load":{"distinct_locations":1,"characters_in_frame":2,"readable_text_required":false,"notes":null},"unresolved":[],"creator_acceptance":{"status":"pending","decision_ref":null}}
2
+ {"example_only":true,"destination":"项目开发/source-analysis/episode-candidates.jsonl","schema_version":"1.0.0-draft","record_type":"episode_candidate","candidate_id":"NVA-EPC-EXAMPLE-001","status":"candidate","source_ref":{"src":"original-source"},"index_ref":{"src":"index"},"story_units":["UNIT-EXAMPLE-03"],"chapter_range":{"sequence_start":14,"sequence_end":19},"screen_judgement":"needs_carrier","trope_tags":["信息差","反转打脸"],"payoffs":["PAY-EXAMPLE-07"],"entering_knowledge":"观众已知两人共用一份旧证据,但不知道其中一人已经改过它","promise_paid":"改动被第三方当场指出,怀疑从猜测变成具体指控","exit_pressure":"被指控者必须在下一次公开场合前决定认或不认","inherited_facts":["改动过的证据仍在对方手里","两人的合作关系尚未破裂"],"preserved_functions":["关系压力","信息不对称"],"carrier_change":{"original_carrier":"长段内心权衡","new_carrier":"第三方当众比对两份文件的可见动作","lost_or_changed":["读者原本先于角色知道改动,改编后观众与角色同时知道"]},"production_load":{"distinct_locations":2,"characters_in_frame":3,"readable_text_required":true,"notes":"证据文件的可读文字需与美术确认"},"unresolved":["第三方的立场在原文中前后不一致,待创作者裁定"],"creator_acceptance":{"status":"pending","decision_ref":null}}
3
+ {"example_only":true,"destination":"项目开发/source-analysis/episode-candidates.jsonl","schema_version":"1.0.0-draft","record_type":"episode_candidate","candidate_id":"NVA-EPC-EXAMPLE-002","status":"candidate","source_ref":{"src":"original-source"},"index_ref":{"src":"index"},"story_units":["UNIT-EXAMPLE-04"],"chapter_range":{"sequence_start":20,"sequence_end":22},"screen_judgement":"screen_ready","trope_tags":["打脸"],"payoffs":["PAY-EXAMPLE-02"],"entering_knowledge":"观众已知指控成立,不知道被指控者手里还有一份未公开的记录","promise_paid":"记录被主动交出,代价是失去唯一的退路","exit_pressure":"退路没了,对手却仍未出手","inherited_facts":["记录已进入公开视野"],"preserved_functions":["代价","权力转移"],"carrier_change":null,"production_load":{"distinct_locations":1,"characters_in_frame":2,"readable_text_required":false,"notes":null},"unresolved":[],"creator_acceptance":{"status":"pending","decision_ref":null}}
@@ -83,14 +83,18 @@ python3 {技能目录}/scripts/novel_index.py sample \
83
83
 
84
84
  回答一个问题:**如果这本书改成短剧,第 1 集从哪里开始**?
85
85
 
86
- 找**第一个可见的、有代价的、当场发生的转折**——主角第一次做出会付出代价的选择,
87
- 且这个选择能被拍出来而不是被想出来。它通常不在第一章。写清三条:
86
+ 找**观众在此处收益最强、且能同时交代主角身份、眼前危机与目标的一处**:打脸、奇观、
87
+ 反转、身份揭露、奖励兑现或危机爆发,能被拍出来而不是被想出来。兑现它的可以是旁观者——
88
+ 群体改口、对手当众吃瘪,收益照样落在观众身上。它通常不在第一章,也常常不是时间上最早的那个
89
+ 爽点:后文的高潮可以提前做冷开。写清四条:
88
90
 
89
- - 落在第几章(用索引的 `sequence`);
91
+ - 落在第几章(用索引的 `sequence`),收益类型是什么;
92
+ - 抽样里若另有更晚、更强的高光,一并写出,它是冷开候选;
90
93
  - 它之前的内容里,哪些是观众必须知道的,可以怎样在开场后补进去;
91
94
  - 哪些是原著读者需要、短剧观众不需要的。
92
95
 
93
- 抽样里没有这样的转折时,写「抽样内未见可用的开篇替换点」,并列进第 5 段的风险。
96
+ 抽样里没有这样的一处时,写「抽样内未见可用的开篇替换点」,并列进第 5 段的风险。
97
+ 全量拆解后,S3 的爽点表会给出完整排名,S5 回填时拿它对照这里的判断。
94
98
 
95
99
  ## 结论限于抽样范围
96
100
 
@@ -76,7 +76,13 @@
76
76
 
77
77
  ## 分集候选
78
78
 
79
- 按**局部戏剧结果与精确交接**切,不按章号、字数或平均分配。一个候选集必须能回答:
79
+ 按**爽点分布、局部戏剧结果与精确交接**切,不按章号、字数或平均分配。先读
80
+ [爽点表](aggregation-and-entities.md#爽点表):候选集的边界跟着爽点走,没有爽点的长间隔
81
+ 并进相邻候选或标为可删,而不是单独成集;排名靠前、落在后文的高光写进交接摘要,
82
+ 由 `$short-drama-develop` 决定是否提前或做冷开。章与集不是 1:1——一章撑不起一集时合并,
83
+ 一章里有两个大爽点时可以拆。
84
+
85
+ 一个候选集必须能回答:
80
86
 
81
87
  1. 进入时观众已经知道什么;
82
88
  2. 本集内兑现了哪一部分承诺(不能一条都不兑现);
@@ -87,7 +93,8 @@
87
93
 
88
94
  每条候选写进 `episode-candidates.jsonl`,字段见
89
95
  [分集候选样例](../assets/episode-candidate.example.jsonl)。每条都带:来源单元与章号区间、
90
- 承担的功能、判定类别、桥段标签、未决项、以及 `creator_acceptance: pending`。
96
+ 承担的功能、判定类别、桥段标签、承接的爽点(`payoffs`,没有就写空并说明这一集靠什么留人)、
97
+ 未决项、以及 `creator_acceptance: pending`。
91
98
 
92
99
  **集数不由本技能决定**。 候选可以多于、也可以少于创作者设定的集数;差多少要明说,
93
100
  由创作者与 `$short-drama-develop` 决定合并还是拆分。
@@ -120,5 +127,5 @@
120
127
  - 没有把本技能的判定写成结论——它们是候选,等创作者接受。
121
128
 
122
129
  交接摘要给创作者读,说清:拆了多少章、跳过哪些、多少单元分别落进三类、
123
- 切出多少候选集、最大的三处改编风险、快评里被推翻的判断。风险要具体到单元,
130
+ 切出多少候选集、排名前列的爽点落在哪几个候选、最大的三处改编风险、快评里被推翻的判断。风险要具体到单元,
124
131
  不写「改编难度较大」。
@@ -99,16 +99,40 @@
99
99
 
100
100
  ## 节奏与情绪
101
101
 
102
- `rhythm-and-emotion.md` 写三件事,全部要能回指到章或情节点:
102
+ `rhythm-and-emotion.md` 写四件事,全部要能回指到章或情节点:
103
103
 
104
104
  - **关键信息推进**:某条信息何时进入读者视野 → 如何被延迟、误导或验证 → 何时爆发 →
105
105
  余波与新钩子。
106
106
  - **情绪触动点索引**:每个触动点落在哪一章、由哪条情节点承担。
107
107
  - **长间隔说明**:连续 3 章以上没有触动点时,写清作者用什么维持期待。
108
108
  改编时这些长间隔就是要合并或砍掉的段落——短剧没有这个耐心。
109
+ - **爽点表**:见下一节。
109
110
 
110
111
  回指不到章或情节点的条目删掉,不要保留无源断言。
111
112
 
113
+ ### 爽点表
114
+
115
+ 选段和切候选集之前,先按**观众收益**给全书情节点排名。原著的叙述顺序是给读者的,
116
+ 短剧观众为爽点付费;不先排名,候选集就会按时序一章一章往下切,全书最强的高光可能落到
117
+ 好几集之后。
118
+
119
+ 每行一个爽点,按收益强度从高到低排:
120
+
121
+ | 列 | 写什么 |
122
+ |---|---|
123
+ | `PAY-<N>` | 稳定编号,供候选集引用 |
124
+ | 位置 | 章(`sequence`)与情节点 |
125
+ | 类型 | 打脸、奇观、反转、身份揭露、奖励兑现、危机,可多选 |
126
+ | 谁兑现 | 主角、对手、旁观者或群体;**旁观者完成的打脸同样算**——群里改口、围观者集体道歉、老前辈当众表态,收益都落在观众身上 |
127
+ | 收益落在谁身上 | 被打脸的是谁、他之前压迫得多具体;压迫越具体,落差越大 |
128
+ | 首集能力 | 这一处能否同时交代主角的身份、眼前的危机与目标;能的标出来,它是开篇替换点的候选 |
129
+ | 依赖 | 观众要先知道什么才看得懂;可以怎样在开场后补 |
130
+
131
+ 强度按本书内部相对排,不跨书比较,也不给分数。原著里一段喜剧反应、一张奖励清单
132
+ 也可能是爽点,照实列,不要因为它「只是反应」就漏掉。
133
+
134
+ **`craft_default · NVA-13`**:切候选集之前先排爽点表,旁观者兑现的爽点同样入表;候选集引用它承接的 `PAY-<N>`。
135
+
112
136
  ## 人物归并
113
137
 
114
138
  跨章去重时,**一人一实体**:无法确定两个称谓是否指同一人,就分开建两条,不合并。
@@ -61,6 +61,7 @@
61
61
  | NVA-10 | reviewed_invariant | Episode candidates are cut on local dramatic result and precise handoff, not on chapter count or word budget. |
62
62
  | NVA-11 | craft_default | Triage a deterministic spread of chapters across the whole book and stop for the creator before committing to a full pass. |
63
63
  | NVA-12 | taste_option | Where to open, which line to keep and which ending to promise remain creator choices; analysis may argue but never blocks. |
64
+ | NVA-13 | craft_default | Before cutting episode candidates, rank the book's plot points by audience payoff — face-slap, spectacle, reversal, identity reveal, reward delivered, crisis — counting payoffs a bystander or crowd delivers; candidates follow the payoff distribution rather than one chapter per episode and cite the payoffs they carry. The opening replacement point is the strongest payoff that can also establish the protagonist's identity, crisis and goal, and a stronger later peak is reported as a cold-open option. |
64
65
 
65
66
  规则分级由高到低:`structural_invariant`(结构缺陷,阻断)、
66
67
  `reviewed_invariant`(需证据判断)、`craft_default`(常用做法,可覆盖)、
@@ -16,7 +16,8 @@ license: MIT
16
16
  取出本次提示词,建立一个有边界的运行 job。creator-first job 的 `source` 必须指向拥有这条提示词的
17
17
  当前 Markdown,`source_entry` 必须点名该文档允许的二级标题:`图片提示词.md` 用 `IMG-*`,
18
18
  `视频提示词.md` 用 `MOTION-*`,`分镜.md` 用 `SHOT-*`(modality 为 `image`,正文取该镜的
19
- `### 冻结关键帧提示词`)。分镜这一路是本套件里唯一能把某一镜的起始画面渲染成文件的入口,但不是创作者获得起始帧的唯一办法——
19
+ `### 冻结关键帧提示词`)。此选择器只提取首帧;尾帧需先由图片提示词阶段建立独立 `IMG-*` 状态图条目,
20
+ 再从 `图片提示词.md` 准备 image job。创作者也可以提供已有起始帧——
20
21
  在自己的工具里出图再放进项目同样成立,图片始终不进项目时走分镜的 `PLAN-...`;
21
22
  产出落在 `剧集/<EP>/制作成果/images/` 后,分镜 owner 才能把它绑成 `用途:起始帧` 的 `REF-...`。存在真实参考图时,
22
23
  还必须逐张填写 `reference_bindings` 的槽位、顺序、路径、中文名、用途以及允许/禁止控制范围;
@@ -126,6 +127,9 @@ adapter 配置必须在项目外,只包含 argv 命令和超时;凭据由 ad
126
127
  固定高保真引用并校验尺寸、格式与透明背景限制。
127
128
  - [MiniMax Music](references/providers/minimax-music.md):使用 `music-3.0` 与 hex 结果,区分主题曲
128
129
  和纯配乐,不伪造时长请求字段。
130
+ - [MiniMax 语音](references/providers/minimax-speech.md):`tts` 模态;模型与 `voice_id` 都必须
131
+ 由账号与文档显式给出,不内置音色清单。只从预置音色合成,不做声音克隆——克隆是授权问题,
132
+ 创作者授权的参考录音按普通创作者输入走 `输入/`。
129
133
  - [MiniMax H3 视频](references/providers/minimax-h3-video.md):模型 ID、分辨率集合与时长区间必须
130
134
  由账号显式配置;提示词进 `content` 的 text 项,参考图按显式 role 绑定,本地参考在没有可信上传时
131
135
  fail closed。该模型与画面同一次生成声音,写法影响见视频提示词技能的目标模型能力档案。
@@ -99,6 +99,12 @@ Keep this file outside the project:
99
99
  `command` is an argv array, never a shell string. Timeout is 1–3600 seconds. Do not put credentials in this file;
100
100
  let the adapter read its environment or operating-system credential store.
101
101
 
102
+ ## Capability sources
103
+
104
+ Use the provider's current API reference for roles, limits and supported combinations.
105
+ A relay can expose a different subset, reject inputs itself or transform requests.
106
+ Record the tested execution path and distinguish its observations from the native API contract.
107
+
102
108
  ## Adapter stdin
103
109
 
104
110
  The adapter receives one UTF-8 JSON document as raw stdin bytes. Read the
@@ -121,26 +127,14 @@ on the machine locale. The document contains the confirmed job plus:
121
127
  adapter must **not submit anything**; it polls and downloads that existing
122
128
  task and returns its outputs as usual.
123
129
 
124
- ## Why the handle exists
125
-
126
- A video task is billed the moment it is submitted, not when its result is
127
- collected. Everything after submission — polling for minutes, downloading — can
128
- be interrupted by a killed process, a dropped connection, or a sleeping laptop.
129
- Without a durable id the attempt record says `failed` while the provider's task
130
- is alive and already paid for, and the only way forward is to submit again and
131
- pay a second time for the same shot.
132
-
133
- So: write the handle before the first poll, and treat failing to write it as
134
- non-fatal — a submitted task must never be failed because its id could not be
135
- recorded locally. The tool copies the handle onto the attempt record on both the
136
- success and the failure path, `audit` reports any unfinished attempt that
137
- carries one as `orphaned_provider_job` with `action: collect_before_retry`, and
138
- `production_tool.py collect` fetches it.
139
-
140
- `collect` deliberately sits outside the confirmation gate. That gate exists to
141
- prevent an unintended charge; collecting spends nothing because the charge
142
- already happened. Requiring a fresh confirmation would make paying again the
143
- cheapest way out of an interruption — the exact outcome the gate is for.
130
+ ## Recovering a submitted task
131
+
132
+ Record the provider task ID before polling so an interrupted task can be collected without resubmission.
133
+ A local handle-write failure is non-fatal after submission. The tool copies the handle into the attempt
134
+ record on success or failure; `audit` reports unfinished tasks as `orphaned_provider_job` with
135
+ `action: collect_before_retry`.
136
+
137
+ `production_tool.py collect` retrieves the existing task without new submission or confirmation.
144
138
 
145
139
  It may translate provider-neutral parameters into its chosen SDK/API. Optional
146
140
  provider adapters under `scripts/` document and implement known translations;
@@ -74,31 +74,13 @@ structured: base/first-frame/first-last-frame tasks use `integrated_multimodal_d
74
74
  form. Chinese dialogue remains exact inside `<d>[Chinese] ...</d>`. Full details live in the
75
75
  video-prompt skill's `references/minimax-h3.md`.
76
76
 
77
- Audio generation is a **capability**, not a style:
78
- what changes upstream is only which axes of the target-model profile a project declares — see the
79
- video-prompt skill's target-model profile. Two consequences are worth stating here because they
80
- show up as production defects rather than as API errors:
81
-
82
- - an unstated **music** channel is not a silent one. Probing this suite's own prompts against H3, a
83
- body carrying `non_diegetic_music: N/A` came back without a score in 14 of 14 runs, while a body
84
- that said nothing about music came back with an invented score in 2 of 3. State the music intent.
85
- - the **speech** channel did not behave the same way in those probes: no run invented dialogue,
86
- including 8 runs whose body carried a contradictory `No dialogue` exclusion. Treat "an unstated
87
- vocal channel gets filled" as unverified rather than as a known failure, and write the shot's
88
- sound intent because the body should say what this shot sounds like — not on the strength of a
89
- mechanism this suite has not observed.
90
- - readable on-screen text was **not** produced unmasked in those probes either: across 44 sampled
91
- frames from 11 clips — including dialogue clips carrying no exclusion sentence, on H3 and on
92
- Seedance 2.0/2.5 — no burned-in subtitle or caption appeared. The exclusion sentence this suite
93
- mandates is therefore precautionary **for video** rather than evidence-driven. Keep writing it:
94
- a one-line exclusion costs nothing, these probes are small enough that they only show the failure
95
- was not produced here, and generator behaviour changes between versions. What should change is the
96
- justification — do not defend it as a fix for an observed defect. Note the asymmetry before carrying this reasoning anywhere else:
97
- the same probe run against `gpt-image-2` found the opposite — an unconstrained still came back
98
- covered in invented readable text, and the exclusion sentence cleaned it up. The image stages
99
- keep their text policy on evidence; only the video stage's copy of it is precautionary.
100
-
101
- Neither is written here as a fixed phrase, and this suite never injects one. The wording belongs to
102
- the shot and to the project's declared prompt language.
77
+ State the intended sound layers in the prompt. For no non-diegetic music, the
78
+ H3 dialect uses `non_diegetic_music: N/A`; small probes observed unwanted music
79
+ when this layer was omitted. They did not establish that omitted speech or
80
+ negative clauses cause extra dialogue.
81
+
82
+ Follow the project's subtitle and in-scene-text policy. Prompt wording belongs
83
+ to the video-prompt skill and the declared language, not to adapter-generated
84
+ boilerplate.
103
85
 
104
86
  Protocol reference: [MiniMax video generation API](https://platform.minimax.io/docs/api-reference/video-generation-v2-create).
@@ -0,0 +1,41 @@
1
+ # MiniMax Speech adapter
2
+
3
+ Adapter command:
4
+
5
+ ```json
6
+ {"command": ["python3", "/absolute/path/provider_adapters.py", "minimax-speech"], "timeout_seconds": 600}
7
+ ```
8
+
9
+ Required environment: `MINIMAX_API_KEY`. `MINIMAX_BASE_URL` optionally overrides the default
10
+ `https://api.minimax.io/v1` and must remain HTTPS.
11
+
12
+ The job uses the suite's `tts` modality and must have exactly one output. The production prompt is the
13
+ line to be spoken, verbatim — not a description of it. Supported public parameters are `model`,
14
+ `voice_id`, `emotion`, `speed`, `vol`, `pitch`, `sample_rate`, `bitrate`, and `format`. The requested
15
+ format must match the target extension and be `mp3` or `wav`.
16
+
17
+ `model` and `voice_id` are both required and neither has a default. The model is an account-enabled
18
+ endpoint, exactly as for the video providers. The voice is a creative decision recorded in
19
+ `视觉设定.md` under the character's 声音方向, and it reaches the adapter through the confirmed job.
20
+
21
+ ## Voice selection
22
+
23
+ Read the provider's voice listing and confirm availability for the chosen model and account.
24
+ The adapter validates the ID format, not catalogue membership. Record the selected ID in the
25
+ character's 声音方向 and pass it through the confirmed job.
26
+
27
+ This workflow selects preset voices. The adapter does not enrol or clone a voice;
28
+ any supplied recording retains its documented authorization and usage scope.
29
+
30
+ ## Request shape
31
+
32
+ The request is non-streaming with `output_format: hex`, `POST /t2a_v2`, and carries
33
+ `voice_setting` (`voice_id`, and any of `emotion`, `speed`, `vol`, `pitch`) alongside `audio_setting`
34
+ (`sample_rate`, `bitrate`, `format`). The adapter validates `base_resp.status_code`, decodes
35
+ `data.audio` as hexadecimal bytes, and writes it to a private temporary file.
36
+
37
+ `emotion` accepts the provider's seven values: `happy`, `sad`, `angry`, `fearful`, `disgusted`,
38
+ `surprised`, `neutral`. Anything outside that set is refused rather than passed through — a rejected
39
+ emotion is a typo caught before it is paid for.
40
+
41
+ Protocol reference: [MiniMax Text to Speech](https://platform.minimax.io/docs/api-reference/speech-t2a-http).