@oh-story/dsh 0.1.8 → 0.1.10

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 (360) hide show
  1. package/README.md +14 -14
  2. package/lib/client.js +237 -84
  3. package/lib/client.js.map +3 -3
  4. package/lib/drama/manifest.json +183 -77
  5. package/lib/drama/skills/short-drama/SKILL.md +5 -1
  6. package/lib/drama/skills/short-drama/scripts/creator_markdown_check.py +140 -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 +28 -0
  9. package/lib/drama/skills/short-drama-assets/references/continuity-lock.md +8 -2
  10. package/lib/drama/skills/short-drama-assets/references/voice-direction.md +28 -0
  11. package/lib/drama/skills/short-drama-edit/SKILL.md +146 -0
  12. package/lib/drama/skills/short-drama-edit/agents/openai.yaml +4 -0
  13. package/lib/drama/skills/short-drama-edit/assets/remotion/README.md +60 -0
  14. package/lib/drama/skills/short-drama-edit/assets/remotion/package.json +15 -0
  15. package/lib/drama/skills/short-drama-edit/assets/remotion/remotion.config.ts +6 -0
  16. package/lib/drama/skills/short-drama-edit/assets/remotion/src/Root.tsx +26 -0
  17. package/lib/drama/skills/short-drama-edit/assets/remotion/src/Subtitles.tsx +88 -0
  18. package/lib/drama/skills/short-drama-edit/assets/remotion/src/font.ts +46 -0
  19. package/lib/drama/skills/short-drama-edit/assets/remotion/src/index.ts +4 -0
  20. package/lib/drama/skills/short-drama-edit/assets/remotion/src/schema.ts +32 -0
  21. package/lib/drama/skills/short-drama-edit/assets/remotion/tsconfig.json +13 -0
  22. package/lib/drama/skills/short-drama-edit/assets//345/211/252/350/276/221/345/215/225.md +43 -0
  23. package/lib/drama/skills/short-drama-edit/references/cut-craft.md +38 -0
  24. package/lib/drama/skills/short-drama-edit/references/delivery-verify.md +29 -0
  25. package/lib/drama/skills/short-drama-edit/references/generated-footage.md +54 -0
  26. package/lib/drama/skills/short-drama-edit/references/sound-and-subtitles.md +60 -0
  27. package/lib/drama/skills/short-drama-edit/references/stage-contract.md +51 -0
  28. package/lib/drama/skills/short-drama-edit/scripts/edit_tool.py +1156 -0
  29. package/lib/drama/skills/short-drama-edit/scripts/selftest.py +520 -0
  30. package/lib/drama/skills/short-drama-image-prompts/SKILL.md +2 -0
  31. package/lib/drama/skills/short-drama-image-prompts/assets/image-prompts.md +5 -0
  32. package/lib/drama/skills/short-drama-image-prompts/assets/lookdev-prompts.md +3 -0
  33. package/lib/drama/skills/short-drama-image-prompts/references/common-recipe.md +11 -0
  34. package/lib/drama/skills/short-drama-novel-analyze/references/aggregation-and-entities.md +2 -2
  35. package/lib/drama/skills/short-drama-novel-analyze/references/chapter-extraction.md +4 -1
  36. package/lib/drama/skills/short-drama-produce/SKILL.md +29 -4
  37. package/lib/drama/skills/short-drama-produce/references/adapter-contract.md +22 -0
  38. package/lib/drama/skills/short-drama-produce/references/providers/minimax-h3-video.md +13 -12
  39. package/lib/drama/skills/short-drama-produce/references/providers/minimax-speech.md +41 -0
  40. package/lib/drama/skills/short-drama-produce/references/providers/seedance.md +7 -0
  41. package/lib/drama/skills/short-drama-produce/scripts/fixture_adapter.py +18 -1
  42. package/lib/drama/skills/short-drama-produce/scripts/production_tool.py +181 -2
  43. package/lib/drama/skills/short-drama-produce/scripts/provider_adapters.py +199 -3
  44. package/lib/drama/skills/short-drama-review/SKILL.md +2 -0
  45. package/lib/drama/skills/short-drama-review/references/production-quality-gates.md +7 -0
  46. package/lib/drama/skills/short-drama-review/references/rubric-visual-motion.md +10 -0
  47. package/lib/drama/skills/short-drama-storyboard/SKILL.md +12 -1
  48. package/lib/drama/skills/short-drama-storyboard/assets/keyframe-prompts.md +4 -0
  49. package/lib/drama/skills/short-drama-storyboard/references/lighting-craft.md +39 -0
  50. package/lib/drama/skills/short-drama-storyboard/references/shot-craft.md +78 -2
  51. package/lib/drama/skills/short-drama-storyboard/references/stage-contract.md +2 -0
  52. package/lib/drama/skills/short-drama-video-prompts/SKILL.md +12 -5
  53. package/lib/drama/skills/short-drama-video-prompts/references/camera-audio-continuity.md +17 -0
  54. package/lib/drama/skills/short-drama-video-prompts/references/minimax-h3.md +76 -7
  55. package/lib/drama/skills/short-drama-video-prompts/references/motion-recipe.md +5 -2
  56. package/lib/drama/skills/short-drama-video-prompts/references/performance-action-timing.md +21 -0
  57. package/lib/drama/skills/short-drama-video-prompts/references/production-prompt-grammar.md +6 -17
  58. package/lib/drama/skills/short-drama-video-prompts/references/seedance-2.0.md +12 -3
  59. package/lib/drama/skills/short-drama-video-prompts/references/seedance-2.5.md +61 -5
  60. package/lib/drama/skills/short-drama-video-prompts/references/stage-contract.md +3 -3
  61. package/lib/drama/skills/short-drama-write/SKILL.md +11 -2
  62. package/lib/drama/skills/short-drama-write/references/screenplay-format.md +6 -0
  63. package/lib/drama/skills/short-drama-write/references/stage-contract.md +1 -0
  64. package/lib/index.js +290 -90
  65. package/lib/index.js.map +4 -4
  66. package/lib/novel-to-game/README.md +299 -59
  67. package/lib/novel-to-game/README_ZH.md +299 -56
  68. package/lib/novel-to-game/VERSION +1 -1
  69. package/lib/novel-to-game/examples/jin-ping-mei/build/BUILD_BRIEF.md +3 -1
  70. package/lib/novel-to-game/examples/jin-ping-mei/build/app/RUN.md +11 -3
  71. package/lib/novel-to-game/examples/jin-ping-mei/build/app/css/new-guofeng.css +397 -8
  72. package/lib/novel-to-game/examples/jin-ping-mei/build/app/css/style.css +0 -31
  73. package/lib/novel-to-game/examples/jin-ping-mei/build/app/js/data.js +71 -73
  74. package/lib/novel-to-game/examples/jin-ping-mei/build/app/js/engine.js +78 -89
  75. package/lib/novel-to-game/examples/jin-ping-mei/build/app/js/main.js +37 -14
  76. package/lib/novel-to-game/examples/jin-ping-mei/build/app/js/text.js +5 -5
  77. package/lib/novel-to-game/examples/jin-ping-mei/build/app/package.json +2 -1
  78. package/lib/novel-to-game/examples/jin-ping-mei/qa/README.md +11 -16
  79. package/lib/novel-to-game/examples/jin-ping-mei/qa/verification.json +11 -11
  80. package/lib/novel-to-game/examples/jin-ping-mei/qa/verify_playable_model.mjs +23 -0
  81. package/lib/novel-to-game/manifest.json +77 -87
  82. package/lib/novel-to-game/skills/game-art-direction/SKILL.md +9 -35
  83. package/lib/novel-to-game/skills/game-art-direction/references/art-direction-method.md +27 -106
  84. package/lib/novel-to-game/skills/game-build/SKILL.md +17 -35
  85. package/lib/novel-to-game/skills/game-build/references/blender-asset-workflow.md +24 -0
  86. package/lib/novel-to-game/skills/game-build/references/build-brief-contract.md +45 -82
  87. package/lib/novel-to-game/skills/game-build/references/generative-media-pipeline.md +14 -45
  88. package/lib/novel-to-game/skills/game-build/references/playable-model-contract.md +30 -65
  89. package/lib/novel-to-game/skills/game-build/references/tts-production-contract.md +13 -27
  90. package/lib/novel-to-game/skills/game-concept/SKILL.md +16 -34
  91. package/lib/novel-to-game/skills/game-concept/references/concept-method.md +28 -75
  92. package/lib/novel-to-game/skills/game-qa/SKILL.md +9 -20
  93. package/lib/novel-to-game/skills/game-qa/references/test-design-method.md +10 -6
  94. package/lib/novel-to-game/skills/game-world-design/SKILL.md +19 -32
  95. package/lib/novel-to-game/skills/game-world-design/references/narrative-design-method.md +23 -72
  96. package/lib/novel-to-game/skills/game-world-design/references/numeric-design-method.md +14 -48
  97. package/lib/novel-to-game/skills/game-world-design/references/world-design-method.md +36 -103
  98. package/lib/novel-to-game/skills/novel-game-analyze/SKILL.md +9 -18
  99. package/lib/novel-to-game/skills/novel-game-analyze/references/gameability-protocol.md +4 -4
  100. package/lib/novel-to-game/skills/novel-to-game/SKILL.md +10 -27
  101. package/lib/novel-to-game/skills/novel-to-game/references/intake-method.md +5 -6
  102. package/lib/novel-to-game/skills/novel-to-game/references/pipeline-contract.md +6 -11
  103. package/lib/oh-story/manifest.json +419 -254
  104. package/lib/oh-story/roles/chapter-extractor.md +177 -237
  105. package/lib/oh-story/roles/character-designer.md +1 -1
  106. package/lib/oh-story/roles/consistency-checker.md +4 -4
  107. package/lib/oh-story/roles/narrative-writer.md +56 -243
  108. package/lib/oh-story/roles/story-architect.md +6 -6
  109. package/lib/oh-story/roles/story-explorer.md +11 -11
  110. package/lib/oh-story/skills/story/SKILL.md +13 -7
  111. package/lib/oh-story/skills/story/VERSION +1 -1
  112. package/lib/oh-story/skills/story/references/author-memory.md +61 -29
  113. package/lib/oh-story/skills/story/scripts/author_memory_commit.py +934 -170
  114. package/lib/oh-story/skills/story-cover/SKILL.md +10 -1
  115. package/lib/oh-story/skills/story-deslop/SKILL.md +54 -229
  116. package/lib/oh-story/skills/story-deslop/references/anti-ai-writing.md +29 -56
  117. package/lib/oh-story/skills/story-deslop/references/author-memory.md +61 -29
  118. package/lib/oh-story/skills/story-deslop/references/banned-words.md +3 -1
  119. package/lib/oh-story/skills/story-deslop/references/deslop-gates.md +154 -0
  120. package/lib/oh-story/skills/story-deslop/references/style-resolution.md +27 -0
  121. package/lib/oh-story/skills/story-deslop/scripts/author_memory_commit.py +934 -170
  122. package/lib/oh-story/skills/story-deslop/scripts/check-ai-patterns.js +6 -1
  123. package/lib/oh-story/skills/story-deslop/scripts/check-degeneration.js +39 -20
  124. package/lib/oh-story/skills/story-deslop/scripts/normalize-punctuation.js +10 -5
  125. package/lib/oh-story/skills/story-deslop/scripts/style-whitelist.js +39 -0
  126. package/lib/oh-story/skills/story-import/SKILL.md +78 -82
  127. package/lib/oh-story/skills/story-import/references/character-state-reverse.md +1 -1
  128. package/lib/oh-story/skills/story-import/references/format-and-structure.md +2 -2
  129. package/lib/oh-story/skills/story-import/references/state-tracking.md +4 -69
  130. package/lib/oh-story/skills/story-import/references/structure-mapping-long.md +10 -8
  131. package/lib/oh-story/skills/story-import/references/tracking-initialization.md +31 -0
  132. package/lib/oh-story/skills/story-import/references/tracking-transaction.md +9 -34
  133. package/lib/oh-story/skills/story-import/scripts/check-outline-contract.js +197 -15
  134. package/lib/oh-story/skills/story-import/scripts/tracking_commit.py +210 -2
  135. package/lib/oh-story/skills/story-import/scripts/wordcount_core.py +3 -0
  136. package/lib/oh-story/skills/story-long-analyze/SKILL.md +91 -258
  137. package/lib/oh-story/skills/story-long-analyze/references/author-facing.md +245 -0
  138. package/lib/oh-story/skills/story-long-analyze/references/deconstruction-notes.md +2 -2
  139. package/lib/oh-story/skills/story-long-analyze/references/inspiration-library.md +105 -0
  140. package/lib/oh-story/skills/story-long-analyze/references/material-decomposition.md +113 -105
  141. package/lib/oh-story/skills/story-long-analyze/references/output-templates.md +169 -125
  142. package/lib/oh-story/skills/story-long-analyze/references/pipeline-ops.md +172 -64
  143. package/lib/oh-story/skills/story-long-analyze/references/semantic-acceptance-fixtures.md +84 -0
  144. package/lib/oh-story/skills/story-long-analyze/references/style-profile-generator.md +42 -132
  145. package/lib/oh-story/skills/story-long-analyze/references/style-profile-protocol.md +5 -5
  146. package/lib/oh-story/skills/story-long-analyze/scripts/build_chapter_index.py +466 -0
  147. package/lib/oh-story/skills/story-long-analyze/scripts/inspect_existing_assets.py +702 -0
  148. package/lib/oh-story/skills/story-long-analyze/scripts/inspiration_index.py +864 -0
  149. package/lib/oh-story/skills/story-long-analyze/scripts/manage_analysis_run.py +1106 -0
  150. package/lib/oh-story/skills/story-long-analyze/scripts/render_relation_chart.py +425 -0
  151. package/lib/oh-story/skills/story-long-scan/SKILL.md +4 -1
  152. package/lib/oh-story/skills/story-long-write/SKILL.md +52 -216
  153. package/lib/oh-story/skills/story-long-write/references/anti-ai-writing.md +29 -56
  154. package/lib/oh-story/skills/story-long-write/references/artifact-protocols.md +72 -12
  155. package/lib/oh-story/skills/story-long-write/references/author-memory.md +61 -29
  156. package/lib/oh-story/skills/story-long-write/references/banned-words.md +3 -1
  157. package/lib/oh-story/skills/story-long-write/references/benchmark-recall.md +20 -0
  158. package/lib/oh-story/skills/story-long-write/references/cross-book-recall.md +26 -0
  159. package/lib/oh-story/skills/story-long-write/references/dialogue-mastery.md +10 -4
  160. package/lib/oh-story/skills/story-long-write/references/emotional-methods.md +2 -2
  161. package/lib/oh-story/skills/story-long-write/references/long-chapter-quality.md +6 -15
  162. package/lib/oh-story/skills/story-long-write/references/long-format.md +2 -0
  163. package/lib/oh-story/skills/story-long-write/references/outline-structure-theory.md +2 -0
  164. package/lib/oh-story/skills/story-long-write/references/project-files.md +110 -0
  165. package/lib/oh-story/skills/story-long-write/references/reader-contract-and-progression.md +12 -4
  166. package/lib/oh-story/skills/story-long-write/references/reference-index.md +86 -0
  167. package/lib/oh-story/skills/story-long-write/references/style-combat-face.md +1 -1
  168. package/lib/oh-story/skills/story-long-write/references/style-craft.md +9 -29
  169. package/lib/oh-story/skills/story-long-write/references/style-genre-modules.md +1 -1
  170. package/lib/oh-story/skills/story-long-write/references/style-resolution.md +27 -0
  171. package/lib/oh-story/skills/story-long-write/references/tracking-initialization.md +31 -0
  172. package/lib/oh-story/skills/story-long-write/references/tracking-transaction.md +9 -34
  173. package/lib/oh-story/skills/story-long-write/references/workflow-chapter.md +88 -118
  174. package/lib/oh-story/skills/story-long-write/references/workflow-daily.md +55 -119
  175. package/lib/oh-story/skills/story-long-write/references/workflow-revision.md +15 -11
  176. package/lib/oh-story/skills/story-long-write/references/workflow-setup.md +73 -54
  177. package/lib/oh-story/skills/story-long-write/references/writer-prompt-fallback.md +22 -0
  178. package/lib/oh-story/skills/story-long-write/references/writing-craft.md +63 -4
  179. package/lib/oh-story/skills/story-long-write/scripts/author_memory_commit.py +934 -170
  180. package/lib/oh-story/skills/story-long-write/scripts/build_writer_prompt.py +531 -0
  181. package/lib/oh-story/skills/story-long-write/scripts/check-ai-patterns.js +6 -1
  182. package/lib/oh-story/skills/story-long-write/scripts/check-degeneration.js +39 -20
  183. package/lib/oh-story/skills/story-long-write/scripts/check-outline-contract.js +197 -15
  184. package/lib/oh-story/skills/story-long-write/scripts/check-outline-copy.js +90 -23
  185. package/lib/oh-story/skills/story-long-write/scripts/normalize-punctuation.js +10 -5
  186. package/lib/oh-story/skills/story-long-write/scripts/outline_view.py +285 -0
  187. package/lib/oh-story/skills/story-long-write/scripts/storyctl.py +58 -0
  188. package/lib/oh-story/skills/story-long-write/scripts/style-whitelist.js +39 -0
  189. package/lib/oh-story/skills/story-long-write/scripts/tracking_commit.py +210 -2
  190. package/lib/oh-story/skills/story-long-write/scripts/wordcount_core.py +3 -0
  191. package/lib/oh-story/skills/story-review/SKILL.md +80 -87
  192. package/lib/oh-story/skills/story-review/references/anti-ai-writing.md +29 -56
  193. package/lib/oh-story/skills/story-review/references/author-memory.md +61 -29
  194. package/lib/oh-story/skills/story-review/references/banned-words.md +3 -1
  195. package/lib/oh-story/skills/story-review/references/dialogue-mastery.md +10 -4
  196. package/lib/oh-story/skills/story-review/references/review-quality.md +6 -12
  197. package/lib/oh-story/skills/story-review/references/style-resolution.md +27 -0
  198. package/lib/oh-story/skills/story-review/references/tracking-initialization.md +31 -0
  199. package/lib/oh-story/skills/story-review/references/tracking-transaction.md +9 -34
  200. package/lib/oh-story/skills/story-review/scripts/author_memory_commit.py +934 -170
  201. package/lib/oh-story/skills/story-review/scripts/check-ai-patterns.js +6 -1
  202. package/lib/oh-story/skills/story-review/scripts/check-degeneration.js +39 -20
  203. package/lib/oh-story/skills/story-review/scripts/normalize-punctuation.js +10 -5
  204. package/lib/oh-story/skills/story-review/scripts/style-whitelist.js +39 -0
  205. package/lib/oh-story/skills/story-review/scripts/tracking_commit.py +210 -2
  206. package/lib/oh-story/skills/story-review/scripts/wordcount_core.py +3 -0
  207. package/lib/oh-story/skills/story-setup/SKILL.md +58 -43
  208. package/lib/oh-story/skills/story-setup/references/agent-references/anti-ai-writing.md +29 -56
  209. package/lib/oh-story/skills/story-setup/references/agent-references/banned-words.md +3 -1
  210. package/lib/oh-story/skills/story-setup/references/agent-references/deslop-gates.md +154 -0
  211. package/lib/oh-story/skills/story-setup/references/agent-references/dialogue-mastery.md +10 -4
  212. package/lib/oh-story/skills/story-setup/references/agent-references/format-and-structure.md +2 -2
  213. package/lib/oh-story/skills/story-setup/references/agent-references/long-emotional-methods.md +2 -2
  214. package/lib/oh-story/skills/story-setup/references/agent-references/long-quality.md +1 -1
  215. package/lib/oh-story/skills/story-setup/references/agent-references/short-genre-formulas.md +1 -1
  216. package/lib/oh-story/skills/story-setup/references/agent-references/style-combat-face.md +1 -1
  217. package/lib/oh-story/skills/story-setup/references/agent-references/style-genre-modules.md +1 -1
  218. package/lib/oh-story/skills/story-setup/references/agent-references/style-resolution.md +27 -0
  219. package/lib/oh-story/skills/story-setup/references/agent-references/writing-craft.md +63 -4
  220. package/lib/oh-story/skills/story-setup/references/diagnostics.md +38 -0
  221. package/lib/oh-story/skills/story-short-analyze/SKILL.md +22 -3
  222. package/lib/oh-story/skills/story-short-analyze/references/analysis-writing-techniques.md +1 -1
  223. package/lib/oh-story/skills/story-short-analyze/references/material-decomposition.md +5 -1
  224. package/lib/oh-story/skills/story-short-analyze/references/source-story-quality.md +2 -2
  225. package/lib/oh-story/skills/story-short-scan/SKILL.md +5 -1
  226. package/lib/oh-story/skills/story-short-write/SKILL.md +15 -324
  227. package/lib/oh-story/skills/story-short-write/references/author-memory.md +61 -29
  228. package/lib/oh-story/skills/story-short-write/references/banned-words.md +3 -1
  229. package/lib/oh-story/skills/story-short-write/references/benchmark-recall.md +60 -0
  230. package/lib/oh-story/skills/story-short-write/references/dialogue-mastery.md +10 -4
  231. 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
  232. package/lib/oh-story/skills/story-short-write/references/genre-styles//345/217/214/347/224/267/344/270/273.md +1 -1
  233. 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
  234. 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
  235. 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
  236. package/lib/oh-story/skills/story-short-write/references/genre-styles//346/202/254/347/226/221.md +5 -5
  237. 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
  238. package/lib/oh-story/skills/story-short-write/references/genre-styles//347/224/234/345/256/240.md +5 -5
  239. 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
  240. package/lib/oh-story/skills/story-short-write/references/genre-writing-formulas.md +1 -1
  241. package/lib/oh-story/skills/story-short-write/references/genre-writing-techniques.md +1 -1
  242. package/lib/oh-story/skills/story-short-write/references/reference-index.md +55 -0
  243. package/lib/oh-story/skills/story-short-write/references/short-craft.md +12 -14
  244. package/lib/oh-story/skills/story-short-write/references/short-deslop.md +10 -10
  245. package/lib/oh-story/skills/story-short-write/references/short-format.md +3 -1
  246. package/lib/oh-story/skills/story-short-write/references/short-prose-quality.md +2 -2
  247. package/lib/oh-story/skills/story-short-write/references/style-resolution.md +27 -0
  248. package/lib/oh-story/skills/story-short-write/references/workflow-design.md +78 -0
  249. package/lib/oh-story/skills/story-short-write/references/workflow-draft.md +126 -0
  250. package/lib/oh-story/skills/story-short-write/references/workflow-revision.md +32 -0
  251. package/lib/oh-story/skills/story-short-write/references/writing-workflow.md +5 -5
  252. package/lib/oh-story/skills/story-short-write/scripts/author_memory_commit.py +934 -170
  253. package/lib/oh-story/skills/story-short-write/scripts/check-ai-patterns.js +6 -1
  254. package/lib/oh-story/skills/story-short-write/scripts/check-degeneration.js +39 -20
  255. package/lib/oh-story/skills/story-short-write/scripts/check-delivery-contract.js +34 -5
  256. package/lib/oh-story/skills/story-short-write/scripts/check-outline-copy.js +90 -23
  257. package/lib/oh-story/skills/story-short-write/scripts/normalize-punctuation.js +10 -5
  258. package/lib/oh-story/skills/story-short-write/scripts/style-whitelist.js +39 -0
  259. package/lib/types/client/drama-production-view.d.ts.map +1 -1
  260. package/lib/types/client/file-activity.d.ts +19 -1
  261. package/lib/types/client/file-activity.d.ts.map +1 -1
  262. package/lib/types/client/index.d.ts.map +1 -1
  263. package/lib/types/client/production-prompts.d.ts +7 -0
  264. package/lib/types/client/production-prompts.d.ts.map +1 -1
  265. package/lib/types/client/production-runtime.d.ts +33 -0
  266. package/lib/types/client/production-runtime.d.ts.map +1 -1
  267. package/lib/types/drama-adapters.d.ts +5 -3
  268. package/lib/types/drama-adapters.d.ts.map +1 -1
  269. package/lib/types/native-hooks.d.ts +52 -0
  270. package/lib/types/native-hooks.d.ts.map +1 -1
  271. package/lib/types/role-identity.d.ts +17 -0
  272. package/lib/types/role-identity.d.ts.map +1 -0
  273. package/lib/types/role-tool.d.ts.map +1 -1
  274. package/lib/types/skill-provider.d.ts.map +1 -1
  275. package/lib/video-recap/CHANGELOG.md +31 -1
  276. package/lib/video-recap/manifest.json +162 -162
  277. package/lib/video-recap/skills/video-assemble/scripts/artifacts.py +4 -9
  278. package/lib/video-recap/skills/video-assemble/scripts/assemble.py +47 -60
  279. package/lib/video-recap/skills/video-assemble/scripts/assembly_contract.py +77 -115
  280. package/lib/video-recap/skills/video-assemble/scripts/assembly_settings.py +41 -40
  281. package/lib/video-recap/skills/video-assemble/scripts/audio_automation.py +22 -32
  282. package/lib/video-recap/skills/video-assemble/scripts/audio_mix.py +102 -192
  283. package/lib/video-recap/skills/video-assemble/scripts/jianying_builders.py +14 -35
  284. package/lib/video-recap/skills/video-assemble/scripts/jianying_model.py +14 -12
  285. package/lib/video-recap/skills/video-assemble/scripts/jianying_optional.py +8 -9
  286. package/lib/video-recap/skills/video-assemble/scripts/jianying_schema.py +3 -14
  287. package/lib/video-recap/skills/video-assemble/scripts/jianying_timeline_contract.py +23 -12
  288. package/lib/video-recap/skills/video-assemble/scripts/jianying_tracks.py +1 -4
  289. package/lib/video-recap/skills/video-assemble/scripts/jianying_writer.py +24 -25
  290. package/lib/video-recap/skills/video-assemble/scripts/lib.py +31 -85
  291. package/lib/video-recap/skills/video-assemble/scripts/media.py +100 -144
  292. package/lib/video-recap/skills/video-assemble/scripts/narration_audio.py +101 -195
  293. package/lib/video-recap/skills/video-assemble/scripts/render_preflight.py +10 -21
  294. package/lib/video-recap/skills/video-assemble/scripts/source_subtitles.py +90 -169
  295. package/lib/video-recap/skills/video-assemble/scripts/subtitle_core.py +69 -122
  296. package/lib/video-recap/skills/video-assemble/scripts/subtitle_render.py +10 -17
  297. package/lib/video-recap/skills/video-assemble/scripts/timeline.py +33 -48
  298. package/lib/video-recap/skills/video-assemble/scripts/timeline_emit.py +14 -20
  299. package/lib/video-recap/skills/video-assemble/scripts/visual_render.py +135 -213
  300. package/lib/video-recap/skills/video-cut/scripts/cut_cli.py +49 -57
  301. package/lib/video-recap/skills/video-cut/scripts/cut_contract.py +38 -74
  302. package/lib/video-recap/skills/video-cut/scripts/cut_render.py +46 -95
  303. package/lib/video-recap/skills/video-cut/scripts/lib.py +23 -25
  304. package/lib/video-recap/skills/video-cut/scripts/media_geometry.py +70 -173
  305. package/lib/video-recap/skills/video-cut/scripts/narration_mapping.py +28 -53
  306. package/lib/video-recap/skills/video-cut/scripts/sentence_boundaries.py +162 -322
  307. package/lib/video-recap/skills/video-recap/references/timeline-and-jianying.md +6 -7
  308. package/lib/video-recap/skills/video-recap/scripts/doctor.py +104 -124
  309. package/lib/video-recap/skills/video-recap/scripts/final_qc.py +255 -412
  310. package/lib/video-recap/skills/video-recap/scripts/lib.py +30 -52
  311. package/lib/video-recap/skills/video-recap/scripts/materials.py +97 -120
  312. package/lib/video-recap/skills/video-recap/scripts/mimo_qc_client.py +7 -12
  313. package/lib/video-recap/skills/video-recap/scripts/mimo_qc_evidence.py +46 -97
  314. package/lib/video-recap/skills/video-recap/scripts/mimo_qc_observations.py +18 -36
  315. package/lib/video-recap/skills/video-recap/scripts/mimo_qc_payload.py +29 -47
  316. package/lib/video-recap/skills/video-recap/scripts/mimo_qc_report.py +43 -76
  317. package/lib/video-recap/skills/video-recap/scripts/mimo_qc_runner.py +2 -1
  318. package/lib/video-recap/skills/video-recap/scripts/qc_contract.py +2 -1
  319. package/lib/video-recap/skills/video-recap/scripts/recap_cli.py +2 -2
  320. package/lib/video-recap/skills/video-recap/scripts/recap_inspect.py +129 -145
  321. package/lib/video-recap/skills/video-recap/scripts/recap_review.py +27 -20
  322. package/lib/video-recap/skills/video-recap/scripts/recap_runner.py +20 -31
  323. package/lib/video-recap/skills/video-recap/scripts/recap_runtime.py +31 -106
  324. package/lib/video-recap/skills/video-recap/scripts/recap_stage_qc.py +43 -113
  325. package/lib/video-recap/skills/video-recap/scripts/recap_timeline.py +196 -377
  326. package/lib/video-recap/skills/video-script/scripts/agent_brief.py +1 -1
  327. package/lib/video-recap/skills/video-script/scripts/agent_text.py +63 -172
  328. package/lib/video-recap/skills/video-script/scripts/brief_context.py +80 -135
  329. package/lib/video-recap/skills/video-script/scripts/brief_inputs.py +125 -167
  330. package/lib/video-recap/skills/video-script/scripts/brief_timeline.py +93 -208
  331. package/lib/video-recap/skills/video-script/scripts/deslop_qc.py +20 -46
  332. package/lib/video-recap/skills/video-script/scripts/lib.py +30 -26
  333. package/lib/video-recap/skills/video-script/scripts/narration_lint.py +145 -140
  334. package/lib/video-recap/skills/video-script/scripts/review_response.py +12 -42
  335. package/lib/video-recap/skills/video-script/scripts/review_runner.py +0 -6
  336. package/lib/video-recap/skills/video-script/scripts/speech_ownership.py +39 -100
  337. package/lib/video-recap/skills/video-script/scripts/timeline_fusion.py +33 -124
  338. package/lib/video-recap/skills/video-understanding/scripts/agent_brief.py +1 -1
  339. package/lib/video-recap/skills/video-understanding/scripts/agent_text.py +63 -172
  340. package/lib/video-recap/skills/video-understanding/scripts/asr.py +1 -2
  341. package/lib/video-recap/skills/video-understanding/scripts/brief_context.py +80 -135
  342. package/lib/video-recap/skills/video-understanding/scripts/brief_inputs.py +125 -167
  343. package/lib/video-recap/skills/video-understanding/scripts/brief_timeline.py +93 -208
  344. package/lib/video-recap/skills/video-understanding/scripts/consolidate.py +1 -1
  345. package/lib/video-recap/skills/video-understanding/scripts/deslop_qc.py +20 -46
  346. package/lib/video-recap/skills/video-understanding/scripts/lib.py +31 -26
  347. package/lib/video-recap/skills/video-understanding/scripts/narration_lint.py +145 -140
  348. package/lib/video-recap/skills/video-understanding/scripts/speech_ownership.py +39 -100
  349. package/lib/video-recap/skills/video-understanding/scripts/timeline_fusion.py +33 -124
  350. package/lib/video-recap/skills/video-understanding/scripts/vlm.py +1 -4
  351. package/lib/video-recap/skills/video-voiceover/scripts/dub.py +7 -13
  352. package/lib/video-recap/skills/video-voiceover/scripts/fish_audio.py +12 -30
  353. package/lib/video-recap/skills/video-voiceover/scripts/lib.py +98 -131
  354. package/lib/video-recap/skills/video-voiceover/scripts/tts_audio.py +17 -28
  355. package/lib/video-recap/skills/video-voiceover/scripts/voiceover.py +151 -240
  356. package/package.json +45 -45
  357. package/lib/novel-to-game/skills/game-world-design/references/dialogue-design-method.md +0 -59
  358. package/lib/novel-to-game/skills/game-world-design/references/game-writing-craft.md +0 -53
  359. package/lib/novel-to-game/skills/novel-to-game/references/intake-benchmark-reference.md +0 -42
  360. package/lib/oh-story/skills/story-long-write/references/state-tracking.md +0 -108
