@oh-story/dsh 0.1.7 → 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 +30 -15
  2. package/lib/client.js +93 -16
  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
package/README.md CHANGED
@@ -7,34 +7,40 @@
7
7
  `oh-story-dsh` 是基于 DeepSeek Harness(DSH)构建的社区小说、短剧、互动游戏与视频解说创作插件,提供:
8
8
 
9
9
  - 13 个 Oh Story 小说 Skills 与 7 个专业 Roles;
10
- - 10 个 Drama Skills 0.6.5 短剧流程,每集按请求维护最多五份 creator-first Markdown;
11
- - 7 个 NovelToGame 0.3.0 Skills、`game-adaptations/<project>` 产物协议与《金瓶梅 · 风月总账》可玩构建;
12
- - 6 个 video-recap-skills 0.4.0 Skills、`video-recaps/<project>` 项目约定与轻量视频预览工作台;
10
+ - 11 个 Drama Skills 0.7.0 短剧流程,每集按请求维护最多五份 creator-first Markdown,成片装配另写《剪辑单.md》;
11
+ - 7 个 NovelToGame 0.3.1 Skills、`game-adaptations/<project>` 产物协议与《金瓶梅 · 风月总账》可玩构建;
12
+ - 6 个 video-recap-skills 0.5.0 Skills、`video-recaps/<project>` 项目约定与轻量视频预览工作台;
13
13
  - 小说协议 hooks 与安全的 Session workspace 文件路由;
14
14
  - 小说/短剧的文件树、编辑器、Chat 三栏工作台,以及游戏/视频的“左侧工作台 + 右侧 Chat”制作面板;
15
15
  - Markdown 与 JSONL 结构化预览;
16
- - 短剧镜头/素材/任务/成片/画布生产视图、跨集项目媒体库、成果版本与参考复用;轻量 Markdown 协议会诊断重复 ID、悬空引用和畸形标题;
16
+ - 短剧镜头/素材/任务/成片/画布生产视图、跨集项目媒体库、成果版本与参考复用;「成片」页把排定的镜序交给 `/short-drama-edit` 写《剪辑单.md》并渲染到 `制作成果/成片/`;轻量 Markdown 协议会诊断重复 ID、悬空引用和畸形标题;
17
17
  - `oh_story_role` 原生子 Agent,以及无媒体副作用的 `oh_story_production` 生产界面/任务意图工具视图。
18
18
 
19
19
  本项目与 DeepSeek 官方无隶属、合作或背书关系;DeepSeek Harness 名称与品牌素材归其权利人所有。
20
20
 
21
21
  ## 安装
22
22
 
23
+ 安装命令会临时提供 pnpm;只安装 Node.js 的机器也能执行。DSH 的 `plugin add` 内部需要 pnpm,单独运行 `npx @deepseek-ai/dsh ... plugin add` 不会自动补上它。
24
+
23
25
  ```bash
24
- npx -y @deepseek-ai/dsh@0.1.2-rc.1 plugin --profile web add @oh-story/dsh@0.1.7
25
- npx -y @deepseek-ai/dsh@0.1.2-rc.1 web
26
+ npx -y --package pnpm@11.7.0 --package @deepseek-ai/dsh@0.1.5-rc.1 dsh plugin --profile web add @oh-story/dsh@0.1.9 &&
27
+ npx -y @deepseek-ai/dsh@0.1.5-rc.1 web
26
28
  ```
27
29
 
28
30
  也可以直接安装 GitHub Release 中的预构建包:
29
31
 
30
32
  ```bash
31
- npx -y @deepseek-ai/dsh@0.1.2-rc.1 plugin --profile web add https://github.com/zenstory-ai/oh-story-dsh/releases/download/v0.1.7/oh-story-dsh-0.1.7.tgz
32
- npx -y @deepseek-ai/dsh@0.1.2-rc.1 web
33
+ npx -y --package pnpm@11.7.0 --package @deepseek-ai/dsh@0.1.5-rc.1 dsh plugin --profile web add https://github.com/zenstory-ai/oh-story-dsh/releases/download/v0.1.9/oh-story-dsh-0.1.9.tgz &&
34
+ npx -y @deepseek-ai/dsh@0.1.5-rc.1 web
33
35
  ```
34
36
 
