@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
@@ -8,6 +8,7 @@ from artifacts import _explicit_source_video, _value_fingerprint
8
8
  from lib import log, run_cmd
9
9
 
10
10
  def _load_cut_timeline_plan(work_dir):
11
+ """The cut plan, preferring clip_plan_validated.json when it matches the raw plan; None in full mode."""
11
12
  raw_plan_path = Path(work_dir) / "clip_plan.json"
12
13
  validated_plan_path = Path(work_dir) / "clip_plan_validated.json"
13
14
  if not validated_plan_path.exists():
@@ -16,73 +17,79 @@ def _load_cut_timeline_plan(work_dir):
16
17
  return json.loads(validated_plan_path.read_text(encoding="utf-8"))
17
18
  raw_plan = json.loads(raw_plan_path.read_text(encoding="utf-8"))
18
19
  validated_plan = json.loads(validated_plan_path.read_text(encoding="utf-8"))
19
- if (
20
- isinstance(validated_plan, dict)
21
- and validated_plan.get("raw_plan_fingerprint") == _value_fingerprint(raw_plan)
22
- ):
20
+ if validated_plan.get("raw_plan_fingerprint") == _value_fingerprint(raw_plan):
23
21
  return validated_plan
24
22
  return raw_plan
25
23
 
26
24
 
27
- def _ratio_to_float(value, default=1.0):
28
- value = str(value or "").strip()
29
- if not value or value in {"0:1", "0/1", "N/A"}:
30
- return default
31
- try:
32
- if ":" in value:
33
- num, den = value.split(":", 1)
34
- elif "/" in value:
35
- num, den = value.split("/", 1)
25
+ def _plan_clip_spans(work_dir):
26
+ """Cut-mode clip spans [{source_start, source_end, output_start, output_end, entry}], or None.
27
+
28
+ clip_plan.json is either a bare list or {"clips": [...]}; a clip names its source range as
29
+ source_start/source_end or start/end. Clips without explicit output_start/output_end are laid
30
+ out back to back on the output timeline.
31
+ """
32
+ plan = _load_cut_timeline_plan(work_dir)
33
+ if plan is None:
34
+ return None
35
+ entries = plan["clips"] if isinstance(plan, dict) else plan
36
+ spans, cursor = [], 0.0
37
+ for entry in entries:
38
+ ss = float(entry.get("source_start", entry.get("start")))
39
+ se = float(entry.get("source_end", entry.get("end")))
40
+ if "output_start" in entry:
41
+ out_s, out_e = float(entry["output_start"]), float(entry["output_end"])
42
+ cursor = max(cursor, out_e)
36
43
  else:
37
- return float(value)
38
- den_f = float(den or 0)
39
- return float(num) / den_f if den_f else default
40
- except (TypeError, ValueError, ZeroDivisionError):
44
+ out_s, out_e = cursor, cursor + (se - ss)
45
+ cursor = out_e
46
+ spans.append({
47
+ "source_start": ss, "source_end": se,
48
+ "output_start": out_s, "output_end": out_e,
49
+ "entry": entry,
50
+ })
51
+ return spans
52
+
53
+
54
+ def _ratio_to_float(value, default=1.0):
55
+ """Parse an ffprobe ratio ("4:3", "16/9" or a bare number); unknown ratios yield `default`."""
56
+ value = value.strip()
57
+ if value in {"", "0:1", "0/1", "N/A"}:
41
58
  return default
59
+ if ":" in value:
60
+ num, den = value.split(":", 1)
61
+ elif "/" in value:
62
+ num, den = value.split("/", 1)
63
+ else:
64
+ return float(value)
65
+ return float(num) / float(den) if float(den) else default
42
66
 
43
67
 
44
68
  def _fps_from_rate(value, default=30.0):