@@ -1,75 +1,10 @@
1
- # 状态追踪协议
1
+ # 角色状态记录格式
2
2
 
3
- > 本文件定义"本节速记"的提取逻辑和"角色状态记录"的格式。写作 skill 在写前准备的状态筛选步骤中加载此文件。
4
-
5
- ---
6
-
7
- ## 本节速记
8
-
9
- 写作每一章/每一节前,从所有已加载的上下文中筛选出只与本节相关的信息。目的是避免全量加载导致 LLM 上下文被无关信息稀释。
10
-
11
- ### 筛选逻辑
12
-
13
- 从上下文中提取三类信息:
14
-
15
- 1. **当前状态**:本章涉及角色的最新能力、关系变化、公众形象
16
- 2. **历史因果**:与本章事件直接相关的伏笔成因、前史事件
17
- 3. **世界约束**:本章涉及的世界观规则(力量体系、社会规则、地理限制)
18
-
19
- ### 筛选标准
20
-
21
- **只保留"如果不知道这个,本章会写错"的信息。**
22
-
23
- 具体判断方法:
24
- - 本章细纲中提到了某个角色 → 保留该角色的当前状态
25
- - 本章有伏笔回收 → 保留伏笔的埋设细节和前文铺垫
26
- - 本章涉及特定地点/能力/规则 → 保留相关世界观约束
27
- - 纯背景知识(与本章事件无因果关联) → 丢弃
28
-
29
- ### 输出格式
30
-
31
- 筛选后输出一个简洁的"本节速记":
32
-
33
- ```
34
- ## 本节速记(第{N}章)
35
-
36
- ### 角色状态
37
- {角色A}:{一句话当前状态,含最近变化}
38
- {角色B}:{一句话当前状态}
39
-
40
- ### 相关伏笔/前史
41
- {伏笔1}:{埋设细节,{埋设章节}},本章需要{回收/推进}
42
-
43
- ### 世界约束
44
- {约束1}:{与本章相关的规则/设定}
45
- ```
46
-
47
- **示例(demo《让你管账号,你高燃混剪炸全网》第 10 章):**
48
- ```
49
- ## 本节速记(第10章)
50
-
51
- ### 角色状态
52
- 江晨:火箭军文工团宣传兵,《诸君,且听龙吟》已爆红,正从军宣新人升为军内认可的创作者
53
- 钟嘉嘉:军报记者,采访稿已经过审,与江晨从采访关系转为稳定合作
54
- 周薄森:文工团副团长,已从担心江晨惹事转为认可其创作能力
55
-
56
- ### 相关伏笔/前史
57
- 五天百万粉任务:第1章发布,第10章仍未结算;本章只推进声量,留到第11章结算
58
- 专业团队重拍:本章用高清专业版“缺了灵魂”反衬江晨手机原版不可替代
59
-
60
- ### 世界约束
61
- 军宣作品采用要经过组织决策;江晨可以靠作品效果赢得认可,不能跳过军内流程直接拍板
62
- ```
63
-
64
- ---
65
-
66
- ## 角色状态记录格式
67
-
68
- > ⚠️ **本节仅适用于长篇写作。** 短篇通常不需要独立角色状态追踪。
3
+ > story-import 反推角色状态(character-state-reverse.md)时按本格式写 `追踪/角色状态/{角色名}.md`。
69
4
 