35
- 需要 Node.js 24+。首次使用需要在 DSH 的「设置 → 模型」中添加 Provider 并填入 API Key,或在启动前设置环境变量 `DEEPSEEK_API_KEY`。
37
+ 保持终端运行。若浏览器未自动打开,访问终端打印的完整 `http://127.0.0.1:3080/?token=...` 链接完成首次认证。
38
+
39
+ 需要 Node.js 24+。开始 AI 创作前需要在 DSH 的「设置 → 模型」中添加 Provider 并填入 API Key,或在启动前设置环境变量 `DEEPSEEK_API_KEY`。
40
+
41
+ 首次首页尚无创作工作台。点击左侧 Workspaces 旁的 +(添加工作区 / Add workspace)选择作品文件夹,再在下方「选择工作区 / Choose workspace」中选中该目录(或打开已有会话),目录里已有创作项目时,会显示「小说 / 短剧 / 游戏 / 视频」标签;查看已有作品无需 API Key。
36
42
 
37
- 将作品目录添加为 DSH workspace,然后在普通 Agent 会话中使用 `/story`、`/short-drama`、`/novel-to-game quick` 或 `/video-recap`。四个入口始终可见;尚未创建的类型显示对应的创建引导。模型、凭据、Preset、权限、会话记录、停止/继续、Todo、审批和 Composer 均沿用当前 DeepSeek Harness 配置与界面。
43
+ 配置模型后,在普通 Agent 会话中使用 `/story`、`/short-drama`、`/novel-to-game quick` 或 `/video-recap`。空目录会保留 DSH 原生 Chat,Agent 写出第一个创作文件后工作台才会自动出现。工作台收起后,可通过会话区的「创作工作台」按钮重新打开。模型、凭据、Preset、权限、会话记录、停止/继续、Todo、审批和 Composer 均沿用当前 DeepSeek Harness 配置与界面。
38
44
 
39
45
  ## 短剧工作台
40
46
 
@@ -64,19 +70,28 @@ npx -y @deepseek-ai/dsh@0.1.2-rc.1 web
64
70
 
65
71
  Drama Skills 0.6.0 不支持把 v0.5 结构化项目原地升级为 creator-first 项目。旧项目应继续锁定 v0.5 并只读保留;迁移时请新建项目根,逐集人工确认当前工作实际需要的 `剧本.md`、`视觉设定.md`、`分镜.md`、`图片提示词.md` 或 `视频提示词.md`,不要预建空文档。
66
72
 
73
+ ## 没看到界面时
74
+
75
+ - **安装报 `pnpm not found on PATH`**:重新执行上面带 `--package pnpm@11.7.0` 的完整安装命令,确认安装成功后再启动。
76
+ - **浏览器未打开或要求认证**:打开终端打印的完整带 `?token=...` 链接;端口被占用时用 `web --port 3081`,并访问新打印的链接。
77
+ - **没有四个创作标签**:先添加作品目录并打开会话。空目录需要先在 Chat 中运行创作命令,生成创作文件后工作台才会出现;已收起的工作台可用会话区的「创作工作台」按钮恢复。已有作品仍不显示时,检查安装与启动是否使用同一个 profile,重启 DSH 并刷新页面。
78
+ - **独立 `story` profile 没有网页服务**:按下节补上 `@deepseek-ai/dsh-web-app`,仅安装创作插件不会给新 profile 添加 Web 界面。
79
+
67
80
  ## 按需加载
68
81
 
69
- 插件装进哪个 profile,那个 profile 的每个 Session 就都会加载创作 Skills 与三栏工作台。想让原版 `web` 保持干净、只在创作时打开工作台,就装进独立 profile:
82
+ 插件装进哪个 profile,那个 profile 的每个 Session 就都会加载创作 Skills;工作台只在有创作项目时显示。想让原版 `web` 保持干净、只在创作时打开工作台,就装进独立 profile:
70
83
 
71
84
  ```bash
72
- npx -y @deepseek-ai/dsh@0.1.2-rc.1 plugin --profile story add @oh-story/dsh@0.1.7
85
+ npx -y --package pnpm@11.7.0 --package @deepseek-ai/dsh@0.1.5-rc.1 dsh plugin --profile story add @oh-story/dsh@0.1.9
73
86
  ```
74
87
 
75
- 新 profile 默认没有界面。编辑 `~/.dsh/profiles/story/package.json`,把 `dsh.profile.bundles` 改成 `["@deepseek-ai/dsh-base", "@deepseek-ai/dsh-web-app", "@oh-story/dsh"]`,顺序照抄,这个包不用另外安装。
88
+ 新 profile 默认没有界面。编辑 `~/.dsh/profiles/story/package.json`,把 `dsh.profile.bundles` 改成 `["@deepseek-ai/dsh-base", "@deepseek-ai/dsh-web-app", "@oh-story/dsh"]`。
89
+
90
+ `@deepseek-ai/dsh-web-app` 是 DSH 自带的 Web 界面包,需要在创作插件之前加载。
76
91
 