45
- try:
46
- if "/" in str(value):
47
- num, den = str(value).split("/", 1)
48
- den_f = float(den or 0)
49
- return round(float(num) / den_f, 3) if den_f else default
50
- return round(float(value), 3)
51
- except (TypeError, ValueError, ZeroDivisionError):
52
- return default
69
+ """Parse an ffprobe frame rate ("30000/1001" or a bare number); a 0/0 rate yields `default`."""
70
+ if "/" in value:
71
+ num, den = value.split("/", 1)
72
+ return round(float(num) / float(den), 3) if float(den) else default
73
+ return round(float(value), 3)
53
74
 
54
75
 
55
76
  def _stream_rotation(stream):
56
77
  """Extract rotation from tags or side_data_list in ffprobe JSON."""
57
- if not isinstance(stream, dict):
58
- return 0
59
- for source in (
60
- (stream.get("tags") or {}).get("rotate"),
61
- stream.get("rotation"),
62
- ):
78
+ for source in (stream.get("tags", {}).get("rotate"), stream.get("rotation")):
63
79
  if source not in (None, ""):
64
- try:
65
- return int(round(float(source))) % 360
66
- except (TypeError, ValueError):
67
- pass
68
- for item in stream.get("side_data_list") or []:
69
- if not isinstance(item, dict):
70
- continue
71
- for key in ("rotation", "displaymatrix"):
72
- if item.get(key) not in (None, ""):
73
- try:
74
- return int(round(float(item.get(key)))) % 360
75
- except (TypeError, ValueError):
76
- pass
80
+ return int(round(float(source))) % 360
81
+ for item in stream.get("side_data_list", []):
82
+ if item.get("rotation") not in (None, ""):
83
+ return int(round(float(item["rotation"]))) % 360
77
84
  return 0
78
85
 
79
86
 
80
- def _canvas_from_stream(stream, *, default_width=1280, default_height=720, default_fps=30.0):
81
- storage_w = int(stream.get("width") or default_width)
82
- storage_h = int(stream.get("height") or default_height)
83
- fps = _fps_from_rate(stream.get("r_frame_rate") or stream.get("avg_frame_rate"), default_fps)
84
- sar_text = stream.get("sample_aspect_ratio") or "1:1"
85
- dar_text = stream.get("display_aspect_ratio") or ""
87
+ def _canvas_from_stream(stream):
88
+ storage_w = stream["width"]
89
+ storage_h = stream["height"]
90
+ fps = _fps_from_rate(stream["r_frame_rate"])
91
+ sar_text = stream.get("sample_aspect_ratio", "1:1")
92
+ dar_text = stream.get("display_aspect_ratio", "")
86
93
  sar = _ratio_to_float(sar_text, 1.0)
87
94
  rotation = _stream_rotation(stream)
88
95
 
