@oh-story/dsh 0.1.8 → 0.1.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (272) hide show
  1. package/README.md +11 -11
  2. package/lib/client.js +35 -14
  3. package/lib/client.js.map +2 -2
  4. package/lib/drama/manifest.json +165 -69
  5. package/lib/drama/skills/short-drama/SKILL.md +5 -1
  6. package/lib/drama/skills/short-drama/scripts/creator_markdown_check.py +126 -9
  7. package/lib/drama/skills/short-drama/scripts/project_tool.py +11 -0
  8. package/lib/drama/skills/short-drama-assets/references/character-and-look.md +18 -0
  9. package/lib/drama/skills/short-drama-assets/references/continuity-lock.md +10 -1
  10. package/lib/drama/skills/short-drama-edit/SKILL.md +148 -0
  11. package/lib/drama/skills/short-drama-edit/agents/openai.yaml +4 -0
  12. package/lib/drama/skills/short-drama-edit/assets/remotion/README.md +60 -0
  13. package/lib/drama/skills/short-drama-edit/assets/remotion/package.json +15 -0
  14. package/lib/drama/skills/short-drama-edit/assets/remotion/remotion.config.ts +6 -0
  15. package/lib/drama/skills/short-drama-edit/assets/remotion/src/Root.tsx +26 -0
  16. package/lib/drama/skills/short-drama-edit/assets/remotion/src/Subtitles.tsx +88 -0
  17. package/lib/drama/skills/short-drama-edit/assets/remotion/src/font.ts +46 -0
  18. package/lib/drama/skills/short-drama-edit/assets/remotion/src/index.ts +4 -0
  19. package/lib/drama/skills/short-drama-edit/assets/remotion/src/schema.ts +32 -0
  20. package/lib/drama/skills/short-drama-edit/assets/remotion/tsconfig.json +13 -0
  21. package/lib/drama/skills/short-drama-edit/assets//345/211/252/350/276/221/345/215/225.md +43 -0
  22. package/lib/drama/skills/short-drama-edit/references/cut-craft.md +81 -0
  23. package/lib/drama/skills/short-drama-edit/references/delivery-verify.md +58 -0
  24. package/lib/drama/skills/short-drama-edit/references/generated-footage.md +96 -0
  25. package/lib/drama/skills/short-drama-edit/references/sound-and-subtitles.md +113 -0
  26. package/lib/drama/skills/short-drama-edit/references/stage-contract.md +55 -0
  27. package/lib/drama/skills/short-drama-edit/scripts/edit_tool.py +1041 -0
  28. package/lib/drama/skills/short-drama-edit/scripts/selftest.py +456 -0
  29. package/lib/drama/skills/short-drama-image-prompts/assets/image-prompts.md +5 -0
  30. package/lib/drama/skills/short-drama-image-prompts/assets/lookdev-prompts.md +3 -0
  31. package/lib/drama/skills/short-drama-novel-analyze/references/aggregation-and-entities.md +2 -2
  32. package/lib/drama/skills/short-drama-novel-analyze/references/chapter-extraction.md +4 -1
  33. package/lib/drama/skills/short-drama-produce/SKILL.md +24 -3
  34. package/lib/drama/skills/short-drama-produce/references/adapter-contract.md +28 -0
  35. package/lib/drama/skills/short-drama-produce/references/providers/minimax-h3-video.md +24 -5
  36. package/lib/drama/skills/short-drama-produce/references/providers/seedance.md +7 -0
  37. package/lib/drama/skills/short-drama-produce/scripts/fixture_adapter.py +18 -1
  38. package/lib/drama/skills/short-drama-produce/scripts/production_tool.py +181 -2
  39. package/lib/drama/skills/short-drama-produce/scripts/provider_adapters.py +57 -2
  40. package/lib/drama/skills/short-drama-review/SKILL.md +3 -0
  41. package/lib/drama/skills/short-drama-review/references/production-quality-gates.md +20 -0
  42. package/lib/drama/skills/short-drama-review/references/rubric-visual-motion.md +36 -0
  43. package/lib/drama/skills/short-drama-storyboard/SKILL.md +7 -0
  44. package/lib/drama/skills/short-drama-storyboard/assets/keyframe-prompts.md +4 -0
  45. package/lib/drama/skills/short-drama-storyboard/references/shot-craft.md +39 -0
  46. package/lib/drama/skills/short-drama-storyboard/references/stage-contract.md +2 -0
  47. package/lib/drama/skills/short-drama-video-prompts/SKILL.md +7 -1
  48. package/lib/drama/skills/short-drama-video-prompts/references/minimax-h3.md +101 -6
  49. package/lib/drama/skills/short-drama-video-prompts/references/motion-recipe.md +7 -1
  50. package/lib/drama/skills/short-drama-video-prompts/references/performance-action-timing.md +35 -0
  51. package/lib/drama/skills/short-drama-video-prompts/references/production-prompt-grammar.md +3 -1
  52. package/lib/drama/skills/short-drama-video-prompts/references/seedance-2.0.md +13 -3
  53. package/lib/drama/skills/short-drama-video-prompts/references/seedance-2.5.md +35 -4
  54. package/lib/drama/skills/short-drama-video-prompts/references/stage-contract.md +1 -1
  55. package/lib/drama/skills/short-drama-write/SKILL.md +13 -2
  56. package/lib/drama/skills/short-drama-write/references/screenplay-format.md +6 -0
  57. package/lib/drama/skills/short-drama-write/references/stage-contract.md +1 -0
  58. package/lib/index.js +4 -2
  59. package/lib/index.js.map +2 -2
  60. package/lib/novel-to-game/VERSION +1 -1
  61. package/lib/novel-to-game/manifest.json +28 -28
  62. package/lib/novel-to-game/skills/game-art-direction/SKILL.md +6 -27
  63. package/lib/novel-to-game/skills/game-build/SKILL.md +12 -29
  64. package/lib/novel-to-game/skills/game-concept/SKILL.md +10 -26
  65. package/lib/novel-to-game/skills/game-qa/SKILL.md +5 -15
  66. package/lib/novel-to-game/skills/game-qa/references/test-design-method.md +1 -1
  67. package/lib/novel-to-game/skills/game-world-design/SKILL.md +19 -28
  68. package/lib/novel-to-game/skills/game-world-design/references/dialogue-design-method.md +1 -2
  69. package/lib/novel-to-game/skills/novel-game-analyze/SKILL.md +6 -9
  70. package/lib/novel-to-game/skills/novel-to-game/SKILL.md +6 -11
  71. package/lib/novel-to-game/skills/novel-to-game/references/intake-benchmark-reference.md +0 -4
  72. package/lib/novel-to-game/skills/novel-to-game/references/intake-method.md +1 -3
  73. package/lib/novel-to-game/skills/novel-to-game/references/pipeline-contract.md +3 -5
  74. package/lib/oh-story/manifest.json +292 -172
  75. package/lib/oh-story/roles/character-designer.md +1 -1
  76. package/lib/oh-story/roles/narrative-writer.md +56 -242
  77. package/lib/oh-story/roles/story-architect.md +1 -1
  78. package/lib/oh-story/skills/story/SKILL.md +1 -1
  79. package/lib/oh-story/skills/story/VERSION +1 -1
  80. package/lib/oh-story/skills/story/references/author-memory.md +10 -8
  81. package/lib/oh-story/skills/story-deslop/SKILL.md +20 -182
  82. package/lib/oh-story/skills/story-deslop/references/anti-ai-writing.md +19 -47
  83. package/lib/oh-story/skills/story-deslop/references/author-memory.md +10 -8
  84. package/lib/oh-story/skills/story-deslop/references/banned-words.md +3 -1
  85. package/lib/oh-story/skills/story-deslop/references/deslop-gates.md +154 -0
  86. package/lib/oh-story/skills/story-deslop/references/style-resolution.md +27 -0
  87. package/lib/oh-story/skills/story-deslop/scripts/check-ai-patterns.js +6 -1
  88. package/lib/oh-story/skills/story-deslop/scripts/check-degeneration.js +39 -20
  89. package/lib/oh-story/skills/story-deslop/scripts/normalize-punctuation.js +10 -5
  90. package/lib/oh-story/skills/story-deslop/scripts/style-whitelist.js +39 -0
  91. package/lib/oh-story/skills/story-import/SKILL.md +2 -2
  92. package/lib/oh-story/skills/story-import/references/format-and-structure.md +2 -2
  93. package/lib/oh-story/skills/story-import/references/tracking-initialization.md +31 -0
  94. package/lib/oh-story/skills/story-import/references/tracking-transaction.md +2 -29
  95. package/lib/oh-story/skills/story-import/scripts/check-outline-contract.js +176 -12
  96. package/lib/oh-story/skills/story-long-analyze/SKILL.md +1 -1
  97. package/lib/oh-story/skills/story-long-write/SKILL.md +20 -193
  98. package/lib/oh-story/skills/story-long-write/references/anti-ai-writing.md +19 -47
  99. package/lib/oh-story/skills/story-long-write/references/artifact-protocols.md +62 -7
  100. package/lib/oh-story/skills/story-long-write/references/author-memory.md +10 -8
  101. package/lib/oh-story/skills/story-long-write/references/banned-words.md +3 -1
  102. package/lib/oh-story/skills/story-long-write/references/benchmark-recall.md +20 -0
  103. package/lib/oh-story/skills/story-long-write/references/dialogue-mastery.md +6 -4
  104. package/lib/oh-story/skills/story-long-write/references/long-chapter-quality.md +2 -2
  105. package/lib/oh-story/skills/story-long-write/references/long-format.md +2 -0
  106. package/lib/oh-story/skills/story-long-write/references/outline-structure-theory.md +2 -0
  107. package/lib/oh-story/skills/story-long-write/references/project-files.md +108 -0
  108. package/lib/oh-story/skills/story-long-write/references/reference-index.md +87 -0
  109. package/lib/oh-story/skills/story-long-write/references/style-combat-face.md +1 -1
  110. package/lib/oh-story/skills/story-long-write/references/style-craft.md +9 -29
  111. package/lib/oh-story/skills/story-long-write/references/style-genre-modules.md +1 -1
  112. package/lib/oh-story/skills/story-long-write/references/style-resolution.md +27 -0
  113. package/lib/oh-story/skills/story-long-write/references/tracking-initialization.md +31 -0
  114. package/lib/oh-story/skills/story-long-write/references/tracking-transaction.md +2 -29
  115. package/lib/oh-story/skills/story-long-write/references/workflow-chapter.md +51 -52
  116. package/lib/oh-story/skills/story-long-write/references/workflow-daily.md +8 -7
  117. package/lib/oh-story/skills/story-long-write/references/workflow-setup.md +36 -15
  118. package/lib/oh-story/skills/story-long-write/references/writer-prompt-fallback.md +22 -0
  119. package/lib/oh-story/skills/story-long-write/references/writing-craft.md +69 -2
  120. package/lib/oh-story/skills/story-long-write/scripts/build_writer_prompt.py +410 -0
  121. package/lib/oh-story/skills/story-long-write/scripts/check-ai-patterns.js +6 -1
  122. package/lib/oh-story/skills/story-long-write/scripts/check-degeneration.js +39 -20
  123. package/lib/oh-story/skills/story-long-write/scripts/check-outline-contract.js +176 -12
  124. package/lib/oh-story/skills/story-long-write/scripts/check-outline-copy.js +90 -23
  125. package/lib/oh-story/skills/story-long-write/scripts/normalize-punctuation.js +10 -5
  126. package/lib/oh-story/skills/story-long-write/scripts/outline_view.py +283 -0
  127. package/lib/oh-story/skills/story-long-write/scripts/style-whitelist.js +39 -0
  128. package/lib/oh-story/skills/story-review/SKILL.md +13 -3
  129. package/lib/oh-story/skills/story-review/references/anti-ai-writing.md +19 -47
  130. package/lib/oh-story/skills/story-review/references/author-memory.md +10 -8
  131. package/lib/oh-story/skills/story-review/references/banned-words.md +3 -1
  132. package/lib/oh-story/skills/story-review/references/dialogue-mastery.md +6 -4
  133. package/lib/oh-story/skills/story-review/references/review-quality.md +2 -2
  134. package/lib/oh-story/skills/story-review/references/style-resolution.md +27 -0
  135. package/lib/oh-story/skills/story-review/references/tracking-initialization.md +31 -0
  136. package/lib/oh-story/skills/story-review/references/tracking-transaction.md +2 -29
  137. package/lib/oh-story/skills/story-review/scripts/check-ai-patterns.js +6 -1
  138. package/lib/oh-story/skills/story-review/scripts/check-degeneration.js +39 -20
  139. package/lib/oh-story/skills/story-review/scripts/normalize-punctuation.js +10 -5
  140. package/lib/oh-story/skills/story-review/scripts/style-whitelist.js +39 -0
  141. package/lib/oh-story/skills/story-setup/SKILL.md +17 -10
  142. package/lib/oh-story/skills/story-setup/references/agent-references/anti-ai-writing.md +19 -47
  143. package/lib/oh-story/skills/story-setup/references/agent-references/banned-words.md +3 -1
  144. package/lib/oh-story/skills/story-setup/references/agent-references/deslop-gates.md +154 -0
  145. package/lib/oh-story/skills/story-setup/references/agent-references/dialogue-mastery.md +6 -4
  146. package/lib/oh-story/skills/story-setup/references/agent-references/format-and-structure.md +2 -2
  147. package/lib/oh-story/skills/story-setup/references/agent-references/short-genre-formulas.md +1 -1
  148. package/lib/oh-story/skills/story-setup/references/agent-references/style-combat-face.md +1 -1
  149. package/lib/oh-story/skills/story-setup/references/agent-references/style-genre-modules.md +1 -1
  150. package/lib/oh-story/skills/story-setup/references/agent-references/style-resolution.md +27 -0
  151. package/lib/oh-story/skills/story-setup/references/agent-references/writing-craft.md +69 -2
  152. package/lib/oh-story/skills/story-setup/references/diagnostics.md +38 -0
  153. package/lib/oh-story/skills/story-short-analyze/references/analysis-writing-techniques.md +1 -1
  154. package/lib/oh-story/skills/story-short-analyze/references/source-story-quality.md +2 -2
  155. package/lib/oh-story/skills/story-short-write/SKILL.md +18 -186
  156. package/lib/oh-story/skills/story-short-write/references/author-memory.md +10 -8
  157. package/lib/oh-story/skills/story-short-write/references/banned-words.md +3 -1
  158. package/lib/oh-story/skills/story-short-write/references/benchmark-recall.md +60 -0
  159. package/lib/oh-story/skills/story-short-write/references/dialogue-mastery.md +6 -4
  160. package/lib/oh-story/skills/story-short-write/references/genre-styles//344/270/226/346/203/205/346/211/223/350/204/270.md +2 -2
  161. package/lib/oh-story/skills/story-short-write/references/genre-styles//345/217/214/347/224/267/344/270/273.md +1 -1
  162. package/lib/oh-story/skills/story-short-write/references/genre-styles//345/244/215/344/273/207/346/211/223/350/204/270.md +3 -3
  163. package/lib/oh-story/skills/story-short-write/references/genre-styles//345/256/205/346/226/227/345/256/253/346/226/227.md +3 -3
  164. package/lib/oh-story/skills/story-short-write/references/genre-styles//346/200/273/350/243/201/350/261/252/351/227/250.md +3 -3
  165. package/lib/oh-story/skills/story-short-write/references/genre-styles//346/202/254/347/226/221.md +5 -5
  166. package/lib/oh-story/skills/story-short-write/references/genre-styles//346/260/221/344/277/227/346/200/252/350/260/210.md +4 -4
  167. package/lib/oh-story/skills/story-short-write/references/genre-styles//347/224/234/345/256/240.md +5 -5
  168. package/lib/oh-story/skills/story-short-write/references/genre-styles//350/277/275/345/246/273/347/201/253/350/221/254/345/234/272.md +3 -3
  169. package/lib/oh-story/skills/story-short-write/references/genre-writing-formulas.md +1 -1
  170. package/lib/oh-story/skills/story-short-write/references/genre-writing-techniques.md +1 -1
  171. package/lib/oh-story/skills/story-short-write/references/reference-index.md +53 -0
  172. package/lib/oh-story/skills/story-short-write/references/short-craft.md +12 -14
  173. package/lib/oh-story/skills/story-short-write/references/short-deslop.md +10 -10
  174. package/lib/oh-story/skills/story-short-write/references/short-format.md +3 -1
  175. package/lib/oh-story/skills/story-short-write/references/short-prose-quality.md +2 -2
  176. package/lib/oh-story/skills/story-short-write/references/style-resolution.md +27 -0
  177. package/lib/oh-story/skills/story-short-write/references/workflow-design.md +77 -0
  178. package/lib/oh-story/skills/story-short-write/references/writing-workflow.md +5 -5
  179. package/lib/oh-story/skills/story-short-write/scripts/check-ai-patterns.js +6 -1
  180. package/lib/oh-story/skills/story-short-write/scripts/check-degeneration.js +39 -20
  181. package/lib/oh-story/skills/story-short-write/scripts/check-delivery-contract.js +34 -5
  182. package/lib/oh-story/skills/story-short-write/scripts/check-outline-copy.js +90 -23
  183. package/lib/oh-story/skills/story-short-write/scripts/normalize-punctuation.js +10 -5
  184. package/lib/oh-story/skills/story-short-write/scripts/style-whitelist.js +39 -0
  185. package/lib/types/client/drama-production-view.d.ts.map +1 -1
  186. package/lib/types/client/index.d.ts.map +1 -1
  187. package/lib/types/client/production-prompts.d.ts.map +1 -1
  188. package/lib/types/client/production-runtime.d.ts +17 -0
  189. package/lib/types/client/production-runtime.d.ts.map +1 -1
  190. package/lib/types/skill-provider.d.ts.map +1 -1
  191. package/lib/video-recap/CHANGELOG.md +31 -1
  192. package/lib/video-recap/manifest.json +162 -162
  193. package/lib/video-recap/skills/video-assemble/scripts/artifacts.py +4 -9
  194. package/lib/video-recap/skills/video-assemble/scripts/assemble.py +47 -60
  195. package/lib/video-recap/skills/video-assemble/scripts/assembly_contract.py +77 -115
  196. package/lib/video-recap/skills/video-assemble/scripts/assembly_settings.py +41 -40
  197. package/lib/video-recap/skills/video-assemble/scripts/audio_automation.py +22 -32
  198. package/lib/video-recap/skills/video-assemble/scripts/audio_mix.py +102 -192
  199. package/lib/video-recap/skills/video-assemble/scripts/jianying_builders.py +14 -35
  200. package/lib/video-recap/skills/video-assemble/scripts/jianying_model.py +14 -12
  201. package/lib/video-recap/skills/video-assemble/scripts/jianying_optional.py +8 -9
  202. package/lib/video-recap/skills/video-assemble/scripts/jianying_schema.py +3 -14
  203. package/lib/video-recap/skills/video-assemble/scripts/jianying_timeline_contract.py +23 -12
  204. package/lib/video-recap/skills/video-assemble/scripts/jianying_tracks.py +1 -4
  205. package/lib/video-recap/skills/video-assemble/scripts/jianying_writer.py +24 -25
  206. package/lib/video-recap/skills/video-assemble/scripts/lib.py +31 -85
  207. package/lib/video-recap/skills/video-assemble/scripts/media.py +100 -144
  208. package/lib/video-recap/skills/video-assemble/scripts/narration_audio.py +101 -195
  209. package/lib/video-recap/skills/video-assemble/scripts/render_preflight.py +10 -21
  210. package/lib/video-recap/skills/video-assemble/scripts/source_subtitles.py +90 -169
  211. package/lib/video-recap/skills/video-assemble/scripts/subtitle_core.py +69 -122
  212. package/lib/video-recap/skills/video-assemble/scripts/subtitle_render.py +10 -17
  213. package/lib/video-recap/skills/video-assemble/scripts/timeline.py +33 -48
  214. package/lib/video-recap/skills/video-assemble/scripts/timeline_emit.py +14 -20
  215. package/lib/video-recap/skills/video-assemble/scripts/visual_render.py +135 -213
  216. package/lib/video-recap/skills/video-cut/scripts/cut_cli.py +49 -57
  217. package/lib/video-recap/skills/video-cut/scripts/cut_contract.py +38 -74
  218. package/lib/video-recap/skills/video-cut/scripts/cut_render.py +46 -95
  219. package/lib/video-recap/skills/video-cut/scripts/lib.py +23 -25
  220. package/lib/video-recap/skills/video-cut/scripts/media_geometry.py +70 -173
  221. package/lib/video-recap/skills/video-cut/scripts/narration_mapping.py +28 -53
  222. package/lib/video-recap/skills/video-cut/scripts/sentence_boundaries.py +162 -322
  223. package/lib/video-recap/skills/video-recap/references/timeline-and-jianying.md +6 -7
  224. package/lib/video-recap/skills/video-recap/scripts/doctor.py +104 -124
  225. package/lib/video-recap/skills/video-recap/scripts/final_qc.py +255 -412
  226. package/lib/video-recap/skills/video-recap/scripts/lib.py +30 -52
  227. package/lib/video-recap/skills/video-recap/scripts/materials.py +97 -120
  228. package/lib/video-recap/skills/video-recap/scripts/mimo_qc_client.py +7 -12
  229. package/lib/video-recap/skills/video-recap/scripts/mimo_qc_evidence.py +46 -97
  230. package/lib/video-recap/skills/video-recap/scripts/mimo_qc_observations.py +18 -36
  231. package/lib/video-recap/skills/video-recap/scripts/mimo_qc_payload.py +29 -47
  232. package/lib/video-recap/skills/video-recap/scripts/mimo_qc_report.py +43 -76
  233. package/lib/video-recap/skills/video-recap/scripts/mimo_qc_runner.py +2 -1
  234. package/lib/video-recap/skills/video-recap/scripts/qc_contract.py +2 -1
  235. package/lib/video-recap/skills/video-recap/scripts/recap_cli.py +2 -2
  236. package/lib/video-recap/skills/video-recap/scripts/recap_inspect.py +129 -145
  237. package/lib/video-recap/skills/video-recap/scripts/recap_review.py +27 -20
  238. package/lib/video-recap/skills/video-recap/scripts/recap_runner.py +20 -31
  239. package/lib/video-recap/skills/video-recap/scripts/recap_runtime.py +31 -106
  240. package/lib/video-recap/skills/video-recap/scripts/recap_stage_qc.py +43 -113
  241. package/lib/video-recap/skills/video-recap/scripts/recap_timeline.py +196 -377
  242. package/lib/video-recap/skills/video-script/scripts/agent_brief.py +1 -1
  243. package/lib/video-recap/skills/video-script/scripts/agent_text.py +63 -172
  244. package/lib/video-recap/skills/video-script/scripts/brief_context.py +80 -135
  245. package/lib/video-recap/skills/video-script/scripts/brief_inputs.py +125 -167
  246. package/lib/video-recap/skills/video-script/scripts/brief_timeline.py +93 -208
  247. package/lib/video-recap/skills/video-script/scripts/deslop_qc.py +20 -46
  248. package/lib/video-recap/skills/video-script/scripts/lib.py +30 -26
  249. package/lib/video-recap/skills/video-script/scripts/narration_lint.py +145 -140
  250. package/lib/video-recap/skills/video-script/scripts/review_response.py +12 -42
  251. package/lib/video-recap/skills/video-script/scripts/review_runner.py +0 -6
  252. package/lib/video-recap/skills/video-script/scripts/speech_ownership.py +39 -100
  253. package/lib/video-recap/skills/video-script/scripts/timeline_fusion.py +33 -124
  254. package/lib/video-recap/skills/video-understanding/scripts/agent_brief.py +1 -1
  255. package/lib/video-recap/skills/video-understanding/scripts/agent_text.py +63 -172
  256. package/lib/video-recap/skills/video-understanding/scripts/asr.py +1 -2
  257. package/lib/video-recap/skills/video-understanding/scripts/brief_context.py +80 -135
  258. package/lib/video-recap/skills/video-understanding/scripts/brief_inputs.py +125 -167
  259. package/lib/video-recap/skills/video-understanding/scripts/brief_timeline.py +93 -208
  260. package/lib/video-recap/skills/video-understanding/scripts/consolidate.py +1 -1
  261. package/lib/video-recap/skills/video-understanding/scripts/deslop_qc.py +20 -46
  262. package/lib/video-recap/skills/video-understanding/scripts/lib.py +31 -26
  263. package/lib/video-recap/skills/video-understanding/scripts/narration_lint.py +145 -140
  264. package/lib/video-recap/skills/video-understanding/scripts/speech_ownership.py +39 -100
  265. package/lib/video-recap/skills/video-understanding/scripts/timeline_fusion.py +33 -124
  266. package/lib/video-recap/skills/video-understanding/scripts/vlm.py +1 -4
  267. package/lib/video-recap/skills/video-voiceover/scripts/dub.py +7 -13
  268. package/lib/video-recap/skills/video-voiceover/scripts/fish_audio.py +12 -30
  269. package/lib/video-recap/skills/video-voiceover/scripts/lib.py +98 -131
  270. package/lib/video-recap/skills/video-voiceover/scripts/tts_audio.py +17 -28
  271. package/lib/video-recap/skills/video-voiceover/scripts/voiceover.py +151 -240
  272. package/package.json +41 -41