77
92
  ```bash
78
- npx -y @deepseek-ai/dsh@0.1.2-rc.1 web # 原版 DSH
79
- npx -y @deepseek-ai/dsh@0.1.2-rc.1 --profile story --port 3081 # 创作工作台
93
+ npx -y @deepseek-ai/dsh@0.1.5-rc.1 web # 原版 DSH
94
+ npx -y @deepseek-ai/dsh@0.1.5-rc.1 --profile story --port 3081 # 创作工作台
80
95
  ```
81
96
 
82
97
  模型、凭据、workspace 与历史会话由 DSH 统一保存,切换 profile 不会丢。安装与启动请使用同一个 dsh 版本。
package/lib/client.js CHANGED
@@ -815,17 +815,18 @@ ${item.prompt}`).join(`
815
815
  \u628A\u6570\u91CF\u3001\u9010\u9879\u8F93\u51FA\u548C\u6210\u672C\u8FB9\u754C\u5B8C\u6574\u5C55\u793A\u7ED9\u521B\u4F5C\u8005\u3002\u6B64\u6309\u94AE\u53EA\u8868\u8FBE\u201C\u51C6\u5907\u9884\u89C8\u201D\uFF0C\u4E0D\u6784\u6210\u770B\u5230\u9884\u89C8\u540E\u7684\u751F\u4EA7\u786E\u8BA4\uFF1B\u4E0D\u5F97 confirm \u6216 run\u3002\u7528\u6237\u5728\u540E\u7EED\u6D88\u606F\u660E\u786E\u786E\u8BA4\u8FD9\u4EFD\u9884\u89C8\u540E\uFF0C\u624D\u53EF\u8C03\u7528 oh_story_production track_job \u767B\u8BB0\u540C\u4E00\u4E2A\u6279\u6B21\u4EFB\u52A1 ID\uFF0C\u5E76\u8FD0\u884C Provider\u3002${authorityBoundary}`;
816
816
  }
817
817
  function nativeCompositionPrompt(production, job, orderedPaths) {
818
- return `/short-drama-produce
818
+ return `/short-drama-edit
819
819
 
820
- \u6267\u884C\u521B\u4F5C\u8005\u5DF2\u660E\u786E\u786E\u8BA4\u7684\u6210\u7247\u5408\u6210\u4EFB\u52A1\u3002
820
+ \u6267\u884C\u521B\u4F5C\u8005\u5DF2\u660E\u786E\u786E\u8BA4\u7684\u6210\u7247\u88C5\u914D\u4EFB\u52A1\u3002
821
821
  - \u4EFB\u52A1 ID\uFF1A${job.id}
822
822
  - \u5267\u96C6\uFF1A${production.episodeDirectory}
823
- - \u6309\u4EE5\u4E0B\u987A\u5E8F\u5408\u6210\uFF0C\u4E0D\u5F97\u81EA\u884C\u6362\u5E8F\uFF1A
823
+ - \u521B\u4F5C\u8005\u5728\u6210\u7247\u89C6\u56FE\u6392\u5B9A\u7684\u955C\u5E8F\uFF0C\u4E0D\u5F97\u81EA\u884C\u6362\u5E8F\uFF1A
824
824
  ${orderedPaths.map((path, index) => `${String(index + 1)}. ${path}`).join(`
