@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
@@ -0,0 +1,27 @@
1
+ # 文风与参考冲突裁决
2
+
3
+ 写正文、改写、去 AI 味和审稿都先做这一步;inline 与 agent 用同一份裁决。无需另建画像或要求作者填写配置。
4
+
5
+ ## 按维度取值,不把整份文件互相覆盖
6
+
7
+ 表达选择按以下顺序取第一个明确、适用的要求:**当前请求 > 本书文风/设定 > 本书 active 作者记忆 > 题材、流程、全局 active 记忆 > 主对标文风 > 题材包与通用 references 默认值**。未声明的维度才向下补齐;本书例外不撤销全局习惯,临时要求不写回长期记忆。
8
+
9
+ 句长、视角、标点、对话落法、情绪直写、修辞、叙述者评论和收尾方式都是表达维度。reference 中的“必须”“禁用”“最高优先级”、示例和检测阈值不使默认写法升级为作者不可覆盖的规则。主对标的低置信观察不压过作者的明确选择。
10
+
11
+ 事实与表达分开裁决:文风不能改变细纲事件、已知事实、信息揭露边界、用户字数范围、改写范围、文件结构或追踪协议;有限全知允许换视角,不等于可提前揭底。转限知时可暂不叙述该人物无从得知的信息,事实本身不变;不得补出“早已知道”“后来发现”或新观察经历来保全原文信息。审稿照常评价因果、可读性与情绪效果,不能仅因使用了作者选定的写法就判错,也不能因为作者喜欢就忽略真实缺陷。
12
+
13
+ ## 加载与传递
14
+
15
+ 1. 从本次正文路径确定书目录(长篇为 `正文/` 的父目录,短篇为 `正文.md` 所在目录)。读该书 `设定/文风.md`;短篇同时读 `设定.md` 的文风约定。无文件就继续,不创建占位文件、不猜其他书。文风无最低字数限制,一句可执行的偏好也有效;空白、纯标题、待补充不算。
16
+ 2. `_文风摘要.md` 只能辅助定位,不能独立替代全文。当前会话已读全文时无需反复读;摘要与全文不一致用全文,不让旧摘要压过作者的新修改。
17
+ 3. 作者记忆 query 显式传当前书名、已知题材和流程以及需要的 kind,避免只取到 global。只用 active;同一维度窄范围覆盖宽范围,不拼成同时满足的清单。无法判定的同范围冲突才问作者,已能按优先级解决的不询问。
18
+ 4. 在现有 prompt 填 `style_resolution`:本次生效的表达要求及来源、被覆盖的默认条款、必须保留的事实/信息边界;只列与任务有关的冲突,无冲突可写“按本书文风”。原样传给正文、去味和文字 reviewer,并传文风全文路径。同一批次复用,当前请求或文风变动时更新。单独调用去味/审稿也执行本步骤,不能靠上一次会话的记忆。
19
+
20
+ ## 检测器如何服从裁决
21
+
22
+ 检测器不理解作者意图。保留现有默认检查;明确采用且有功能的命中,复用**书目录**下的 `.deslop-whitelist`:UTF-8,一行一个原文字面片段,空行和以 `#` 开头的整行注释忽略,不支持正则或通配符。不向父目录找,避免跨书继承。
23
+
24
+ - 本书文风明确允许某种停顿标点时,可登记 `——` 或 `……`;具体修辞登记完整的获准原句,不能登记“不是”“没有”等泛词来关闭整类检查。
25
+ - 每项用上一行 `# 来源:…;用途:…` 说明当前请求或文风依据。只为执行作者已明确的选择登记,不因脚本报警自动放行。当前请求禁止某写法时移除相冲突的豁免;一次性保留只登记该句,不推断长期习惯。
26
+ - 深扫、标点整理和写后/下一章检查读取同一白名单。豁免只影响对应字面片段的风格检查;同一行其他问题照报,事实、字数、占位、工程词、截断和文件结构检查不豁免。
27
+ - 所选 Gate 仍执行:检查该写法是否重复、冗余、破坏节奏或越过信息边界;有这些具体问题才改。裁决与发现可简短写在正常交付报告中,不写进小说正文。
@@ -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 栏状态输入。阶段/卷级回看按需查询正文,不作为每章强一致追踪产物。
@@ -20,14 +20,13 @@ Markdown 只负责给作者和 Agent 阅读,工具不再反向解析 Markdown
20
20
  ```text
21
21
  {PYTHON} {当前 skill 根}/scripts/tracking_commit.py init --project {书项目根} --input {初始化事务.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}
24
23
  {PYTHON} {story-long-write skill 根}/scripts/storyctl.py chapter check --project {书项目根} --chapter {N}
25
24
  {PYTHON} {story-long-write skill 根}/scripts/storyctl.py chapter commit --project {书项目根} --chapter {N} --input {逐章事务.json}
26
25
  {PYTHON} {story-long-write skill 根}/scripts/storyctl.py chapter accept-current-length --project {书项目根} --chapter {N} --input {逐章事务.json}
27
26
  ```
28
27
 
29
28
  - `init`:只在 `_tracking-state.json` 不存在时执行,绝不覆盖已初始化项目。