@@ -91,9 +98,9 @@ def _canvas_from_stream(stream, *, default_width=1280, default_height=720, defau
91
98
  if dar_text and dar_text not in {"0:1", "N/A"}:
92
99
  dar = _ratio_to_float(dar_text, 0.0)
93
100
  # ffprobe sources are not consistent: some report DAR before rotation
94
- # (landscape value > 1 for a 90° stream), while simple line mocks and
95
- # some containers report the already-rotated portrait DAR (< 1). Only
96
- # apply DAR before swapping when it describes the stored orientation.
101
+ # (landscape value > 1 for a 90° stream), while some containers report the
102
+ # already-rotated portrait DAR (< 1). Only apply DAR before swapping when it
103
+ # describes the stored orientation.
97
104
  if dar > 0 and not (rotation in {90, 270} and dar < 1.0):
98
105
  # Preserve height and adjust width. This keeps legacy square-pixel landscape
99
106
  # byte-identical while honoring non-square pixel DAR metadata.
@@ -110,10 +117,6 @@ def _canvas_from_stream(stream, *, default_width=1280, default_height=720, defau
110
117
  "rotation": rotation,
111
118
  "sample_aspect_ratio": sar_text,
112
119
  "display_aspect_ratio": dar_text or f"{display_w}:{display_h}",
113
- "sar": sar_text,
114
- "dar": dar_text or f"{display_w}:{display_h}",
115
- "display_width": display_w,
116
- "display_height": display_h,
117
120
  }
118
121
 
119
122
 
@@ -122,44 +125,19 @@ def _probe_canvas(video_path, *, command_runner=run_cmd):
122
125
 
123
126
  ``width``/``height`` are the display canvas used by subtitle/overlay geometry.
124
127
  For legacy square-pixel landscape sources, these remain the raw storage dimensions.
125
- Extra storage/rotation/SAR/DAR fields are visual QC facts and are safe for callers
126
- that only consume width/height/fps.
127
128
  """
128
- defaults = {"width": 1280, "height": 720, "fps": 30.0}
129
129
  res = command_runner([
130
130
  "ffprobe", "-v", "error", "-select_streams", "v:0",
131
131
  "-show_entries",
132
132
  "stream=width,height,r_frame_rate,avg_frame_rate,sample_aspect_ratio,display_aspect_ratio:stream_tags=rotate:stream_side_data=rotation",
133
133
  "-of", "json", str(video_path),
134
134
  ])
135
- if res.returncode == 0:
136
- try:
137
- data = json.loads(res.stdout or "{}")
138
- stream = (data.get("streams") or [{}])[0]
139
- if isinstance(stream, dict) and stream:
140
- return _canvas_from_stream(stream)
141
- except (ValueError, TypeError, KeyError):
142
- pass
143
- # Tests and older mocks may still feed default=nw=1:nk=0 style lines.
144
- stream = {}
145
- for line in (res.stdout or "").splitlines():
146
- line = line.strip()
147
- if not line or "=" not in line:
148
- continue
149
- key, value = line.split("=", 1)
150
- stream[key] = value
151
- if stream:
152
- return _canvas_from_stream(stream)
153
- return {
154
- **defaults,
155
- "storage_width": defaults["width"],
156
- "storage_height": defaults["height"],
157
- "rotation": 0,
158
- "sample_aspect_ratio": "1:1",
159
- "display_aspect_ratio": "16:9",
160
- "display_width": defaults["width"],
161
- "display_height": defaults["height"],
162
- }
135
+ if res.returncode != 0:
136
+ raise RuntimeError(f"ffprobe 无法读取视频流 {video_path}: {res.stderr}")
137
+ streams = json.loads(res.stdout)["streams"]
138
+ if not streams:
139
+ raise RuntimeError(f"{video_path} 没有视频流")
140
+ return _canvas_from_stream(streams[0])
163
141
 
164
142
 
165
143
  def _has_audio_stream(video_path, *, command_runner=run_cmd):
@@ -183,61 +161,39 @@ def _build_video_clips(
183
161
 
184
162
  In cut mode each plan entry becomes a clip referencing the ORIGINAL source
185
163
  range. Multi-source validated plans carry per-clip source_path and do not
186
- require an explicit ambient --source-video.
164
+ require an explicit ambient --source-video. Without any declared source (full
165
+ mode, or cut mode rendered without --source-video) the rendered input is one clip.
187
166
  """
188
167
  explicit_source_video = source_video_getter()
189
- try:
190
- plan = _load_cut_timeline_plan(work_dir)
191
- if plan is not None:
192
- entries = plan.get("clips", plan) if isinstance(plan, dict) else plan
193
- # A plan is "multi-source" once any clip carries its own source_path; such
194
- # clips must never be silently dropped — a missing one is degraded in place.
195
- multi_source = any(
196
- isinstance(c, dict) and str(c.get("source_path") or "").strip() for c in entries
197
- )
198
- clips, cursor = [], 0.0
199
- for c in entries:
200
- per_clip_source = str(c.get("source_path") or "").strip()
201
- source_path = per_clip_source or explicit_source_video
202
- ss = float(c.get("source_start", c.get("start")))
203
- se = float(c.get("source_end", c.get("end")))
204
- timeline_start = c.get("output_start")
205
- timeline_end = c.get("output_end")
206
- dur = max(0.0, se - ss)
207
- if dur <= 0:
208
- continue
209
- if timeline_start is None or timeline_end is None:
210
- timeline_start = cursor
211
- timeline_end = cursor + dur
212
- cursor += dur
213
- else:
214
- timeline_start = float(timeline_start)
215
- timeline_end = float(timeline_end)
216
- cursor = max(cursor, timeline_end)
217
- if not source_path or not os.path.exists(source_path):
218
- if per_clip_source or multi_source:
219
- # Degrade ONLY this clip — point it at the rendered cut for its own
220
- # output window — and keep real provenance for every present source,
221
- # instead of collapsing the whole multi-source timeline.
222
- seg = max(0.0, float(timeline_end) - float(timeline_start))
223
- logger(f" 时间线: source_path 不存在,该片段降级为剪后成片片段: {source_path or '(unset)'}")
224
- clips.append({"source_id": c.get("source_id"),
225
- "source_path": str(input_video),
226
- "source_start": float(timeline_start),
227
- "source_end": float(timeline_start) + seg,
228
- "timeline_start": float(timeline_start),
229
- "timeline_end": float(timeline_end),
230
- "provenance_degraded": True,
231
- "provenance_reason": f"missing_source_path:{source_path or 'unset'}"})
232
- continue
233
- clips.append({"source_id": c.get("source_id"),
234
- "source_path": source_path, "source_start": ss,
235
- "source_end": se, "timeline_start": timeline_start,
236
- "timeline_end": timeline_end})
237
- if clips:
238
- return clips
239
- except (TypeError, ValueError, KeyError, OSError) as exc:
240
- logger(f" 时间线: clip_plan 解析失败,回退单片 ({exc})")
241
- return [{"source_path": str(input_video), "source_start": 0.0,
242
- "source_end": float(duration_s), "timeline_start": 0.0,
243
- "timeline_end": float(duration_s)}]
168
+ spans = _plan_clip_spans(work_dir)
169
+ multi_source = spans is not None and any(span["entry"].get("source_path") for span in spans)
170
+ if spans is None or not (explicit_source_video or multi_source):
171
+ return [{"source_path": str(input_video), "source_start": 0.0,
172
+ "source_end": float(duration_s), "timeline_start": 0.0,
173
+ "timeline_end": float(duration_s)}]
174
+ clips = []
175
+ for span in spans:
176
+ entry = span["entry"]
177
+ source_path = entry.get("source_path") or explicit_source_video
178
+ timeline_start, timeline_end = span["output_start"], span["output_end"]
179
+ if not source_path or not os.path.exists(source_path):
180
+ # Degrade ONLY this clip — point it at the rendered cut for its own output
181
+ # window — and keep real provenance for every present source, instead of
182
+ # collapsing the whole multi-source timeline.
183
+ logger(f" 时间线: source_path 不存在,该片段降级为剪后成片片段: {source_path or '(unset)'}")
184
+ clips.append({"source_id": entry.get("source_id"),
185
+ "source_path": str(input_video),
186
+ "source_start": timeline_start,
187
+ "source_end": timeline_end,
188
+ "timeline_start": timeline_start,
189
+ "timeline_end": timeline_end,
190
+ "provenance_degraded": True,
191
+ "provenance_reason": f"missing_source_path:{source_path or 'unset'}"})
192
+ continue
193
+ clips.append({"source_id": entry.get("source_id"),
194
+ "source_path": source_path,
195
+ "source_start": span["source_start"],
196
+ "source_end": span["source_end"],
197
+ "timeline_start": timeline_start,
198
+ "timeline_end": timeline_end})
199
+ return clips