825
825
  `)}
826
- - \u8F93\u51FA\uFF1A${production.episodeDirectory}/\u5236\u4F5C\u6210\u679C/\u6210\u7247-${job.id}.mp4
826
+ - \u526A\u8F91\u5355\uFF1A${production.episodeDirectory}/\u526A\u8F91\u5355.md
827
+ - \u8F93\u51FA\uFF1A${production.episodeDirectory}/\u5236\u4F5C\u6210\u679C/\u6210\u7247/
827
828
 
828
- \u5148\u9A8C\u8BC1\u8F93\u5165\u5747\u5B58\u5728\u4E14\u53EF\u8BFB\uFF0C\u518D\u4F7F\u7528\u5F53\u524D DSH Preset \u53EF\u89C1\u7684\u5A92\u4F53/\u547D\u4EE4\u5DE5\u5177\u6267\u884C\uFF1B\u97F3\u89C6\u9891\u53C2\u6570\u4E0D\u517C\u5BB9\u65F6\u505A\u660E\u786E\u3001\u53EF\u5BA1\u8BA1\u7684\u6807\u51C6\u5316\u3002\u6240\u6709\u547D\u4EE4\u548C\u5199\u5165\u7EE7\u7EED\u9075\u5B88 DSH \u6743\u9650\u4E0E\u5BA1\u6279\uFF0C\u4E0D\u5F97\u4F2A\u9020\u6210\u529F\u3002`;
829
+ \u5148\u5199\u526A\u8F91\u5355\u518D\u6E32\u67D3\u3002\u9010\u6BB5\u770B\u5B8C\u7D20\u6750\u540E\u5199\u4E0B\u771F\u5B9E\u7684\u5165\u51FA\u70B9\u3001\u53D6\u820D\u7406\u7531\u3001\u58F0\u97F3\u5904\u7406\u4E0E\u5B57\u5E55\uFF0C\u4E0D\u8981\u6309\u955C\u5E8F\u51ED\u7A7A\u586B\u65F6\u95F4\uFF1B\u5B57\u5E55\u9010\u5B57\u53D6\u81EA\u5267\u672C.md\u3002\u526A\u8F91\u5355\u843D\u76D8\u540E\u4F9D\u6B21\u8FD0\u884C edit_tool.py \u7684 check \u4E0E render\uFF0Ccheck \u62A5\u51FA\u7684\u95EE\u9898\u5148\u6539\u6587\u6863\u518D\u91CD\u8DD1\u3002\u7F3A\u5931\u6216\u4E0D\u53EF\u7528\u7684\u7D20\u6750\u5199\u8FDB\u300C\u672A\u91C7\u7528\u955C\u5934\u300D\u5E76\u8BF4\u660E\u5C5E\u4E8E\u54EA\u4E00\u7C7B\uFF0C\u4E0D\u8981\u9000\u56DE\u53BB\u751F\u6210\u65B0\u7D20\u6750\uFF0C\u4E5F\u4E0D\u8981\u6539\u52A8\u5267\u672C\u3001\u5206\u955C\u6216\u89C6\u9891\u63D0\u793A\u8BCD\u7684\u8BED\u4E49\u3002\u5B57\u5E55\u9ED8\u8BA4\u8D70\u96F6\u4F9D\u8D56\u7684 ffmpeg \u8DEF\u7EBF\uFF1B\u6539\u7528 Remotion \u9700\u8981\u5148\u5B89\u88C5 Node \u4F9D\u8D56\u5E76\u9010\u5E27\u8FC7\u65E0\u5934\u6D4F\u89C8\u5668\uFF0C\u53EA\u6709\u521B\u4F5C\u8005\u660E\u786E\u540C\u610F\u8FD9\u6B21\u5B89\u88C5\u65F6\u624D\u8D70\u3002ffmpeg \u4E0E ffprobe \u901A\u8FC7\u5F53\u524D DSH \u6267\u884C\u73AF\u5883\u8C03\u7528\uFF0C\u4E0D\u53EF\u7528\u65F6\u5982\u5B9E\u62A5\u51FA\u6765\uFF0C\u4E0D\u8981\u628A\u300C\u6CA1\u6D4B\u300D\u5199\u6210\u300C\u901A\u8FC7\u300D\u3002\u6240\u6709\u547D\u4EE4\u548C\u5199\u5165\u7EE7\u7EED\u9075\u5B88 DSH \u6743\u9650\u4E0E\u5BA1\u6279\uFF0C\u4E0D\u5F97\u4F2A\u9020\u6210\u529F\u3002`;
829
830
  }
830
831
 
831
832
  // src/client/production-runtime.ts
@@ -838,7 +839,9 @@ function createPendingJob(input) {
838
839
  progress: 0,
839
840
  prompt: input.prompt,
840
841
  expectedOutputs: Math.max(1, Math.floor(input.expectedOutputs ?? 1)),
841
- completedOutputs: 0
842
+ completedOutputs: 0,
843
+ outputPath: input.outputPath,
844
+ supersededOutputIds: input.supersededOutputIds
842
845
  };
843
846
  }
844
847
  function selectedVersionForTarget(targetId, versions, selections, kind) {
@@ -857,6 +860,14 @@ function mediaVersionMatchesJob(version, jobId) {
857
860
  let escaped = jobId.replace(/[.*+?^${}()|[\]\\]/gu, "\\$&"), basename = version.path.split("/").at(-1) ?? "";
858
861
  return new RegExp(`(?:^|[-_.])${escaped}(?:[-_.]|$)`, "u").test(basename);
859
862
  }
863
+ function outputsForJob(job, versions) {
864
+ if (job.outputPath === void 0) return versions.filter((version) => mediaVersionMatchesJob(version, job.id));
865
+ let superseded = new Set(job.supersededOutputIds ?? []);
866
+ return versions.filter((version) => version.path === job.outputPath && !superseded.has(version.id));
867
+ }
868
+ function compositionInFlight(jobs) {
869
+ return jobs.some((job) => job.kind === "composition" && (job.status === "awaiting_confirmation" || job.status === "pending" || job.status === "running"));
870
+ }
860
871
  function referencesForTarget(targetId, production, versions, selections, libraryVersions = versions, manualReferences = {}) {
861
872
  let shot = production.shots.find((item) => item.id === targetId);
862
873
  if (shot === void 0) return [];
@@ -881,7 +892,9 @@ function activeProductionJobId(jobs, queue, sessionRunning) {
881
892
  function reconcileProductionJobs(jobs, queue, sessionRunning, versions) {
882
893
  let latestPending = [...jobs].reverse().find((job) => job.status === "pending" && queuedItemForJob(job.id, queue) === void 0);
883
894
  return jobs.map((job) => {
884
- let queued = queuedItemForJob(job.id, queue) !== void 0, outputs = versions.filter((version) => mediaVersionMatchesJob(version, job.id));
895
+ let queued = queuedItemForJob(job.id, queue) !== void 0;
896
+ if (job.status === "canceled" || job.status === "succeeded" || job.status === "failed" && job.outputPath !== void 0) return job;
897
+ let outputs = outputsForJob(job, versions);
885
898
  return outputs.length >= job.expectedOutputs ? {
886
899
  ...job,
887
900
  status: "succeeded",
@@ -889,7 +902,7 @@ function reconcileProductionJobs(jobs, queue, sessionRunning, versions) {
889
902
  completedOutputs: outputs.length,
890
903
  output: outputs[0],
891
904
  error: void 0
892
- } : job.status === "canceled" || job.status === "succeeded" || job.status === "awaiting_confirmation" && outputs.length === 0 ? job : job.status === "running" && queued ? { ...job, status: "pending", progress: 0 } : job.status === "pending" && sessionRunning && !queued && job === latestPending ? { ...job, status: "running", progress: Math.max(10, job.progress), error: void 0 } : !sessionRunning && !queued && (job.status === "running" || job.status === "dispatched_unknown") ? {
905
+ } : job.status === "awaiting_confirmation" && outputs.length === 0 ? job : job.status === "running" && queued ? { ...job, status: "pending", progress: 0 } : job.status === "pending" && sessionRunning && !queued && job === latestPending ? { ...job, status: "running", progress: Math.max(10, job.progress), error: void 0 } : !sessionRunning && !queued && (job.status === "running" || job.status === "dispatched_unknown") ? {
893
906
  ...job,
894
907
  status: "dispatched_unknown",
895
908
  progress: Math.round(outputs.length / job.expectedOutputs * 100),
@@ -927,7 +940,7 @@ function reorderSequence(sequence, source, target) {
927
940
  }
928
941
 
929
942
  // src/client/drama-production-view.tsx
930
- var import_jsx_runtime3 = require("react/jsx-runtime"), SECTION_LABELS = { shots: "\u955C\u5934", assets: "\u7D20\u6750", tasks: "\u4EFB\u52A1", sequence: "\u6210\u7247", canvas: "\u753B\u5E03" }, SECTION_ORDER = Object.keys(SECTION_LABELS), STATUS_LABELS = { awaiting_confirmation: "\u7B49\u5F85\u786E\u8BA4", pending: "\u5DF2\u63D0\u4EA4", running: "DSH \u6267\u884C\u4E2D", dispatched_unknown: "\u5F85\u6838\u5BF9", succeeded: "\u5DF2\u5B8C\u6210", failed: "\u5931\u8D25", canceled: "\u5DF2\u53D6\u6D88" }, ASSET_KIND_LABEL = { character: "\u4EBA\u7269", scene: "\u573A\u666F", prop: "\u9053\u5177", state: "\u72B6\u6001", unknown: "\u8BBE\u5B9A" }, JOB_KIND_LABEL = { image: "\u56FE\u7247", video: "\u89C6\u9891", composition: "\u6210\u7247" }, MODALITY_LABEL = { image: "\u56FE\u7247", video: "\u89C6\u9891", music: "\u97F3\u4E50" };
943
+ var import_jsx_runtime3 = require("react/jsx-runtime"), SECTION_LABELS = { shots: "\u955C\u5934", assets: "\u7D20\u6750", tasks: "\u4EFB\u52A1", sequence: "\u6210\u7247", canvas: "\u753B\u5E03" }, SECTION_ORDER = Object.keys(SECTION_LABELS), STATUS_LABELS = { awaiting_confirmation: "\u7B49\u5F85\u786E\u8BA4", pending: "\u5DF2\u63D0\u4EA4", running: "DSH \u6267\u884C\u4E2D", dispatched_unknown: "\u5F85\u6838\u5BF9", succeeded: "\u5DF2\u5B8C\u6210", failed: "\u5931\u8D25", canceled: "\u5DF2\u53D6\u6D88" }, ASSET_KIND_LABEL = { character: "\u4EBA\u7269", scene: "\u573A\u666F", prop: "\u9053\u5177", state: "\u72B6\u6001", unknown: "\u8BBE\u5B9A" }, JOB_KIND_LABEL = { image: "\u56FE\u7247", video: "\u89C6\u9891", composition: "\u6210\u7247" }, ASSEMBLED_CUT_PATH = "\u5236\u4F5C\u6210\u679C/\u6210\u7247/\u6210\u7247.mp4", MODALITY_LABEL = { image: "\u56FE\u7247", video: "\u89C6\u9891", music: "\u97F3\u4E50" };
931
944
  function ProductionEnvironment({ sessionId }) {
932
945
  let [preflight, setPreflight] = (0, import_react.useState)(), [attempt, setAttempt] = (0, import_react.useState)(0);
933
946
  (0, import_react.useEffect)(() => {
@@ -1053,7 +1066,15 @@ ${item.prompt}`).join(`
1053
1066
  setNotice(issues[0]);
1054
1067
  return;
1055
1068
  }
1056
- dispatchComposition(createPendingJob({ id: crypto.randomUUID(), targetId: props.production.episodeDirectory, kind: "composition", prompt: "\u6309\u6210\u7247\u987A\u5E8F\u5408\u6210" }));
1069
+ let outputPath = `${props.production.episodeDirectory}/${ASSEMBLED_CUT_PATH}`;
1070
+ dispatchComposition(createPendingJob({
1071
+ id: crypto.randomUUID(),
1072
+ targetId: props.production.episodeDirectory,
1073
+ kind: "composition",
1074
+ prompt: "\u6309\u6210\u7247\u987A\u5E8F\u5408\u6210",
1075
+ outputPath,
1076
+ supersededOutputIds: props.libraryVersions.flatMap((version) => version.path === outputPath ? [version.id] : [])
1077
+ }));
1057
1078
  };
1058
1079
  return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "oh-story-production", children: [
1059
1080
  /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "oh-story-production-bar", children: [
@@ -1275,7 +1296,7 @@ function TaskBoard({ jobs, queue, sessionRunning, onCancel, onRemoveQueued }) {
1275
1296
  ] });
1276
1297
  }
1277
1298
  function SequenceBoard(props) {
1278
- let issues = sequenceIssues(props.sequence, props.versions), versionById = new Map(props.versions.map((version) => [version.id, version])), move = (index, delta) => {
1299
+ let composing = compositionInFlight(props.jobs), issues = sequenceIssues(props.sequence, props.versions), versionById = new Map(props.versions.map((version) => [version.id, version])), move = (index, delta) => {
1279
1300
  let source = props.sequence[index], target = props.sequence[index + delta];
1280
1301
  source !== void 0 && target !== void 0 && props.onSequenceChange(reorderSequence(props.sequence, index, index + delta));
1281
1302
  };
@@ -1285,8 +1306,8 @@ function SequenceBoard(props) {
1285
1306
  props.sequence.length,
1286
1307
  " \u4E2A\u955C\u5934"
1287
1308
  ] }),
1288
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { children: props.sequence.length === 0 ? "\u8FD8\u6CA1\u6709\u955C\u5934" : issues.length === 0 ? "\u5DF2\u53EF\u5408\u6210" : `${String(issues.length)} \u4E2A\u963B\u585E\u9879` }),
1289
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("button", { type: "button", disabled: issues.length > 0 || props.sequence.length < 2, onClick: props.onCompose, children: "\u5408\u6210\u6210\u7247" })
1309
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { children: props.sequence.length === 0 ? "\u8FD8\u6CA1\u6709\u955C\u5934" : composing ? "\u6210\u7247\u4EFB\u52A1\u8FDB\u884C\u4E2D" : issues.length === 0 ? "\u5DF2\u53EF\u5408\u6210" : `${String(issues.length)} \u4E2A\u963B\u585E\u9879` }),
1310
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("button", { type: "button", disabled: composing || issues.length > 0 || props.sequence.length < 2, onClick: props.onCompose, children: "\u5408\u6210\u6210\u7247" })
1290
1311
  ] }),
1291
1312
  issues.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("ul", { className: "oh-story-sequence-issues", children: [
1292
1313
  issues.slice(0, 3).map((issue) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("li", { children: issue }, issue)),
@@ -1810,6 +1831,23 @@ function workbenchPreferenceStorage() {
1810
1831
 
1811
1832
  // inline-css:/home/runner/work/oh-story-dsh/oh-story-dsh/packages/dsh-plugin/src/client/plugin.css
1812
1833
  var plugin_default = `.oh-story-bridge-marker { display: none; }
1834
+ .oh-story-welcome {
1835
+ box-sizing: border-box;
1836
+ order: -1;
1837
+ flex-shrink: 0;
1838
+ width: min(640px, calc(100% - 32px));
1839
+ margin: 24px auto;
1840
+ padding: 20px 24px;
1841
+ border: 1px solid var(--dsw-alias-border-l2);
1842
+ border-radius: 12px;
1843
+ color: var(--dsw-alias-label-primary);
1844
+ background: var(--dsw-alias-bg-base);
1845
+ font: 14px/1.7 var(--dsw-font-family);
1846
+ overflow-wrap: anywhere;
1847
+ }
1848
+ .oh-story-welcome h2 { margin: 0 0 8px; font-size: 20px; }
1849
+ .oh-story-welcome p { margin: 8px 0 0; }
1850
+ .oh-story-welcome ol { margin: 12px 0; padding-left: 24px; }
1813
1851
  .oh-story-split-surface { display: contents; font-family: var(--dsw-font-family); }
1814
1852
 
1815
1853
  /* Collapsed, the plugin owns nothing but this control: DSH renders the
@@ -3415,7 +3453,7 @@ function CreativeWorkbench({
3415
3453
  ...episodeProduction.motions.map((motion) => motion.id)
3416
3454
  ].sort((left, right) => right.length - left.length), motionTargets = new Map(episodeProduction.motions.flatMap((motion) => motion.shotId === void 0 ? [] : [[motion.id, motion.shotId]])), fromWorkspace = productionLibrary.flatMap((version) => {
3417
3455
  if (version.path === void 0 || !version.path.startsWith(`${episodeProduction.episodeDirectory}/`) && !version.path.startsWith(`\u4EA4\u4ED8/${episodeName}/`)) return [];
3418
- let matched = mediaTargetFromPath(version.path, knownTargets), composition = /(?:^|\/)成片-[^/]+\.mp4$/iu.test(version.path);
3456
+ let matched = mediaTargetFromPath(version.path, knownTargets), composition = /(?:^|\/)成片-[^/]+\.mp4$/iu.test(version.path) || /(?:^|\/)制作成果\/成片\//u.test(version.path);
3419
3457
  if (matched === void 0 && !composition) return [];
3420
3458
  let targetId = matched === void 0 ? episodeProduction.episodeDirectory : motionTargets.get(matched) ?? matched;
3421
3459
  return [{ ...version, targetId }];
@@ -4120,7 +4158,7 @@ function CreativeSplitBridge({ sessionId, useSession, useChat, useStore, actions
4120
4158
  };
4121
4159
  }
4122
4160
  let composerSeat = () => scroller.querySelector(":scope > [data-composer-seat]"), parkedAtTail = () => scroller.scrollHeight - scroller.scrollTop - scroller.clientHeight <= 8, parked = parkedAtTail(), drivenAt = 0, markDriven = (event) => {
4123
- event.target instanceof Node && composerSeat()?.contains(event.target) === !0 || (drivenAt = performance.now());
4161
+ event.target instanceof Node && composerSeat()?.contains(event.target) === !0 || event.type === "pointerdown" && event.target !== scroller || (drivenAt = performance.now());
4124
4162
  }, trackParked = () => {
4125
4163
  parkedAtTail() ? parked = !0 : performance.now() - drivenAt < 400 && (parked = !1);
4126
4164
  }, publishLayout = () => {
@@ -4179,8 +4217,47 @@ function CreativeSplitBridge({ sessionId, useSession, useChat, useStore, actions
4179
4217
  ), target)
4180
4218
  ] });
4181
4219
  }
4220
+ function WorkbenchWelcome() {
4221
+ let marker = (0, import_react3.useRef)(null), [target, setTarget] = (0, import_react3.useState)();
4222
+ return (0, import_react3.useLayoutEffect)(() => {
4223
+ let document = marker.current?.ownerDocument;
4224
+ if (document === void 0) return;
4225
+ let locate = () => {
4226
+ let anchor = document.querySelector("[data-conversation-scroll]");
4227
+ setTarget((current) => current === anchor ? current : anchor ?? void 0);
4228
+ };
4229
+ locate();
4230
+ let observer = new MutationObserver(locate);
4231
+ return observer.observe(document.body, { childList: !0, subtree: !0 }), () => {
4232
+ observer.disconnect();
4233
+ };
4234
+ }, []), /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
4235
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("style", { children: plugin_default }),
4236
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { ref: marker, className: "oh-story-bridge-marker", "aria-hidden": !0 }),
4237
+ target === void 0 ? null : (0, import_react_dom.createPortal)(/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("section", { className: "oh-story-welcome", "aria-label": "Oh Story \u4F7F\u7528\u5F15\u5BFC", children: [
4238
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("h2", { children: "Oh Story \u5DF2\u52A0\u8F7D" }),
4239
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { children: "\u4F5C\u54C1\u76EE\u5F55\u4E2D\u6709\u521B\u4F5C\u6587\u4EF6\u65F6\uFF0C\u5C0F\u8BF4\u3001\u77ED\u5267\u3001\u6E38\u620F\u3001\u89C6\u9891\u5DE5\u4F5C\u53F0\u4F1A\u81EA\u52A8\u663E\u793A\u3002" }),
4240
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("ol", { children: [
4241
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("li", { children: "\u70B9\u51FB\u5DE6\u4FA7\u300C\u6DFB\u52A0\u5DE5\u4F5C\u533A / Add workspace\u300D\u7684 \uFF0B\uFF0C\u9009\u62E9\u5B58\u653E\u4F5C\u54C1\u7684\u6587\u4EF6\u5939\u3002" }),
4242
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("li", { children: "\u5728\u4E0B\u65B9\u300C\u9009\u62E9\u5DE5\u4F5C\u533A / Choose workspace\u300D\u4E2D\u9009\u4E2D\u8BE5\u76EE\u5F55\uFF0C\u6216\u6253\u5F00\u5DF2\u6709\u4F1A\u8BDD\u3002" }),
4243
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("li", { children: "\u7A7A\u76EE\u5F55\u5148\u5728 Chat \u4E2D\u5F00\u59CB\u521B\u4F5C\uFF0C\u751F\u6210\u7B2C\u4E00\u4E2A\u521B\u4F5C\u6587\u4EF6\u540E\uFF0C\u5DE5\u4F5C\u53F0\u4F1A\u81EA\u52A8\u51FA\u73B0\u3002" })
4244
+ ] }),
4245
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("p", { children: [
4246
+ "\u67E5\u770B\u5DF2\u6709\u4F5C\u54C1\u65E0\u9700 API Key\u3002\u5F00\u59CB AI \u521B\u4F5C\u524D\uFF0C\u5728\u300C\u8BBE\u7F6E \u2192 \u6A21\u578B\u300D\u914D\u7F6E\u6A21\u578B\uFF0C\u518D\u8F93\u5165 ",
4247
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("code", { children: "/story" }),
4248
+ "\u3001",
4249
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("code", { children: "/short-drama" }),
4250
+ "\u3001",
4251
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("code", { children: "/novel-to-game quick" }),
4252
+ " \u6216 ",
4253
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("code", { children: "/video-recap" }),
4254
+ "\u3002"
4255
+ ] })
4256
+ ] }), target)
4257
+ ] });
4258
+ }
4182
4259
  function WorkbenchSeat({ SessionProvider, renderSlot }) {
4183
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(SessionProvider, { children: renderSlot("oh-story.workspace", {}) });
4260
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(SessionProvider, { empty: () => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(WorkbenchWelcome, {}), children: renderSlot("oh-story.workspace", {}) });
4184
4261
  }
4185
4262
  function argsOf(block) {
4186
4263
  let raw = ("kind" in block ? block.call?.argsRaw : block.argsRaw) ?? "{}";