70
5
  动态状态按核心角色拆成 `追踪/角色状态/{角色名}.md`,由 `tracking_commit.py` 根据事务 JSON 整份覆盖;静态原始人设仍在 `设定/角色/{角色名}.md`。只为后续会复用的主角、反派、核心配角建快照,不为路人、一次性功能角色建文件。
71
6
 
72
- ### 格式
7
+ ## 格式
73
8
 
74
9
  ```markdown
75
10
  # 江晨|当前状态
@@ -98,7 +33,7 @@
98
33
  - 钟嘉嘉所谓“只猜对一半”仍未解释
99
34
  ```
100
35
 
101
- ### 更新规则
36
+ ## 更新规则
102
37
 
103
38
  1. 每章只记录身份、位置、目标、身心状态、能力资源、关系、已知信息、未结事项中真正发生变化的内容。
104
39
  2. 核心复用角色发生变化时,在同一事务的 `character_changes` 写变化,并在 `character_snapshots` 提交其**截至当前已写最后一章**的完整快照;工具以快照是否存在判断核心/临时角色,整份覆盖核心角色小文件,不追加历史。
@@ -33,6 +33,8 @@ Phase 3-L 长篇结构迁移的详细映射规则和模板。将 `拆文库/{导
33
33
  | `剧情/散落情节.md` | `大纲/大纲.md` 附录或对应卷纲 | 合并到相关卷的大纲 |
34
34
  | — | `追踪/上下文.md` | 由初始化事务生成续写状态卡(固定 7 栏),≤12288 字节 |
35
35
 
36
+ 旧拆文的目录或字段名与上表不同时,先建立一次“旧路径 → 当前目标”的来源映射,再按实际可读内容转换;不要为了改名复制出第二套拆文真源。`剧情/节奏.md`、`剧情/情绪模块.md` 或主题化设定缺失时,旧内容能支持的导入步骤照常执行,对应摘要写「未知/待增强」;只有用户要启用依赖这些资料的新对标召回时,才回到 story-long-analyze 做按需增强。
37
+
36
38
  ---
37
39
 
38
40
  ## 正文标准化规则
@@ -263,17 +265,17 @@ A<->B:关系类型 | 情感 | 描述(50-200字)| 演变轨迹
263
265
 
264
266
  | 摘要字段 | 细纲字段 | 转换方式 |
265
267
  |---------|---------|---------|
266
- | 关键事件 | 核心事件 | 直接复用 |
268
+ | 关键事件 + 局面结果 | 核心事件 | 合并为“谁采取什么行动 → 局面如何变化”;旧摘要没有 `局面结果` 时只用 `关键事件` |
267
269
  | 章节字数 | 字数目标 + 字数口径 | 对原文章节运行 `storyctl.py wordcount measure`,写入 `actual` 与 `visible_chars_v1` |
268
- | 章节基调 / 情绪曲线 | 目标情绪 | 从摘要提取;缺失写 `[待补充]` |
269
- | 第一个情节点 | 章首钩子 | 只作为证据,设计目标标 `[待补充]` |
270
+ | `基调:` | 目标情绪 | 读取紧张/轻松/悲伤/热血/爽/甜/温馨/恐怖/压抑/其他枚举;缺失写 `[待补充]` |
271
+ | 章尾钩子 | 章首承接证据 | 作为下一章开篇需要承接的等待;新的章首钩子设计目标仍标 `[待补充]` |
270
272
  | 爽点类情节点 | 爽点 | 从情节点类型推断;没有则写“无显性爽点 / [待补充]” |
271
- | 情节点起承转合 | 内容概括(起因/发展/转折/高潮/结尾) | 按情节点顺序归纳;证据不足写 `[待补充]` |
273
+ | 情节点起承转合 + 因果 | 内容概括(起因/发展/转折/高潮/结尾) | 按情节点顺序归纳,用因果链校正起因与转折;证据不足写 `[待补充]` |
272
274
  | 主线/支线/任务线索 | 情节安排(主线/辅线/事件线/感情线/逻辑线) | 从剧情单元索引与摘要反推;无证据的辅线/感情线写“无”或 `[待补充]`,不得杜撰 |
273
- | 出场角色 / 关键物件 | 人物关系和出场顺序 | 按摘要出现顺序列出;关系变化只写有证据的“前 → 后”,缺失写 `[待补充]` |
274
- | 全部情节点 | 情节细化 / 情节点序列 | 按表格逐行写(# / 情节点 / 功能标签 / 执行边界);功能或边界不明写 `[待补充]`,不反推逐点字数配额 |
275
+ | 涉及 + 状态变化 | 人物关系和出场顺序 | `涉及` 给出候选人物,`状态变化` 只写有证据的“前 → 后”;关键物件从证据或旧情节点补充,缺失写 `[待补充]` |
276
+ | 全部情节点 | 情节细化 / 情节点序列 | 按表格逐行写(# / 情节点 / 功能标签 / 执行边界);保持原顺序,功能或边界不明写 `[待补充]`,不反推逐点字数配额 |
275
277
  | 胜负/反转/收益损失 | 行动成本(可无)/收益归属 | 有明确证据才填写;行动成本可无、不硬造;否则 `[待补充]` |
276
- | 最后一个情节点 / 悬念类情节点 | 结尾设定和钩子 | 收束状态可归纳;章尾钩子设计目标标 `[待补充]` |
278
+ | 章尾钩子 + 局面结果 | 结尾设定和钩子 | 局面结果写收束状态,章尾钩子写已存在的等待;未来设计仍标 `[待补充]` |
277
279
 
278
280
  ---
279
281
 
@@ -410,7 +412,7 @@ A<->B:关系类型 | 情感 | 描述(50-200字)| 演变轨迹
410
412
  | `拆文库/{对标书名}/剧情/节奏.md` | `{项目}/对标/{对标书名}/剧情/节奏.md` | 日更选择 `rhythm_reference` 的必备权威文件;缺失则不登记该对标 |
411
413
  | `拆文库/{对标书名}/剧情/情绪模块.md` | `{项目}/对标/{对标书名}/剧情/情绪模块.md` | 日更选择 `selected_emotion_module` 的必备权威文件;缺失则不登记该对标 |
412
414
  | `拆文库/{对标书名}/剧情/*.md` | `{项目}/对标/{对标书名}/剧情/*.md` | 剧情单元、故事线、散落情节等剧情资产;与权威节奏/情绪文件冲突时以后者为准 |
413
- | `拆文库/{对标书名}/章节/*.md`(第N章_摘要.md + 黄金三章 第1-3章_深度拆解.md)| `{项目}/对标/{对标书名}/章节/*.md` | 匹配章证据,含「关键信息与扩写技法」 |
415
+ | `拆文库/{对标书名}/章节/*.md`(第N章_摘要.md + 黄金三章 第1-3章_深度拆解.md)| `{项目}/对标/{对标书名}/章节/*.md` | 匹配章证据;摘要读取概要、关键事件、局面结果、涉及、状态变化与情节点序列(含类型、主题标签与基调),黄金三章另含深度写法 |
414
416
  | `拆文库/{对标书名}/角色/*.md` | `{项目}/对标/{对标书名}/角色/*.md` | 角色功能位、关系与反应层参考 |
415
417
  | `拆文库/{对标书名}/设定/` | `{项目}/对标/{对标书名}/设定/` | 世界观、势力、金手指等设定约束参考 |
416
418
  | `拆文库/{对标书名}/拆文报告.md` | `{项目}/对标/{对标书名}/拆文报告.md` | 人类可读摘要投影 |
@@ -0,0 +1,31 @@
1
+ # 追踪初始化事务
2
+
3
+ ## 初始化事务
4
+
5
+ 新书从第 0 章初始化。`story-import` 导入已有小说时把最后完整章写入 `last_chapter=N`;第 1..N 章不伪造日更记录,常规续写从 N+1 章开始。
6
+
7
+ ```json
8
+ {
9
+ "schema_version": 1,
10
+ "book_title": "让你管账号,你高燃混剪炸全网",
11
+ "last_chapter": 0,
12
+ "context": {
13
+ "position": {
14
+ "volume": "第一卷·军宣整顿",
15
+ "volume_start_chapter": 1,
16
+ "story_time": "江晨到火箭军文工团报到前",
17
+ "scene": "火箭军文工团"
18
+ },
19
+ "long_term_constraints": ["军宣爽点要用作品效果和围观反应链兑现,不能只靠系统播报"],
20
+ "active_character_names": [],
21
+ "continuity_risks": [],
22
+ "recent_chapters": [],
23
+ "next_chapter_commitments": ["让江晨报到,并落下五天百万粉的新手任务"]
24
+ },
25
+ "character_snapshots": {},
26
+ "foreshadow": [],
27
+ "timeline_events": []
28
+ }
29
+ ```
30
+
31
+ 导入初始化时直接传入当前核心角色快照、伏笔当前行、时间线事件和固定 7 栏状态输入。阶段/卷级回看按需查询正文,不作为每章强一致追踪产物。
@@ -18,24 +18,25 @@ Markdown 只负责给作者和 Agent 阅读,工具不再反向解析 Markdown
18
18
  先按运行环境探测 Python 3 解释器(依次尝试 `python3`、`python`、`py -3`)。追踪事务脚本使用当前 skill 根目录;字数与章节闭环统一使用 `story-long-write` skill 根目录:
19
19
 
20
20
  ```text
21
- {PYTHON} {当前 skill 根}/scripts/tracking_commit.py init --project {书项目根} --input {初始化事务.json}
21
+ {PYTHON} {当前 skill 根}/scripts/tracking_commit.py init --project {书项目根} --input {书项目根}/.story/work/init.json
22
22
  {PYTHON} {当前 skill 根}/scripts/tracking_commit.py check --project {书项目根}
23
- {PYTHON} {story-long-write skill 根}/scripts/storyctl.py wordcount checkpoint --file {前半段临时文件} --target {目标} --chapter {N}
23
+ {PYTHON} {当前 skill 根}/scripts/tracking_commit.py draft --project {书项目根} --chapter {N}
24
24
  {PYTHON} {story-long-write skill 根}/scripts/storyctl.py chapter check --project {书项目根} --chapter {N}
25
- {PYTHON} {story-long-write skill 根}/scripts/storyctl.py chapter commit --project {书项目根} --chapter {N} --input {逐章事务.json}
26
- {PYTHON} {story-long-write skill 根}/scripts/storyctl.py chapter accept-current-length --project {书项目根} --chapter {N} --input {逐章事务.json}
25
+ {PYTHON} {story-long-write skill 根}/scripts/storyctl.py chapter commit --project {书项目根} --chapter {N} --input {书项目根}/.story/work/第{NNN}章/tracking.json
26
+ {PYTHON} {story-long-write skill 根}/scripts/storyctl.py chapter accept-current-length --project {书项目根} --chapter {N} --input {书项目根}/.story/work/第{NNN}章/tracking.json
27
27
  ```
28
28
 
29
29
  - `init`:只在 `_tracking-state.json` 不存在时执行,绝不覆盖已初始化项目。
30
- - `wordcount checkpoint`:纯测量;返回当前实际字数、用户带与剩余用户区间,不写正文、不写 tracking、不做语义判断。每章最多调用一次。
31
- - `chapter check`:重新读取当前正文与细纲目标,返回确定性长度状态、现有 blocking quality、`state_revision` 和当前可执行动作,不保存 approval。`under` 不提供自动补写;`over` 额外返回一次净删型 `compress-once` 及进入内带/用户带所需的机器删除区间。
30
+ - `draft`:按当前 state 把逐章事务预填到 `.story/work/第NNN章/tracking.json`(修订号、模式、章名、`context` 四项当前值),并输出各文本字段的字数上限与在场核心角色的当前快照;调用方只填 `delta` 与有变化角色的快照。
31
+ - `wordcount measure` / `wordcount checkpoint`:纯测量入口;不写正文、不写 tracking、不做语义判断。长篇正文只在前组写完后由父流程调用一次 `checkpoint`(见 workflow-chapter 步骤 6),整章长度由 `chapter check` 收口。
32
+ - `chapter check`:重新读取当前正文与细纲目标,返回确定性长度状态、现有 blocking quality、`state_revision` 和当前可执行动作,不保存 approval。`under` 不提供自动补写;`over` 额外返回一次净删型 `compress-once` 及回到内部区间或作者给定区间所需的删除字数。
32
33
  - `chapter commit`:再次读取当前文件、重新计数并重跑 blocking quality;只接受用户带内章节,把简短字数记录与逐章事务一起原子提交。
33
34
  - `chapter accept-current-length`:只接受带外但 quality pass 的章节;接受动作发生时重新读取、重新计数并立即原子提交,不保存可陈旧的历史决议。
34
35
  - `check`:严格验证 state schema、逐章记录连续性/规范名/体积、固定 7 栏、角色快照硬上限、派生文件集合,以及所有派生视图与 state 的逐字一致性。
35
36
 
36
37
  每本书由 `追踪/.tracking-commit.lock` 串行写事务,`expected_state_revision` 再拒绝基于旧状态构造的 stale transaction。两个不同事务并发时至多一个修订成功。字数记录也在锁内对当前正文和目标重新验证,正文或目标变化会让预先构造的记录直接失败。
37
38
 
38
- 事务 JSON 是临时输入,不是项目产物:成功前必须保留;提交成功且紧随其后的 `check` 通过后立即删除,不能把 `init_transaction.json`、`chapter_*_transaction.json` 等输入长期留在书项目根目录。若文件写入失败,`_tracking-state.json` 尚未推进;修正环境后直接重跑**同一份** `commit`。append 重跑只接受内容完全相同的既有逐章记录,不维护 `dirty/pending/repair` 状态机。
39
+ 事务 JSON 是临时输入,不是项目产物:只写在书目录 `.story/work/` 下(逐章事务放 `.story/work/第NNN章/tracking.json`),不写系统 `/tmp`、书根、`大纲/` 或 `正文/`;成功前必须保留,提交成功后即可删除(`storyctl.py chapter commit` / `accept-current-length` 成功时自动删除该章目录;直接调用 `tracking_commit.py commit` 时由调用方删除)——之后 `check` 失败按下文提交 `mode=revision` 新事务修复,不需要原事务。若文件写入失败,`_tracking-state.json` 尚未推进;修正环境后直接重跑**同一份** `commit`。append 重跑只接受内容完全相同的既有逐章记录,不维护 `dirty/pending/repair` 状态机。
39
40
 
40
41
  校验失败与写入失败处理方式不同:校验失败(字段非法、退役结构、容量超限)要按报错改事务本身,重跑同一份结果不变。派生视图被手改或外部改动导致 `check` 报 `derived view differs from _tracking-state.json` 时,重新提交**该章**的 `mode=revision` 事务让工具整份重建,`expected_state_revision` 取 `追踪/_tracking-state.json` 的 `state_revision` 字段——`check` 失败时只往 stderr 打 ERROR,不输出 JSON;不手改派生文件,也不删 `_tracking-state.json` 重来。手写出的逐章记录会让同章 `append` 永久报 `chapter delta N already exists with different content`——删掉那个手写文件后重跑原事务即可。
41
42
 
@@ -43,33 +44,7 @@ Markdown 只负责给作者和 Agent 阅读,工具不再反向解析 Markdown
43
44
 
44
45
  ## 初始化事务
45
46
 
46
- 新书从第 0 章初始化。`story-import` 导入已有小说时把最后完整章写入 `last_chapter=N`;第 1..N 章不伪造日更记录,常规续写从 N+1 章开始。
47
-
48
- ```json
49
- {
50
- "schema_version": 1,
51
- "book_title": "让你管账号,你高燃混剪炸全网",
52
- "last_chapter": 0,
53
- "context": {
54
- "position": {
55
- "volume": "第一卷·军宣整顿",
56
- "volume_start_chapter": 1,
57
- "story_time": "江晨到火箭军文工团报到前",
58
- "scene": "火箭军文工团"
59
- },
60
- "long_term_constraints": ["军宣爽点要用作品效果和围观反应链兑现,不能只靠系统播报"],
61
- "active_character_names": [],
62
- "continuity_risks": [],
63
- "recent_chapters": [],
64
- "next_chapter_commitments": ["让江晨报到,并落下五天百万粉的新手任务"]
65
- },
66
- "character_snapshots": {},
67
- "foreshadow": [],
68
- "timeline_events": []
69
- }
70
- ```
71
-
72
- 导入初始化时直接传入当前核心角色快照、伏笔当前行、时间线事件和固定 7 栏状态输入。阶段/卷级回看按需查询正文,不作为每章强一致追踪产物。
47
+ 仅新书或导入初始化时,执行 `init` 前必须完整读取 [tracking-initialization.md](tracking-initialization.md),按其中原始 JSON 与导入边界构造事务。已有项目续写直接使用下方逐章事务,不重复读初始化示例。
73
48
 
74
49
  调用方的逐章 JSON 不写 `wordcount`;正式入口 `chapter commit` 或 `chapter accept-current-length` 在提交当下生成并注入。最终 state 只为已提交章节保留 `metric / target / actual / status / resolution / body_sha256`,不保存 MEASURE/RESOLVE 事件、ID 链、policy fingerprint 或独立 chapter state。
75
50
 
@@ -18,11 +18,13 @@
18
18
  const fs = require('fs')
19
19
  const path = require('path')
20
20
 
21
- // 权威模板:references/workflow-setup.md「细纲(全书每章)」
21
+ // 权威模板:references/workflow-setup.md「排纲自查与细纲」里的细纲模板
22
+ // 必填只留有证据或事故撑腰的核心字段;阶段位置、章节定位、结构公式、本章标价、闭环状态、
23
+ // 写手自由区、契约风险、镜头准入、信息差触发点与「分辨率」列是可选的阅读体验字段——
24
+ // 写了照样消费,没写不拦(#383 隔离实验:只补目标情绪与主角目标就复现了补满全部字段的收益)。
22
25
  const FIELDS = [
23
- '核心事件', '字数目标', '字数口径', '阶段位置', '单元ID/位置', '目标情绪',
24
- '主角目标/关键选择', '章节定位', '本章结构公式', '章首钩子', '爽点',
25
- '本章禁止提前释放', '契约风险',
26
+ '核心事件', '字数目标', '字数口径', '单元ID/位置', '目标情绪',
27
+ '主角目标/关键选择', '章首钩子', '爽点', '本章禁止提前释放',
26
28
  ]
27
29
  const SUBSECTIONS = ['内容概括', '情节安排', '人物关系和出场顺序', '情节细化']
28
30
  const FIVE_ACT = ['起因', '发展', '转折', '高潮', '结尾']
@@ -46,11 +48,11 @@ function readUtf8(file) {
46
48
  }
47
49
  }
48
50
 
49
- function makeCheck(id, ok, file, evidence, expected, repair) {
51
+ function makeCheck(id, ok, file, evidence, expected, repair, severity = 'blocking') {
50
52
  return {
51
53
  id,
52
54
  ok,
53
- severity: 'blocking',
55
+ severity,
54
56
  file,
55
57
  evidence,
56
58
  expected,
@@ -65,7 +67,47 @@ function parseTableRow(line) {
65
67
  return trimmed.slice(1, -1).split('|').map((cell) => cell.replace(/\*\*/g, '').replace(/`/g, '').trim())
66
68
  }
67
69
 
68
- function verify(file) {
70
+ function resolveBookRoot(file, projectRoot) {
71
+ if (projectRoot) return path.resolve(projectRoot)
72
+ const parent = path.dirname(path.resolve(file))
73
+ if (path.basename(parent) === '大纲') return path.dirname(parent)
74
+ return null
75
+ }
76
+
77
+ // 项目引用须写目录路径;裸文件名可能指向 skill reference,不猜测其归属。
78
+ const REF_DIR_PREFIX = /^(?:设定|大纲|追踪|正文|读者笔记|对标)\//
79
+
80
+ function checkSettingRefs(text, name, file, projectRoot) {
81
+ const bookRoot = resolveBookRoot(file, projectRoot)
82
+ if (!bookRoot) {
83
+ return makeCheck('outline.setting-refs-exist', true, name, '未能定位书目录(细纲不在 大纲/ 下且未传 --project),跳过', '细纲引用的项目内文件真实存在', '无需修复。')
84
+ }
85
+ const refs = new Set()
86
+ const pattern = /`([^`\n]+?\.md)[^`\n]*`/g
87
+ let match
88
+ while ((match = pattern.exec(text)) !== null) {
89
+ const token = match[1].trim().replace(/\\/g, '/')
90
+ if (token.includes('{') || token.includes('}')) continue
91
+ if (REF_DIR_PREFIX.test(token) || /^\.{1,2}\//.test(token)) refs.add(token)
92
+ }
93
+ const missing = []
94
+ for (const token of refs) {
95
+ const base = /^\.{1,2}\//.test(token) ? path.dirname(path.resolve(file)) : bookRoot
96
+ try {
97
+ if (!fs.statSync(path.resolve(base, token)).isFile()) missing.push(token)
98
+ } catch { missing.push(token) }
99
+ }
100
+ return makeCheck(
101
+ 'outline.setting-refs-exist',
102
+ missing.length === 0,
103
+ name,
104
+ missing.length ? `引用的路径不是可用文件:${missing.join('、')}` : `${refs.size} 处项目内引用全部存在`,
105
+ '细纲引用的每个项目内 .md 文件都真实存在——不许把槽位指向查无实据的权威文件',
106
+ '修正引用路径;或按新增物三级先把缺的设定落档(「写了要报」直接补并登记、「先问作者」进排纲底稿的供给自查提案),再在细纲引用。'
107
+ )
108
+ }
109
+
110
+ function verify(file, projectRoot = null) {
69
111
  const name = path.basename(file)
70
112
  const read = readUtf8(file)
71
113
  const checks = []
@@ -133,21 +175,82 @@ function verify(file) {
133
175
  let header = null
134
176
  for (const line of lines) {
135
177
  const cells = parseTableRow(line)
136
- if (cells && cells.length === 4 && PLOT_HEADER_FIRST.test(cells[0])) {
178
+ // 现行模板默认四列(# / 情节点 / 功能标签 / 执行边界(禁+放)),需要时在功能标签后加「分辨率」列成五列。
179
+ // 两种都收:功能标签固定在第 3 列,执行边界一律取最后一列。
180
+ if (cells && (cells.length === 4 || cells.length === 5) && PLOT_HEADER_FIRST.test(cells[0])) {
137
181
  header = cells
138
182
  break
139
183
  }
140
184
  }
141
- const headerOk = Boolean(header) && header[2].includes('功能标签') && header[3].includes('执行边界')
185
+ const headerOk = Boolean(header)
186
+ && header[2].includes('功能标签')
187
+ && header[header.length - 1].includes('执行边界')
188
+ && (header.length === 4 || header[3].includes('分辨率'))
142
189
  checks.push(makeCheck(
143
190
  'outline.plotpoint-table',
144
191
  headerOk,
145
192
  name,
146
- header ? `表头:${header.join(' | ')}` : '未找到 | # | 情节点 | 功能标签 | 执行边界 | 表头',
147
- '情节细化使用四列表格:# / 情节点(谁做了什么) / 功能标签 / 执行边界',
148
- '只把情节点序列改成四列表格,逐点补功能标签与执行边界;不增删情节点本身。'
193
+ header ? `表头:${header.join(' | ')}` : '未找到 | # | 情节点 | 功能标签 | [分辨率] | 执行边界 | 表头',
194
+ '情节细化使用表格:# / 情节点(谁做了什么) / 功能标签 / 执行边界(禁+放);需要时可在功能标签后加「分辨率」列',
195
+ '只把情节点序列改成这张表,逐点补功能标签与执行边界;不增删情节点本身。'
149
196
  ))
150
197
 
198
+ // 「放」半边:五列表或表头写明「禁+放」的四列表,执行边界必须至少一个点解除限制,
199
+ // 全是禁令的情节点表实测会把整章压成同一个温度(015 章十一个点全「不许」)。表头没写「禁+放」的四列表不追溯。
200
+ if (headerOk && (header.length === 5 || /放/.test(header[header.length - 1]))) {
201
+ const rows = []
202
+ for (const line of lines) {
203
+ const cells = parseTableRow(line)
204
+ if (cells && cells.length === header.length && /^\d+$/.test(cells[0])) rows.push(cells)
205
+ }
206
+ if (rows.length) {
207
+ const released = rows.filter((cells) => {
208
+ const match = cells[cells.length - 1].match(/(?:^|[。;;\s])放\s*[::]([^]*?)(?=(?:禁|放)\s*[::]|$)/)
209
+ if (!match) return false
210
+ const value = match[1].replace(/[\s。;;,,、\[\]【】]/g, '')
211
+ return value.length > 0 && !/^(?:无|暂无|待补充|待定|无缺口)$/.test(value)
212
+ })
213
+ checks.push(makeCheck(
214
+ 'outline.plotpoint-release',
215
+ released.length > 0,
216
+ name,
217
+ `${rows.length} 个情节点里 ${released.length} 个写了「放」`,
218
+ '执行边界写成「禁+放」两半,每章至少一个点写了「放」——放行是解除限制,不是义务',
219
+ '给最该出彩的一两个点补「放」半边(谁可以出声、谁可以失态、允不允许当场标价),不改情节点本身。'
220
+ ))
221
+ if (released.length > 0 && rows.length >= 3 && released.length * 3 < rows.length) {
222
+ checks.push(makeCheck(
223
+ 'outline.plotpoint-release-ratio',
224
+ false,
225
+ name,
226
+ `${rows.length} 个情节点里只有 ${released.length} 个写了「放」(不足三分之一)`,
227
+ '建议至少三分之一的情节点写「放」半边,避免整章只剩禁令',
228
+ '按人工判断酌情补「放」;本项不阻断。',
229
+ 'advisory'
230
+ ))
231
+ }
232
+ }
233
+ }
234
+
235
+ // 章级「禁止提前释放」只写本章特有的三五条;条目过多多半是把卷级常任禁忌逐章复读了。
236
+ const releaseMatch = text.match(/^\s*[-*+]\s*\*{0,2}本章禁止提前释放\*{0,2}\s*[::]\s*(.*)$/m)
237
+ if (releaseMatch) {
238
+ const items = releaseMatch[1].split(/[、;;,,\/]/).map((s) => s.trim()).filter(Boolean)
239
+ if (items.length > 5) {
240
+ checks.push(makeCheck(
241
+ 'outline.release-brevity',
242
+ false,
243
+ name,
244
+ `本章禁止提前释放列了 ${items.length} 条`,
245
+ '章级只写本章特有的三五条;卷级常任禁忌写在卷纲「本卷禁碰的终局底牌」,不逐章复读',
246
+ '把与卷纲常任重复的条目删掉,只留本章特有;本项不阻断。',
247
+ 'advisory'
248
+ ))
249
+ }
250
+ }
251
+
252
+ checks.push(checkSettingRefs(text, name, file, projectRoot))
253
+
151
254
  const targetMatch = text.match(/字数目标\s*[::]\s*(?:约\s*)?([\d,,]+)/)
152
255
  const target = targetMatch ? Number(targetMatch[1].replace(/[,,]/g, '')) : null
153
256
  const caliberOk = new RegExp(`字数口径\\s*[::]\\s*${CALIBER}`).test(text)
@@ -164,7 +267,8 @@ function verify(file) {
164
267
  }
165
268
 
166
269
  function report(file, checks) {
167
- const failures = checks.filter((check) => !check.ok)
270
+ const failures = checks.filter((check) => !check.ok && check.severity === 'blocking')
271
+ const advisories = checks.filter((check) => !check.ok && check.severity === 'advisory')
168
272
  return {
169
273
  schema_version: 1,
170
274
  verifier: 'story-long-write.outline-contract',
@@ -172,6 +276,7 @@ function report(file, checks) {
172
276
  ok: failures.length === 0,
173
277
  checks,
174
278
  failures,
279
+ advisories,
175
280
  repair_scope: failures.map((failure) => ({
176
281
  id: failure.id,
177
282
  file: failure.file,
@@ -200,13 +305,81 @@ function resolveChapter(project, chapter) {
200
305
  return { file: path.join(dir, hit) }
201
306
  }
202
307
 
308
+ // --supply:批末验证供给自查已落盘。新书写在卷纲旁的 排纲底稿_{单元ID}.md;老卷纲写在单元卡块内。
309
+ function hasSupplyHeading(text) {
310
+ return text.split(/\r?\n/).some((line) => {
311
+ const heading = line.replace(/\*\*/g, '').match(/^#{1,6}\s+(.+)$/)
312
+ return Boolean(heading) && /^供给自查(?:\s|[((]|$)/.test(heading[1])
313
+ })
314
+ }
315
+
316
+ function verifySupply(volumeFile, unitId) {
317
+ const draftFile = path.join(path.dirname(volumeFile), `排纲底稿_${unitId}.md`)
318
+ const draft = readUtf8(draftFile)
319
+ if (draft.ok) {
320
+ const ok = hasSupplyHeading(draft.text)
321
+ return {
322
+ schema_version: 1, verifier: 'story-long-write.outline-supply', file: path.resolve(draftFile), unit: unitId, ok,
323
+ evidence: ok ? '排纲底稿含「供给自查」小节' : `${path.basename(draftFile)} 里没有「供给自查」小节——每批出细纲前须做供给自查(含「无缺口」情形),见 workflow-setup.md「排纲自查与细纲」步骤 3`,
324
+ }
325
+ }
326
+ const read = readUtf8(volumeFile)
327
+ if (!read.ok) {
328
+ return { schema_version: 1, verifier: 'story-long-write.outline-supply', file: path.resolve(volumeFile), unit: unitId, ok: false, evidence: read.error || '卷纲文件为空' }
329
+ }
330
+ // 只检查目标单元内的标题,不把正文提及或代码示例当成小节。
331
+ let fence = null
332
+ const lines = read.text.split(/\r?\n/).map((line) => {
333
+ const marker = line.match(/^\s{0,3}(`{3,}|~{3,})/)
334
+ if (marker) {
335
+ if (!fence) fence = marker[1]
336
+ else if (marker[1][0] === fence[0] && marker[1].length >= fence.length) fence = null
337
+ return ''
338
+ }
339
+ return fence ? '' : line.replace(/\*\*/g, '')
340
+ })
341
+ const headings = []
342
+ for (let index = 0; index < lines.length; index++) {
343
+ const heading = lines[index].match(/^(#{1,6})\s+(.+)$/)
344
+ if (heading) headings.push({ index, level: heading[1].length, title: heading[2] })
345
+ }
346
+ const card = headings.find((heading) => {
347
+ const id = heading.title.match(/剧情单元\s+([A-Za-z][\w-]*)/)
348
+ if (id) return id[1] === unitId
349
+ const end = headings.find((next) => next.index > heading.index)?.index ?? lines.length
350
+ return lines.slice(heading.index + 1, end).some((line) => {
351
+ const field = line.match(/^\s*[-*+]\s*单元ID\s*[::]\s*([A-Za-z][\w-]*)\s*$/)
352
+ return field?.[1] === unitId
353
+ })
354
+ })
355
+ const end = card ? (headings.find((next) => next.index > card.index && next.level <= card.level)?.index ?? lines.length) : 0
356
+ const ok = Boolean(card) && headings.some((heading) => heading.index > card.index && heading.index < end && /^供给自查(?:\s|[((]|$)/.test(heading.title))
357
+ if (!card) {
358
+ return { schema_version: 1, verifier: 'story-long-write.outline-supply', file: path.resolve(volumeFile), unit: unitId, ok: false, evidence: `卷纲中未找到剧情单元 ${unitId}` }
359
+ }
360
+ return {
361
+ schema_version: 1,
362
+ verifier: 'story-long-write.outline-supply',
363
+ file: path.resolve(volumeFile),
364
+ unit: unitId,
365
+ ok,
366
+ evidence: ok ? '单元卡含「供给自查」小节' : `没有 排纲底稿_${unitId}.md,剧情单元 ${unitId} 的卡内也没有「供给自查」小节——每批出细纲前须做供给自查(含「无缺口」情形),见 workflow-setup.md「排纲自查与细纲」步骤 3`,
367
+ }
368
+ }
369
+
203
370
  function parseArgs(argv) {
204
371
  const files = []
205
372
  let project = null
206
373
  let chapter = null
374
+ let supply = null
207
375
  for (let index = 0; index < argv.length; index++) {
208
376
  const arg = argv[index]
209
377
  if (arg === '--json') continue
378
+ if (arg === '--supply') {
379
+ if (index + 2 >= argv.length) return null
380
+ supply = { volumeFile: argv[++index], unitId: argv[++index] }
381
+ continue
382
+ }
210
383
  if (arg === '--project' || arg === '--chapter') {
211
384
  if (index + 1 >= argv.length || argv[index + 1].startsWith('--')) return null
212
385
  const value = argv[++index]
@@ -217,6 +390,10 @@ function parseArgs(argv) {
217
390
  if (arg.startsWith('--')) return null
218
391
  files.push(arg)
219
392
  }
393
+ if (supply) {
394
+ if (project || chapter || files.length) return null
395
+ return { supply }
396
+ }
220
397
  if (project || chapter) {
221
398
  if (!project || !chapter || files.length || !/^\d+$/.test(chapter)) return null
222
399
  return { project, chapter }
@@ -228,9 +405,14 @@ function parseArgs(argv) {
228
405
  function main(argv) {
229
406
  const parsed = parseArgs(argv)
230
407
  if (!parsed) {
231
- process.stderr.write('用法: node scripts/check-outline-contract.js --json <细纲路径...> | --json --project <书目录> --chapter N\n')
408
+ process.stderr.write('用法: node scripts/check-outline-contract.js --json <细纲路径...> | --json --project <书目录> --chapter N | --json --supply <卷纲路径> <单元ID>\n')
232
409
  return 2
233
410
  }
411
+ if (parsed.supply) {
412
+ const supplyReport = verifySupply(parsed.supply.volumeFile, parsed.supply.unitId)
413
+ process.stdout.write(`${JSON.stringify(supplyReport, null, 2)}\n`)
414
+ return supplyReport.ok ? 0 : 1
415
+ }
234
416
  let targets = parsed.files
235
417
  if (!targets) {
236
418
  const resolved = resolveChapter(parsed.project, parsed.chapter)
@@ -240,7 +422,7 @@ function main(argv) {
240
422
  }
241
423
  targets = [resolved.file]
242
424
  }
243
- const reports = targets.map((file) => verify(file))
425
+ const reports = targets.map((file) => verify(file, parsed.project || null))
244
426
  const ok = reports.every((entry) => entry.ok)
245
427
  process.stdout.write(`${JSON.stringify(reports.length === 1 ? reports[0] : reports, null, 2)}\n`)
246
428
  return ok ? 0 : 1