30
- - `wordcount checkpoint`:纯测量;返回当前实际字数、用户带与剩余用户区间,不写正文、不写 tracking、不做语义判断。每章最多调用一次。
29
+ - `wordcount measure` / `wordcount checkpoint`:纯测量入口;不写正文、不写 tracking、不做语义判断。长篇正文流程一次写完整章,**不在章中调用测量**,长度由 `chapter check` 一次收口;这两个入口供导入、审查等其他场景使用。
31
30
  - `chapter check`:重新读取当前正文与细纲目标,返回确定性长度状态、现有 blocking quality、`state_revision` 和当前可执行动作,不保存 approval。`under` 不提供自动补写;`over` 额外返回一次净删型 `compress-once` 及进入内带/用户带所需的机器删除区间。
32
31
  - `chapter commit`:再次读取当前文件、重新计数并重跑 blocking quality;只接受用户带内章节,把简短字数记录与逐章事务一起原子提交。
33
32
  - `chapter accept-current-length`:只接受带外但 quality pass 的章节;接受动作发生时重新读取、重新计数并立即原子提交,不保存可陈旧的历史决议。
@@ -43,33 +42,7 @@ Markdown 只负责给作者和 Agent 阅读,工具不再反向解析 Markdown
43
42
 
44
43
  ## 初始化事务
45
44
 
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 栏状态输入。阶段/卷级回看按需查询正文,不作为每章强一致追踪产物。
45
+ 仅新书或导入初始化时,执行 `init` 前必须完整读取 [tracking-initialization.md](tracking-initialization.md),按其中原始 JSON 与导入边界构造事务。已有项目续写直接使用下方逐章事务,不重复读初始化示例。
73
46
 
74
47
  调用方的逐章 JSON 不写 `wordcount`;正式入口 `chapter commit` 或 `chapter accept-current-length` 在提交当下生成并注入。最终 state 只为已提交章节保留 `metric / target / actual / status / resolution / body_sha256`,不保存 MEASURE/RESOLVE 事件、ID 链、policy fingerprint 或独立 chapter state。
75
48
 
@@ -2,6 +2,7 @@
2
2
  'use strict';
3
3
 
4
4
  const fs = require('fs');
5
+ const { loadStyleWhitelist, maskStyleText } = require('./style-whitelist.js');
5
6
  const path = require('path');
6
7
 