@@ -22,7 +22,7 @@ const path = require('path')
22
22
  const FIELDS = [
23
23
  '核心事件', '字数目标', '字数口径', '阶段位置', '单元ID/位置', '目标情绪',
24
24
  '主角目标/关键选择', '章节定位', '本章结构公式', '章首钩子', '爽点',
25
- '本章禁止提前释放', '契约风险',
25
+ '本章标价', '闭环状态', '本章禁止提前释放', '写手自由区', '契约风险',
26
26
  ]
27
27
  const SUBSECTIONS = ['内容概括', '情节安排', '人物关系和出场顺序', '情节细化']
28
28
  const FIVE_ACT = ['起因', '发展', '转折', '高潮', '结尾']
@@ -46,11 +46,11 @@ function readUtf8(file) {
46
46
  }
47
47
  }
48
48
 
49
- function makeCheck(id, ok, file, evidence, expected, repair) {
49
+ function makeCheck(id, ok, file, evidence, expected, repair, severity = 'blocking') {
50
50
  return {
51
51
  id,
52
52
  ok,
53
- severity: 'blocking',
53
+ severity,
54
54
  file,
55
55
  evidence,
56
56
  expected,
@@ -65,7 +65,47 @@ function parseTableRow(line) {
65
65
  return trimmed.slice(1, -1).split('|').map((cell) => cell.replace(/\*\*/g, '').replace(/`/g, '').trim())
66
66
  }
67
67
 
68
- function verify(file) {
68
+ function resolveBookRoot(file, projectRoot) {
69
+ if (projectRoot) return path.resolve(projectRoot)
70
+ const parent = path.dirname(path.resolve(file))
71
+ if (path.basename(parent) === '大纲') return path.dirname(parent)
72
+ return null
73
+ }
74
+
75
+ // 项目引用须写目录路径;裸文件名可能指向 skill reference,不猜测其归属。
76
+ const REF_DIR_PREFIX = /^(?:设定|大纲|追踪|正文|读者笔记|对标)\//
77
+
78
+ function checkSettingRefs(text, name, file, projectRoot) {
79
+ const bookRoot = resolveBookRoot(file, projectRoot)
80
+ if (!bookRoot) {
81
+ return makeCheck('outline.setting-refs-exist', true, name, '未能定位书目录(细纲不在 大纲/ 下且未传 --project),跳过', '细纲引用的项目内文件真实存在', '无需修复。')
82
+ }
83
+ const refs = new Set()
84
+ const pattern = /`([^`\n]+?\.md)[^`\n]*`/g
85
+ let match
86
+ while ((match = pattern.exec(text)) !== null) {
87
+ const token = match[1].trim().replace(/\\/g, '/')
88
+ if (token.includes('{') || token.includes('}')) continue
89
+ if (REF_DIR_PREFIX.test(token) || /^\.{1,2}\//.test(token)) refs.add(token)
90
+ }
91
+ const missing = []
92
+ for (const token of refs) {
93
+ const base = /^\.{1,2}\//.test(token) ? path.dirname(path.resolve(file)) : bookRoot
94
+ try {
95
+ if (!fs.statSync(path.resolve(base, token)).isFile()) missing.push(token)
96
+ } catch { missing.push(token) }
97
+ }
98
+ return makeCheck(
99
+ 'outline.setting-refs-exist',
100
+ missing.length === 0,
101
+ name,
102
+ missing.length ? `引用的路径不是可用文件:${missing.join('、')}` : `${refs.size} 处项目内引用全部存在`,
103
+ '细纲引用的每个项目内 .md 文件都真实存在——不许把槽位指向查无实据的权威文件',
104
+ '修正引用路径;或按「创作自主权分级」先把缺的设定落档(B 级直接补、C 级进《供给单》提案),再在细纲引用。'
105
+ )
106
+ }
107
+
108
+ function verify(file, projectRoot = null) {
69
109
  const name = path.basename(file)
70
110
  const read = readUtf8(file)
71
111
  const checks = []
@@ -133,21 +173,82 @@ function verify(file) {
133
173
  let header = null
134
174
  for (const line of lines) {
135
175
  const cells = parseTableRow(line)
136
- if (cells && cells.length === 4 && PLOT_HEADER_FIRST.test(cells[0])) {
176
+ // 四列是旧表(# / 情节点 / 功能标签 / 执行边界),五列是现行模板(中间多一列「分辨率」)。
177
+ // 两种都收:功能标签固定在第 3 列,执行边界一律取最后一列,旧细纲不因加列而失效。
178
+ if (cells && (cells.length === 4 || cells.length === 5) && PLOT_HEADER_FIRST.test(cells[0])) {
137
179
  header = cells
138
180
  break
139
181
  }
140
182
  }
141
- const headerOk = Boolean(header) && header[2].includes('功能标签') && header[3].includes('执行边界')
183
+ const headerOk = Boolean(header)
184
+ && header[2].includes('功能标签')
185
+ && header[header.length - 1].includes('执行边界')
186
+ && (header.length === 4 || header[3].includes('分辨率'))
142
187
  checks.push(makeCheck(
143
188
  'outline.plotpoint-table',
144
189
  headerOk,
145
190
  name,
146
- header ? `表头:${header.join(' | ')}` : '未找到 | # | 情节点 | 功能标签 | 执行边界 | 表头',
147
- '情节细化使用四列表格:# / 情节点(谁做了什么) / 功能标签 / 执行边界',
148
- '只把情节点序列改成四列表格,逐点补功能标签与执行边界;不增删情节点本身。'
191
+ header ? `表头:${header.join(' | ')}` : '未找到 | # | 情节点 | 功能标签 | [分辨率] | 执行边界 | 表头',
192
+ '情节细化使用五列表格:# / 情节点(谁做了什么) / 功能标签 / 分辨率 / 执行边界(四列旧表仍收,但新建细纲按五列模板走)',
193
+ '只把情节点序列改成五列表格,逐点补功能标签、分辨率与执行边界;不增删情节点本身。'
149
194
  ))
150
195
 
196
+ // 「放」半边:五列表的执行边界必须至少一个点解除限制(模板既有要求),
197
+ // 全是禁令的情节点表实测会把整章压成同一个温度(015 章十一个点全「不许」)。
198
+ if (headerOk && header.length === 5) {
199
+ const rows = []
200
+ for (const line of lines) {
201
+ const cells = parseTableRow(line)
202
+ if (cells && cells.length === 5 && /^\d+$/.test(cells[0])) rows.push(cells)
203
+ }
204
+ if (rows.length) {
205
+ const released = rows.filter((cells) => {
206
+ const match = cells[4].match(/(?:^|[。;;\s])放\s*[::]([^]*?)(?=(?:禁|放)\s*[::]|$)/)
207
+ if (!match) return false
208
+ const value = match[1].replace(/[\s。;;,,、\[\]【】]/g, '')
209
+ return value.length > 0 && !/^(?:无|暂无|待补充|待定|无缺口)$/.test(value)
210
+ })
211
+ checks.push(makeCheck(
212
+ 'outline.plotpoint-release',
213
+ released.length > 0,
214
+ name,
215
+ `${rows.length} 个情节点里 ${released.length} 个写了「放」`,
216
+ '执行边界写成「禁+放」两半,每章至少一个点写了「放」——放行是解除限制,不是义务',
217
+ '给最该出彩的一两个点补「放」半边(谁可以出声、谁可以失态、允不允许当场标价),不改情节点本身。'
218
+ ))
219
+ if (released.length > 0 && rows.length >= 3 && released.length * 3 < rows.length) {
220
+ checks.push(makeCheck(
221
+ 'outline.plotpoint-release-ratio',
222
+ false,
223
+ name,
224
+ `${rows.length} 个情节点里只有 ${released.length} 个写了「放」(不足三分之一)`,
225
+ '建议至少三分之一的情节点写「放」半边,避免整章只剩禁令',
226
+ '按人工判断酌情补「放」;本项不阻断。',
227
+ 'advisory'
228
+ ))
229
+ }
230
+ }
231
+ }
232
+
233
+ // 章级「禁止提前释放」只写本章特有的三五条;条目过多多半是把卷级常任禁忌逐章复读了。
234
+ const releaseMatch = text.match(/^\s*[-*+]\s*\*{0,2}本章禁止提前释放\*{0,2}\s*[::]\s*(.*)$/m)
235
+ if (releaseMatch) {
236
+ const items = releaseMatch[1].split(/[、;;,,\/]/).map((s) => s.trim()).filter(Boolean)
237
+ if (items.length > 5) {
238
+ checks.push(makeCheck(
239
+ 'outline.release-brevity',
240
+ false,
241
+ name,
242
+ `本章禁止提前释放列了 ${items.length} 条`,
243
+ '章级只写本章特有的三五条;卷级常任禁忌写在卷纲「本卷禁碰的终局底牌」,不逐章复读',
244
+ '把与卷纲常任重复的条目删掉,只留本章特有;本项不阻断。',
245
+ 'advisory'
246
+ ))
247
+ }
248
+ }
249
+
250
+ checks.push(checkSettingRefs(text, name, file, projectRoot))
251
+
151
252
  const targetMatch = text.match(/字数目标\s*[::]\s*(?:约\s*)?([\d,,]+)/)
152
253
  const target = targetMatch ? Number(targetMatch[1].replace(/[,,]/g, '')) : null
153
254
  const caliberOk = new RegExp(`字数口径\\s*[::]\\s*${CALIBER}`).test(text)
@@ -164,7 +265,8 @@ function verify(file) {
164
265
  }
165
266
 
166
267
  function report(file, checks) {
167
- const failures = checks.filter((check) => !check.ok)
268
+ const failures = checks.filter((check) => !check.ok && check.severity === 'blocking')
269
+ const advisories = checks.filter((check) => !check.ok && check.severity === 'advisory')
168
270
  return {
169
271
  schema_version: 1,
170
272
  verifier: 'story-long-write.outline-contract',
@@ -172,6 +274,7 @@ function report(file, checks) {
172
274
  ok: failures.length === 0,
173
275
  checks,
174
276
  failures,
277
+ advisories,
175
278
  repair_scope: failures.map((failure) => ({
176
279
  id: failure.id,
177
280
  file: failure.file,
@@ -200,13 +303,65 @@ function resolveChapter(project, chapter) {
200
303
  return { file: path.join(dir, hit) }
201
304
  }
202
305
 
306
+ // --supply:批末验证《供给单》已落卷纲——定位单元卡块,确认其中有「供给自查」小节。
307
+ function verifySupply(volumeFile, unitId) {
308
+ const read = readUtf8(volumeFile)
309
+ if (!read.ok) {
310
+ return { schema_version: 1, verifier: 'story-long-write.outline-supply', file: path.resolve(volumeFile), unit: unitId, ok: false, evidence: read.error || '卷纲文件为空' }
311
+ }
312
+ // 只检查目标单元内的标题,不把正文提及或代码示例当成小节。
313
+ let fence = null
314
+ const lines = read.text.split(/\r?\n/).map((line) => {
315
+ const marker = line.match(/^\s{0,3}(`{3,}|~{3,})/)
316
+ if (marker) {
317
+ if (!fence) fence = marker[1]
318
+ else if (marker[1][0] === fence[0] && marker[1].length >= fence.length) fence = null
319
+ return ''
320
+ }
321
+ return fence ? '' : line.replace(/\*\*/g, '')
322
+ })
323
+ const headings = []
324
+ for (let index = 0; index < lines.length; index++) {
325
+ const heading = lines[index].match(/^(#{1,6})\s+(.+)$/)
326
+ if (heading) headings.push({ index, level: heading[1].length, title: heading[2] })
327
+ }
328
+ const card = headings.find((heading) => {
329
+ const id = heading.title.match(/剧情单元\s+([A-Za-z][\w-]*)/)
330
+ if (id) return id[1] === unitId
331
+ const end = headings.find((next) => next.index > heading.index)?.index ?? lines.length
332
+ return lines.slice(heading.index + 1, end).some((line) => {
333
+ const field = line.match(/^\s*[-*+]\s*单元ID\s*[::]\s*([A-Za-z][\w-]*)\s*$/)
334
+ return field?.[1] === unitId
335
+ })
336
+ })
337
+ const end = card ? (headings.find((next) => next.index > card.index && next.level <= card.level)?.index ?? lines.length) : 0
338
+ const ok = Boolean(card) && headings.some((heading) => heading.index > card.index && heading.index < end && /^供给自查(?:\s|[((]|$)/.test(heading.title))
339
+ if (!card) {
340
+ return { schema_version: 1, verifier: 'story-long-write.outline-supply', file: path.resolve(volumeFile), unit: unitId, ok: false, evidence: `卷纲中未找到剧情单元 ${unitId}` }
341
+ }
342
+ return {
343
+ schema_version: 1,
344
+ verifier: 'story-long-write.outline-supply',
345
+ file: path.resolve(volumeFile),
346
+ unit: unitId,
347
+ ok,
348
+ evidence: ok ? '单元卡含「供给自查」小节' : `剧情单元 ${unitId} 的卡内没有「供给自查」小节——每批出细纲前须产出《供给单》(含「无缺口」情形),见 workflow-setup.md「按剧情批出细纲」步骤 3`,
349
+ }
350
+ }
351
+
203
352
  function parseArgs(argv) {
204
353
  const files = []
205
354
  let project = null
206
355
  let chapter = null
356
+ let supply = null
207
357
  for (let index = 0; index < argv.length; index++) {
208
358
  const arg = argv[index]
209
359
  if (arg === '--json') continue
360
+ if (arg === '--supply') {
361
+ if (index + 2 >= argv.length) return null
362
+ supply = { volumeFile: argv[++index], unitId: argv[++index] }
363
+ continue
364
+ }
210
365
  if (arg === '--project' || arg === '--chapter') {
211
366
  if (index + 1 >= argv.length || argv[index + 1].startsWith('--')) return null
212
367
  const value = argv[++index]
@@ -217,6 +372,10 @@ function parseArgs(argv) {
217
372
  if (arg.startsWith('--')) return null
218
373
  files.push(arg)
219
374
  }
375
+ if (supply) {
376
+ if (project || chapter || files.length) return null
377
+ return { supply }
378
+ }
220
379
  if (project || chapter) {
221
380
  if (!project || !chapter || files.length || !/^\d+$/.test(chapter)) return null
222
381
  return { project, chapter }
@@ -228,9 +387,14 @@ function parseArgs(argv) {
228
387
  function main(argv) {
229
388
  const parsed = parseArgs(argv)
230
389
  if (!parsed) {
231
- process.stderr.write('用法: node scripts/check-outline-contract.js --json <细纲路径...> | --json --project <书目录> --chapter N\n')
390
+ process.stderr.write('用法: node scripts/check-outline-contract.js --json <细纲路径...> | --json --project <书目录> --chapter N | --json --supply <卷纲路径> <单元ID>\n')
232
391
  return 2
233
392
  }
393
+ if (parsed.supply) {
394
+ const supplyReport = verifySupply(parsed.supply.volumeFile, parsed.supply.unitId)
395
+ process.stdout.write(`${JSON.stringify(supplyReport, null, 2)}\n`)
396
+ return supplyReport.ok ? 0 : 1
397
+ }
234
398
  let targets = parsed.files
235
399
  if (!targets) {
236
400
  const resolved = resolveChapter(parsed.project, parsed.chapter)
@@ -240,7 +404,7 @@ function main(argv) {
240
404
  }
241
405
  targets = [resolved.file]
242
406
  }
243
- const reports = targets.map((file) => verify(file))
407
+ const reports = targets.map((file) => verify(file, parsed.project || null))
244
408
  const ok = reports.every((entry) => entry.ok)
245
409
  process.stdout.write(`${JSON.stringify(reports.length === 1 ? reports[0] : reports, null, 2)}\n`)
246
410
  return ok ? 0 : 1
@@ -14,7 +14,7 @@ metadata: {"openclaw":{"source":"https://github.com/zenstory-ai/oh-story-claudec
14
14
 
15
15
  > Agent 兼容性:只检查当前运行时的 canonical 目录:Claude `.claude/agents/{agent}.md`、OpenCode `.opencode/agents/{agent}.md`、Codex `.codex/agents/{agent}.toml`、Antigravity `.agents/agents/agent-name/agent.md`(`agent-name` 为目标 agent 名),不得因其他端文件存在而误判。Codex 使用同名 `agent_type`;Antigravity 使用 `invoke_subagent` + `TypeName`。对应运行时未暴露 custom-agent registry / `invoke_subagent` 或返回未知 agent 时,必须降级 solo/direct。检测到 `.zcode/` 时同样直接 solo/direct,因为 ZCode 3.3.4 不执行项目 custom agents;报告 `Fallback: project custom agents unavailable -> solo`。Claude/OpenCode 兼容面保留 `subagent_type`。
16
16
  >
17
- > Spawn 版本提示(不阻断 spawn):先读取项目根 `.story-deployed` 的 `agents_version`。与本版 `agents_version: 29` 不一致时(标记缺失、字段缺失/非整数、小于或大于 29)**照常按文件存在性检查并 spawn**,同时报告 `Notice: agents bundle 版本不匹配(项目 {N},本版 29)` 并提示重新运行 `/story-setup` 后新开会话;大于 29 时额外提示先更新 oh-story-claudecode,不要用本地旧版 setup 降级覆盖。只有 agent 文件缺失、或运行时不暴露 custom agent 时才降级 solo/direct,报告 `Fallback: ... -> solo`。
17
+ > Spawn 版本提示(不阻断 spawn):先读取项目根 `.story-deployed` 的 `agents_version`。与本版 `agents_version: 30` 不一致时(标记缺失、字段缺失/非整数、小于或大于 30)**照常按文件存在性检查并 spawn**,同时报告 `Notice: agents bundle 版本不匹配(项目 {N},本版 30)` 并提示重新运行 `/story-setup` 后新开会话;大于 30 时额外提示先更新 oh-story-claudecode,不要用本地旧版 setup 降级覆盖。只有 agent 文件缺失、或运行时不暴露 custom agent 时才降级 solo/direct,报告 `Fallback: ... -> solo`。
18
18
 
19
19
  ## 拆解边界声明(主线程同样适用)
20
20
 
@@ -25,7 +25,9 @@ metadata: {"openclaw":{"source":"https://github.com/zenstory-ai/oh-story-claudec
25
25
 
26
26
  > 内置适配 Claude Code / OpenCode / Codex / Antigravity / ZCode / OpenClaw。专业 agent 只查当前端 canonical 目录(`.claude/agents`、`.opencode/agents`、`.codex/agents` TOML、`.agents/agents`);Antigravity 用 `invoke_subagent` + 同名 `TypeName`。文件或运行时能力缺失、返回 unknown agent,或当前为不执行 custom agents 的 ZCode 3.3.4 时,报告 fallback 并 solo/direct 执行。
27
27
  >
28
- > Spawn 版本提示(不阻断 spawn):先读取项目根 `.story-deployed` 的 `agents_version`。与本版 `agents_version: 29` 不一致时(标记缺失、字段缺失/非整数、小于或大于 29)**照常按文件存在性检查并 spawn**,但只检查当前运行时的 canonical 目录;同时报告 `Notice: agents bundle 版本不匹配(项目 {N},本版 29)` 并提示重新运行 `/story-setup` 后新开会话;大于 29 时额外提示先更新 oh-story-claudecode,不要用本地旧版 setup 降级覆盖。只有 agent 文件缺失、或运行时不暴露 custom agent 时才降级 solo/direct,报告 `Fallback: ... -> solo`。
28
+ > Spawn 版本提示(不阻断 spawn):先读取项目根 `.story-deployed` 的 `agents_version`。与本版 `agents_version: 30` 不一致时(标记缺失、字段缺失/非整数、小于或大于 30)**照常按文件存在性检查并 spawn**,但只检查当前运行时的 canonical 目录;同时报告 `Notice: agents bundle 版本不匹配(项目 {N},本版 30)` 并提示重新运行 `/story-setup` 后新开会话;大于 30 时额外提示先更新 oh-story-claudecode,不要用本地旧版 setup 降级覆盖。只有 agent 文件缺失、或运行时不暴露 custom agent 时才降级 solo/direct,报告 `Fallback: ... -> solo`。
29
+
30
+ **文风裁决**:正文写作、改写或审稿前先读 [references/style-resolution.md](references/style-resolution.md),加载本书文风并形成 `style_resolution`;无作者记忆也执行。当前请求、本书文风和 active 偏好按维度覆盖通用 references;同一裁决交给后续执行者。
29
31
 
30
32
  ## 核心方法
31
33
 
@@ -36,7 +38,7 @@ metadata: {"openclaw":{"source":"https://github.com/zenstory-ai/oh-story-claudec
36
38
  3. **用模块组装,不要重新发明**。每个题材都有验证过的剧情模式——反转怎么铺、爽点怎么爆、感情怎么拉扯。找到对的模块,把对标书的具体角色看成功能位(对手/盟友/催化剂),再映射到你的角色。用你自己的素材填充这些功能位。
37
39
  4. **只加载必需信息**。写每章只读“不知道就会写错”的角色状态、待收伏笔、相关设定。其余留在文件系统里。
38
40
  5. **契约与推进决策走权威参考文件**。涉及读者契约、主角代理权、利益安全、期待债、终局储备(终局底牌/升级台阶)、机构/势力边界和 契约安全 / 需补强 / 契约破坏 风险判定时,先按 `references/reader-contract-and-progression.md` 校准,不在 SKILL.md 内复制长规则。
39
- 6. **复用作者习惯**。若作者记忆 state 已存在,正文前用 `scripts/author_memory_commit.py query --kind prose_style --kind story_design` 获取本次相关 active 条目(总输出 ≤2KB),原样传给实际正文/改写 agent;设定/大纲按任务查询其他 kind。硬门禁、当前请求、本书设定/文风优先。明确长期声明在收尾用 `record` 写入并回传回执;完整规则见 [references/author-memory.md](references/author-memory.md),不混入追踪。
41
+ 6. **作者记忆**:按 [references/author-memory.md](references/author-memory.md) 查询本次相关 active 项、≤2KB,正文前原样传给执行者;当前请求、本书文风优先。长期声明用 `record` 写入并回传回执。
40
42
 
41
43
  | 题材 | 核心情绪 | 重点参考 |
42
44
  |------|---------|---------|
@@ -87,6 +89,18 @@ metadata: {"openclaw":{"source":"https://github.com/zenstory-ai/oh-story-claudec
87
89
  > **拆文库/对标关系**:`拆文库/` = analyze skill 的原始产出,是数据源。`对标/` = 写作项目的引用视图,存放与本项目相关的对标数据子集。首次引用对标书时,从 `拆文库/{书名}/` 复制相关子目录(章节/角色/剧情/设定)、`剧情/节奏.md`、`剧情/情绪模块.md`、`文风.md` 和 `拆文报告.md` 到 `对标/{书名}/`。
88
90
  >
89
91
  > **对标书路径查找**:优先 `{项目}/对标/{书名}/`,不存在则回退 `拆文库/{书名}/`。下文所有对标数据加载均使用此规则。
92
+ >
93
+ > **卷纲不整读(取段器)**:任何场景要卷纲内容一律走
94
+ > `{PYTHON} {skill 根}/scripts/outline_view.py --unit {单元ID} {卷纲路径}`(脚本统一输出 UTF-8),
95
+ > 只要契约不要单元时用 `--contract`,先看一屏目录用 `--toc`。
96
+ > **两档分明**:**写正文用 `--stage write`**(卷级常任+单元级,批次底稿一概不给);**排纲/补纲用默认 `--stage outline`**(另带该单元在用的批次底稿)。
97
+ > 供给自查、建纲追加、批次级复检这类底稿是**排纲期的工作底稿,写作期不是输入**——它们里头凡有写作期约束力的条目,
98
+ > 建纲时就必须下沉到单元级段或细纲(`--check` 的 W1 告警专盯这个)。
99
+ > 取的是**闭包不是点名段**——输出恒等于「全部卷级常任段 + 该单元的单元级段 + 该单元在用的批次底稿」,逐章表(情绪弧线等)按该单元章区间裁行,
100
+ > 带退役标记的行默认不输出(要看历史加 `--history`)。
101
+ > 找不到单元时脚本 exit 1 并报错,不静默降级——报错就去核对单元ID或先补卷纲,不要改用整读绕过。
102
+ > 段头的 `> 作用域:` 声明是这套的地基,格式与 checker 见 `references/artifact-protocols.md` 卷纲模板;
103
+ > 未声明作用域的段会被保守纳入并告警,跑 `outline_view.py --check {卷纲路径}` 修。
90
104
 
91
105
  ---
92
106
 
@@ -116,112 +130,9 @@ metadata: {"openclaw":{"source":"https://github.com/zenstory-ai/oh-story-claudec
116
130
 
117
131
  ### Phase 4:正文写作辅助
118
132
 
119
- #### 项目文件结构
120
-
121
- 长篇写作必须用文件系统管理,不要把内容堆在对话里。在用户指定的工作目录下创建:
122
-
123
- ```
124
- {书名}/
125
- ├── 设定/
126
- │ ├── 世界观/
127
- │ │ ├── 背景设定.md # 时代背景、地理、历史
128
- │ │ ├── 力量体系.md # 修炼/能力/等级体系
129
- │ │ └── ...
130
- │ ├── 角色/
131
- │ │ ├── 沈栀.md # 每个人物一个文件,文件名用角色名
132
- │ │ └── ...
133
- │ ├── 势力/
134
- │ │ ├── 天机阁.md # 每个势力/组织一个文件
135
- │ │ └── ...
136
- │ ├── 关系.md # 角色关系映射
137
- │ ├── 题材定位.md # 题材核心梗+对标分析+终局底牌/升级台阶(防写无可写)
138
- │ └── 题材正文提示卡.md # 题材正文核心:边界/期待/爽点/节奏/禁漂移
139
- ├── 大纲/
140
- │ ├── 大纲.md # 全书卷级结构
141
- │ ├── 卷纲_第一卷.md # 每卷一个:对标结构坐标+剧情单元+情绪弧线(含章节定位)+人物弧线+伏笔+反转
142
- │ └── 细纲_第001章.md # 每章一个:章节定位+事件+钩子(按章节定位,章首/章尾/段落级)+爽点+悬念
143
- ├── 正文/
144
- │ ├── 第001章_章名.md
145
- │ └── ...
146
- ├── 对标/ ← 拆文产出的结构化资产
147
- │ └── {对标书名}/
148
- │ ├── 原文/
149
- │ │ ├── 第001章_章名.md
150
- │ │ └── ...
151
- │ ├── 角色/ ← 从拆文库/结构化输出同步
152
- │ │ └── {角色名}.md
153
- │ ├── 剧情/ ← 从拆文库/结构化输出同步
154
- │ │ ├── {剧情单元名}.md
155
- │ │ ├── 故事线.md
156
- │ │ ├── 节奏.md # 关键信息推进 + 情绪触动点 + 爆发节奏(权威节奏索引)
157
- │ │ └── 情绪模块.md # 读者需求/情绪引擎 + 可复现模块(权威模块索引)
158
- │ ├── 设定/ ← 从拆文库/结构化输出同步
159
- │ │ ├── 世界观/ ← 按主题拆分到子目录
160
- │ │ │ ├── 背景设定.md
161
- │ │ │ ├── 力量体系.md
162
- │ │ │ ├── 地理.md
163
- │ │ │ └── 金手指.md
164
- │ │ └── 势力/
165
- │ │ └── {势力名}.md
166
- │ └── 拆文报告.md
167
- ├── 追踪/
168
- │ ├── _tracking-state.json ← 唯一结构化权威状态
169
- │ ├── 上下文.md ← 派生续写状态卡(固定 7 栏),≤12KB
170
- │ ├── 逐章记录/第NNN章.md ← 未来相关紧凑记录,≤3072 字节
171
- │ ├── 角色状态/{角色名}.md ← 派生核心角色当前快照
172
- │ ├── 伏笔.md ← 派生伏笔当前视图
173
- │ └── 时间线/{作者真相.md,读者已知.md}
174
- ├── 参考资料/
175
- │ └── {topic}.md # story-researcher 输出的研究资料
176
- ```
177
-
178
- **产物映射表**(创建模板详见 [references/artifact-protocols.md](references/artifact-protocols.md)):
179
-
180
- | 文件 | 粒度 | 创建阶段 | 读取时机 |
181
- |------|------|---------|---------|
182
- | 设定/关系.md | 全书 | Phase 2 | 按需:story-explorer relationship 查询、story-review 查设定(不在每章写作回路里逐章读) |
183
- | 设定/题材定位.md(含 `主对标书` 字段,多对标时必填) | 全书 | Phase 2 | Phase 3 大纲、每卷开始前、Phase 4 写前召回 |
184
- | 设定/题材正文提示卡.md | 全书/题材 | Phase 2(缺失则 Phase 4 写前即时生成) | Phase 4 每章写作前:按 `genre-prose-cards.md` 索引匹配后读取 `genre-prose-cards/` 目录对应单题材卡优先、`style-genre-modules.md` 通用模块兜底,与通用正文要求、情绪/节奏召回和文风一起组装 prompt |
185
- | 设定/角色/{角色名}.md、设定/势力/{名}.md | 角色/势力 | Phase 3 细纲后增量补全(首批含主角/主要角色) | Phase 4 状态筛选/写作 |
186
- | 设定/文风.md(自定义文风·优先级最高) | 本书 | 用户自写(Claude Code 可代写);导入/拆解不覆盖 | Phase 4 每章写作前:含实质内容则取代对标文风作权威风格基 |
187
- | 对标/{书名}/文风.md | 对标书 | analyze Stage 6 输出 → story-import 显式绑定或本 skill 首次引用时同步 | Phase 4 每章写作前(文风召回;有自定义文风时降为参考/句长兜底) |
188
- | 大纲/卷纲_第X卷.md | 卷 | Phase 3 | Phase 4 写卷首章前 |
189
- | 追踪/_tracking-state.json | 全书 | Phase 3 初始化 | 唯一结构化权威,不进正文 prompt;每章运行 `tracking_commit.py check` 读取章号和修订号 |
190
- | 追踪/伏笔.md | 全书当前视图 | Phase 3 初始化 | 续写状态卡缺项时按 ID 定点查询;每 ID 只一行 |
191
- | 追踪/时间线/{作者真相.md,读者已知.md} | 全书当前事实/认知派生视图 | Phase 3 初始化 | 按作者真相或读者认知的实际问题选择视图 |
192
- | 对标/{书名}/拆文报告.md | 对标书 | 用户手动+analyze | Phase 2 核心设定、Phase 3 大纲、Phase 4 写作 |
193
- | 追踪/逐章记录/第NNN章.md | 章 | Phase 4 每章事务 | 日更不读;目标 ≤1536 字节、硬上限 3072 字节,按需查询历史原因 |
194
- | 追踪/上下文.md(续写状态卡,≤12KB) | 全书当前状态 | Phase 3 初始化 | 日更每章整份读;由事务工具整份重建,固定 7 栏 |
195
- | 参考资料/{topic}.md | 按需 | Phase 4(story-researcher 输出) | Phase 4 后续章节写作时复用 |
196
- | 追踪/角色状态/{角色名}.md | 核心角色 | 首次进入正文或导入初始化 | 久别角色按名读取一个小快照;目标 ≤4096 字节、硬上限 8192 字节;静态人设仍读 `设定/角色/` |
197
- | 对标/{书名}/角色/{角色名}.md | 对标书 | analyze 输出 | Phase 4 模块召回(角色参考) |
198
- | 对标/{书名}/剧情/{剧情单元名}.md | 对标书 | analyze 输出 | Phase 3 卷纲选段与细纲成批(剧情单元卡「对标剧情参照」)、Phase 4 模块召回(剧情模块参考) |
199
- | 对标/{书名}/剧情/情绪模块.md | 对标书 | analyze Stage 3 输出 → story-import 显式绑定或本 skill 首次引用时同步 | Phase 2 核心设定、Phase 3 大纲、Phase 4 每章写作前(读者需求 / 情绪引擎、可复现模块选择) |
200
- | 对标/{书名}/剧情/节奏.md | 对标书 | analyze Stage 3 输出 → story-import 显式绑定或本 skill 首次引用时同步 | Phase 3 大纲、Phase 4 每章写作前(关键信息推进、情绪触动点、爆发节奏参考) |
201
- | 对标/{书名}/设定/*.md | 对标书 | analyze 输出 | Phase 2 设定参考、Phase 4 世界观约束 |
202
-
203
- **缺失文件处理**:当前主产物缺失时显式修复,不拼装降级结果:
204
- 1. **角色状态文件缺失** → 当前协议项目先运行 `tracking_commit.py check`,再重跑产生该状态的完整事务;已有正文但 `_tracking-state.json` 缺失时重新 `/story-import`。不得从前文临时推断后直接手写快照。
205
- 2. **角色、普通剧情单元或设定等非主产物子目录缺失** → 按「对标书路径查找」查找项目视图与根目录数据源,仍缺失则跳过该可选模块。本条不适用于 `剧情/情绪模块.md` 和 `剧情/节奏.md`。
206
- 3. **`剧情/情绪模块.md` / `剧情/节奏.md` 缺失** → 写前准备必须停下,设置 `missing_primary_contract: true` 并给出 `repair_action`:重跑 `/story-long-analyze` Stage 3+ 或重新 `/story-import`,不得用摘要文件假装已召回权威模块。
207
- 4. **有对标书但 `文风.md` 缺失** → 若有 `设定/文风.md`(含实质内容)走自定义文风模式继续;否则日更文风召回 fail-fast,提示先运行 `/story-long-analyze` Stage 6 并 `/story-import` 同步。**完全无对标项目**则跳过文风召回、不阻塞(有 `设定/文风.md` 时用它写作)。情绪/节奏轴(`missing_primary_contract`)独立,自定义文风模式不豁免其 fail-fast。
208
- 5. **伏笔/时间线文件缺失** → 视为当前语义检查点损坏,停止写正文;先运行 `tracking_commit.py check`,再用事务修复。卷纲/大纲中的计划不能代替已发生事实的当前检查点。
209
- 6. **`设定/题材正文提示卡.md` 缺失** → 不阻塞;写前从 `设定/题材定位.md` 精确匹配 `references/genre-prose-cards.md` 索引,并只读取 `references/genre-prose-cards/` 中对应题材单卡(高/中/低置信照原卡标注),无命中再用 `references/style-genre-modules.md` 通用流派模块即时生成短 `genre_prose_card`。只有 `设定/题材定位.md` 也缺失时,退回细纲和目标平台做低置信题材卡,并在意图确认写明。
210
-
211
- **对标分析权威优先级(权威读取顺序)**:
212
- 1. `剧情/情绪模块.md` 是读者需求 / 情绪引擎、爽文套路框架、可复现模块和重组指南的权威来源。
213
- 2. `剧情/节奏.md` 是关键信息推进、章节扩写技法聚合、情绪触动点和爆发节奏的权威来源。
214
- 3. `文风.md` 只管句长、标点、对话潜台词、原文锚点等风格;它不能覆盖情绪模块或节奏意图。**自定义文风 `设定/文风.md`(用户自写、不被导入/拆解覆盖)优先级高于对标 `文风.md`**:含实质内容时作权威风格基,对标文风降为参考与句长数值兜底;命中硬安全线的写法(`……` / 破折号 / 段间空行 / 碎句)仍按 narrative-writer 归一,自定义只接管句长 / 软标点 / 潜台词 / 情绪交替。
215
- 4. `章节/第K章_摘要.md` 是具体章节证据,用来校验和补足权威索引,不反向覆盖 `情绪模块.md` / `节奏.md`。
216
- 5. `拆文报告.md`、`剧情/故事线.md` 是投影/摘要;若与 `剧情/情绪模块.md` 或 `剧情/节奏.md` 冲突,写作以两个权威文件为准,并在写前准备 `gaps.conflict` 记录冲突来源。
217
-
218
- **文件组织原则:**
219
- - **人物一个一个文件**:`角色/角色名.md`,方便按需读取
220
- - **势力一个一个文件**:`势力/势力名.md`,组织/门派/家族/国家等
221
- - **世界观按主题拆分**:背景、力量体系、社会结构等各自独立
222
- - **细纲一章一个文件**:`细纲_第XXX章.md`,含钩子设计,与正文一一对应
223
- - **正文按章拆分**:每章一个文件,`第XXX章_章名.md`
224
- - 每章写完直接写入 `正文/` 目录,不要先输出到对话
133
+ #### 项目文件与产物
134
+
135
+ 创建目录、首次引用对标、定位产物或遇到文件缺失时,先完整读取 [references/project-files.md](references/project-files.md),按其中目录结构、产物映射、缺失处理和权威顺序执行;正常续写不重复加载目录表。
225
136
 
226
137
  #### 单章写作流程
227
138
 
@@ -249,91 +160,7 @@ metadata: {"openclaw":{"source":"https://github.com/zenstory-ai/oh-story-claudec
249
160
 
250
161
  ## 参考资料索引
251
162
 
252
- 按场景加载,不一次全部加载。
253
-
254
- 各场景的完整步骤按需加载,本文件只保留场景路由、项目文件结构与产物契约、参考索引:开书三阶段(Phase 1-3)在 `references/workflow-setup.md`,单章正文与质量检查(Phase 4-5)在 `references/workflow-chapter.md`,日更批量在 `references/workflow-daily.md`,回炉大修在 `references/workflow-revision.md`。
255
-
256
- ### Phase 1:选题方向
257
-
258
- | 场景 | 加载文件 |
259
- |------|---------|
260
- | 确定题材类型 | `references/long-genre-catalog.md` |
261
- | 判断市场方向 | `references/genre-readers.md` |
262
- | 特殊题材考量 | `references/plot-special-topics.md` |
263
- | 女频长篇(题材/文案/平台/感情线) | `references/female-audience-writing.md` |
264
-
265
- ### Phase 2:核心设定
266
-
267
- | 场景 | 加载文件 |
268
- |------|---------|
269
- | 设定人物 | `references/character-basics.md` |
270
- | 设计关系 | `references/character-relations.md` |
271
- | 题材框架与定位 | `references/long-genre-catalog.md` + `references/long-genre-mechanics.md` |
272
- | 创建 artifact | `references/artifact-protocols.md` |
273
- | 读者契约与主角高光 | `references/reader-contract-and-progression.md` |
274
-
275
- ### Phase 3:大纲搭建
276
-
277
- | 场景 | 加载文件 |
278
- |------|---------|
279
- | 搭建大纲 | `references/outline-methods.md` |
280
- | 设计矛盾与结构 | `references/outline-conflict.md` |
281
- | 深度结构设计 | `references/outline-structure-theory.md` |
282
- | 节奏与升级感 | `references/outline-rhythm.md` |
283
- | 小纲与卡文 | `references/plot-core-methods.md` |
284
- | 选择叙事框架 | `references/plot-frameworks.md` |
285
- | 题材结构 | `references/genre-prose-cards.md` 索引 + `references/genre-prose-cards/` 单题材卡 |
286
- | 黄金三章 | `references/opening-design.md` |
287
- | 情绪弧线 | `references/emotional-arc-design.md` |
288
- | 契约/终局储备/剧情单元安全审查 | `references/reader-contract-and-progression.md` |
289
- | 反转设计 | `references/long-reversal.md` |
290
- | 细纲结构验收 | `scripts/check-outline-contract.js`(新建/补建后跑,只判字段与表结构) |
291
-
292
- ### Phase 4:正文写作
293
-
294
- | 场景 | 加载文件 |
295
- |------|---------|
296
- | 章节钩子 | `references/long-chapter-hooks.md` |
297
- | 悬念设计 | `references/long-suspense.md` |
298
- | 题材正文提示卡 / 题材分类卡 | `references/genre-prose-cards.md` 索引 + `references/genre-prose-cards/` 单题材卡目录(按题材分类优先) + `references/style-genre-modules.md`(通用流派补充) |
299
- | 打斗/装逼 | `references/style-combat-face.md` |
300
- | 写作技法 | `references/style-craft.md` |
301
- | 商业创作核心方法 | `references/commercial-core-methods.md` |
302
- | 对话 | `references/dialogue-mastery.md` |
303
- | 人物深化 | `references/character-design-methods.md` |
304
- | 情绪技法 + 叙事单元 | `references/plot-emotion-system.md` + `references/emotional-methods.md` |
305
- | 写作技法全程参考 | `references/writing-craft.md` |
306
- | 格式 | `references/long-format.md`(章节、段落、对话、标点与工程元信息) |
307
- | 状态追踪协议 | `references/state-tracking.md` |
308
- | 当前剧情单元与契约校准 | `references/reader-contract-and-progression.md` |
309
-
310
- ### Phase 5:质量检查
311
-
312
- | 场景 | 加载文件 |
313
- |------|---------|
314
- | 质量检查 | `references/long-chapter-quality.md` + `references/reader-contract-and-progression.md` |
315
- | 禁用词扫描 | `references/banned-words.md` |
316
- | AI句式脚本复扫 | `scripts/check-ai-patterns.js` |
317
- | 去AI味 | `references/anti-ai-writing.md` |
318
-
319
- ### 按主题快速定位(横切主题)
320
-
321
- 有些主题横跨多个阶段、散在多个文件里。下表给每个主题一个**权威文件**(先读它,通常够用),配套文件只在需要那个角度时再加载。括号是该文件里对应的小节。
322
-
323
- | 主题 | 权威文件(先读) | 配套文件(按角度补充) |
324
- |------|-----------------|----------------------|
325
- | 爽点(按意图分流) | **`references/plot-emotion-system.md`**(爽点设计体系:本质/六种类型/倒推法——"怎么设计爽点"先读这个) | 翻盘/高潮式爽点→`references/plot-core-methods.md`(假胜→崩解)· 打脸/装逼释放→`references/style-combat-face.md`· 题材声线与长线约束→`references/genre-prose-cards.md`· 爽文循环/多层→`references/outline-methods.md`·`references/outline-conflict.md` |
326
- | 情绪模块 | **`对标/{书名}/剧情/情绪模块.md`(项目/书级权威)**;无对标或设计新模块时再读 `references/plot-emotion-system.md` | `references/outline-rhythm.md` 只作理论参考;不得覆盖对标书权威模块 |
327
- | 节奏 | **`对标/{书名}/剧情/节奏.md`(项目/书级权威)**;无对标或设计新节奏时再读 `references/outline-rhythm.md` | `references/plot-core-methods.md` 只作理论参考;不得覆盖对标书权威节奏 |
328
- | 高潮 | **`references/plot-core-methods.md`**(高潮构建公式:蓄能→假胜→崩解) | `references/outline-rhythm.md`(高潮分类与反推)· `references/outline-methods.md`(八节点故事结构:结构定位) |
329
- | 金手指 | **`references/plot-special-topics.md`**(金手指拆分理解与战力防崩 + 进阶设计) | `references/outline-conflict.md`(金手指与身份:四点统一) |
330
- | 感情线 | **`references/character-relations.md`**(好感度体系/四阶段 + 男女频差异) | `references/outline-conflict.md`(感情线设计)· `references/style-combat-face.md`(后宫文女主 / 男频极简爱情线构型)· `references/plot-special-topics.md`(爱情线提纯策略) |
331
- | 反转 | **`references/long-reversal.md`**(单元/卷级/全书反转、铺垫、有效性自检) | `references/plot-core-methods.md`(假胜:先给希望再击碎) |
332
- | 人物 | **`references/character-basics.md`**(主角/配角/反派/动机模板速填) | `references/character-design-methods.md`(三层标签反差/九维深化)· `references/character-relations.md`(关系类型/感情线) |
333
- | 女频写作 | **`references/female-audience-writing.md`**(女频长篇:核心原则/文案/题材/感情线长线/平台) | `references/genre-readers.md`(读者心理/平台差异)· `references/character-relations.md`(感情线总框架) |
334
- | 去AI味 | **`references/anti-ai-writing.md`**(AI指纹/核心规则/Show Don't Tell) | `references/banned-words.md`(禁用词扫描)· `references/long-chapter-quality.md`(成稿检查) |
335
-
336
- ---
163
+ 阶段必读项按首屏 Reference Gate 执行;其他题材、结构与写作技法按 [参考索引](references/reference-index.md) 的加载条件选用。
337
164
 
338
165
  ## 语言
339
166