7
8
  const USAGE = `Usage: node check-ai-patterns.js [--check] [--json] [--fail-on=blocking|all] <file...>
@@ -30,6 +31,7 @@ Detect high-risk AI-flavor prose patterns that need human rewrite:
30
31
  - 章尾状态总结体 (文末窗口 这一夜注定/这一切都结束了/新的人生才刚刚开始/命运的齿轮)
31
32
  - 引号强调滥用 (叙述里 1-4 字短词加引号强调,密度型)
32
33
 
34
+ Book-local .deslop-whitelist literal spans are excluded from style scanning (no regex or ancestor inheritance).
33
35
  Each finding carries severity: blocking by default for generation/deslop cleanup (not-is-comparison / em-dash / voice-contrast / negation-parade / reverse-not-is / trailer-ending / trailer-summary). This is a local style/readability gate, not an AIGC detector score; functional human text can be marked for review instead of hard-edited for a detector.
34
36
  或 advisory (period-stutter / long-paragraph / micro-action-tic / stock-reaction-tic / action-list-tic / abstract-summary-tic / cliche-density-tic / metaphor-density-tic / reasoning-chain-tic / system-notice-formality-tic / overcompressed-prose-tic / low-connective-density-tic / quote-emphasis-tic / formulaic-parallelism,是提示,justified 的长推理/氛围段可保留)。
35
37
  --fail-on=blocking 只在出现 blocking finding 时退出 1;默认 --fail-on=all 有任何 finding 即退出 1。
@@ -308,7 +310,10 @@ for (const file of options.files) {
308
310
  continue;
309
311
  }
310
312
 
311
- const findings = scanDocument(input).map((finding) => ({ file, ...finding }));
313
+ let whitelist;
314
+ try { whitelist = loadStyleWhitelist(fullPath); }
315
+ catch (error) { die(`${file}: unable to read .deslop-whitelist (${error.message})`); }
316
+ const findings = scanDocument(maskStyleText(input, whitelist)).map((finding) => ({ file, ...finding }));
312
317
  allFindings.push(...findings);
313
318
  }
314
319
 
@@ -43,6 +43,17 @@ const PLACEHOLDER_PATTERNS = [
43
43
  { re: /我(无法|不能)(继续(写|创作|生成|下去)|生成(内容|文本|正文)?|创作|续写|完成(这个|本)?(章|篇|创作|请求))/, label: '元信息泄漏(生成拒绝语)', hard: false },
44
44
  ];
45
45
 
46
+ const QUOTED_SPAN_PATTERNS = [
47
+ /「[^」]*」/g,
48
+ /『[^』]*』/g,
49
+ /【[^】]*】/g,
50
+ /“[^”]*”/g,
51
+ // 单引号须成对;词内撇号(don't、O’Connor)不作为开闭引号。
52
+ /(?<![A-Za-z0-9_])‘(?:[^’]|(?<=[A-Za-z0-9_])’(?=[A-Za-z0-9_]))*(?!(?<=[A-Za-z0-9_])’[A-Za-z0-9_])’/g,
53
+ /"[^"]*"/g,
54
+ /(?<![A-Za-z0-9_])'(?:[^']|(?<=[A-Za-z0-9_])'(?=[A-Za-z0-9_]))*(?!(?<=[A-Za-z0-9_])'[A-Za-z0-9_])'/g,
55
+ ];
56
+
46
57
  // 工程词泄漏(正文元信息扫描的确定性版):弱模型把写作工程词漏进正文,破坏代入感
47
58
  // (DeepSeek-v4 这类会在对话里冒「该到下一章了」)。漏词的模型自己发现不了,靠脚本兜。
48
59
  // tier1 = 纯写作流水线术语,正文里几乎永不合法;tier2 = 章节结构/歧义词,角色在故事内
@@ -150,21 +161,23 @@ function isContent(trimmed) {
150
161
  return trimmed && !trimmed.startsWith('#') && !/^-{3,}$/.test(trimmed);
151
162
  }
152
163
 
153
- function isDialogueLike(trimmed) {
154
- return /[“”"'‘’「」『』【】]/.test(trimmed);
164
+ // 等长遮住成对引号内的内容以保留列号;未闭合引号不豁免。
165
+ function maskQuotedSpans(text) {
166
+ let masked = text;
167
+ for (const pattern of QUOTED_SPAN_PATTERNS) {
168
+ masked = masked.replace(pattern, (match) => ' '.repeat(match.length));
169
+ }
170
+ return masked;
155
171
  }
156
172
 
157
173
  // 去掉成对引号内的片段(台词/系统词/引用物件),只留引号外叙述。复读判定用:重复台词是体裁
158
174
  // 手法(豁免),但「叙述 + 引号内物件/短台词」混合行里引号外叙述的复读仍是退化,不能整行豁免。
159
175
  function stripQuoted(text) {
160
- return text
161
- .replace(/「[^」]*」/g, '')
162
- .replace(/『[^』]*』/g, '')
163
- .replace(/【[^】]*】/g, '')
164
- .replace(/“[^”]*”/g, '')
165
- .replace(/‘[^’]*’/g, '')
166
- .replace(/"[^"]*"/g, '')
167
- .replace(/'[^']*'/g, '');
176
+ let stripped = text;
177
+ for (const pattern of QUOTED_SPAN_PATTERNS) {
178
+ stripped = stripped.replace(pattern, '');
179
+ }
180
+ return stripped;
168
181
  }
169
182
 
170
183
  function visibleLength(text) {
@@ -253,18 +266,19 @@ function findPlaceholders(content) {
253
266
  const findings = [];
254
267
  for (const { trimmed, lineNo } of content) {
255
268
  if (!isContent(trimmed)) continue;
256
- const dialogue = isDialogueLike(trimmed);
269
+ const outsideQuotes = maskQuotedSpans(trimmed);
257
270
  for (const { re, label, hard } of PLACEHOLDER_PATTERNS) {
258
- if (!hard && dialogue) continue; // soft 拒绝语在对话行里可能是正常台词,豁免
259
- const m = re.exec(trimmed);
271
+ // hard 信号仍扫描整行;soft 自指/拒绝语只扫描成对引号外,且遮罩等长以保留列号。
272
+ const m = re.exec(hard ? trimmed : outsideQuotes);
260
273
  if (m) {
274
+ const index = m.index || 0;
261
275
  findings.push({
262
276
  line: lineNo,
263
- column: (m.index || 0) + 1,
277
+ column: index + 1,
264
278
  type: 'placeholder-leak',
265
279
  severity: 'blocking',
266
280
  message: `${label}:正文混入元信息/拒绝语/占位符,重写本段干净落地。`,
267
- excerpt: compact(trimmed.slice(Math.max(0, (m.index || 0) - 4), (m.index || 0) + 20)),
281
+ excerpt: compact(trimmed.slice(Math.max(0, index - 4), index + 20)),
268
282
  });
269
283
  break; // one finding per line is enough
270
284
  }
@@ -283,17 +297,22 @@ function findMetaLeak(content) {
283
297
  // 标题行(第N章 章名,无 ## 前缀时也算)属「标题行以外的正文」之外,排除
284
298
  if (/^第[一二三四五六七八九十百千万两0-9]+章/.test(trimmed)) continue;
285
299
  }
286
- const dialogue = isDialogueLike(trimmed);
287
- let m = META_TIER1_RE.exec(trimmed);
300
+ const outsideQuotes = maskQuotedSpans(trimmed);
301
+ let m = META_TIER1_RE.exec(outsideQuotes);
302
+ let quotedTier1 = false;
303
+ if (!m) {
304
+ m = META_TIER1_RE.exec(trimmed);
305
+ quotedTier1 = Boolean(m);
306
+ }
288
307
  if (m) {
289
308
  // tier1 纯工程词正文里几乎永不合法→blocking;但写手/编剧题材里角色在故事内真讨论创作,
290
- // 台词(对话行)里可能合法,降级为 advisory(仍报告,交人/LLM 判,不强制回炉)。
309
+ // 且命中实际位于成对引号内时可能合法,降级为 advisory。同一行别处出现引号不影响判定。
291
310
  findings.push({
292
311
  line: lineNo,
293
312
  column: m.index + 1,
294
313
  type: 'meta-leak',
295
- severity: dialogue ? 'advisory' : 'blocking',
296
- message: `工程词泄漏:「${m[0]}」是写作流水线术语,正文里不该出现;改成角色/场景内表达。${dialogue ? '例外:角色为作者/编剧、在故事内真实讨论创作时,台词里可能合法。' : ''}`,
314
+ severity: quotedTier1 ? 'advisory' : 'blocking',
315
+ message: `工程词泄漏:「${m[0]}」是写作流水线术语,正文里不该出现;改成角色/场景内表达。${quotedTier1 ? '例外:角色为作者/编剧、在故事内真实讨论创作时,台词里可能合法。' : ''}`,
297
316
  excerpt: compact(trimmed.slice(Math.max(0, m.index - 6), m.index + 18)),
298
317
  });
299
318
  continue; // tier1 命中即可,不再叠 tier2
@@ -2,6 +2,7 @@
2
2
  'use strict';
3
3
 
4
4
  const fs = require('fs');
5
+ const { loadStyleWhitelist, styleSpans } = require('./style-whitelist.js');
5
6
  const path = require('path');
6
7
 
7
8
  const USAGE = `Usage: node normalize-punctuation.js [--check] [--quote-mode keep|ascii|yan] <file...>
@@ -9,6 +10,7 @@ const USAGE = `Usage: node normalize-punctuation.js [--check] [--quote-mode keep
9
10
  Normalize正文 punctuation deterministically:
10
11
  - replace ellipses, em dashes, and double hyphens with Chinese punctuation
11
12
  - remove markdown divider lines (---) from正文
13
+ - preserve pause punctuation covered by book-local .deslop-whitelist literals
12
14
  - keep quote style by default; convert quotes only when explicitly requested
13
15
  `;
14
16
 
@@ -61,7 +63,10 @@ for (const file of options.files) {
61
63
  continue;
62
64
  }
63
65
 
64
- const result = normalizeDocument(input, options.quoteMode);
66
+ let whitelist;
67
+ try { whitelist = loadStyleWhitelist(fullPath); }
68
+ catch (error) { die(`${file}: unable to read .deslop-whitelist (${error.message})`); }
69
+ const result = normalizeDocument(input, options.quoteMode, whitelist);
65
70
  totalFindings += result.findings.length;
66
71
 
67
72
  if (options.check) {
@@ -94,7 +99,7 @@ function die(message) {
94
99
  process.exit(2);
95
100
  }
96
101
 
97
- function normalizeDocument(input, quoteMode) {
102
+ function normalizeDocument(input, quoteMode, whitelist) {
98
103
  const { lines, endings } = splitLinesKeepingEndings(input);
99
104
 
100
105
  const findings = [];
@@ -159,7 +164,7 @@ function normalizeDocument(input, quoteMode) {
159
164
  }
160
165
 
161
166
  const commentOpenBefore = commentOpen;
162
- const punctuationResult = normalizePausePunctuation(line, lineNo, commentOpen);
167
+ const punctuationResult = normalizePausePunctuation(line, lineNo, commentOpen, whitelist);
163
168
  findings.push(...punctuationResult.findings);
164
169
  line = punctuationResult.line;
165
170
  commentOpen = punctuationResult.commentOpen;
@@ -237,7 +242,7 @@ function isClosingFence(line, fence) {
237
242
  // 一遍归一化留不干净,再跑一遍还会改已定稿的正文;所以反复归一化到不动点。
238
243
  // 每遍至少把一个 `…/./—/-` 换成非停顿字符,字符数严格递减,必然收敛。
239
244
  // findings 只留第一遍:同一处不重复计数,column 也仍然是原行的偏移。
240
- function normalizePausePunctuation(line, lineNo, commentOpen) {
245
+ function normalizePausePunctuation(line, lineNo, commentOpen, whitelist) {
241
246
  let current = line;
242
247
  let findings = null;
243
248
  let commentOpenAfter = commentOpen;
@@ -245,7 +250,7 @@ function normalizePausePunctuation(line, lineNo, commentOpen) {
245
250
  for (;;) {
246
251
  const comments = htmlCommentSpans(current, commentOpen);
247
252
  commentOpenAfter = comments.open;
248
- const pass = normalizePausePunctuationPass(current, lineNo, comments.spans);
253
+ const pass = normalizePausePunctuationPass(current, lineNo, comments.spans.concat(styleSpans(current, whitelist)));
249
254
  if (findings === null) findings = pass.findings;
250
255
  if (pass.line === current) break;
251
256
  current = pass.line;
@@ -0,0 +1,39 @@
1
+ 'use strict';
2
+
3
+ const fs = require('fs');
4
+ const path = require('path');
5
+
6
+ // Book-local only: never inherit an unrelated workspace or another book's choices.
7
+ function loadStyleWhitelist(file) {
8
+ const parent = path.dirname(path.resolve(file));
9
+ const book = path.basename(parent) === '正文' ? path.dirname(parent) : parent;
10
+ try {
11
+ return fs.readFileSync(path.join(book, '.deslop-whitelist'), 'utf8')
12
+ .split(/\r?\n/).map(line => line.trim())
13
+ .filter(line => line && !line.startsWith('#'))
14
+ .sort((a, b) => b.length - a.length);
15
+ } catch (error) {
16
+ if (error.code === 'ENOENT') return [];
17
+ throw error;
18
+ }
19
+ }
20
+
21
+ function styleSpans(text, whitelist) {
22
+ const spans = [];
23
+ for (const literal of whitelist) {
24
+ for (let at = text.indexOf(literal); at !== -1; at = text.indexOf(literal, at + 1)) {
25
+ spans.push([at, at + literal.length]);
26
+ }
27
+ }
28
+ return spans;
29
+ }
30
+
31
+ function maskStyleText(text, whitelist) {
32
+ const chars = text.split('');
33
+ for (const [start, end] of styleSpans(text, whitelist)) {
34
+ chars.fill('?', start, end);
35
+ }
36
+ return chars.join('');
37
+ }
38
+
39
+ module.exports = { loadStyleWhitelist, styleSpans, maskStyleText };
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: story-setup
3
3
  version: 1.2.10
4
- description: "网文写作工具集基础设施部署。为 Claude Code / OpenCode / Codex / Google Antigravity / ZCode / OpenClaw / Reasonix 提供内置适配;Web AI / 通用 Agent 可走 skills + AGENTS.md 文件模式。触发方式:/story-setup、$story-setup、「准备写书」「帮我搭一下环境」「配置写作项目」。"
4
+ description: "网文写作工具集基础设施部署与检查。为 Claude Code / OpenCode / Codex / Google Antigravity / ZCode / OpenClaw / Reasonix 提供内置适配;Web AI / 通用 Agent 可走 skills + AGENTS.md 文件模式。触发方式:/story-setup、$story-setup、「准备写书」「帮我搭一下环境」「配置写作项目」「检查写作环境」。"
5
5
  metadata: {"openclaw":{"source":"https://github.com/zenstory-ai/oh-story-claudecode"}}
6
6
  ---
7
7
  # story-setup:网文写作工具集基础设施部署
@@ -10,6 +10,11 @@ metadata: {"openclaw":{"source":"https://github.com/zenstory-ai/oh-story-claudec
10
10
 
11
11
  **执行铁律:不覆盖用户已有配置,合并而非替换。**
12
12
 
13
+ ## 选择模式
14
+
15
+ - 参数为 `check`,或用户只要求检查部署、诊断环境、排查 agent 不可用时:完整读取 [references/diagnostics.md](references/diagnostics.md),按其中流程仅检查并报告;不进入下面的部署流程。
16
+ - 用户要求安装、更新或修复时:执行下面的部署流程。检查后已明确授权的修复沿用本文件的部署与合并规则。
17
+
13
18
  ---
14
19
 
15
20
  ## Phase 1:检测项目状态
@@ -19,9 +24,9 @@ metadata: {"openclaw":{"source":"https://github.com/zenstory-ai/oh-story-claudec
19
24
  > 判据是「有没有 `SKILL.md`」:只看正在执行的 `SKILL.md` 同级的 `references/`。项目内 `.claude/skills/story-setup/`、`.codex/skills/story-setup/` 和 OpenCode 的 `skills/story-setup/` 只有 `references/agent-references/`、不含 `SKILL.md`,不会是执行目录,也不要拿它们核对。Antigravity / ZCode / OpenClaw / Reasonix / generic 的项目副本是整份 skill 拷贝、自带 `SKILL.md`,9 个子目录本就齐全,照常核对即可。
20
25
 
21
26
  1. 检查当前目录是否已部署过(存在 `.story-deployed`)
22
- - `agents_version` 缺失、非整数或小于 `29` → 标记为待更新,继续执行当前部署
23
- - `agents_version: 29` → 使用 AskUserQuestion 确认是否重新部署;提示里写明重新部署只用**当前本地 skill 包**刷新项目文件,要拿 skill 本身的新版本得先更新 oh-story-claudecode(`npx skills add` 或 marketplace),再回来重跑
24
- - `agents_version` 大于 `29` → 当前 story-setup 比项目部署旧;停止以避免降级覆盖,提示先更新 oh-story-claudecode,不写任何部署文件
27
+ - `agents_version` 缺失、非整数或小于 `30` → 标记为待更新,继续执行当前部署
28
+ - `agents_version: 30` → 使用 AskUserQuestion 确认是否重新部署;提示里写明重新部署只用**当前本地 skill 包**刷新项目文件,要拿 skill 本身的新版本得先更新 oh-story-claudecode(`npx skills add` 或 marketplace),再回来重跑
29
+ - `agents_version` 大于 `30` → 当前 story-setup 比项目部署旧;停止以避免降级覆盖,提示先更新 oh-story-claudecode,不写任何部署文件
25
30
  - 同时读 `target_cli` 字段。**已部署项目以 sentinel 里的值为准**:非空时(逗号分隔的多端组合原样保留)跳过下面第 5-12 步的环境探测与选择,直接按这些端重新部署。只有字段缺失或为空,才回落到探测。用户明确要求增删目标端时,用 AskUserQuestion 在现有值基础上改,改完的值写回 sentinel。
26
31
  2. 检查是否有书名目录(包含 `追踪/` 子目录的目录,或用户自定义结构)
27
32
  - 有 → 识别为长篇项目,显示当前项目信息
@@ -372,7 +377,7 @@ Reasonix(DeepSeek-Reasonix CLI)当前只部署 skills 与 `AGENTS.md`,不
372
377
  - 写入以下字段(YAML `key: value` 格式,hook 用 `references/templates/hooks/lib/sentinel.sh` 读取):
373
378
  ```
374
379
  deployed_at: <date -u +"%Y-%m-%dT%H:%M:%SZ">
375
- agents_version: 29
380
+ agents_version: 30
376
381
  setup_skill_version: 1.2.10
377
382
  target_cli: claude-code(或 opencode、codex、antigravity、zcode、openclaw、reasonix、generic,或其任意组合)
378
383
  resolver_strategy: project-local-skill-reference
@@ -380,10 +385,12 @@ Reasonix(DeepSeek-Reasonix CLI)当前只部署 skills 与 `AGENTS.md`,不
380
385
  ```
381
386
  - 此文件供 session-start.sh 和写作 skill 检测部署状态,避免重复提示
382
387
  - target_cli 含 claude-code 时,同时创建一次性标记文件 `.claude/.agents-pending-restart`(空文件即可)。session-start.sh 在下一个会话启动时据此确认 agents 已随新会话注册,并自动删除该标记——用来向用户确认「重启已生效」。ZCode 不创建该标记,因为它不部署项目 agents。
383
- - 如果 `.story-deployed` 已存在但 `agents_version` 缺失、非整数或小于 `29`,按本次流程更新 hooks/agents/rules/reference bundle(具体变更见 `UPGRADING.md`);大于 `29` 时已在 Phase 1 停止,不得降级覆盖
388
+ - 如果 `.story-deployed` 已存在但 `agents_version` 缺失、非整数或小于 `30`,按本次流程更新 hooks/agents/rules/reference bundle(具体变更见 `UPGRADING.md`);大于 `30` 时已在 Phase 1 停止,不得降级覆盖
384
389
 
385
390
  ## Phase 3:验证安装
386
391
 
392
+ 按 `.story-deployed.target_cli` 选择对应端的检查:第 1–4 项仅用于 Claude Code,第 5 项是所有端共有的部署标记检查,第 6 项是部署报告,第 7–13 项按目标端各选其一。仅检查模式复用第 1–5 项与对应端的第 7–13 项,跳过第 6 项,且其中要求实际执行 hook 或写入 fixture 的子项改为只做静态校验(文件存在、语法有效、注册项齐全),不运行会写入项目的 hook,也不创建部署标记。
393
+
387
394
  1. 验证 hooks 注册:
388
395
  - 检查 `.claude/settings.local.json` 中的 hooks 字段是否正确
389
396
  - 检查 `.claude/hooks/` 下的脚本是否存在且有执行权限
@@ -396,7 +403,7 @@ Reasonix(DeepSeek-Reasonix CLI)当前只部署 skills 与 `AGENTS.md`,不
396
403
  - 检查 `.claude/skills/story-setup/references/agent-references/` 下 reference 文件完整
397
404
  - 检查所有 `story-setup/references/agent-references/<file>.md` 都能解析到 deployed bundle
398
405
  5. 验证部署标记:
399
- - 检查 `.story-deployed` 是否存在且包含时间戳、`agents_version: 29`、`setup_skill_version: 1.2.10`、`target_cli`、`resolver_strategy`、`references_dir`
406
+ - 检查 `.story-deployed` 是否存在且包含时间戳、`agents_version: 30`、`setup_skill_version: 1.2.10`、`target_cli`、`resolver_strategy`、`references_dir`
400
407
  6. 输出安装报告:
401
408
  - 列出所有已部署的文件
402
409
  - 列出需要注意的事项(如已有配置已合并)
@@ -509,9 +516,9 @@ Reasonix(DeepSeek-Reasonix CLI)当前只部署 skills 与 `AGENTS.md`,不
509
516
  ## 重新部署
510
517
 
511
518
  - `.story-deployed` 不存在 → 全新安装,Phase 2 全部执行
512
- - `.story-deployed` 存在且 `agents_version: 29` → 提示已部署,AskUserQuestion 确认是否重新部署;提示里写明重新部署只用当前本地 skill 包刷新项目文件,skill 本身的更新走 `npx skills add` 或 marketplace
513
- - `.story-deployed` 存在但 `agents_version` 缺失、非整数或小于 `29` → 提示需要更新,重新执行 Phase 2 覆盖 agents/hooks/rules/reference bundle,CLAUDE.md / AGENTS.md / settings.local.json / .codex/hooks.json / `.agents/hooks.json` / .zcode/config.json 走合并策略
514
- - `.story-deployed` 存在且 `agents_version` 大于 `29` → 当前 skill 版本过旧,停止并提示先更新 oh-story-claudecode;不覆盖项目中的更新部署
519
+ - `.story-deployed` 存在且 `agents_version: 30` → 提示已部署,AskUserQuestion 确认是否重新部署;提示里写明重新部署只用当前本地 skill 包刷新项目文件,skill 本身的更新走 `npx skills add` 或 marketplace
520
+ - `.story-deployed` 存在但 `agents_version` 缺失、非整数或小于 `30` → 提示需要更新,重新执行 Phase 2 覆盖 agents/hooks/rules/reference bundle,CLAUDE.md / AGENTS.md / settings.local.json / .codex/hooks.json / `.agents/hooks.json` / .zcode/config.json 走合并策略
521
+ - `.story-deployed` 存在且 `agents_version` 大于 `30` → 当前 skill 版本过旧,停止并提示先更新 oh-story-claudecode;不覆盖项目中的更新部署
515
522
 
516
523
  ---
517
524
 
@@ -1,5 +1,7 @@
1
1
  # 去AI味完整指南
2
2
 
3
+ > 本文件的句长、视角、标点、修辞与禁用词是默认写法,服从 [style-resolution.md](style-resolution.md) 的逐维裁决。所选 Gate 检查表达效果,不因作者有意选择某写法就机械删除;获准命中按书级 `.deslop-whitelist` 处理。
4
+
3
5
  <!-- 同名副本×5 字节同步,改动后跑 scripts/check-shared-files.sh -->
4
6
 
5
7
  > 识别AI写作指纹、系统性去AI三遍法、禁用词约束、改写范例库。用于正文写作后做去AI味自检和改写时查阅。
@@ -105,18 +107,11 @@
105
107
 
106
108
  ### 规则 2:动作 + 对话 + 情绪反应
107
109
 
108
- 三要素循环推进,不要单写心理活动超过 2 段:
110
+ 动作、对话与情绪反应按场景需要交织,不按固定顺序轮换,不为凑齐三项补反应。
109
111
 
110
- ```
111
- 动作 -> 对话 -> 情绪反应 -> 动作 -> 对话 -> ……
112
- ```
112
+ 情绪没有固定译法,关键节点也可以准确直写。上下文已让情绪成立,不另补反应;需要补足信息时,优先选择、台词、策略、物件或实际后果。
113
113
 
114
- 情绪不用"他感到/他觉得",用身体反应和行为表现:
115
- - 不写"他很紧张" -> 写"手心全是汗,筷子差点掉了"
116
- - 不写"她很愤怒" -> 写"她把杯子摔在地上,碎片弹到脚背上也没弯腰捡"
117
- - 不写"他很伤心" -> 写"他在车里坐了二十分钟才发动引擎"
118
-
119
- 以上替换针对关键情绪节点;低强度过场情绪可一笔直写("他有点烦"),不必处处外化。
114
+ 身体细节只有带来新信息、影响动作或体现人物与场景特点时才保留。只在句尾重复标注情绪的微动作删掉,不换部位或同义动作。去味时沿用原文已有事实,不凭空添加摔杯子、攥袖口等行为。
120
115
 
121
116
  ### 规则 3:句子该多长(短句是工具,不是默认)
122
117
 
@@ -157,7 +152,7 @@
157
152
  1. 用行为代替形容词
158
153
  2. 用细节代替总结
159
154
  3. 用对话代替旁白说明
160
- 4. 用反应代替情绪词
155
+ 4. 用后果代替情绪总结
161
156
 
162
157
  ---
163
158
 
@@ -219,8 +214,7 @@
219
214
  > 完整禁用词表和句式模板见 [banned-words.md](banned-words.md)
220
215
 
221
216
  ### 正确替代示例
222
- - '他感到一丝紧张' -> '他的手在抖'
223
- - '她很伤心' -> '她背过身,把袖口攥皱了'
217
+ - '他感到一丝紧张,手心全是汗' -> '他签名时划破了纸'(身体细节只在造成后果时留)
224
218
  - '"好的。"他说道' -> '"好的。"他把门卡塞回口袋'
225
219
  - '他深吸一口气' -> '他把话咽回去'
226
220
 
@@ -276,7 +270,7 @@ AI 喜欢把事情凑成三个以显"完整"。-> 砍到只剩最有力的一条
276
270
  | 解释因果 | 「之所以…是因为」「原来…」「这意味着」「正是因为」-> 删。因果只从角色动作、对话、反应里让读者自己拼 |
277
271
  | 上帝视角剧透 | 「她不知道的是」「殊不知」「多年以后」「冥冥之中」「仿佛预示着」-> 删。只写角色此刻知道的,悬念让读者自己悬 |
278
272
  | 替读者下结论/定性 | 「演得真好」「这出戏她看过一遍」「他就是这样薄情的人」-> 删。把证据(神态、动作、台词)摆出来,定性留给读者 |
279
- | 替角色总结心理 | 「她明白,这一切都是命」-> 换成一句带偏见的闪念或一个身体反应 |
273
+ | 替角色总结心理 | 「她明白,这一切都是命」-> 无新增信息就删;确有角色判断时保留带偏见的闪念,不强配身体反应 |
280
274
  | 总结/动机/评价链把意义说满 | 「他终于明白」「这是最好的选择」「所有人都会记住这一刻」-> 删掉定性,改成角色当下要处理的具体缺口、未完成动作或局部反馈;不是保留评价再硬塞物件/动作 |
281
275
  | 安排感/硬铺垫 | 为后文强行交代背景、整段回忆倒叙 -> 背景按角色此刻真实所需,用闪念、半句话、物件零碎带出,不集中交代 |
282
276
  | 升华式收尾 | 结尾对仗拔高、金句点题 -> 用一个动作或一句留白收住,把"意思"压进画面里 |
@@ -315,7 +309,7 @@ AI 喜欢把事情凑成三个以显"完整"。-> 砍到只剩最有力的一条
315
309
 
316
310
  自检:删完连读一遍,读感像提纲或流水口令,就是删过了——把非峰值句恢复成自然白话,不是接着删。
317
311
 
318
- 本模式约束的是删减的度,不降低清理力度:禁用词、套路句式、告知式心理照删照改,模式 1-8 与 Gate A-G 全额执行;回填只回结构虚词和连接,不保留、不恢复任何模板措辞。
312
+ 本模式约束的是删减的度,不降低清理力度:选定 Gate 内的禁用词、套路句式、告知式心理照删照改;回填只回结构虚词和连接,不保留、不恢复任何模板措辞。
319
313
 
320
314
  ### 模式 10:二修伪自然(油腻倒装 / 监控动作清单 / 对话指标化)
321
315
 
@@ -381,7 +375,7 @@ AI 喜欢把事情凑成三个以显"完整"。-> 砍到只剩最有力的一条
381
375
  ## 系统性去AI三遍法
382
376
 
383
377
  ### Pass 1:去泛化(Strip Generic)
384
- - 抽象情绪总结句 -> 删或替换为具体动作
378
+ - 抽象情绪总结句 -> 按规则 2 判断:删重复说明,保留准确直写,需要时用原文已有信息落地
385
379
  - 假深度句 -> 删
386
380
  - 意义膨胀 -> 缩小到具体影响
387
381
  - 空洞结论 -> 删
@@ -411,13 +405,9 @@ AI 喜欢把事情凑成三个以显"完整"。-> 砍到只剩最有力的一条
411
405
 
412
406
  **原则**:少即是多。每段加 1-2 个具体细节就够了。
413
407
 
414
- ### 升级策略
408
+ ### 执行范围
415
409
 
416
- | AI味程度 | 策略 |
417
- |----------|------|
418
- | 轻度 | 只做 Pass 1 |
419
- | 中度 | Pass 1 + Pass 2 |
420
- | 重度 | 完整三遍 + 重点段落重写 |
410
+ 调用方指定 Gate 时,只处理选定 Gate;三遍法只安排顺序,不重新分级或扩大范围。未指定范围时,按实际问题选择适用检查。
421
411
 
422
412
  ### 自检清单
423
413
  - 对话自然度检查:对话是否使用口语化表达,是否避免了书面语/正式腔调
@@ -456,31 +446,13 @@ AI 喜欢把事情凑成三个以显"完整"。-> 砍到只剩最有力的一条
456
446
 
457
447
  ## 改写范例库
458
448
 
459
- ### 情绪外化范例
460
-
461
- **紧张**
462
- - '他感到一阵紧张,心跳不由自主地加快了'
463
- - 他攥紧了手里的纸杯,水洒出来一些
449
+ ### 情绪落地示例
464
450
 
465
- **愤怒**
466
- - '愤怒在他心中燃烧,他不由得握紧了拳头'
467
- - 他把筷子往桌上一拍,碗里的汤溅了出来
468
-
469
- **悲伤**
470
- - '一丝悲伤涌上心头,她的眼中闪过泪光'
471
- - 她低头搅着咖啡,搅了很久
472
-
473
- **害怕**
474
- - '恐惧瞬间笼罩了他,他感到一阵战栗'
475
- - 他的背贴在墙上,不敢动
476
-
477
- **失望**
478
- - '她感到一丝失落,心仿佛被什么东西揪住了'
479
- - "哦。"她把手机锁了屏
480
-
481
- **惊讶**
482
- - '他的瞳孔微微收缩,显然没有想到会听到这样的话'
483
- - 他张了张嘴,什么都没说出来
451
+ | 原文与语境 | 处理 |
452
+ |---|---|
453
+ | 「他很紧张。再错一题,补考也过不了。」 | 情绪有具体原因,可以直写,不补手抖或出汗 |
454
+ | 「她已经决定不再等他。她攥了攥袖口。」袖口动作无后续作用 | 删除第二句,不换成低头或咬唇 |
455
+ | 「手腕的伤让他握不住笔,签名只写了一半。」 | 保留,身体状态造成动作失败,不能当作情绪套话删除 |
484
456
 
485
457
  ### 场景描写范例
486
458
 
@@ -571,7 +543,7 @@ AI 喜欢把事情凑成三个以显"完整"。-> 砍到只剩最有力的一条
571
543
  - [ ] **无书面语连词堆砌**:无"于是乎/与此同时/从而/因而/诚然"泛滥
572
544
  - [ ] **章尾无总结升华**:用动作/对话/悬念收束,无感悟/哲理/预告
573
545
  - [ ] **无大段心理描写**:心理活动不超过2段,无括号标注内心
574
- - [ ] **情绪用动作展示**:关键情绪节点无直接写"愤怒/伤心/紧张",用身体反应替代;低强度过场情绪可一笔直写,不必处处外化
546
+ - [ ] **情绪落地**:按规则 2 保留准确直写与有功能的身体细节,删除重复说明,不给每个情绪词配动作
575
547
  - [ ] **对话口语化**:无书面腔,不同角色语气可区分
576
548
  - [ ] **标点不压平**:没有把质问、爆发、犹豫全部压成句号;也没有随机堆砌 `?`/`!`,或用 `……`/`——` 硬造停顿
577
549
  - [ ] **Show Don't Tell**:用行为代替形容词,用细节代替总结
@@ -1,8 +1,10 @@
1
1
  # AI味禁用词与句式表
2
2
 
3
+ > 表达默认值服从 [style-resolution.md](style-resolution.md);文件结构与事实约束不豁免。
4
+
3
5
  <!-- 同名副本×6 字节同步,改动后跑 scripts/check-shared-files.sh -->
4
6
 
5
- ## 最毒禁用句式(出现即修,最高优先级)
7
+ ## 默认优先检查的句式(先对照本书文风)
6
8
 
7
9
  写网文最毒的 AI 句式,作者一旦养成就会反复出现。Gate A 第一遍扫描必须命中:
8
10