@oh-story/dsh 0.1.11 → 0.1.13

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 (264) hide show
  1. package/README.md +17 -11
  2. package/lib/client.js +85 -35
  3. package/lib/client.js.map +3 -3
  4. package/lib/drama/manifest.json +41 -36
  5. package/lib/drama/skills/short-drama/scripts/creator_markdown_check.py +340 -13
  6. package/lib/drama/skills/short-drama-assets/references/voice-direction.md +4 -2
  7. package/lib/drama/skills/short-drama-edit/SKILL.md +32 -12
  8. package/lib/drama/skills/short-drama-edit/references/still-cuts.md +90 -0
  9. package/lib/drama/skills/short-drama-edit/scripts/edit_tool.py +1035 -145
  10. package/lib/drama/skills/short-drama-edit/scripts/selftest.py +48 -0
  11. package/lib/drama/skills/short-drama-produce/SKILL.md +6 -1
  12. package/lib/drama/skills/short-drama-produce/references/adapter-contract.md +12 -0
  13. package/lib/drama/skills/short-drama-produce/scripts/production_tool.py +138 -9
  14. package/lib/drama/skills/short-drama-produce/scripts/provider_adapters.py +6 -0
  15. package/lib/drama/skills/short-drama-storyboard/SKILL.md +2 -0
  16. package/lib/drama/skills/short-drama-storyboard/references/production-shot-grammar.md +3 -1
  17. package/lib/drama/skills/short-drama-video-prompts/SKILL.md +7 -0
  18. package/lib/drama/skills/short-drama-video-prompts/references/performance-action-timing.md +14 -0
  19. package/lib/drama/skills/short-drama-video-prompts/references/seedance-2.5.md +19 -6
  20. package/lib/drama/skills/short-drama-video-prompts/references/stage-contract.md +1 -0
  21. package/lib/drama/skills/short-drama-video-prompts/references/target-model-profile.md +5 -0
  22. package/lib/drama/skills/short-drama-video-prompts/references/wan-3.0.md +4 -1
  23. package/lib/index.js +16 -7
  24. package/lib/index.js.map +2 -2
  25. package/lib/novel-to-game/README.md +98 -44
  26. package/lib/novel-to-game/README_ZH.md +100 -46
  27. package/lib/novel-to-game/VERSION +1 -1
  28. package/lib/novel-to-game/examples/jin-ping-mei/build/BUILD_BRIEF.md +27 -202
  29. package/lib/novel-to-game/examples/jin-ping-mei/build/app/RUN.md +23 -115
  30. package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/bg/chamber.webp +0 -0
  31. package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/bg/court_night.webp +0 -0
  32. package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/bg/court_rain.webp +0 -0
  33. package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/bg/garden.webp +0 -0
  34. package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/bg/hall.webp +0 -0
  35. package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/bg/kitchen.webp +0 -0
  36. package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/bg/street.webp +0 -0
  37. package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/bg/street_dawn.webp +0 -0
  38. package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/bg/temple.webp +0 -0
  39. package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/cg/yue/moon.webp +0 -0
  40. package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/sprite/meng/angry.webp +0 -0
  41. package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/sprite/meng/blush.webp +0 -0
  42. package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/sprite/meng/neutral.webp +0 -0
  43. package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/sprite/meng/sad.webp +0 -0
  44. package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/sprite/meng/smile.webp +0 -0
  45. package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/sprite/meng/surprised.webp +0 -0
  46. package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/sprite/pan/angry.webp +0 -0
  47. package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/sprite/pan/blush.webp +0 -0
  48. package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/sprite/pan/neutral.webp +0 -0
  49. package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/sprite/pan/sad.webp +0 -0
  50. package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/sprite/pan/smile.webp +0 -0
  51. package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/sprite/pan/surprised.webp +0 -0
  52. package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/sprite/pinger/angry.webp +0 -0
  53. package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/sprite/pinger/blush.webp +0 -0
  54. package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/sprite/pinger/neutral.webp +0 -0
  55. package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/sprite/pinger/sad.webp +0 -0
  56. package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/sprite/pinger/smile.webp +0 -0
  57. package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/sprite/pinger/surprised.webp +0 -0
  58. package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/sprite/xuee/angry.webp +0 -0
  59. package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/sprite/xuee/blush.webp +0 -0
  60. package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/sprite/xuee/neutral.webp +0 -0
  61. package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/sprite/xuee/sad.webp +0 -0
  62. package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/sprite/xuee/smile.webp +0 -0
  63. package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/sprite/xuee/surprised.webp +0 -0
  64. package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/sprite/yue/angry.webp +0 -0
  65. package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/sprite/yue/blush.webp +0 -0
  66. package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/sprite/yue/neutral.webp +0 -0
  67. package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/sprite/yue/sad.webp +0 -0
  68. package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/sprite/yue/smile.webp +0 -0
  69. package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/sprite/yue/surprised.webp +0 -0
  70. package/lib/novel-to-game/examples/jin-ping-mei/build/app/css/style.css +326 -2503
  71. package/lib/novel-to-game/examples/jin-ping-mei/build/app/index.html +71 -4
  72. package/lib/novel-to-game/examples/jin-ping-mei/build/app/js/adv.js +221 -0
  73. package/lib/novel-to-game/examples/jin-ping-mei/build/app/js/audio.js +113 -257
  74. package/lib/novel-to-game/examples/jin-ping-mei/build/app/js/main.js +511 -3026
  75. package/lib/novel-to-game/examples/jin-ping-mei/build/app/js/menus.js +277 -0
  76. package/lib/novel-to-game/examples/jin-ping-mei/build/app/js/petals.js +67 -0
  77. package/lib/novel-to-game/examples/jin-ping-mei/build/app/js/stage.js +180 -0
  78. package/lib/novel-to-game/examples/jin-ping-mei/build/app/js/store.js +70 -0
  79. package/lib/novel-to-game/examples/jin-ping-mei/build/app/js/story/common.js +198 -0
  80. package/lib/novel-to-game/examples/jin-ping-mei/build/app/js/story/common2.js +204 -0
  81. package/lib/novel-to-game/examples/jin-ping-mei/build/app/js/story/common3.js +198 -0
  82. package/lib/novel-to-game/examples/jin-ping-mei/build/app/js/story/dates.js +186 -0
  83. package/lib/novel-to-game/examples/jin-ping-mei/build/app/js/story/index.js +122 -0
  84. package/lib/novel-to-game/examples/jin-ping-mei/build/app/js/story/meng.js +190 -0
  85. package/lib/novel-to-game/examples/jin-ping-mei/build/app/js/story/pan.js +212 -0
  86. package/lib/novel-to-game/examples/jin-ping-mei/build/app/js/story/pinger.js +198 -0
  87. package/lib/novel-to-game/examples/jin-ping-mei/build/app/js/story/xuee.js +199 -0
  88. package/lib/novel-to-game/examples/jin-ping-mei/build/app/js/story/yue.js +214 -0
  89. package/lib/novel-to-game/examples/jin-ping-mei/build/app/package.json +2 -2
  90. package/lib/novel-to-game/examples/jin-ping-mei/build/art/generated-art.json +182 -45
  91. package/lib/novel-to-game/examples/jin-ping-mei/qa/README.md +7 -17
  92. package/lib/novel-to-game/examples/jin-ping-mei/qa/verification.json +9 -9
  93. package/lib/novel-to-game/manifest.json +303 -78
  94. package/lib/novel-to-game/skills/game-art-direction/references/art-direction-method.md +7 -2
  95. package/lib/novel-to-game/skills/game-concept/references/concept-method.md +2 -0
  96. package/lib/novel-to-game/skills/game-world-design/references/narrative-design-method.md +2 -0
  97. package/lib/novel-to-game/skills/game-world-design/references/world-design-method.md +9 -0
  98. package/lib/types/client/drama-production-view.d.ts +11 -0
  99. package/lib/types/client/drama-production-view.d.ts.map +1 -1
  100. package/lib/types/client/file-activity.d.ts +1 -1
  101. package/lib/types/client/file-activity.d.ts.map +1 -1
  102. package/lib/types/client/production-prompts.d.ts +7 -1
  103. package/lib/types/client/production-prompts.d.ts.map +1 -1
  104. package/lib/types/client/production-runtime.d.ts +7 -2
  105. package/lib/types/client/production-runtime.d.ts.map +1 -1
  106. package/lib/types/drama-adapters.d.ts.map +1 -1
  107. package/lib/types/skill-provider.d.ts.map +1 -1
  108. package/lib/types/video-project.d.ts.map +1 -1
  109. package/lib/video-recap/CHANGELOG.md +108 -1
  110. package/lib/video-recap/README.en.md +18 -14
  111. package/lib/video-recap/README.md +18 -14
  112. package/lib/video-recap/manifest.json +297 -321
  113. package/lib/video-recap/skills/video-assemble/SKILL.md +18 -16
  114. package/lib/video-recap/skills/video-assemble/references/explicit-audio-mix.md +3 -1
  115. package/lib/video-recap/skills/video-assemble/references/jianying/SOURCE.md +5 -5
  116. package/lib/video-recap/skills/video-assemble/references/packaging.md +4 -4
  117. package/lib/video-recap/skills/video-assemble/references/subtitle-track.md +10 -10
  118. package/lib/video-recap/skills/video-assemble/scripts/adoption/audio_mix_binding.py +13 -2
  119. package/lib/video-recap/skills/video-assemble/scripts/adoption/av_clock.py +109 -0
  120. package/lib/video-recap/skills/video-assemble/scripts/adoption/strict_publish.py +4 -1
  121. package/lib/video-recap/skills/video-assemble/scripts/artifacts.py +2 -9
  122. package/lib/video-recap/skills/video-assemble/scripts/assemble.py +188 -51
  123. package/lib/video-recap/skills/video-assemble/scripts/assemble_constants.py +0 -1
  124. package/lib/video-recap/skills/video-assemble/scripts/assembly_contract.py +32 -75
  125. package/lib/video-recap/skills/video-assemble/scripts/assembly_settings.py +8 -15
  126. package/lib/video-recap/skills/video-assemble/scripts/audio_mix.py +202 -161
  127. package/lib/video-recap/skills/video-assemble/scripts/codec_peak.py +112 -0
  128. package/lib/video-recap/skills/video-assemble/scripts/export_jianying.py +10 -101
  129. package/lib/video-recap/skills/video-assemble/scripts/jianying/builders.py +44 -475
  130. package/lib/video-recap/skills/video-assemble/scripts/jianying/model.py +1 -22
  131. package/lib/video-recap/skills/video-assemble/scripts/jianying/templates.py +0 -3
  132. package/lib/video-recap/skills/video-assemble/scripts/jianying/timeline_contract.py +36 -103
  133. package/lib/video-recap/skills/video-assemble/scripts/jianying/tracks.py +0 -8
  134. package/lib/video-recap/skills/video-assemble/scripts/jianying/writer.py +28 -203
  135. package/lib/video-recap/skills/video-assemble/scripts/lib.py +20 -34
  136. package/lib/video-recap/skills/video-assemble/scripts/loudness.py +332 -0
  137. package/lib/video-recap/skills/video-assemble/scripts/media.py +158 -38
  138. package/lib/video-recap/skills/video-assemble/scripts/narration_audio.py +30 -16
  139. package/lib/video-recap/skills/video-assemble/scripts/render_preflight.py +49 -8
  140. package/lib/video-recap/skills/video-assemble/scripts/source_subtitles.py +17 -6
  141. package/lib/video-recap/skills/video-assemble/scripts/subtitles/core.py +24 -2
  142. package/lib/video-recap/skills/video-assemble/scripts/subtitles/track.py +2 -5
  143. package/lib/video-recap/skills/video-assemble/scripts/subtitles/track_binding.py +2 -9
  144. package/lib/video-recap/skills/video-assemble/scripts/timeline.py +12 -34
  145. package/lib/video-recap/skills/video-assemble/scripts/timeline_emit.py +3 -4
  146. package/lib/video-recap/skills/video-assemble/scripts/visual_render.py +28 -2
  147. package/lib/video-recap/skills/video-cut/SKILL.md +37 -11
  148. package/lib/video-recap/skills/video-cut/references/shot-review.md +1 -1
  149. package/lib/video-recap/skills/video-cut/scripts/cut.py +2 -34
  150. package/lib/video-recap/skills/video-cut/scripts/cut_cli.py +96 -124
  151. package/lib/video-recap/skills/video-cut/scripts/cut_contract.py +97 -182
  152. package/lib/video-recap/skills/video-cut/scripts/cut_render.py +177 -166
  153. package/lib/video-recap/skills/video-cut/scripts/frame_grid.py +249 -0
  154. package/lib/video-recap/skills/video-cut/scripts/lib.py +0 -3
  155. package/lib/video-recap/skills/video-cut/scripts/media_geometry.py +173 -7
  156. package/lib/video-recap/skills/video-cut/scripts/sentence_boundaries.py +234 -151
  157. package/lib/video-recap/skills/video-cut/scripts/sentence_gate.py +189 -0
  158. package/lib/video-recap/skills/video-cut/scripts/shot_review.py +2 -6
  159. package/lib/video-recap/skills/video-recap/SKILL.md +24 -27
  160. package/lib/video-recap/skills/video-recap/references/audio-routing.md +8 -6
  161. package/lib/video-recap/skills/video-recap/references/config-playbook.md +8 -11
  162. package/lib/video-recap/skills/video-recap/references/data-schema.md +131 -74
  163. package/lib/video-recap/skills/video-recap/references/resource-library.md +17 -1
  164. package/lib/video-recap/skills/video-recap/scripts/doctor.py +51 -268
  165. package/lib/video-recap/skills/video-recap/scripts/final_qc.py +89 -254
  166. package/lib/video-recap/skills/video-recap/scripts/lib.py +81 -70
  167. package/lib/video-recap/skills/video-recap/scripts/library.py +40 -4
  168. package/lib/video-recap/skills/video-recap/scripts/materials.py +13 -80
  169. package/lib/video-recap/skills/video-recap/scripts/recap_cli.py +49 -17
  170. package/lib/video-recap/skills/video-recap/scripts/recap_inspect.py +1 -3
  171. package/lib/video-recap/skills/video-recap/scripts/recap_runner.py +86 -116
  172. package/lib/video-recap/skills/video-recap/scripts/recap_runtime.py +87 -23
  173. package/lib/video-recap/skills/video-recap/scripts/recap_source.py +0 -39
  174. package/lib/video-recap/skills/video-recap/scripts/recap_stage_qc.py +37 -135
  175. package/lib/video-recap/skills/video-recap/scripts/recap_timeline.py +118 -127
  176. package/lib/video-recap/skills/video-recap/scripts/resources/__init__.py +4 -0
  177. package/lib/video-recap/skills/video-recap/scripts/{resource_lock.py → resources/lock.py} +1 -1
  178. package/lib/video-recap/skills/video-recap/scripts/{project_binding.py → resources/project_binding.py} +78 -17
  179. package/lib/video-recap/skills/video-reference/SKILL.md +108 -0
  180. package/lib/video-recap/skills/video-reference/references/reference-schema.md +139 -0
  181. package/lib/video-recap/skills/video-reference/scripts/lib.py +85 -0
  182. package/lib/video-recap/skills/video-reference/scripts/reference.py +96 -0
  183. package/lib/video-recap/skills/video-reference/scripts/reference_check.py +553 -0
  184. package/lib/video-recap/skills/video-reference/scripts/reference_frames.py +122 -0
  185. package/lib/video-recap/skills/video-reference/scripts/reference_measure.py +253 -0
  186. package/lib/video-recap/skills/video-reference/scripts/reference_profile.py +271 -0
  187. package/lib/video-recap/skills/video-script/SKILL.md +9 -7
  188. package/lib/video-recap/skills/video-script/scripts/agent_text.py +18 -267
  189. package/lib/video-recap/skills/video-script/scripts/deslop_qc.py +12 -30
  190. package/lib/video-recap/skills/video-script/scripts/entry_suggestion.py +125 -0
  191. package/lib/video-recap/skills/video-script/scripts/evidence_bundle.py +2 -26
  192. package/lib/video-recap/skills/video-script/scripts/lib.py +5 -15
  193. package/lib/video-recap/skills/video-script/scripts/lint_summary.py +184 -0
  194. package/lib/video-recap/skills/video-script/scripts/narration_lint.py +120 -100
  195. package/lib/video-recap/skills/video-script/scripts/review.py +3 -34
  196. package/lib/video-recap/skills/video-script/scripts/review_grounding.py +20 -46
  197. package/lib/video-recap/skills/video-script/scripts/review_response.py +120 -258
  198. package/lib/video-recap/skills/video-script/scripts/review_runner.py +2 -10
  199. package/lib/video-recap/skills/video-script/scripts/speech_ownership.py +89 -5
  200. package/lib/video-recap/skills/video-script/scripts/validate.py +26 -34
  201. package/lib/video-recap/skills/video-understanding/SKILL.md +29 -4
  202. package/lib/video-recap/skills/video-understanding/references/data-schema.md +5 -22
  203. package/lib/video-recap/skills/video-understanding/scripts/agent_text.py +24 -121
  204. package/lib/video-recap/skills/video-understanding/scripts/asr.py +11 -5
  205. package/lib/video-recap/skills/video-understanding/scripts/asr_timing_evidence.py +15 -24
  206. package/lib/video-recap/skills/video-understanding/scripts/briefing/builder.py +59 -25
  207. package/lib/video-recap/skills/video-understanding/scripts/briefing/context.py +39 -3
  208. package/lib/video-recap/skills/video-understanding/scripts/briefing/inputs.py +15 -27
  209. package/lib/video-recap/skills/video-understanding/scripts/briefing/timeline.py +136 -37
  210. package/lib/video-recap/skills/video-understanding/scripts/consolidate.py +121 -37
  211. package/lib/video-recap/skills/video-understanding/scripts/detect.py +118 -16
  212. package/lib/video-recap/skills/video-understanding/scripts/index_normalize.py +359 -0
  213. package/lib/video-recap/skills/video-understanding/scripts/lib.py +62 -21
  214. package/lib/video-recap/skills/video-understanding/scripts/storyboard.py +181 -51
  215. package/lib/video-recap/skills/video-understanding/scripts/timeline_fusion.py +0 -26
  216. package/lib/video-recap/skills/video-understanding/scripts/understanding_brief.py +37 -14
  217. package/lib/video-recap/skills/video-understanding/scripts/understanding_cache.py +40 -32
  218. package/lib/video-recap/skills/video-understanding/scripts/understanding_runner.py +100 -127
  219. package/lib/video-recap/skills/video-understanding/scripts/understanding_storyboard.py +182 -30
  220. package/lib/video-recap/skills/video-understanding/scripts/vlm.py +30 -27
  221. package/lib/video-recap/skills/video-voiceover/SKILL.md +19 -12
  222. package/lib/video-recap/skills/video-voiceover/references/index-tts.md +3 -3
  223. package/lib/video-recap/skills/video-voiceover/scripts/approved_text_policy.py +3 -1
  224. package/lib/video-recap/skills/video-voiceover/scripts/dub.py +60 -135
  225. package/lib/video-recap/skills/video-voiceover/scripts/lib.py +9 -34
  226. package/lib/video-recap/skills/video-voiceover/scripts/providers/fish_audio.py +6 -1
  227. package/lib/video-recap/skills/video-voiceover/scripts/tts_audio.py +64 -1
  228. package/lib/video-recap/skills/video-voiceover/scripts/tts_cache.py +99 -0
  229. package/lib/video-recap/skills/video-voiceover/scripts/voiceover.py +177 -200
  230. package/package.json +45 -45
  231. package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/cg/group/inner_court_accord_five.webp +0 -0
  232. package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/cg/group/public_day15.webp +0 -0
  233. package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/household/li_jiaoer.webp +0 -0
  234. package/lib/novel-to-game/examples/jin-ping-mei/build/app/css/new-guofeng.css +0 -1494
  235. package/lib/novel-to-game/examples/jin-ping-mei/build/app/js/assets.js +0 -147
  236. package/lib/novel-to-game/examples/jin-ping-mei/build/app/js/data.js +0 -7470
  237. package/lib/novel-to-game/examples/jin-ping-mei/build/app/js/engine.js +0 -13066
  238. package/lib/novel-to-game/examples/jin-ping-mei/build/app/js/text.js +0 -32
  239. package/lib/novel-to-game/examples/jin-ping-mei/qa/playable-model.json +0 -99
  240. package/lib/novel-to-game/examples/jin-ping-mei/qa/verify_playable_model.mjs +0 -152
  241. package/lib/video-recap/skills/video-assemble/references/foreground-compose.md +0 -118
  242. package/lib/video-recap/skills/video-assemble/references/jianying/empty_jy_combination_segment.json +0 -84
  243. package/lib/video-recap/skills/video-assemble/references/jianying/empty_jy_combination_video_material.json +0 -98
  244. package/lib/video-recap/skills/video-assemble/references/jianying/empty_jy_draft.json +0 -204
  245. package/lib/video-recap/skills/video-assemble/references/pair-media.md +0 -74
  246. package/lib/video-recap/skills/video-assemble/scripts/compose_foreground.py +0 -293
  247. package/lib/video-recap/skills/video-assemble/scripts/pair_media.py +0 -216
  248. package/lib/video-recap/skills/video-recap/references/shift-left-qc-schema.md +0 -23
  249. package/lib/video-recap/skills/video-recap/scripts/mimo_qc.py +0 -33
  250. package/lib/video-recap/skills/video-recap/scripts/qc/__init__.py +0 -1
  251. package/lib/video-recap/skills/video-recap/scripts/qc/mimo_client.py +0 -13
  252. package/lib/video-recap/skills/video-recap/scripts/qc/mimo_contract.py +0 -9
  253. package/lib/video-recap/skills/video-recap/scripts/qc/mimo_evidence.py +0 -287
  254. package/lib/video-recap/skills/video-recap/scripts/qc/mimo_observations.py +0 -175
  255. package/lib/video-recap/skills/video-recap/scripts/qc/mimo_payload.py +0 -206
  256. package/lib/video-recap/skills/video-recap/scripts/qc/mimo_report.py +0 -318
  257. package/lib/video-recap/skills/video-recap/scripts/qc/mimo_runner.py +0 -130
  258. package/lib/video-recap/skills/video-recap/scripts/qc_contract.py +0 -320
  259. package/lib/video-recap/skills/video-script/scripts/timeline_fusion.py +0 -108
  260. package/lib/video-recap/skills/video-understanding/scripts/brief.py +0 -9
  261. package/lib/video-recap/skills/video-understanding/scripts/deslop_qc.py +0 -211
  262. package/lib/video-recap/skills/video-understanding/scripts/narration_lint.py +0 -707
  263. package/lib/video-recap/skills/video-understanding/scripts/speech_ownership.py +0 -143
  264. /package/lib/video-recap/skills/video-cut/scripts/{narration_mapping.py → cut_qc.py} +0 -0
package/lib/client.js.map CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/client/index.tsx", "../src/client/file-activity.ts", "../src/client/file-tree.ts", "../src/client/jsonl-preview.tsx", "../src/client/markdown-preview.tsx", "../src/client/drama-production.ts", "../src/client/drama-production-view.tsx", "../src/client/workbench-ui.ts", "../src/client/production-prompts.ts", "../src/client/production-runtime.ts", "../src/production-intent.ts", "../src/client/production-intents.ts", "../src/client/video-studio.tsx", "../src/client/workbench-presence.ts", "inline-css:/home/runner/work/oh-story-dsh/oh-story-dsh/packages/dsh-plugin/src/client/plugin.css"],
4
- "sourcesContent": ["import type { Context as ClientContext } from \"@deepseek-ai/cordis\";\nimport type { ISessions } from \"@deepseek-ai/dsh-api-session-controller/client\";\nimport { defineStore } from \"@deepseek-ai/dsh-client-store\";\nimport type { IConversation, PartialAssistant, RunningToolCall } from \"@deepseek-ai/dsh-client-ui-conversation/client\";\nimport type {} from \"@deepseek-ai/dsh-client-ui-chat/client\";\nimport type {} from \"@deepseek-ai/dsh-client-ui-layout/client\";\nimport type {} from \"@deepseek-ai/dsh-client-ui-renderer/client\";\nimport type {} from \"@deepseek-ai/dsh-client-ui-session/client\";\nimport type { PropsRenderSlots, PropsRuntime, PropsStore } from \"@deepseek-ai/dsh-client-ui-slots\";\nimport type { ToolCallViewProps } from \"@deepseek-ai/dsh-client-ui-tool/client\";\nimport { useCallback, useEffect, useId, useLayoutEffect, useMemo, useRef, useState, type CSSProperties } from \"react\";\nimport { createPortal } from \"react-dom\";\nimport {\n creativeRelativePath,\n fileMutations,\n latestSettledMutation,\n latestSettledMutationTurn,\n mutatingCallIds,\n openTurn,\n preferredWorkbenchFile,\n previewMutation,\n sameUndispatchedCalls,\n streamingAssistant,\n undispatchedCalls,\n workbenchLabel,\n workbenchModeForPath,\n type UndispatchedCall,\n type WorkbenchMode\n} from \"./file-activity.js\";\nimport { buildFileTree, type FileTreeNode } from \"./file-tree.js\";\nimport { JsonlPreview } from \"./jsonl-preview.js\";\nimport { MarkdownPreview } from \"./markdown-preview.js\";\nimport {\n creatorDocumentPaths,\n episodeDirectoryForPath,\n isCreatorDocumentPath,\n parseEpisodeProduction,\n type DramaDocumentTarget,\n type DramaProductionSection\n} from \"./drama-production.js\";\nimport { DramaProductionView } from \"./drama-production-view.js\";\nimport { createPendingJob, type\n CanvasPoint,\n mediaTargetFromPath,\n productionQueueFromInbox,\n type ProductionJob,\n type ProductionMediaVersion,\n type ProductionQueueEntry,\n type ProductionSequenceItem\n} from \"./production-runtime.js\";\nimport { settledProductionIntents, type SettledProductionIntent } from \"./production-intents.js\";\nimport { OH_STORY_PRODUCTION_TOOL_NAME } from \"../production-intent.js\";\nimport { VideoStudio, type VideoProject } from \"./video-studio.js\";\nimport {\n hasCreativeProject,\n readWorkbenchPreference,\n resolveWorkbenchOpen,\n workbenchPreferenceStorage,\n writeWorkbenchPreference,\n type WorkbenchPreference\n} from \"./workbench-presence.js\";\nimport { endpoint, handleTabKey } from \"./workbench-ui.js\";\nimport styles from \"./plugin.css?inline\";\n\nexport const name = \"oh-story\";\nexport const inject = [\"slots\", \"sessions\", \"conversation\"];\n\ndeclare module \"@deepseek-ai/dsh-client-ui-slots\" {\n interface SlotMap {\n \"oh-story.workspace\": { kind: \"single\"; scope: \"session\" };\n }\n}\n\ninterface WorkspaceFile {\n readonly path: string;\n readonly bytes: number;\n readonly version: string;\n readonly kind: \"text\" | \"media\";\n readonly mimeType?: string | undefined;\n}\ninterface WorkspacePayload {\n readonly cwd: string;\n readonly files: readonly WorkspaceFile[];\n readonly games: readonly GameProject[];\n readonly videos: readonly VideoProject[];\n readonly shortDrama: Record<string, unknown> | null;\n readonly metadataErrors: readonly string[];\n readonly mode: \"dsh-session\";\n}\ninterface GameProject {\n readonly id: string;\n readonly root: string;\n readonly title: string;\n readonly source: \"workspace\" | \"example\";\n readonly previewReady: boolean;\n readonly previewUrl?: string | undefined;\n readonly previewVersion: string;\n}\ninterface FilePayload {\n readonly path: string;\n readonly content: string;\n readonly bytes: number;\n readonly version: string;\n}\ninterface FileBuffer {\n readonly content: string;\n readonly saved: string;\n readonly source: \"disk\" | \"human\" | \"agent\";\n readonly version: string;\n readonly saving?: boolean | undefined;\n readonly error?: string | undefined;\n readonly missing?: boolean | undefined;\n readonly conflict?: {\n readonly message: string;\n readonly theirs?: string | undefined;\n readonly theirsVersion?: string | undefined;\n } | undefined;\n}\n\ninterface WorkbenchMemory {\n buffers: Record<string, FileBuffer>;\n workbenchPreference: WorkbenchPreference | undefined;\n editorMode: \"preview\" | \"source\" | \"production\";\n expanded: Record<string, boolean>;\n selected: string | undefined;\n workbench: WorkbenchMode;\n gameTab: \"preview\" | \"design\";\n gameProjectId: string | undefined;\n gamePane: \"studio\" | \"chat\";\n videoTab: \"preview\" | \"artifacts\";\n videoProjectId: string | undefined;\n videoPane: \"studio\" | \"chat\";\n productionSection: DramaProductionSection;\n productionSelectedIds: Record<string, string | undefined>;\n productionJobs: Record<string, ProductionJob[]>;\n productionSelections: Record<string, Record<string, string>>;\n productionReferences: Record<string, Record<string, string[]>>;\n productionSequence: Record<string, ProductionSequenceItem[]>;\n productionCanvas: Record<string, Record<string, CanvasPoint>>;\n productionZoom: Record<string, number>;\n productionIntentCalls: Record<string, boolean>;\n /** Latest settled Agent write the workbench has already followed or taken as history. */\n settledMutation: string | undefined;\n /** False only in a Store instance the plugin has not restored this Session's memory into yet. */\n hydrated: boolean;\n}\n\ntype Update<T> = T | ((current: T) => T);\n\nfunction applyUpdate<T>(current: T, update: Update<T>): T {\n return typeof update === \"function\" ? (update as (value: T) => T)(current) : update;\n}\n\n/**\n * DSH 0.1.7 binds session-scoped Store instances to the Session binding's generation and drops\n * them when that generation is released or rebound, which a Session switch is enough to do, and\n * a mounted slot can be handed a fresh instance. The workbench keeps unsaved drafts, production\n * jobs and layout in its Store, and those lived for the page before, so the plugin holds its own\n * page-lifetime copy and restores it into every fresh instance.\n */\nconst workbenchMemoryBySession = new Map<string, WorkbenchMemory>();\n\nconst NO_UNDISPATCHED_CALLS: readonly UndispatchedCall[] = [];\n\nfunction createWorkbenchStore() {\n return defineStore({\n init: (): WorkbenchMemory => ({\n buffers: {},\n workbenchPreference: undefined,\n editorMode: \"preview\",\n expanded: {},\n selected: undefined,\n workbench: \"story\",\n gameTab: \"preview\",\n gameProjectId: undefined,\n gamePane: \"studio\",\n videoTab: \"preview\",\n videoProjectId: undefined,\n videoPane: \"studio\",\n productionSection: \"shots\",\n productionSelectedIds: {},\n productionJobs: {},\n productionSelections: {},\n productionReferences: {},\n productionSequence: {},\n productionCanvas: {},\n productionZoom: {},\n productionIntentCalls: {},\n settledMutation: undefined,\n hydrated: false\n }),\n actions: {\n restore: (draft, memory: WorkbenchMemory | undefined) => {\n if (memory !== undefined) {\n Object.assign(draft, memory);\n // A save in flight belonged to the dropped instance; its completion never lands here.\n draft.buffers = Object.fromEntries(Object.entries(memory.buffers).map(([path, buffer]) => [path, { ...buffer, saving: undefined }]));\n }\n draft.hydrated = true;\n },\n setSettledMutation: (draft, value: string | undefined) => {\n draft.settledMutation = value;\n },\n setBuffers: (draft, update: Update<Record<string, FileBuffer>>) => {\n draft.buffers = applyUpdate(draft.buffers, update);\n },\n setWorkbenchPreference: (draft, update: Update<WorkbenchPreference | undefined>) => {\n draft.workbenchPreference = applyUpdate(draft.workbenchPreference, update);\n },\n setEditorMode: (draft, update: Update<WorkbenchMemory[\"editorMode\"]>) => {\n draft.editorMode = applyUpdate(draft.editorMode, update);\n },\n setExpanded: (draft, update: Update<Record<string, boolean>>) => {\n draft.expanded = applyUpdate(draft.expanded, update);\n },\n setSelected: (draft, update: Update<string | undefined>) => {\n draft.selected = applyUpdate(draft.selected, update);\n },\n setWorkbench: (draft, update: Update<WorkbenchMode>) => {\n draft.workbench = applyUpdate(draft.workbench, update);\n },\n setGameTab: (draft, update: Update<WorkbenchMemory[\"gameTab\"]>) => {\n draft.gameTab = applyUpdate(draft.gameTab, update);\n },\n setGameProjectId: (draft, update: Update<string | undefined>) => {\n draft.gameProjectId = applyUpdate(draft.gameProjectId, update);\n },\n setGamePane: (draft, update: Update<WorkbenchMemory[\"gamePane\"]>) => {\n draft.gamePane = applyUpdate(draft.gamePane, update);\n },\n setVideoTab: (draft, update: Update<WorkbenchMemory[\"videoTab\"]>) => {\n draft.videoTab = applyUpdate(draft.videoTab, update);\n },\n setVideoProjectId: (draft, update: Update<string | undefined>) => {\n draft.videoProjectId = applyUpdate(draft.videoProjectId, update);\n },\n setVideoPane: (draft, update: Update<WorkbenchMemory[\"videoPane\"]>) => {\n draft.videoPane = applyUpdate(draft.videoPane, update);\n },\n setProductionSection: (draft, update: Update<DramaProductionSection>) => {\n draft.productionSection = applyUpdate(draft.productionSection, update);\n },\n setProductionSelectedIds: (draft, update: Update<Record<string, string | undefined>>) => {\n draft.productionSelectedIds = applyUpdate(draft.productionSelectedIds, update);\n },\n setProductionJobs: (draft, update: Update<Record<string, ProductionJob[]>>) => {\n draft.productionJobs = applyUpdate(draft.productionJobs, update);\n },\n setProductionSelections: (draft, update: Update<Record<string, Record<string, string>>>) => {\n draft.productionSelections = applyUpdate(draft.productionSelections, update);\n },\n setProductionReferences: (draft, update: Update<Record<string, Record<string, string[]>>>) => {\n draft.productionReferences = applyUpdate(draft.productionReferences, update);\n },\n setProductionSequence: (draft, update: Update<Record<string, ProductionSequenceItem[]>>) => {\n draft.productionSequence = applyUpdate(draft.productionSequence, update);\n },\n setProductionCanvas: (draft, update: Update<Record<string, Record<string, CanvasPoint>>>) => {\n draft.productionCanvas = applyUpdate(draft.productionCanvas, update);\n },\n setProductionZoom: (draft, update: Update<Record<string, number>>) => {\n draft.productionZoom = applyUpdate(draft.productionZoom, update);\n },\n setProductionIntentCalls: (draft, update: Update<Record<string, boolean>>) => {\n draft.productionIntentCalls = applyUpdate(draft.productionIntentCalls, update);\n }\n }\n });\n}\n\nclass WorkspaceRequestError extends Error {\n constructor(readonly status: number, message: string) { super(message); }\n}\n\nconst GROUP_ORDER: Readonly<Record<WorkbenchMode, readonly string[]>> = {\n story: [\"\u6B63\u6587\", \"\u5927\u7EB2\", \"\u8BBE\u5B9A\", \"\u8FFD\u8E2A\", \"\u5BF9\u6807\", \"\u53C2\u8003\u8D44\u6599\"],\n drama: [\"\u9879\u76EE\", \"\u8F93\u5165\", \"\u9879\u76EE\u5F00\u53D1\", \"\u8BBE\u5B9A\u96C6\", \"\u5267\u96C6\", \"\u5BA1\u67E5\", \"\u521B\u4F5C\u8005\u51B3\u7B56\", \"\u4EA4\u4ED8\"],\n game: [\"game-adaptations\"],\n video: [\"video-recaps\"]\n};\n\nconst WORKBENCH_MODES = [\"story\", \"drama\", \"game\", \"video\"] as const;\nconst EDITOR_MODES = [\"preview\", \"source\", \"production\"] as const;\n\nfunction groupForPath(path: string): string {\n return path === \"short-drama.json\" ? \"\u9879\u76EE\" : path.split(\"/\", 1)[0] ?? \"\u5176\u4ED6\";\n}\n\nasync function json<T>(response: Response): Promise<T> {\n const value = await response.json() as T & { readonly error?: string };\n if (!response.ok) throw new WorkspaceRequestError(response.status, value.error ?? `HTTP ${String(response.status)}`);\n return value;\n}\n\nfunction FileTreeNodes({\n nodes,\n depth,\n expanded,\n selected,\n activityPath,\n onToggle,\n onSelect\n}: {\n readonly nodes: readonly FileTreeNode[];\n readonly depth: number;\n readonly expanded: Readonly<Record<string, boolean>>;\n readonly selected: string | undefined;\n readonly activityPath: string | undefined;\n readonly onToggle: (path: string, open: boolean) => void;\n readonly onSelect: (path: string) => void;\n}) {\n return <>{nodes.map((node) => {\n if (node.kind === \"file\") return <button\n type=\"button\"\n key={node.path}\n style={{ \"--oh-story-indent\": `${String(depth * 14)}px` } as CSSProperties}\n title={node.path}\n aria-label={node.path}\n data-file-path={node.path}\n data-agent-target={node.path === activityPath || undefined}\n aria-current={node.path === selected ? \"page\" : undefined}\n onClick={() => { onSelect(node.path); }}\n >{node.name}</button>;\n const open = selected?.startsWith(`${node.path}/`) === true || expanded[node.path] === true;\n return <details className=\"oh-story-file-folder\" key={node.path} open={open} onToggle={(event) => { onToggle(node.path, event.currentTarget.open); }}>\n <summary style={{ \"--oh-story-indent\": `${String(depth * 14)}px` } as CSSProperties} title={node.path}>{node.name}<span>{node.fileCount}</span></summary>\n <FileTreeNodes\n nodes={node.children}\n depth={depth + 1}\n expanded={expanded}\n selected={selected}\n activityPath={activityPath}\n onToggle={onToggle}\n onSelect={onSelect}\n />\n </details>;\n })}</>;\n}\n\nfunction useWorkspace(sessionId: string): {\n readonly workspace: WorkspacePayload | undefined;\n readonly error: string | undefined;\n readonly loading: boolean;\n readonly reload: () => void;\n} {\n const [version, setVersion] = useState(0);\n const [workspace, setWorkspace] = useState<WorkspacePayload>();\n const [error, setError] = useState<string>();\n const [loading, setLoading] = useState(true);\n const reload = useCallback(() => {\n setLoading(true);\n setVersion((value) => value + 1);\n }, []);\n useEffect(() => {\n const controller = new AbortController();\n setError(undefined);\n void fetch(endpoint(\"workspace\", sessionId), { signal: controller.signal })\n .then((response) => json<WorkspacePayload>(response))\n .then(setWorkspace)\n .catch((reason: unknown) => {\n if (!controller.signal.aborted) setError(reason instanceof Error ? reason.message : String(reason));\n })\n .finally(() => { if (!controller.signal.aborted) setLoading(false); });\n return () => { controller.abort(); };\n }, [sessionId, version]);\n return { workspace, error, loading, reload };\n}\n\nfunction isolatedPreviewUrl(path: string, version: string, revision: number): { readonly href: string; readonly isolated: boolean } {\n const url = new URL(path, globalThis.location.origin);\n if (url.hostname === \"127.0.0.1\") url.hostname = \"localhost\";\n else if (url.hostname === \"localhost\") url.hostname = \"127.0.0.1\";\n url.searchParams.set(\"build\", version);\n url.searchParams.set(\"reload\", String(revision));\n return { href: url.toString(), isolated: url.origin !== globalThis.location.origin };\n}\n\n/**\n * An iframe fires `load`, not `error`, when a navigation commits an HTTP error response, so the\n * frame's own events cannot tell a working preview from the route's JSON error body. Probe the\n * same URL out of band and report a non-OK or non-HTML answer as a real failure.\n */\nfunction PreviewProbe({ href, onFailed }: { readonly href: string; readonly onFailed: () => void }) {\n // Hold the callback in a ref so an inline arrow from the caller cannot re-trigger the probe.\n const failedRef = useRef(onFailed);\n useEffect(() => { failedRef.current = onFailed; }, [onFailed]);\n useEffect(() => {\n const controller = new AbortController();\n void fetch(href, { signal: controller.signal })\n .then((response) => {\n if (controller.signal.aborted) return;\n const type = response.headers.get(\"content-type\") ?? \"\";\n if (!response.ok || !type.includes(\"text/html\")) failedRef.current();\n })\n .catch(() => { if (!controller.signal.aborted) failedRef.current(); });\n return () => { controller.abort(); };\n }, [href]);\n return null;\n}\n\nfunction GamePreview({ project, building }: { readonly project: GameProject; readonly building: boolean }) {\n const shellRef = useRef<HTMLDivElement>(null);\n const fullscreenButtonRef = useRef<HTMLButtonElement>(null);\n const restoreFullscreenFocus = useRef(false);\n const [focused, setFocused] = useState(false);\n const [loaded, setLoaded] = useState(false);\n const [loadError, setLoadError] = useState(false);\n const [revision, setRevision] = useState(0);\n const [loadedVersion, setLoadedVersion] = useState(project.previewVersion);\n useEffect(() => {\n const document = shellRef.current?.ownerDocument;\n if (document === undefined) return;\n const restore = (): void => {\n if (document.fullscreenElement !== null || !restoreFullscreenFocus.current) return;\n restoreFullscreenFocus.current = false;\n fullscreenButtonRef.current?.focus();\n };\n document.addEventListener(\"fullscreenchange\", restore);\n return () => { document.removeEventListener(\"fullscreenchange\", restore); };\n }, []);\n if (!project.previewReady || project.previewUrl === undefined) return <div className=\"oh-game-preview-empty\">\n <span aria-hidden>\u25EB</span>\n <strong>\u8FD8\u6CA1\u6709\u53EF\u8BD5\u73A9\u7248\u672C</strong>\n <p>\u5728\u53F3\u4FA7 Chat \u4F7F\u7528 <code>/novel-to-game quick</code>\uFF0C\u4EA7\u7269\u5199\u5165 <code>game-adaptations/&lt;project&gt;/build/app/</code> \u540E\u4F1A\u81EA\u52A8\u51FA\u73B0\u5728\u8FD9\u91CC\u3002</p>\n <div className=\"oh-game-prompt-example\"><span>\u63CF\u8FF0\u793A\u4F8B</span><q>\u628A\u300A\u4F5C\u54C1\u540D\u300B\u6539\u7F16\u6210\u7F51\u9875\u4E92\u52A8\u6E38\u620F\uFF0C\u76EE\u6807\u73A9\u5BB6\u662F\u2026\u2026\uFF0C\u6838\u5FC3\u73A9\u6CD5\u662F\u2026\u2026\uFF0C\u5E0C\u671B\u6574\u4F53\u98CE\u683C\u2026\u2026</q></div>\n </div>;\n const preview = isolatedPreviewUrl(project.previewUrl, loadedVersion, revision);\n const pending = project.previewVersion !== loadedVersion;\n /** Accept the newer build the creator just chose. */\n const reload = (): void => {\n setLoaded(false);\n setLoadError(false);\n setLoadedVersion(project.previewVersion);\n setRevision((value) => value + 1);\n };\n /** Re-run the build the creator already accepted; never silently adopt a newer one. */\n const refresh = (): void => {\n setLoaded(false);\n setLoadError(false);\n setRevision((value) => value + 1);\n };\n const runtimeState = loadError ? \"\u9884\u89C8\u8F7D\u5165\u5931\u8D25 \u00B7 \u53EF\u91CD\u65B0\u8F7D\u5165\"\n : building ? \"Agent \u6B63\u5728\u66F4\u65B0\u6E38\u620F\u6587\u4EF6 \u00B7 \u5F53\u524D\u9884\u89C8\u4FDD\u6301\u4E0D\u53D8\"\n : pending ? \"\u65B0\u7248\u672C\u5DF2\u5C31\u7EEA \u00B7 \u7531\u4F60\u51B3\u5B9A\u4F55\u65F6\u8F7D\u5165\"\n : loaded ? (preview.isolated ? \"\u9884\u89C8\u5DF2\u8F7D\u5165\" : \"\u9884\u89C8\u5DF2\u8F7D\u5165 \u00B7 \u5F53\u524D\u90E8\u7F72\u65E0\u6CD5\u9694\u79BB\u6765\u6E90\uFF0C\u5B58\u6863\u529F\u80FD\u4E0D\u53EF\u7528\")\n : \"\u6B63\u5728\u8F7D\u5165\u9884\u89C8\u2026\";\n const fullscreen = (): void => {\n const shell = shellRef.current;\n if (shell === null) return;\n restoreFullscreenFocus.current = true;\n void shell.requestFullscreen().catch(() => { restoreFullscreenFocus.current = false; });\n };\n return <div ref={shellRef} className=\"oh-game-preview-shell\" data-state={loadError ? \"error\" : building ? \"building\" : loaded ? \"ready\" : \"loading\"}>\n <div className=\"oh-game-preview-status\">\n <span className=\"oh-game-runtime-state\" role=\"status\" aria-live=\"polite\" title={runtimeState}><i aria-hidden /><em>{runtimeState}</em></span>\n <div>\n {pending && !building && <button type=\"button\" onClick={reload}>\u8F7D\u5165\u65B0\u7248\u672C</button>}\n <button className=\"oh-game-reload\" type=\"button\" onClick={refresh} aria-label=\"\u91CD\u65B0\u8F7D\u5165\u6E38\u620F\"><span aria-hidden>\u21BB</span><b>\u5237\u65B0</b></button>\n <button ref={fullscreenButtonRef} type=\"button\" onClick={fullscreen}>\u5168\u5C4F\u8BD5\u73A9</button>\n </div>\n </div>\n <PreviewProbe href={preview.href} onFailed={() => { setLoaded(false); setLoadError(true); }} />\n <iframe\n key={`${project.id}:${loadedVersion}:${String(revision)}`}\n src={preview.href}\n title={`\u300A${project.title}\u300B\u53EF\u8BD5\u73A9\u9884\u89C8`}\n sandbox={preview.isolated\n ? \"allow-scripts allow-same-origin allow-forms allow-modals allow-downloads\"\n : \"allow-scripts allow-forms allow-modals allow-downloads\"}\n allow=\"autoplay; fullscreen; gamepad\"\n allowFullScreen\n referrerPolicy=\"no-referrer\"\n onLoad={() => { setLoadError(false); setLoaded(true); }}\n onError={() => { setLoaded(false); setLoadError(true); }}\n onFocus={() => { setFocused(true); }}\n onBlur={() => { setFocused(false); }}\n />\n <div className=\"oh-game-focus-hint\" data-focused={focused || undefined}>{focused ? \"\u6E38\u620F\u6B63\u5728\u63A5\u6536\u952E\u9F20\u8F93\u5165\" : \"\u70B9\u51FB\u753B\u9762\u8FDB\u5165\u8BD5\u73A9\"}</div>\n </div>;\n}\n\nfunction GameDesign({\n project,\n files,\n selected,\n sessionId,\n onSelect\n}: {\n readonly project: GameProject;\n readonly files: readonly WorkspaceFile[];\n readonly selected: string | undefined;\n readonly sessionId: string;\n readonly onSelect: (path: string) => void;\n}) {\n const documents = useMemo(() => files.filter((file) => file.path.startsWith(`${project.root}/`) && (\n /\\.(?:md|txt|json|jsonl|html|css|[cm]?js|tsx?|jsx)$/iu.test(file.path)\n )), [files, project.root]);\n const preferred = selected !== undefined && documents.some((file) => file.path === selected)\n ? selected\n : documents.find((file) => file.path === `${project.root}/PRODUCT_BRIEF.md`)?.path ?? documents[0]?.path;\n const [path, setPath] = useState(preferred);\n const [content, setContent] = useState<string>();\n const [error, setError] = useState<string>();\n useEffect(() => { setPath(preferred); }, [preferred, project.id]);\n useEffect(() => {\n if (path === undefined || project.source === \"example\") { setContent(undefined); return; }\n const controller = new AbortController();\n setContent(undefined);\n setError(undefined);\n void fetch(endpoint(\"file\", sessionId, path), { signal: controller.signal })\n .then((response) => json<FilePayload>(response))\n .then((file) => { setContent(file.content); })\n .catch((reason: unknown) => { if (!controller.signal.aborted) setError(reason instanceof Error ? reason.message : String(reason)); });\n return () => { controller.abort(); };\n }, [path, project.source, sessionId]);\n if (project.source === \"example\") return <div className=\"oh-game-design-empty\">\n <strong>\u5185\u7F6E\u5B8C\u6574\u793A\u4F8B</strong>\n <p>\u300A\u91D1\u74F6\u6885 \u00B7 \u98CE\u6708\u603B\u8D26\u300B\u7684\u5B8C\u6574\u53EF\u73A9\u6784\u5EFA\u4E0E QA \u6821\u9A8C\u7ED3\u679C\u968F\u63D2\u4EF6\u6253\u5305\uFF0C\u53EF\u76F4\u63A5\u5728\u5DE6\u4FA7\u8BD5\u73A9\u3002\u4E0A\u6E38\u7684\u4EA7\u54C1\u7B80\u62A5\u3001\u5206\u6790\u3001\u6982\u5FF5\u3001\u8BBE\u8BA1\u4E0E\u6E90\u5C0F\u8BF4\u4E0D\u968F\u5305\u5206\u53D1\uFF0C\u53EF\u5728 novel-to-game \u4ED3\u5E93\u67E5\u770B\u5B8C\u6574\u521B\u4F5C\u8FC7\u7A0B\u3002</p>\n <code>novel-to-game/examples/jin-ping-mei</code>\n </div>;\n if (documents.length === 0 || path === undefined) return <div className=\"oh-game-design-empty\">\u5F53\u524D\u9879\u76EE\u8FD8\u6CA1\u6709\u53EF\u68C0\u67E5\u7684\u8BBE\u8BA1\u6216\u6E90\u6587\u4EF6\u3002</div>;\n const markdown = path.toLocaleLowerCase().endsWith(\".md\");\n return <div className=\"oh-game-design\">\n <label>\u9879\u76EE\u6587\u4EF6<select value={path} onChange={(event) => {\n setPath(event.target.value);\n onSelect(event.target.value);\n }}>{documents.map((file) => <option value={file.path} key={file.path}>{file.path.slice(project.root.length + 1)}</option>)}</select></label>\n {error !== undefined ? <div className=\"oh-story-error\">{error}</div>\n : content === undefined ? <div className=\"oh-game-design-empty\">\u6B63\u5728\u8F7D\u5165\u6587\u4EF6\u2026</div>\n : markdown ? <MarkdownPreview content={content} label={path} />\n : <pre className=\"oh-game-source\" aria-label={`${path} \u6E90\u7801`}>{content}</pre>}\n </div>;\n}\n\nfunction GameStudio({\n sessionId,\n workspace,\n building,\n selected,\n gameTab,\n gameProjectId,\n hidden,\n onGameTab,\n onGameProject,\n workbenches,\n paneId,\n labelledBy,\n onWorkbench,\n onCollapse,\n onSelect\n}: {\n readonly sessionId: string;\n readonly workspace: WorkspacePayload;\n readonly building: boolean;\n readonly selected: string | undefined;\n readonly gameTab: WorkbenchMemory[\"gameTab\"];\n readonly gameProjectId: string | undefined;\n readonly hidden: boolean;\n readonly onGameTab: (tab: WorkbenchMemory[\"gameTab\"]) => void;\n readonly onGameProject: (id: string) => void;\n readonly workbenches: readonly WorkbenchMode[];\n readonly paneId: string;\n readonly labelledBy: string;\n readonly onWorkbench: (mode: WorkbenchMode) => void;\n readonly onCollapse: () => void;\n readonly onSelect: (path: string) => void;\n}) {\n const project = workspace.games.find((value) => value.id === gameProjectId) ?? workspace.games[0];\n const studioRef = useRef<HTMLElement>(null);\n const tabsId = useId();\n useLayoutEffect(() => {\n const studio = studioRef.current;\n if (studio === null) return;\n const publishWidth = () => {\n studio.toggleAttribute(\"data-oh-game-narrow\", studio.clientWidth <= 300);\n };\n publishWidth();\n const observer = new ResizeObserver(publishWidth);\n observer.observe(studio);\n return () => { observer.disconnect(); };\n }, []);\n useEffect(() => {\n if (project !== undefined && project.id !== gameProjectId) onGameProject(project.id);\n }, [gameProjectId, onGameProject, project]);\n if (project === undefined) return <main ref={studioRef} id={paneId} className=\"oh-game-studio\" role=\"tabpanel\" aria-labelledby={labelledBy} hidden={hidden}><div className=\"oh-game-design-empty\">\u6E38\u620F\u80FD\u529B\u6B63\u5728\u8F7D\u5165\u2026</div></main>;\n const tabs = [\"preview\", \"design\"] as const;\n return <main ref={studioRef} id={paneId} className=\"oh-game-studio\" data-source={project.source} role=\"tabpanel\" aria-labelledby={labelledBy} hidden={hidden}>\n <header className=\"oh-game-toolbar\">\n <div className=\"oh-workbench-cluster\">\n {workbenches.length > 1 && <div className=\"oh-game-mode-tabs\" role=\"tablist\" aria-label=\"\u521B\u4F5C\u5DE5\u4F5C\u53F0\">\n {workbenches.map((mode) => <button\n type=\"button\"\n role=\"tab\"\n key={mode}\n aria-selected={mode === \"game\"}\n tabIndex={mode === \"game\" ? 0 : -1}\n onKeyDown={(event) => { handleTabKey(event, workbenches, \"game\", onWorkbench); }}\n onClick={() => { onWorkbench(mode); }}\n >{workbenchLabel(mode)}</button>)}\n </div>}\n <button className=\"oh-workbench-collapse\" type=\"button\" title=\"\u6536\u8D77\u521B\u4F5C\u5DE5\u4F5C\u53F0\" aria-label=\"\u6536\u8D77\u521B\u4F5C\u5DE5\u4F5C\u53F0\" onClick={onCollapse}>\u00D7</button>\n </div>\n <label className=\"oh-game-project\" title=\"\u5207\u6362\u9879\u76EE\u5C06\u91CD\u65B0\u8F7D\u5165\u8BD5\u73A9\"><span>\u6E38\u620F\u9879\u76EE</span><select aria-label=\"\u6E38\u620F\u9879\u76EE\uFF1B\u5207\u6362\u5C06\u91CD\u65B0\u8F7D\u5165\u8BD5\u73A9\" value={project.id} onChange={(event) => { onGameProject(event.target.value); }}>\n {workspace.games.some((item) => item.source === \"workspace\") && <optgroup label=\"\u6211\u7684\u9879\u76EE\">{workspace.games.filter((item) => item.source === \"workspace\").map((item) => <option value={item.id} key={item.id}>{`\u6211\u7684\u9879\u76EE \u00B7 ${item.title}`}</option>)}</optgroup>}\n {workspace.games.some((item) => item.source === \"example\") && <optgroup label=\"\u5185\u7F6E\u793A\u4F8B\">{workspace.games.filter((item) => item.source === \"example\").map((item) => <option value={item.id} key={item.id}>{`\u5185\u7F6E\u793A\u4F8B \u00B7 ${item.title}`}</option>)}</optgroup>}\n </select></label>\n <div className=\"oh-game-tabs\" role=\"tablist\" aria-label=\"\u6E38\u620F\u5DE5\u4F5C\u53F0\">\n {tabs.map((tab) => <button\n key={tab}\n type=\"button\"\n role=\"tab\"\n tabIndex={gameTab === tab ? 0 : -1}\n aria-selected={gameTab === tab}\n id={`${tabsId}-${tab}-tab`}\n aria-controls={`${tabsId}-${tab}-panel`}\n onKeyDown={(event) => { handleTabKey(event, tabs, gameTab, onGameTab); }}\n onClick={() => { onGameTab(tab); }}\n >{tab === \"preview\" ? \"\u8BD5\u73A9\" : project.source === \"example\" ? \"\u8BF4\u660E\" : \"\u9879\u76EE\u6587\u4EF6\"}</button>)}\n </div>\n </header>\n <div className=\"oh-game-panels\">\n <div className=\"oh-game-panel\" role=\"tabpanel\" id={`${tabsId}-preview-panel`} aria-labelledby={`${tabsId}-preview-tab`} hidden={gameTab !== \"preview\"}>\n <GamePreview key={`${project.id}:${String(project.previewReady)}`} project={project} building={building} />\n </div>\n <div className=\"oh-game-panel\" role=\"tabpanel\" id={`${tabsId}-design-panel`} aria-labelledby={`${tabsId}-design-tab`} hidden={gameTab !== \"design\"}>\n <GameDesign project={project} files={workspace.files} selected={selected} sessionId={sessionId} onSelect={onSelect} />\n </div>\n </div>\n </main>;\n}\n\nfunction CreativeWorkbench({\n sessionId,\n runningCalls,\n partial,\n undispatched,\n settledMutation,\n settledMutationTurn,\n liveTurn,\n sessionRunning,\n productionQueue,\n productionIntents,\n sendProductionPrompt,\n cancelProduction,\n removeQueuedProduction,\n workspace,\n error,\n workspaceLoading,\n reload,\n open,\n creativeProject,\n welcome,\n useStore,\n actions\n}: {\n readonly sessionId: string;\n readonly runningCalls: readonly RunningToolCall[];\n readonly partial: PartialAssistant | null;\n readonly undispatched: readonly UndispatchedCall[];\n readonly settledMutation: string | undefined;\n /** Turn of {@link settledMutation}; only a write from a Turn this mount saw open is followed. */\n readonly settledMutationTurn: number | undefined;\n /** The Session's last Turn while it is open. */\n readonly liveTurn: number | undefined;\n readonly sessionRunning: boolean;\n readonly productionQueue: readonly ProductionQueueEntry[];\n readonly productionIntents: readonly SettledProductionIntent[];\n readonly workspace: WorkspacePayload | undefined;\n readonly error: string | undefined;\n readonly workspaceLoading: boolean;\n readonly reload: () => void;\n readonly open: boolean;\n readonly creativeProject: boolean;\n /** A blank Session over a workspace without creative work: the first thing a fresh DSH shows. */\n readonly welcome: boolean;\n} & Pick<WorkbenchSlotProps, \"useStore\" | \"actions\" | \"sendProductionPrompt\" | \"cancelProduction\" | \"removeQueuedProduction\">) {\n const activities = useMemo(\n () => fileMutations(runningCalls, partial, undispatched),\n [partial, runningCalls, undispatched]\n );\n const normalizedActivities = useMemo(() => activities.flatMap((activity) => {\n const path = creativeRelativePath(activity.path, workspace?.cwd);\n return path === undefined ? [] : [{ activity, path }];\n }), [activities, workspace?.cwd]);\n const primaryActivity = normalizedActivities.at(-1);\n const activityPaths = useMemo(() => new Set(normalizedActivities.map((value) => value.path)), [normalizedActivities]);\n const settledPath = settledMutation === undefined\n ? undefined\n : creativeRelativePath(settledMutation.slice(settledMutation.indexOf(\"\\0\") + 1), workspace?.cwd);\n const activity = primaryActivity?.activity;\n const activityPath = primaryActivity?.path;\n const workbench = useStore((memory) => memory.workbench);\n const setWorkbench = actions.setWorkbench;\n const gameTab = useStore((memory) => memory.gameTab);\n const setGameTab = actions.setGameTab;\n const gameProjectId = useStore((memory) => memory.gameProjectId);\n const setGameProjectId = actions.setGameProjectId;\n const gamePane = useStore((memory) => memory.gamePane);\n const setGamePane = actions.setGamePane;\n const videoTab = useStore((memory) => memory.videoTab);\n const setVideoTab = actions.setVideoTab;\n const videoProjectId = useStore((memory) => memory.videoProjectId);\n const setVideoProjectId = actions.setVideoProjectId;\n const videoPane = useStore((memory) => memory.videoPane);\n const setVideoPane = actions.setVideoPane;\n const selected = useStore((memory) => memory.selected);\n const setSelected = actions.setSelected;\n const buffers = useStore((memory) => memory.buffers);\n const setBuffers = actions.setBuffers;\n const buffersRef = useRef<Record<string, FileBuffer>>({});\n const expanded = useStore((memory) => memory.expanded);\n const setExpanded = actions.setExpanded;\n const productionSection = useStore((memory) => memory.productionSection);\n const setProductionSection = actions.setProductionSection;\n const productionSelectedIds = useStore((memory) => memory.productionSelectedIds);\n const productionJobsByEpisode = useStore((memory) => memory.productionJobs);\n const productionSelectionsByEpisode = useStore((memory) => memory.productionSelections);\n const productionReferencesByEpisode = useStore((memory) => memory.productionReferences);\n const productionSequenceByEpisode = useStore((memory) => memory.productionSequence);\n const productionCanvasByEpisode = useStore((memory) => memory.productionCanvas);\n const productionZoomByEpisode = useStore((memory) => memory.productionZoom);\n const productionIntentCalls = useStore((memory) => memory.productionIntentCalls);\n const surfaceRef = useRef<HTMLDivElement>(null);\n const setWorkbenchPreference = actions.setWorkbenchPreference;\n const applyWorkbenchPreference = useCallback((preference: WorkbenchPreference): void => {\n setWorkbenchPreference(preference);\n writeWorkbenchPreference(workbenchPreferenceStorage(), workspace?.cwd, preference);\n }, [setWorkbenchPreference, workspace?.cwd]);\n const compactTabsId = useId();\n const compactStudioId = `${compactTabsId}-studio-panel`;\n const compactVideoStudioId = `${compactTabsId}-video-studio-panel`;\n const compactChatId = `${compactTabsId}-chat-panel`;\n const navRef = useRef<HTMLElement>(null);\n const activityBases = useRef(new Map<string, { readonly path: string; readonly base: string }>());\n const previousSignals = useRef<ReadonlySet<string>>(new Set());\n // The consumed signal lives in the Store so it survives a remount: DSH 0.1.7 reloads a Session's\n // Chat after a switch, and replaying its history must not look like a fresh Agent write.\n const consumedSettledMutation = useStore((memory) => memory.settledMutation);\n // A reloaded Session shows its history as closed Turns; only a Turn seen open is live work.\n const liveTurns = useRef(new Set<number>());\n if (liveTurn !== undefined) liveTurns.current.add(liveTurn);\n const saveLocks = useRef(new Set<string>());\n const buffer = selected === undefined ? undefined : buffers[selected];\n const selectedFile = workspace?.files.find((file) => file.path === selected);\n const selectedMedia = selectedFile?.kind === \"media\";\n const dirty = buffer?.source === \"human\" && buffer.content !== buffer.saved;\n const saving = buffer?.saving === true;\n const fileError = buffer?.error;\n const conflict = buffer?.conflict;\n const selectedLower = selected?.toLocaleLowerCase();\n const markdown = selectedLower?.endsWith(\".md\") === true;\n const jsonl = selectedLower?.endsWith(\".jsonl\") === true;\n const structured = jsonl || selectedLower?.endsWith(\".json\") === true;\n const previewable = markdown || jsonl;\n const episodeDirectory = episodeDirectoryForPath(selected);\n const productionAvailable = selected !== undefined && isCreatorDocumentPath(selected) && episodeDirectory !== undefined;\n const editorModes = productionAvailable ? EDITOR_MODES : EDITOR_MODES.filter((mode) => mode !== \"production\");\n const episodeDocumentPaths = useMemo(\n () => episodeDirectory === undefined ? [] : creatorDocumentPaths(workspace?.files.filter((file) => file.kind === \"text\") ?? [], episodeDirectory),\n [episodeDirectory, workspace?.files]\n );\n const episodeDocuments = useMemo(() => Object.fromEntries(episodeDocumentPaths.flatMap((path) => {\n const current = buffers[path];\n return current === undefined || current.missing === true ? [] : [[path, current.content] as const];\n })), [buffers, episodeDocumentPaths]);\n const episodeProduction = useMemo(\n () => episodeDirectory === undefined ? undefined : parseEpisodeProduction(episodeDocuments, episodeDirectory),\n [episodeDirectory, episodeDocuments]\n );\n const productionLibrary = useMemo(() => (workspace?.files ?? []).flatMap((file): ProductionMediaVersion[] => {\n if (file.kind !== \"media\" || file.mimeType?.startsWith(\"audio/\") === true) return [];\n if (!file.path.startsWith(\"\u5267\u96C6/\") && !file.path.startsWith(\"\u4EA4\u4ED8/\")) return [];\n const targetId = file.path.toLocaleUpperCase().match(/(?:SHOT|IMG|MOTION|VISUAL)-[A-Z0-9-]+/u)?.[0] ?? file.path.split(\"/\").at(-2) ?? \"PROJECT-MEDIA\";\n return [{\n id: `workspace:${file.path}:${file.version}`,\n targetId,\n kind: file.mimeType?.startsWith(\"image/\") === true ? \"image\" : \"video\",\n url: endpoint(\"media\", sessionId, file.path),\n path: file.path\n }];\n }), [sessionId, workspace?.files]);\n const productionVersions = useMemo(() => {\n if (episodeProduction === undefined) return [];\n const episodeName = episodeProduction.episodeDirectory.split(\"/\").at(-1) ?? \"\";\n const knownTargets = [\n ...episodeProduction.shots.map((shot) => shot.id),\n ...episodeProduction.assets.map((asset) => asset.id),\n ...episodeProduction.visualAssets.map((asset) => asset.id),\n ...episodeProduction.motions.map((motion) => motion.id)\n ].sort((left, right) => right.length - left.length);\n const motionTargets = new Map(episodeProduction.motions.flatMap((motion) => motion.shotId === undefined ? [] : [[motion.id, motion.shotId] as const]));\n const fromWorkspace = productionLibrary.flatMap((version) => {\n if (version.path === undefined || (!version.path.startsWith(`${episodeProduction.episodeDirectory}/`) && !version.path.startsWith(`\u4EA4\u4ED8/${episodeName}/`))) return [];\n const matched = mediaTargetFromPath(version.path, knownTargets);\n // Drama Skills 0.7 renders the assembled cut into \u5236\u4F5C\u6210\u679C/\u6210\u7247/; earlier native\n // compositions wrote \u6210\u7247-<job>.mp4 beside the per-shot results.\n const composition = /(?:^|\\/)\u6210\u7247-[^/]+\\.mp4$/iu.test(version.path)\n || /(?:^|\\/)\u5236\u4F5C\u6210\u679C\\/\u6210\u7247\\//u.test(version.path);\n if (matched === undefined && !composition) return [];\n const targetId = matched === undefined ? episodeProduction.episodeDirectory : motionTargets.get(matched) ?? matched;\n return [{ ...version, targetId }];\n });\n const byId = new Map<string, ProductionMediaVersion>();\n for (const version of fromWorkspace) byId.set(version.id, version);\n return [...byId.values()];\n }, [episodeProduction, productionLibrary]);\n const productionSelectedId = episodeDirectory === undefined ? undefined : productionSelectedIds[episodeDirectory];\n const productionJobs = episodeDirectory === undefined ? [] : productionJobsByEpisode[episodeDirectory] ?? [];\n const productionSelections = episodeDirectory === undefined ? {} : productionSelectionsByEpisode[episodeDirectory] ?? {};\n const productionReferences = episodeDirectory === undefined ? {} : productionReferencesByEpisode[episodeDirectory] ?? {};\n const productionSequence = episodeDirectory === undefined ? [] : productionSequenceByEpisode[episodeDirectory] ?? [];\n const productionCanvas = episodeDirectory === undefined ? {} : productionCanvasByEpisode[episodeDirectory] ?? {};\n const productionZoom = episodeDirectory === undefined ? .65 : productionZoomByEpisode[episodeDirectory] ?? .65;\n const setProductionSelectedId = useCallback((selectedId: string | undefined) => {\n if (episodeDirectory !== undefined) actions.setProductionSelectedIds((current) => ({ ...current, [episodeDirectory]: selectedId }));\n }, [actions, episodeDirectory]);\n const setProductionJobs = useCallback((jobs: ProductionJob[]) => {\n if (episodeDirectory !== undefined) actions.setProductionJobs((current) => ({ ...current, [episodeDirectory]: jobs }));\n }, [actions, episodeDirectory]);\n const setProductionSelections = useCallback((selections: Record<string, string>) => {\n if (episodeDirectory !== undefined) actions.setProductionSelections((current) => ({ ...current, [episodeDirectory]: selections }));\n }, [actions, episodeDirectory]);\n const setProductionReferences = useCallback((references: Record<string, string[]>) => {\n if (episodeDirectory !== undefined) actions.setProductionReferences((current) => ({ ...current, [episodeDirectory]: references }));\n }, [actions, episodeDirectory]);\n const setProductionSequence = useCallback((sequence: ProductionSequenceItem[]) => {\n if (episodeDirectory !== undefined) actions.setProductionSequence((current) => ({ ...current, [episodeDirectory]: sequence }));\n }, [actions, episodeDirectory]);\n const setProductionCanvas = useCallback((canvas: Record<string, CanvasPoint>) => {\n if (episodeDirectory !== undefined) actions.setProductionCanvas((current) => ({ ...current, [episodeDirectory]: canvas }));\n }, [actions, episodeDirectory]);\n const setProductionZoom = useCallback((zoom: number) => {\n if (episodeDirectory !== undefined) actions.setProductionZoom((current) => ({ ...current, [episodeDirectory]: zoom }));\n }, [actions, episodeDirectory]);\n const editorMode = useStore((memory) => memory.editorMode);\n const setEditorMode = actions.setEditorMode;\n const modeSelection = useRef(selected);\n const textareaRef = useRef<HTMLTextAreaElement>(null);\n const editorPositions = useRef(new Map<string, { readonly scrollTop: number; readonly selectionStart: number; readonly selectionEnd: number }>());\n const editorReady = buffer !== undefined && buffer.missing !== true;\n const workspaceKind = workbench === \"game\" || workbench === \"video\" ? undefined : workbench;\n const gameBuilding = normalizedActivities.some(({ path }) => path.startsWith(\"game-adaptations/\"));\n const videoBuilding = normalizedActivities.some(({ path }) => path.startsWith(\"video-recaps/\"));\n\n useEffect(() => { buffersRef.current = buffers; }, [buffers]);\n\n const rememberEditorPosition = useCallback((): void => {\n const element = textareaRef.current;\n if (element === null || selected === undefined || element.getAttribute(\"aria-label\") !== selected) return;\n editorPositions.current.set(selected, {\n scrollTop: element.scrollTop,\n selectionStart: element.selectionStart,\n selectionEnd: element.selectionEnd\n });\n }, [selected]);\n\n useLayoutEffect(() => {\n if (editorMode !== \"source\" || selected === undefined || !editorReady) return;\n const element = textareaRef.current;\n const position = editorPositions.current.get(selected);\n if (element === null || position === undefined) return;\n const end = Math.min(position.selectionEnd, element.value.length);\n element.setSelectionRange(Math.min(position.selectionStart, end), end);\n element.scrollTop = position.scrollTop;\n }, [editorMode, editorReady, selected]);\n\n useEffect(() => {\n const warn = (event: BeforeUnloadEvent): void => {\n if (!Object.values(buffersRef.current).some((value) => value.source === \"human\" && value.content !== value.saved)) return;\n event.preventDefault();\n };\n globalThis.addEventListener(\"beforeunload\", warn);\n return () => { globalThis.removeEventListener(\"beforeunload\", warn); };\n }, []);\n\n const expandPath = useCallback((path: string): void => {\n const segments = path.split(\"/\");\n const ancestors = [groupForPath(path)];\n for (let index = 1; index < segments.length - 1; index += 1) ancestors.push(segments.slice(0, index + 1).join(\"/\"));\n setExpanded((current) => {\n const next = { ...current };\n for (const ancestor of ancestors) next[ancestor] = true;\n return next;\n });\n }, []);\n\n const revealPath = useCallback((path: string): void => {\n rememberEditorPosition();\n const nextWorkbench = workbenchModeForPath(path) ?? \"story\";\n setWorkbench(nextWorkbench);\n if (nextWorkbench === \"game\" && !path.includes(\"/build/app/\")) setGameTab(\"design\");\n setSelected(path);\n expandPath(path);\n }, [expandPath, rememberEditorPosition]);\n\n useEffect(() => {\n if (workspace === undefined) return;\n const pending = productionIntents.filter(({ callId }) => productionIntentCalls[callId] !== true);\n if (pending.length === 0) return;\n for (const { intent } of pending) {\n if (intent.action === \"open_section\" || intent.action === \"focus_target\") {\n const documentPath = [\"\u5206\u955C.md\", \"\u56FE\u7247\u63D0\u793A\u8BCD.md\", \"\u89C6\u89C9\u8BBE\u5B9A.md\", \"\u5267\u672C.md\", \"\u89C6\u9891\u63D0\u793A\u8BCD.md\"]\n .map((name) => `${intent.episode}/${name}`)\n .find((path) => workspace.files.some((file) => file.path === path));\n if (documentPath !== undefined) {\n setWorkbench(\"drama\");\n setSelected(documentPath);\n expandPath(documentPath);\n globalThis.setTimeout(() => { setEditorMode(\"production\"); }, 0);\n }\n }\n if (intent.action === \"open_section\") setProductionSection(intent.section ?? \"shots\");\n else if (intent.action === \"focus_target\") {\n actions.setProductionSelectedIds((current) => ({ ...current, [intent.episode]: intent.targetId }));\n setProductionSection(intent.section ?? (intent.targetId?.startsWith(\"SHOT-\") === true ? \"shots\" : \"assets\"));\n } else if (intent.action === \"set_sequence\") {\n actions.setProductionSequence((current) => ({\n ...current,\n [intent.episode]: (intent.shotIds ?? []).map((shotId) => ({ shotId }))\n }));\n } else if (intent.action === \"track_job\" && intent.jobId !== undefined && intent.targetId !== undefined && intent.jobKind !== undefined) {\n const { jobId, targetId, jobKind } = intent;\n actions.setProductionJobs((current) => {\n const jobs = current[intent.episode] ?? [];\n if (jobs.some((job) => job.id === jobId)) {\n return {\n ...current,\n [intent.episode]: jobs.map((job) => job.id === jobId ? {\n ...job,\n targetId,\n kind: jobKind,\n status: \"running\",\n progress: Math.max(10, job.progress),\n prompt: intent.prompt ?? job.prompt,\n expectedOutputs: intent.expectedOutputs ?? job.expectedOutputs,\n error: undefined\n } : job)\n };\n }\n return {\n ...current,\n [intent.episode]: [...jobs, {\n ...createPendingJob({\n id: jobId,\n targetId,\n kind: jobKind,\n prompt: intent.prompt ?? \"\",\n expectedOutputs: intent.expectedOutputs\n }),\n status: \"running\",\n progress: 10\n }]\n };\n });\n }\n }\n actions.setProductionIntentCalls((current) => ({\n ...current,\n ...Object.fromEntries(pending.map(({ callId }) => [callId, true]))\n }));\n }, [actions, expandPath, productionIntentCalls, productionIntents, setEditorMode, setProductionSection, setSelected, setWorkbench, workspace]);\n\n // Latch first entry into the game workbench: before that the Studio must not mount, or every\n // session downloads and runs the bundled example in a display:none iframe. Once mounted it\n // stays mounted so the running game survives later navigation.\n const openedGame = useRef(false);\n if (workbench === \"game\") openedGame.current = true;\n const gameStudioMounted = openedGame.current;\n const openedVideo = useRef(false);\n if (workbench === \"video\") openedVideo.current = true;\n const videoStudioMounted = openedVideo.current;\n\n const followAgentPath = useCallback((path: string): void => {\n expandPath(path);\n const current = selected === undefined ? undefined : buffersRef.current[selected];\n const preserveFocusedDraft = path !== selected\n && current?.source === \"human\"\n && current.content !== current.saved\n && surfaceRef.current?.ownerDocument.activeElement === textareaRef.current;\n if (preserveFocusedDraft) return;\n // The editor textarea is not mounted in the Game Studio, so the draft guard above can never\n // fire there. Never preempt a running game: agent writes may expand the tree, not navigate.\n if ((workbench === \"game\" && gameTab === \"preview\") || (workbench === \"video\" && videoTab === \"preview\")) return;\n revealPath(path);\n }, [expandPath, gameTab, revealPath, selected, videoTab, workbench]);\n\n useEffect(() => {\n if (activityPath !== undefined && activityPath === selected && !selectedMedia) setEditorMode(\"source\");\n }, [activityPath, selected, selectedMedia]);\n\n useEffect(() => {\n if (modeSelection.current === selected) return;\n modeSelection.current = selected;\n setEditorMode(selected !== undefined && activityPaths.has(selected) ? \"source\" : selectedMedia || previewable ? \"preview\" : \"source\");\n }, [activityPaths, previewable, selected, selectedMedia]);\n\n useEffect(() => {\n if (workspaceLoading) return;\n if (activityPath !== undefined) return;\n if (selected !== undefined && (\n (workspace?.files.some((file) => file.path === selected) ?? false)\n || buffers[selected] !== undefined\n ) && workbenchModeForPath(selected) === workbench) return;\n setSelected(workspace === undefined ? undefined : preferredWorkbenchFile(workspace.files, workbench));\n }, [activityPath, buffers, selected, workbench, workspace, workspaceLoading]);\n\n useEffect(() => {\n if (workspace === undefined || workspaceLoading) return;\n const paths = new Set(workspace.files.map((file) => file.path));\n setBuffers((current) => {\n let changed = false;\n const next = { ...current };\n for (const [path, value] of Object.entries(current)) {\n if (paths.has(path) || activityPaths.has(path)) continue;\n // A write that just settled is on disk before the workspace reload lists it; keep its\n // preview (and so the selection) until then. A denied write never settles and is pruned.\n if (value.source === \"agent\" && sessionRunning && path === settledPath) continue;\n if (value.source === \"human\" && value.content !== value.saved) {\n if (value.missing !== true) {\n next[path] = { ...value, missing: true, error: \"\u6587\u4EF6\u5DF2\u4ECE workspace \u79FB\u9664\u3002\u672C\u5730\u8349\u7A3F\u4ECD\u4FDD\u7559\uFF0C\u53EF\u590D\u5236\u540E\u653E\u5F03\u8349\u7A3F\u3002\" };\n changed = true;\n }\n } else {\n delete next[path];\n changed = true;\n }\n }\n return changed ? next : current;\n });\n }, [activityPaths, sessionRunning, settledPath, workspace, workspaceLoading]);\n\n useEffect(() => {\n if (selected === undefined || selectedMedia || activityPaths.has(selected)) return;\n if (!(workspace?.files.some((file) => file.path === selected) ?? false)) return;\n const controller = new AbortController();\n setBuffers((current) => {\n const existing = current[selected];\n return existing === undefined ? current : { ...current, [selected]: { ...existing, error: undefined } };\n });\n void fetch(endpoint(\"file\", sessionId, selected), { signal: controller.signal })\n .then((response) => json<FilePayload>(response))\n .then((file) => {\n setBuffers((current) => {\n const existing = current[file.path];\n if (existing?.source === \"human\" && existing.content !== existing.saved) {\n if (existing.version === file.version) return { ...current, [file.path]: { ...existing, missing: false, error: undefined } };\n return {\n ...current,\n [file.path]: {\n ...existing,\n missing: false,\n error: undefined,\n conflict: {\n message: `${file.path} \u5DF2\u5728\u78C1\u76D8\u4E0A\u66F4\u65B0\uFF1B\u4F60\u7684\u672C\u5730\u8349\u7A3F\u6CA1\u6709\u88AB\u8986\u76D6\u3002`,\n theirs: file.content,\n theirsVersion: file.version\n }\n }\n };\n }\n return {\n ...current,\n [file.path]: { content: file.content, saved: file.content, source: \"disk\", version: file.version }\n };\n });\n })\n .catch((reason: unknown) => {\n if (controller.signal.aborted) return;\n setBuffers((current) => {\n const existing = current[selected];\n return existing === undefined ? current : {\n ...current,\n [selected]: { ...existing, error: reason instanceof Error ? reason.message : String(reason) }\n };\n });\n });\n return () => { controller.abort(); };\n }, [activityPaths, selected, selectedMedia, sessionId, workspace?.files]);\n\n useEffect(() => {\n if (!productionAvailable) return;\n const missing = episodeDocumentPaths.filter((path) => buffersRef.current[path] === undefined && !activityPaths.has(path));\n if (missing.length === 0) return;\n const controller = new AbortController();\n void Promise.all(missing.map((path) => fetch(endpoint(\"file\", sessionId, path), { signal: controller.signal }).then((response) => json<FilePayload>(response))))\n .then((files) => {\n setBuffers((current) => {\n const next = { ...current };\n for (const file of files) {\n const existing = next[file.path];\n if (existing?.source === \"human\" && existing.content !== existing.saved) continue;\n next[file.path] = { content: file.content, saved: file.content, source: \"disk\", version: file.version };\n }\n return next;\n });\n })\n .catch((reason: unknown) => {\n if (!controller.signal.aborted) {\n setBuffers((current) => {\n const next = { ...current };\n for (const path of missing) {\n const existing = next[path];\n if (existing !== undefined) next[path] = { ...existing, error: reason instanceof Error ? reason.message : String(reason) };\n }\n return next;\n });\n }\n });\n return () => { controller.abort(); };\n }, [activityPaths, episodeDocumentPaths, productionAvailable, sessionId]);\n\n useEffect(() => {\n if (normalizedActivities.length === 0) return;\n for (const { path } of normalizedActivities) expandPath(path);\n if (activityPath !== undefined) followAgentPath(activityPath);\n setBuffers((current) => {\n let next = current;\n for (const { activity: currentActivity, path } of normalizedActivities) {\n const existing = next[path];\n if (existing?.source === \"human\" && existing.content !== existing.saved) {\n next = {\n ...next,\n [path]: {\n ...existing,\n conflict: { message: `${path} \u6B63\u7531 Agent \u4FEE\u6539\uFF1B\u4F60\u7684\u672C\u5730\u8349\u7A3F\u5DF2\u9501\u5B9A\uFF0C\u4E0D\u4F1A\u88AB\u8986\u76D6\u3002` }\n }\n };\n continue;\n }\n let basis = activityBases.current.get(currentActivity.callId);\n if (basis === undefined || basis.path !== path) {\n basis = { path, base: existing?.content ?? \"\" };\n activityBases.current.set(currentActivity.callId, basis);\n }\n const preview = previewMutation(currentActivity, basis.base);\n if (preview === undefined || (existing?.source === \"agent\" && existing.content === preview)) continue;\n next = {\n ...next,\n [path]: {\n content: preview,\n saved: existing?.saved ?? \"\",\n source: \"agent\",\n version: existing?.version ?? \"\"\n }\n };\n }\n return next;\n });\n }, [activityPath, expandPath, followAgentPath, normalizedActivities]);\n\n useEffect(() => {\n const signals = new Set(mutatingCallIds(runningCalls));\n for (const { activity: currentActivity } of normalizedActivities) signals.add(currentActivity.callId.split(\":\", 1)[0] ?? currentActivity.callId);\n const settled = [...previousSignals.current].some((callId) => !signals.has(callId));\n for (const callId of activityBases.current.keys()) {\n if (!signals.has(callId.split(\":\", 1)[0] ?? callId)) activityBases.current.delete(callId);\n }\n previousSignals.current = signals;\n if (!settled) return;\n reload();\n }, [normalizedActivities, reload, runningCalls]);\n\n useEffect(() => {\n if (settledMutation === undefined || settledMutation === consumedSettledMutation) return;\n // History replayed after a reload or a Session switch is not a fresh Agent write.\n if (settledMutationTurn === undefined || !liveTurns.current.has(settledMutationTurn)) {\n actions.setSettledMutation(settledMutation);\n return;\n }\n // The signal carries an absolute path, so creativeRelativePath cannot resolve it until the\n // workspace (and its cwd) has loaded. Consuming the signal first would burn it: the effect\n // re-runs when cwd arrives, but the guard above then short-circuits and the agent's file is\n // never selected. Wait for cwd instead of dropping the follow.\n if (workspace?.cwd === undefined) return;\n actions.setSettledMutation(settledMutation);\n const path = creativeRelativePath(settledMutation.slice(settledMutation.indexOf(\"\\0\") + 1), workspace.cwd);\n if (path !== undefined) followAgentPath(path);\n reload();\n }, [actions, consumedSettledMutation, followAgentPath, reload, settledMutation, settledMutationTurn, workspace?.cwd]);\n\n useEffect(() => {\n if (selected === undefined) return;\n for (const button of navRef.current?.querySelectorAll<HTMLButtonElement>(\"button[data-file-path]\") ?? []) {\n if (button.dataset.filePath === selected) {\n button.scrollIntoView({ block: \"nearest\" });\n break;\n }\n }\n }, [selected]);\n\n useEffect(() => {\n if (!open || normalizedActivities.length > 0 || workspace === undefined) return;\n const sessionSurface = surfaceRef.current?.parentElement;\n if (sessionSurface === undefined || sessionSurface === null) return;\n const knownPaths = new Set(workspace.files.map((file) => file.path));\n const followOfficialFileLink = (event: MouseEvent): void => {\n const origin = event.target;\n if (!(origin instanceof Element)) return;\n const control = origin.closest<HTMLElement>(\"button, a\");\n if (control === null || control.closest(\".oh-story-split-surface\") !== null) return;\n const candidates = [control.title, control.getAttribute(\"aria-label\"), control.textContent];\n for (const candidate of candidates) {\n const path = creativeRelativePath(candidate?.trim().replace(/^(?:Open|\u6253\u5F00)\\s+/u, \"\"), workspace.cwd);\n if (path === undefined || !knownPaths.has(path)) continue;\n event.preventDefault();\n event.stopPropagation();\n revealPath(path);\n break;\n }\n };\n sessionSurface.addEventListener(\"click\", followOfficialFileLink, true);\n return () => { sessionSurface.removeEventListener(\"click\", followOfficialFileLink, true); };\n }, [normalizedActivities.length, open, revealPath, workspace]);\n\n useEffect(() => {\n if (workbench !== \"game\" && workbench !== \"video\") return;\n const surface = surfaceRef.current;\n const sessionSurface = surface?.parentElement;\n const chat = Array.from(sessionSurface?.children ?? []).find((child) => child !== surface && child instanceof HTMLElement);\n if (!(chat instanceof HTMLElement)) return;\n const previous = {\n id: chat.id,\n role: chat.getAttribute(\"role\"),\n labelledBy: chat.getAttribute(\"aria-labelledby\")\n };\n chat.id = compactChatId;\n chat.setAttribute(\"role\", \"tabpanel\");\n chat.setAttribute(\"aria-labelledby\", `${compactTabsId}-chat-tab`);\n return () => {\n chat.id = previous.id;\n if (previous.role === null) chat.removeAttribute(\"role\");\n else chat.setAttribute(\"role\", previous.role);\n if (previous.labelledBy === null) chat.removeAttribute(\"aria-labelledby\");\n else chat.setAttribute(\"aria-labelledby\", previous.labelledBy);\n };\n }, [compactChatId, compactTabsId, workbench]);\n\n const savePath = useCallback(async (path: string) => {\n if (saveLocks.current.has(path)) return;\n const submitted = buffersRef.current[path];\n if (submitted === undefined || submitted.missing === true || submitted.content === submitted.saved) return;\n saveLocks.current.add(path);\n setBuffers((current) => {\n const existing = current[path];\n return existing === undefined ? current : { ...current, [path]: { ...existing, saving: true, error: undefined } };\n });\n try {\n const file = await json<FilePayload>(await fetch(endpoint(\"file\", sessionId, path), {\n method: \"PUT\",\n headers: { \"content-type\": \"application/json\" },\n body: JSON.stringify({ content: submitted.content, baseVersion: submitted.version })\n }));\n setBuffers((current) => {\n const latest = current[path];\n if (latest === undefined) return current;\n const unchanged = latest.content === submitted.content;\n return {\n ...current,\n [path]: {\n content: unchanged ? file.content : latest.content,\n saved: file.content,\n source: unchanged ? \"disk\" : \"human\",\n version: file.version,\n saving: false\n }\n };\n });\n reload();\n } catch (reason) {\n if (reason instanceof WorkspaceRequestError && reason.status === 412) {\n try {\n const theirs = await json<FilePayload>(await fetch(endpoint(\"file\", sessionId, path)));\n setBuffers((current) => {\n const latest = current[path];\n if (latest === undefined) return current;\n return {\n ...current,\n [path]: {\n ...latest,\n saving: false,\n conflict: {\n message: `${path} \u5DF2\u5728\u78C1\u76D8\u4E0A\u66F4\u65B0\uFF1B\u8BF7\u9009\u62E9\u4FDD\u7559\u54EA\u4E00\u7248\u3002`,\n theirs: theirs.content,\n theirsVersion: theirs.version\n }\n }\n };\n });\n } catch (refreshError) {\n setBuffers((current) => {\n const existing = current[path];\n return existing === undefined ? current : {\n ...current,\n [path]: { ...existing, saving: false, error: refreshError instanceof Error ? refreshError.message : String(refreshError) }\n };\n });\n }\n } else {\n setBuffers((current) => {\n const existing = current[path];\n return existing === undefined ? current : {\n ...current,\n [path]: { ...existing, saving: false, error: reason instanceof Error ? reason.message : String(reason) }\n };\n });\n }\n } finally {\n saveLocks.current.delete(path);\n }\n }, [reload, sessionId]);\n\n useEffect(() => {\n if (!open) return;\n const saveShortcut = (event: KeyboardEvent): void => {\n if (!(event.metaKey || event.ctrlKey) || event.key.toLocaleLowerCase() !== \"s\") return;\n event.preventDefault();\n if (selected !== undefined) void savePath(selected);\n };\n globalThis.addEventListener(\"keydown\", saveShortcut);\n return () => { globalThis.removeEventListener(\"keydown\", saveShortcut); };\n }, [open, savePath, selected]);\n\n const groups = useMemo(() => {\n const value = new Map<string, WorkspaceFile[]>();\n const all = [...(workspace?.files ?? [])].filter((file) => workbenchModeForPath(file.path) === workbench);\n if (activityPath !== undefined && !all.some((file) => file.path === activityPath)) all.push({ path: activityPath, bytes: 0, version: \"\", kind: \"text\" });\n all.sort((left, right) => left.path.localeCompare(right.path, \"zh-Hans-CN\"));\n for (const file of all) {\n const directory = groupForPath(file.path);\n const files = value.get(directory) ?? [];\n files.push(file);\n value.set(directory, files);\n }\n const order = GROUP_ORDER[workbench];\n return [...value.entries()].sort(([left], [right]) => {\n const leftIndex = order.indexOf(left);\n const rightIndex = order.indexOf(right);\n return (leftIndex < 0 ? order.length : leftIndex) - (rightIndex < 0 ? order.length : rightIndex)\n || left.localeCompare(right, \"zh-Hans-CN\");\n });\n }, [activityPath, workbench, workspace]);\n\n const selectWorkbench = (next: WorkbenchMode): void => {\n setWorkbench(next);\n if (next === \"game\" || next === \"video\") {\n if (next === \"game\") setGameTab(\"preview\");\n else setVideoTab(\"preview\");\n setSelected(undefined);\n return;\n }\n const target = workspace === undefined ? undefined : preferredWorkbenchFile(workspace.files, next);\n if (target === undefined) setSelected(undefined);\n else revealPath(target);\n };\n const selectEditorMode = (next: WorkbenchMemory[\"editorMode\"]): void => {\n if (next === \"preview\") rememberEditorPosition();\n setEditorMode(next);\n };\n const navigateProductionTarget = (target: DramaDocumentTarget): void => {\n const content = buffersRef.current[target.path]?.content ?? \"\";\n const before = content.slice(0, target.offset);\n const approximateScrollTop = Math.max(0, before.split(/\\r?\\n/u).length * 28 - 96);\n editorPositions.current.set(target.path, { scrollTop: approximateScrollTop, selectionStart: target.offset, selectionEnd: target.offset });\n modeSelection.current = target.path;\n revealPath(target.path);\n setEditorMode(\"source\");\n };\n const selectedLabel = selected ?? `\u5728\u5F53\u524D DSH workspace \u4E2D\u9009\u62E9${workbenchLabel(workbench)}\u6587\u4EF6`;\n const selectedBasename = selected?.split(\"/\").at(-1) ?? selectedLabel;\n const selectedGroup = selected === undefined ? undefined : groupForPath(selected);\n const toggleGroup = (key: string, open: boolean): void => {\n setExpanded((current) => ({ ...current, [key]: open }));\n };\n const resolveConflict = (keepLocal: boolean): void => {\n if (selected === undefined || conflict?.theirs === undefined || conflict.theirsVersion === undefined) return;\n const theirs = conflict.theirs;\n const theirsVersion = conflict.theirsVersion;\n setBuffers((current) => {\n const existing = current[selected];\n if (existing === undefined) return current;\n return {\n ...current,\n [selected]: keepLocal\n ? { ...existing, saved: theirs, version: theirsVersion, source: \"human\", conflict: undefined }\n : { content: theirs, saved: theirs, source: \"disk\", version: theirsVersion }\n };\n });\n };\n\n if (!open) {\n // Without creative work there is nothing to reveal, so the plugin leaves the\n // official conversation exactly as DSH renders it. A failed workspace request\n // still offers the way in, because that error is only readable inside the workbench.\n if (!creativeProject && error === undefined) return welcome ? <WelcomeGuide /> : null;\n return <div ref={surfaceRef} className=\"oh-story-split-surface\" data-open=\"false\">\n <style>{styles}</style>\n <button className=\"oh-story-launcher\" type=\"button\" title={error ?? \"\u6253\u5F00\u521B\u4F5C\u5DE5\u4F5C\u53F0\"} aria-label=\"\u6253\u5F00\u521B\u4F5C\u5DE5\u4F5C\u53F0\" onClick={() => { applyWorkbenchPreference(\"open\"); }}>\n <span aria-hidden>\u2726</span><b>\u521B\u4F5C\u5DE5\u4F5C\u53F0</b>\n </button>\n </div>;\n }\n\n return <div ref={surfaceRef} className=\"oh-story-split-surface\" data-open=\"true\" data-workbench={workbench}>\n <style>{styles}</style>\n {(workbench === \"game\" || workbench === \"video\") && <div className=\"oh-game-mobile-switcher\" role=\"tablist\" aria-label={workbench === \"game\" ? \"\u7A84\u5C4F\u6E38\u620F\u5DE5\u4F5C\u53F0\" : \"\u7A84\u5C4F\u89C6\u9891\u5DE5\u4F5C\u53F0\"}>\n {([\"studio\", \"chat\"] as const).map((pane) => <button\n type=\"button\"\n role=\"tab\"\n key={pane}\n id={`${compactTabsId}-${pane}-tab`}\n aria-controls={pane === \"chat\" ? compactChatId : workbench === \"game\" ? compactStudioId : compactVideoStudioId}\n aria-selected={(workbench === \"game\" ? gamePane : videoPane) === pane}\n tabIndex={(workbench === \"game\" ? gamePane : videoPane) === pane ? 0 : -1}\n onKeyDown={(event) => { handleTabKey(event, [\"studio\", \"chat\"] as const, workbench === \"game\" ? gamePane : videoPane, workbench === \"game\" ? setGamePane : setVideoPane); }}\n onClick={() => { if (workbench === \"game\") setGamePane(pane); else setVideoPane(pane); }}\n >{pane === \"studio\" ? \"\u5236\u4F5C\" : \"\u5BF9\u8BDD\"}</button>)}\n </div>}\n {workbench === \"game\" && workspace === undefined && <main id={compactStudioId} className=\"oh-game-studio\" role=\"tabpanel\" aria-labelledby={`${compactTabsId}-studio-tab`}><div className=\"oh-game-design-empty\">{error ?? \"\u6B63\u5728\u8FDE\u63A5\u6E38\u620F\u5DE5\u4F5C\u53F0\u2026\"}</div></main>}\n {workspace !== undefined && gameStudioMounted && <GameStudio\n sessionId={sessionId}\n workspace={workspace}\n building={gameBuilding}\n selected={selected}\n gameTab={gameTab}\n gameProjectId={gameProjectId}\n hidden={workbench !== \"game\"}\n onGameTab={setGameTab}\n onGameProject={setGameProjectId}\n workbenches={WORKBENCH_MODES}\n paneId={compactStudioId}\n labelledBy={`${compactTabsId}-studio-tab`}\n onWorkbench={selectWorkbench}\n onCollapse={() => { applyWorkbenchPreference(\"closed\"); }}\n onSelect={revealPath}\n />}\n {workbench === \"video\" && workspace === undefined && <main id={compactVideoStudioId} className=\"oh-video-studio\" role=\"tabpanel\" aria-labelledby={`${compactTabsId}-studio-tab`}><div className=\"oh-video-preview-empty\">{error ?? \"\u6B63\u5728\u8FDE\u63A5\u89C6\u9891\u5DE5\u4F5C\u53F0\u2026\"}</div></main>}\n {workspace !== undefined && videoStudioMounted && <VideoStudio\n sessionId={sessionId}\n projects={workspace.videos}\n running={videoBuilding}\n projectId={videoProjectId}\n tab={videoTab}\n hidden={workbench !== \"video\"}\n workbenches={WORKBENCH_MODES}\n paneId={compactVideoStudioId}\n labelledBy={`${compactTabsId}-studio-tab`}\n onProject={setVideoProjectId}\n onTab={setVideoTab}\n onWorkbench={selectWorkbench}\n onCollapse={() => { applyWorkbenchPreference(\"closed\"); }}\n />}\n {workbench !== \"game\" && workbench !== \"video\" && <>\n <aside className=\"oh-story-tree\">\n <div className=\"oh-story-brand\">\n <span className=\"oh-story-brand-cluster\"><strong>\u2726 <span>Oh Story</span></strong>{workspaceKind !== undefined && <span className=\"oh-story-kind\">{workspaceKind === \"story\" ? \"\u5C0F\u8BF4\" : \"\u77ED\u5267\"}</span>}</span>\n <span className=\"oh-story-brand-actions\">\n <button type=\"button\" onClick={reload} title=\"\u5237\u65B0\" aria-label=\"\u5237\u65B0\u9879\u76EE\u6587\u4EF6\">\u21BB</button>\n <button type=\"button\" onClick={() => { applyWorkbenchPreference(\"closed\"); }} title=\"\u6536\u8D77\u521B\u4F5C\u5DE5\u4F5C\u53F0\" aria-label=\"\u6536\u8D77\u521B\u4F5C\u5DE5\u4F5C\u53F0\">\u00D7</button>\n </span>\n </div>\n {workspace !== undefined && <div className=\"oh-story-mode-tabs\" role=\"tablist\" aria-label=\"\u521B\u4F5C\u5DE5\u4F5C\u53F0\">\n {WORKBENCH_MODES.map((mode) => <button\n type=\"button\"\n role=\"tab\"\n key={mode}\n tabIndex={workbench === mode ? 0 : -1}\n aria-selected={workbench === mode}\n onKeyDown={(event) => { handleTabKey(event, WORKBENCH_MODES, workbench, selectWorkbench); }}\n onClick={() => { selectWorkbench(mode); }}\n >{workbenchLabel(mode)}</button>)}\n </div>}\n {error !== undefined && <div className=\"oh-story-error\">{error}</div>}\n {workspace?.metadataErrors.map((message) => <div className=\"oh-story-warning\" key={message}>{message}</div>)}\n <nav ref={navRef} aria-label={workbench === \"story\" ? \"\u5C0F\u8BF4\u9879\u76EE\u6587\u4EF6\" : \"\u77ED\u5267\u9879\u76EE\u6587\u4EF6\"}>\n {groups.map(([directory, files]) => {\n const groupOpen = selectedGroup === directory || expanded[directory] === true;\n return <details className=\"oh-story-file-group\" key={directory} open={groupOpen} onToggle={(event) => { toggleGroup(directory, event.currentTarget.open); }}>\n <summary>{directory}<span>{files.length}</span></summary>\n <FileTreeNodes\n nodes={buildFileTree(files, directory)}\n depth={1}\n expanded={expanded}\n selected={selected}\n activityPath={activityPath}\n onToggle={toggleGroup}\n onSelect={revealPath}\n />\n </details>;\n })}\n </nav>\n </aside>\n <main className=\"oh-story-editor\">\n <header>\n <span className=\"oh-story-editor-path\" title={selected}><span>{selectedLabel}</span><strong>{selectedBasename}</strong></span>\n <div className=\"oh-story-editor-actions\">\n {(previewable || productionAvailable) && !selectedMedia && <div className=\"oh-story-editor-tabs\" role=\"tablist\" aria-label={productionAvailable ? \"\u77ED\u5267\u6587\u6863\u67E5\u770B\u65B9\u5F0F\" : markdown ? \"Markdown \u67E5\u770B\u65B9\u5F0F\" : \"JSONL \u67E5\u770B\u65B9\u5F0F\"}>\n {editorModes.map((mode) => <button\n type=\"button\"\n role=\"tab\"\n key={mode}\n tabIndex={editorMode === mode ? 0 : -1}\n aria-selected={editorMode === mode}\n onKeyDown={(event) => { handleTabKey(event, editorModes, editorMode, selectEditorMode); }}\n onClick={() => { selectEditorMode(mode); }}\n >{mode === \"preview\" ? \"\u9884\u89C8\" : mode === \"source\" ? \"\u6E90\u7801\" : \"\u751F\u4EA7\"}</button>)}\n </div>}\n {(dirty || saving) && selected !== undefined && <button className=\"oh-story-save\" type=\"button\" disabled={saving || buffer?.missing === true} onClick={() => { void savePath(selected); }}>\n {saving ? \"\u4FDD\u5B58\u4E2D\u2026\" : \"\u4FDD\u5B58\"}\n </button>}\n </div>\n </header>\n {activity !== undefined && activityPath !== undefined && activityPath === selected && <div className=\"oh-story-stream\" data-stage={activity.stage} role=\"status\" aria-live=\"polite\">\u25CF {activity.stage === \"running\" ? \"Agent \u6B63\u5728\u5E94\u7528\u4FEE\u6539\" : \"Agent \u6B63\u5728\u751F\u6210\u6587\u4EF6\u5185\u5BB9\"}</div>}\n {conflict !== undefined && <div className=\"oh-story-conflict\" role=\"alert\">\n <span>{conflict.message}</span>\n {conflict.theirs !== undefined && conflict.theirsVersion !== undefined && selected !== undefined && <div>\n <button type=\"button\" onClick={() => { resolveConflict(false); }}>\u8F7D\u5165\u78C1\u76D8\u7248\u672C</button>\n <button type=\"button\" onClick={() => { resolveConflict(true); }}>\u4FDD\u7559\u672C\u5730\u8349\u7A3F</button>\n </div>}\n </div>}\n {fileError !== undefined && <div className=\"oh-story-error\">{fileError}</div>}\n {selected === undefined\n ? <div className=\"oh-story-empty\">{workbench === \"story\"\n ? <>\u5F53\u524D workspace \u8FD8\u6CA1\u6709\u5C0F\u8BF4\u6587\u4EF6\u3002\u53EF\u5728\u53F3\u4FA7 Chat \u4E2D\u8FD0\u884C <code>/story-setup</code>\u3002</>\n : <>\u5F53\u524D workspace \u8FD8\u6CA1\u6709\u77ED\u5267\u9879\u76EE\u3002\u53EF\u5728\u53F3\u4FA7 Chat \u4E2D\u8FD0\u884C <code>/short-drama</code>\u3002</>}</div>\n : selectedMedia && selectedFile !== undefined\n ? <div className=\"oh-story-media-document\">{selectedFile.mimeType?.startsWith(\"image/\") === true\n ? <img src={endpoint(\"media\", sessionId, selectedFile.path)} alt={selectedFile.path} />\n : selectedFile.mimeType?.startsWith(\"audio/\") === true\n ? <audio src={endpoint(\"media\", sessionId, selectedFile.path)} controls />\n : <video src={endpoint(\"media\", sessionId, selectedFile.path)} controls preload=\"metadata\" />}</div>\n : buffer === undefined\n ? <div className=\"oh-story-empty\">\u6B63\u5728\u52A0\u8F7D {selected}\u2026</div>\n : buffer.missing === true\n ? <div className=\"oh-story-empty\">\u6587\u4EF6\u5DF2\u4ECE workspace \u79FB\u9664\uFF0C\u672C\u5730\u8349\u7A3F\u4ECD\u4FDD\u7559\u3002\u8BF7\u5148\u590D\u5236\u9700\u8981\u7684\u5185\u5BB9\uFF0C\u518D\u653E\u5F03\u8349\u7A3F\u3002<button type=\"button\" onClick={() => {\n setBuffers((current) => {\n const next = { ...current };\n delete next[selected];\n return next;\n });\n setSelected(workspace === undefined ? undefined : preferredWorkbenchFile(workspace.files, workbench));\n }}>\u653E\u5F03\u672C\u5730\u8349\u7A3F</button></div>\n : editorMode === \"production\" && productionAvailable && episodeProduction !== undefined\n ? <DramaProductionView\n sessionId={sessionId}\n production={episodeProduction}\n sessionRunning={sessionRunning}\n queue={productionQueue}\n section={productionSection}\n selectedId={productionSelectedId}\n jobs={productionJobs}\n versions={productionVersions}\n libraryVersions={productionLibrary}\n selections={productionSelections}\n manualReferences={productionReferences}\n sequence={productionSequence}\n canvas={productionCanvas}\n zoom={productionZoom}\n onSectionChange={setProductionSection}\n onSelect={setProductionSelectedId}\n onNavigate={navigateProductionTarget}\n onJobsChange={setProductionJobs}\n onSelectionsChange={setProductionSelections}\n onManualReferencesChange={setProductionReferences}\n onOpenMedia={(path) => { revealPath(path); }}\n onSequenceChange={setProductionSequence}\n onCanvasChange={setProductionCanvas}\n onZoomChange={setProductionZoom}\n onDispatchPrompt={sendProductionPrompt}\n onCancelTurn={cancelProduction}\n onRemoveQueued={removeQueuedProduction}\n onRefresh={reload}\n />\n : previewable && editorMode === \"preview\"\n ? markdown\n ? <MarkdownPreview content={buffer.content} label={selected} />\n : <JsonlPreview content={buffer.content} label={selected} />\n : <textarea\n ref={textareaRef}\n value={buffer.content}\n data-format={structured ? \"structured\" : \"prose\"}\n onBlur={rememberEditorPosition}\n onScroll={rememberEditorPosition}\n onSelect={rememberEditorPosition}\n onChange={(event) => {\n const content = event.target.value;\n setBuffers((current) => ({\n ...current,\n [selected]: {\n content,\n saved: current[selected]?.saved ?? \"\",\n source: \"human\",\n version: current[selected]?.version ?? \"\",\n conflict: current[selected]?.conflict,\n saving: current[selected]?.saving\n }\n }));\n }}\n spellCheck={!structured}\n aria-label={selected}\n />}\n </main>\n </>}\n </div>;\n}\n\ninterface ProductionConversationFace {\n readonly sendProductionPrompt: (prompt: string) => Promise<void>;\n readonly cancelProduction: () => Promise<void>;\n readonly removeQueuedProduction: (itemId: string) => Promise<void>;\n}\n\ntype WorkbenchSlotProps = PropsRuntime<\"oh-story.workspace\"> & PropsStore<ReturnType<typeof createWorkbenchStore>> & ProductionConversationFace;\n\n/**\n * DSH 0.1.7's SessionProvider stopped keying its subtree by Session, so switching Sessions\n * would carry one Session's selection, drafts and dedup guards into the next. Keep the\n * one-mount-per-Session contract the workbench was written against.\n */\nfunction CreativeSplitBridge(props: WorkbenchSlotProps) {\n return <SessionWorkbenchMemory key={props.sessionId} {...props} />;\n}\n\n/** Restore this Session's workbench memory into a fresh Store before anything reads it. */\nfunction SessionWorkbenchMemory(props: WorkbenchSlotProps) {\n const { sessionId, useStore, actions } = props;\n const hydrated = useStore((state) => state.hydrated);\n // Nothing renders from a fresh instance: its initial state would be mirrored over the saved\n // copy, and the workbench's own effects would act on an empty selection.\n useLayoutEffect(() => {\n if (!hydrated) actions.restore(workbenchMemoryBySession.get(sessionId));\n }, [actions, hydrated, sessionId]);\n return hydrated ? <>\n <WorkbenchMemoryMirror sessionId={sessionId} useStore={useStore} />\n <SessionWorkbenchBridge {...props} />\n </> : null;\n}\n\n/** Keeps the page-lifetime copy current without re-rendering the workbench on every edit. */\nfunction WorkbenchMemoryMirror({ sessionId, useStore }: Pick<WorkbenchSlotProps, \"sessionId\" | \"useStore\">) {\n const memory = useStore((state) => state);\n useEffect(() => {\n workbenchMemoryBySession.set(sessionId, memory);\n }, [memory, sessionId]);\n return null;\n}\n\n/** Mount beside the official conversation without replacing Chat or Composer. */\nfunction SessionWorkbenchBridge({ sessionId, useSession, useSessions, useProjection, useChat, useStore, actions, sendProductionPrompt, cancelProduction, removeQueuedProduction }: WorkbenchSlotProps) {\n const marker = useRef<HTMLSpanElement>(null);\n const [target, setTarget] = useState<HTMLElement>();\n const runningCalls = useChat((snapshot) => snapshot.legacy.runningCalls);\n const partial = useChat((snapshot) => streamingAssistant(snapshot.timeline));\n const undispatched = useChat((snapshot) => undispatchedCalls(snapshot), sameUndispatchedCalls);\n const settledMutation = useChat((snapshot) => latestSettledMutation(snapshot));\n const settledMutationTurn = useChat((snapshot) => latestSettledMutationTurn(snapshot));\n const liveTurn = useChat((snapshot) => openTurn(snapshot));\n const workbench = useStore((memory) => memory.workbench);\n const gamePane = useStore((memory) => memory.gamePane);\n const videoPane = useStore((memory) => memory.videoPane);\n const sessionRunning = useSession((snapshot) => snapshot.running);\n const inboxRows = useProjection(\"inbox\", (inbox) => inbox?.[\"next-turn\"]);\n const pendingSubmissions = useSession((snapshot) => snapshot.pendingSubmissions);\n const productionQueue = useMemo(() => productionQueueFromInbox(\n inboxRows,\n new Set(pendingSubmissions.filter((item) => item.placement === \"transcript\").map((item) => item.requestId))\n ), [inboxRows, pendingSubmissions]);\n const chat = useChat((snapshot) => snapshot);\n const productionIntents = useMemo(() => settledProductionIntents(chat), [chat]);\n const { workspace, error, loading: workspaceLoading, reload } = useWorkspace(sessionId);\n const chosenPreference = useStore((memory) => memory.workbenchPreference);\n const creativeProject = hasCreativeProject(workspace);\n // DSH 0.1.7 opens a fresh home straight into a blank Session in its default workspace, so\n // \"no Session yet\" no longer marks a first launch. A blank Session without creative work does.\n const sessionBlank = useSessions((state) => state.byId[sessionId]?.blank === true);\n const welcome = sessionBlank && workspace !== undefined && !workspaceLoading && !creativeProject;\n // The Session Store holds this Session's choice; localStorage carries the workspace's\n // last choice across restarts. Reading it here keeps the decision in the same render\n // that learns the workspace, so a collapsed workbench never flashes the layout open.\n const storedPreference = useMemo(\n () => readWorkbenchPreference(workbenchPreferenceStorage(), workspace?.cwd),\n [workspace?.cwd]\n );\n const preference = chosenPreference ?? storedPreference;\n const open = resolveWorkbenchOpen(preference, creativeProject);\n useLayoutEffect(() => {\n const document = marker.current?.ownerDocument;\n if (document === undefined) return;\n const locate = (): void => {\n // DSH 0.1.7 renders the same conversation content inside the right sidebar's subagent\n // chats, so only this Session's main column is a valid seat.\n const anchor = document.querySelector<HTMLElement>(\n `[data-conversation-content][data-conversation-session=\"${CSS.escape(sessionId)}\"]:not([data-sidebar-chat] *) > [data-conversation-scroll] > [data-slot='conversation.session']`\n );\n setTarget((current) => current === anchor ? current : anchor ?? undefined);\n };\n locate();\n const observer = new MutationObserver(locate);\n observer.observe(document.body, { childList: true, subtree: true });\n return () => { observer.disconnect(); };\n }, [sessionId]);\n useLayoutEffect(() => {\n const scroller = target?.parentElement;\n if (scroller === undefined || scroller === null) return;\n if (!open) {\n // A collapsed workbench returns the conversation to DSH untouched, so the only\n // measurement left is where that column sits: the launcher floats over its corner.\n const publishSeam = (): void => {\n const box = scroller.getBoundingClientRect();\n scroller.style.setProperty(\"--oh-story-seam-top\", `${String(box.top)}px`);\n scroller.style.setProperty(\"--oh-story-seam-right\", `${String(scroller.ownerDocument.documentElement.clientWidth - box.right)}px`);\n };\n publishSeam();\n const seams = new ResizeObserver(publishSeam);\n seams.observe(scroller);\n const view = scroller.ownerDocument.defaultView;\n view?.addEventListener(\"resize\", publishSeam);\n return () => {\n seams.disconnect();\n view?.removeEventListener(\"resize\", publishSeam);\n scroller.style.removeProperty(\"--oh-story-seam-top\");\n scroller.style.removeProperty(\"--oh-story-seam-right\");\n };\n }\n const composerSeat = (): HTMLElement | null => scroller.querySelector(\":scope > [data-composer-seat]\");\n // The seat overlaps the Chat column here, so a reader parked at the tail has\n // to be carried across every layout pass; losing the tail does not merely\n // scroll it out of sight, it leaves the last lines behind the Composer.\n // Being parked cannot be read inside the pass \u2014 a reflow moves the tail\n // before the observer runs \u2014 and it cannot be read from scroll events alone\n // either: the Chat settles over several frames after a resize and every one\n // of those frames scrolls without the reader asking. So only a scroll the\n // reader actually drove releases the tail; reaching the bottom always\n // reclaims it.\n const parkedAtTail = (): boolean => scroller.scrollHeight - scroller.scrollTop - scroller.clientHeight <= 8;\n let parked = parkedAtTail();\n let drivenAt = 0;\n const markDriven = (event: Event): void => {\n if (event.target instanceof Node && composerSeat()?.contains(event.target) === true) return;\n // A button click (for example switching the editor preview) is not a\n // scrollbar drag. Its subsequent reflow must not release the Chat tail.\n if (event.type === \"pointerdown\" && event.target !== scroller) return;\n drivenAt = performance.now();\n };\n const trackParked = (): void => {\n if (parkedAtTail()) parked = true;\n else if (performance.now() - drivenAt < 400) parked = false;\n };\n const publishLayout = (): void => {\n scroller.style.setProperty(\"--oh-story-scroll-height\", `${String(scroller.clientHeight)}px`);\n // DSH 0.1.2 grows the seat with the streaming Todo panel while\n // --dsh-composer-height keeps reporting the bare input height. Publish the\n // measurement beside it rather than over it: the CSS takes the larger, so\n // writing the variable DSH also owns can never turn into a resize duel.\n scroller.style.setProperty(\"--oh-story-composer-height\", `${String(composerSeat()?.getBoundingClientRect().height ?? 0)}px`);\n scroller.dataset.ohStoryWorkbench = workbench;\n const studioPane = workbench === \"video\" ? videoPane : gamePane;\n scroller.dataset.ohStudioPane = studioPane;\n const compactAt = workbench === \"game\" || workbench === \"video\" ? 720 : 620;\n const mediumAt = workbench === \"game\" || workbench === \"video\" ? 960 : 900;\n const layout = scroller.clientWidth < compactAt ? \"compact\" : scroller.clientWidth < mediumAt ? \"medium\" : \"wide\";\n if (scroller.dataset.ohStoryLayout !== layout) scroller.dataset.ohStoryLayout = layout;\n if (parked) scroller.scrollTop = scroller.scrollHeight - scroller.clientHeight;\n };\n const observer = new ResizeObserver(publishLayout);\n const observed = new WeakSet<Element>();\n // The official seat and Chat flow mount and remount independently of this\n // bridge. The flow is observed because a resized Chat keeps re-wrapping for\n // several frames afterwards: pinning once against the height the first frame\n // reports leaves the reader behind the Composer again once it settles.\n let flowObserved = false;\n const observePanes = (): void => {\n const flow = scroller.querySelector(\"[data-chat-flow]:not([data-step-process-content])\");\n flowObserved = flow !== null;\n for (const pane of [composerSeat(), flow]) {\n if (pane === null || observed.has(pane)) continue;\n observed.add(pane);\n observer.observe(pane);\n }\n };\n publishLayout();\n scroller.addEventListener(\"scroll\", trackParked, { passive: true });\n for (const driven of [\"wheel\", \"touchmove\", \"pointerdown\", \"keydown\"]) {\n scroller.addEventListener(driven, markDriven, { passive: true });\n }\n observer.observe(scroller);\n observePanes();\n const seats = new MutationObserver(() => { observePanes(); publishLayout(); });\n seats.observe(scroller, { childList: true });\n // The flow mounts below the seat's level, and streaming mutates it token by\n // token: watch the subtree only until it has been found once.\n const panes = new MutationObserver(() => { if (!flowObserved) observePanes(); });\n panes.observe(scroller, { childList: true, subtree: true });\n return () => {\n panes.disconnect();\n scroller.removeEventListener(\"scroll\", trackParked);\n for (const driven of [\"wheel\", \"touchmove\", \"pointerdown\", \"keydown\"]) {\n scroller.removeEventListener(driven, markDriven);\n }\n observer.disconnect();\n seats.disconnect();\n scroller.style.removeProperty(\"--oh-story-scroll-height\");\n scroller.style.removeProperty(\"--oh-story-composer-height\");\n delete scroller.dataset.ohStoryLayout;\n delete scroller.dataset.ohStoryWorkbench;\n delete scroller.dataset.ohStudioPane;\n };\n }, [gamePane, open, target, videoPane, workbench]);\n return <>\n <span ref={marker} className=\"oh-story-bridge-marker\" aria-hidden />\n {target === undefined ? null : createPortal(<CreativeWorkbench\n sessionId={sessionId}\n runningCalls={runningCalls}\n partial={partial}\n undispatched={sessionRunning ? undispatched : NO_UNDISPATCHED_CALLS}\n settledMutation={settledMutation}\n settledMutationTurn={settledMutationTurn}\n liveTurn={liveTurn}\n sessionRunning={sessionRunning}\n productionQueue={productionQueue}\n productionIntents={productionIntents}\n workspace={workspace}\n error={error}\n workspaceLoading={workspaceLoading}\n reload={reload}\n open={open}\n creativeProject={creativeProject}\n welcome={welcome}\n sendProductionPrompt={sendProductionPrompt}\n cancelProduction={cancelProduction}\n removeQueuedProduction={removeQueuedProduction}\n useStore={useStore}\n actions={actions}\n />, target)}\n </>;\n}\n\ntype WorkbenchSeatProps = PropsRuntime<\"shell.overlay\"> & PropsRenderSlots<\"oh-story.workspace\">;\n\n/** How to reach the workbench from a DSH that has no creative work open yet. */\nfunction WelcomeGuide() {\n return <section className=\"oh-story-welcome\" aria-label=\"Oh Story \u4F7F\u7528\u5F15\u5BFC\">\n <style>{styles}</style>\n <h2>Oh Story \u5DF2\u52A0\u8F7D</h2>\n <p>\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</p>\n <ol>\n <li>\u70B9\u51FB\u5DE6\u4FA7\u300C\u5DE5\u4F5C\u533A / Workspaces\u300D\u65C1\u7684\u300C\u6DFB\u52A0\u5DE5\u4F5C\u533A / Add workspace\u300D\uFF0C\u9009\u62E9\u5B58\u653E\u4F5C\u54C1\u7684\u6587\u4EF6\u5939\u3002</li>\n <li>\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</li>\n <li>\u7A7A\u76EE\u5F55\uFF08\u5305\u62EC DSH \u81EA\u52A8\u5EFA\u7ACB\u7684\u300C\u9ED8\u8BA4\u5DE5\u4F5C\u533A / Default workspace\u300D\uFF09\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</li>\n </ol>\n <p>\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 <code>/story</code>\u3001<code>/short-drama</code>\u3001<code>/novel-to-game quick</code> \u6216 <code>/video-recap</code>\u3002</p>\n </section>;\n}\n\n/** Without any Session the session-scoped workbench cannot mount, so the guide mounts on its own. */\nfunction WorkbenchWelcome() {\n const marker = useRef<HTMLSpanElement>(null);\n const [target, setTarget] = useState<HTMLElement>();\n useLayoutEffect(() => {\n const document = marker.current?.ownerDocument;\n if (document === undefined) return;\n const locate = (): void => {\n const anchor = document.querySelector<HTMLElement>(\"[data-conversation-content]:not([data-sidebar-chat] *) > [data-conversation-scroll]\");\n setTarget((current) => current === anchor ? current : anchor ?? undefined);\n };\n locate();\n const observer = new MutationObserver(locate);\n observer.observe(document.body, { childList: true, subtree: true });\n return () => { observer.disconnect(); };\n }, []);\n return <>\n <span ref={marker} className=\"oh-story-bridge-marker\" aria-hidden />\n {target === undefined ? null : createPortal(<WelcomeGuide />, target)}\n </>;\n}\n\nfunction WorkbenchSeat({ SessionProvider, renderSlot }: WorkbenchSeatProps) {\n return <SessionProvider empty={() => <WorkbenchWelcome />}>{renderSlot(\"oh-story.workspace\", {})}</SessionProvider>;\n}\n\nfunction argsOf(block: ToolCallViewProps[\"block\"]): Record<string, unknown> {\n const raw = (\"kind\" in block ? block.call?.argsRaw : block.phase === \"start\" ? block.argsRaw : undefined) ?? \"{}\";\n try {\n const value = JSON.parse(raw) as unknown;\n return typeof value === \"object\" && value !== null && !Array.isArray(value) ? value as Record<string, unknown> : {};\n } catch { return {}; }\n}\n\nfunction resultOf(block: ToolCallViewProps[\"block\"]): string | undefined {\n if (!(\"kind\" in block)) return undefined;\n return block.content.map((item) => item.type === \"text\" ? item.text : JSON.stringify(item, null, 2)).join(\"\\n\");\n}\n\nfunction RoleToolView({ block, inspect }: ToolCallViewProps) {\n const args = argsOf(block);\n const role = typeof args.role === \"string\" ? args.role : \"story-role\";\n const output = resultOf(block);\n const state = !(\"kind\" in block) ? \"running\" : block.isError ? \"error\" : \"done\";\n return <details className=\"oh-story-role\" data-state={state}>\n <style>{styles}</style>\n <summary><span>\u2726 Role</span><strong>{role}</strong><em>{state === \"running\" ? \"\u8FD0\u884C\u4E2D\" : state === \"error\" ? \"\u5931\u8D25\" : \"\u5B8C\u6210\"}</em></summary>\n {output !== undefined && <pre>{output}</pre>}\n {inspect !== undefined && <button type=\"button\" onClick={inspect}>\u5728\u8F68\u8FF9\u4E2D\u68C0\u67E5</button>}\n </details>;\n}\n\nfunction ProductionToolView({ block, inspect }: ToolCallViewProps) {\n const args = argsOf(block);\n const action = typeof args.action === \"string\" ? args.action : \"production\";\n const episode = typeof args.episode === \"string\" ? args.episode : \"\u77ED\u5267\";\n const state = !(\"kind\" in block) ? \"running\" : block.isError ? \"error\" : \"done\";\n return <details className=\"oh-story-role\" data-state={state}>\n <style>{styles}</style>\n <summary><span>\u25A6 \u751F\u4EA7</span><strong>{episode} \u00B7 {action}</strong><em>{state === \"running\" ? \"\u6267\u884C\u4E2D\" : state === \"error\" ? \"\u5931\u8D25\" : \"\u5DF2\u5E94\u7528\"}</em></summary>\n {resultOf(block) !== undefined && <pre>{resultOf(block)}</pre>}\n {inspect !== undefined && <button type=\"button\" onClick={inspect}>\u5728\u8F68\u8FF9\u4E2D\u68C0\u67E5</button>}\n </details>;\n}\n\n/** Register only official DSH surfaces; the split bridge never replaces Chat. */\nexport function apply(context: ClientContext): void {\n context.slots.inject(\"shell.overlay\", () => {\n const disposeSeat = context.slots.register({\n name: \"shell.overlay\",\n id: \"oh-story-workspace\",\n order: -100,\n children: { \"oh-story.workspace\": { kind: \"single\", scope: \"session\" } }\n }, WorkbenchSeat);\n const disposeWorkbench = context.slots.register({\n name: \"oh-story.workspace\",\n store: createWorkbenchStore,\n inject: (sessionId) => {\n const binding = (context.sessions as unknown as ISessions).binding(sessionId);\n const conversation = binding?.ctx.get(\"conversation\");\n if (binding === undefined || conversation === undefined) {\n return {\n sendProductionPrompt: () => Promise.reject(new Error(\"DSH \u4F1A\u8BDD\u5F53\u524D\u4E0D\u53EF\u7528\u3002\")),\n cancelProduction: () => Promise.reject(new Error(\"DSH \u4F1A\u8BDD\u5F53\u524D\u4E0D\u53EF\u7528\u3002\")),\n removeQueuedProduction: () => Promise.reject(new Error(\"DSH \u4F1A\u8BDD\u5F53\u524D\u4E0D\u53EF\u7528\u3002\"))\n };\n }\n return {\n sendProductionPrompt: (prompt: string) => conversation.send(prompt),\n cancelProduction: () => conversation.cancel(),\n removeQueuedProduction: (itemId: string) => conversation.updateQueue(itemId as Parameters<IConversation[\"updateQueue\"]>[0], { kind: \"remove\" })\n };\n }\n }, CreativeSplitBridge);\n return [disposeSeat, disposeWorkbench];\n });\n context.slots.inject(\"tool.call.toolview\", () => context.slots.register({\n name: \"tool.call.toolview\",\n key: \"oh_story_role\"\n }, RoleToolView));\n context.slots.inject(\"tool.call.toolview\", () => context.slots.register({\n name: \"tool.call.toolview\",\n key: OH_STORY_PRODUCTION_TOOL_NAME\n }, ProductionToolView));\n}\n\nexport default { name, inject, apply };\n", "import type { AssistantChatData, ChatSnapshot } from \"@deepseek-ai/dsh-client-ui-chat/client\";\nimport type {\n ConversationTimelineSnapshot,\n PartialAssistant,\n RunningToolCall,\n ToolCallBlock\n} from \"@deepseek-ai/dsh-client-ui-conversation/client\";\n\nexport type MutationToolName = \"write\" | \"edit\" | \"str_replace_editor\";\n\nexport interface FileMutationActivity {\n readonly callId: string;\n readonly name: MutationToolName;\n readonly argsRaw: string;\n readonly stage: \"streaming\" | \"running\";\n readonly path: string | undefined;\n readonly operation: \"replace-file\" | \"replace-text\" | \"insert-text\" | undefined;\n readonly oldText: string | undefined;\n readonly newText: string | undefined;\n readonly replaceAll: boolean;\n}\n\ninterface JsonStringPrefix {\n readonly value: string;\n readonly complete: boolean;\n}\n\nexport type WorkbenchMode = \"story\" | \"drama\" | \"game\" | \"video\";\n\nconst WORKBENCH_LABELS: Readonly<Record<WorkbenchMode, string>> = {\n story: \"\u5C0F\u8BF4\",\n drama: \"\u77ED\u5267\",\n game: \"\u6E38\u620F\",\n video: \"\u89C6\u9891\"\n};\n\nexport function workbenchLabel(mode: WorkbenchMode): string {\n return WORKBENCH_LABELS[mode];\n}\n\nexport interface WorkspaceFilePath {\n readonly path: string;\n}\n\nconst STORY_DIRECTORIES = new Set([\"\u6B63\u6587\", \"\u5927\u7EB2\", \"\u8BBE\u5B9A\", \"\u8FFD\u8E2A\", \"\u5BF9\u6807\", \"\u53C2\u8003\u8D44\u6599\"]);\nconst DRAMA_DIRECTORIES = new Set([\"\u8F93\u5165\", \"\u9879\u76EE\u5F00\u53D1\", \"\u8BBE\u5B9A\u96C6\", \"\u5267\u96C6\", \"\u4EA4\u4ED8\", \"\u521B\u4F5C\u8005\u51B3\u7B56\", \"\u5BA1\u67E5\"]);\nconst GAME_DIRECTORY = \"game-adaptations\";\nconst VIDEO_DIRECTORY = \"video-recaps\";\nconst EDITABLE_EXTENSION = /\\.(?:md|txt|json|jsonl|html|css|[cm]?js|tsx?|jsx)$/iu;\nconst MUTATING_CALLS = new Set([\"write\", \"edit\", \"str_replace_editor\", \"bash\", \"run_code\", \"oh_story_role\"]);\n\n/** Read the latest running Assistant step, including tool-only steps hidden from the Chat list. */\nexport function streamingAssistant(timeline: ConversationTimelineSnapshot): PartialAssistant | null {\n for (const turnNumber of timeline.turnOrder.toReversed()) {\n const turn = timeline.turns.get(turnNumber);\n if (turn === undefined) continue;\n for (const step of turn.steps.toReversed()) {\n const assistant: AssistantChatData | undefined = step.data.get(\"assistant-step\");\n if (assistant?.status === \"running\") return assistant;\n }\n }\n return null;\n}\n\nfunction decodeEscape(character: string): string | undefined {\n switch (character) {\n case \"\\\"\": return \"\\\"\";\n case \"\\\\\": return \"\\\\\";\n case \"/\": return \"/\";\n case \"b\": return \"\\b\";\n case \"f\": return \"\\f\";\n case \"n\": return \"\\n\";\n case \"r\": return \"\\r\";\n case \"t\": return \"\\t\";\n default: return undefined;\n }\n}\n\n/** Read a JSON string even while the model is still streaming its closing quote. */\nexport function jsonStringPrefix(raw: string, key: string): JsonStringPrefix | undefined {\n const match = new RegExp(`\"${key.replace(/[.*+?^${}()|[\\]\\\\]/gu, \"\\\\$&\")}\"\\\\s*:\\\\s*\"`, \"u\").exec(raw);\n if (match === null) return undefined;\n let value = \"\";\n for (let index = match.index + match[0].length; index < raw.length; index += 1) {\n const character = raw[index] ?? \"\";\n if (character === \"\\\"\") return { value, complete: true };\n if (character !== \"\\\\\") { value += character; continue; }\n const escape = raw[index + 1];\n if (escape === undefined) return { value, complete: false };\n if (escape === \"u\") {\n const hex = raw.slice(index + 2, index + 6);\n if (!/^[\\da-f]{4}$/iu.test(hex)) return { value, complete: false };\n value += String.fromCharCode(Number.parseInt(hex, 16));\n index += 5;\n continue;\n }\n const decoded = decodeEscape(escape);\n if (decoded === undefined) return { value, complete: false };\n value += decoded;\n index += 1;\n }\n return { value, complete: false };\n}\n\nfunction completedString(raw: string, key: string): string | undefined {\n const value = jsonStringPrefix(raw, key);\n return value?.complete === true ? value.value : undefined;\n}\n\nfunction parsedArgs(raw: string): Record<string, unknown> | undefined {\n try {\n const value = JSON.parse(raw) as unknown;\n return typeof value === \"object\" && value !== null && !Array.isArray(value) ? value as Record<string, unknown> : undefined;\n } catch { return undefined; }\n}\n\nfunction mutationFromArgs(name: string, callId: string, argsRaw: string, stage: FileMutationActivity[\"stage\"]): FileMutationActivity | undefined {\n const complete = parsedArgs(argsRaw);\n if (name === \"write\") {\n return {\n callId, name, argsRaw, stage,\n path: jsonStringPrefix(argsRaw, \"file_path\")?.value,\n operation: \"replace-file\",\n oldText: undefined,\n newText: jsonStringPrefix(argsRaw, \"content\")?.value,\n replaceAll: false\n };\n }\n if (name === \"edit\") {\n return {\n callId, name, argsRaw, stage,\n path: jsonStringPrefix(argsRaw, \"file_path\")?.value,\n operation: \"replace-text\",\n oldText: completedString(argsRaw, \"old_string\"),\n newText: jsonStringPrefix(argsRaw, \"new_string\")?.value,\n replaceAll: complete?.replace_all === true\n };\n }\n if (name !== \"str_replace_editor\") return undefined;\n const command = completedString(argsRaw, \"command\");\n if (command === \"view\") return undefined;\n const path = jsonStringPrefix(argsRaw, \"path\")?.value;\n if (command === \"create\") {\n return {\n callId, name, argsRaw, stage, path,\n operation: \"replace-file\",\n oldText: undefined,\n newText: jsonStringPrefix(argsRaw, \"file_text\")?.value,\n replaceAll: false\n };\n }\n if (command === \"str_replace\") {\n return {\n callId, name, argsRaw, stage, path,\n operation: \"replace-text\",\n oldText: completedString(argsRaw, \"old_str\"),\n newText: jsonStringPrefix(argsRaw, \"new_str\")?.value ?? (complete !== undefined ? \"\" : undefined),\n replaceAll: complete?.replace_all === true\n };\n }\n if (command === \"insert\") {\n return {\n callId, name, argsRaw, stage, path,\n operation: \"insert-text\",\n oldText: undefined,\n newText: jsonStringPrefix(argsRaw, \"new_str\")?.value,\n replaceAll: false\n };\n }\n return { callId, name, argsRaw, stage, path, operation: undefined, oldText: undefined, newText: undefined, replaceAll: false };\n}\n\nfunction visitRunning(blocks: readonly ToolCallBlock[], visit: (call: RunningToolCall) => void): void {\n for (const block of blocks) {\n if (!(\"kind\" in block)) visit(block);\n visitRunning(block.subCalls, visit);\n }\n}\n\n/** A call a finished Assistant step issued that DSH has not settled yet. */\nexport interface UndispatchedCall {\n readonly callId: string;\n readonly name: string;\n readonly argsRaw: string;\n}\n\n/**\n * Calls of the open Turn whose Assistant step has finished streaming but that have no result yet.\n * DSH 0.1.7 hides such a call's tool row until its durable `tool/call` event \u2014 through pre-execute\n * hooks and any approval \u2014 so it is in neither `partial` nor the running calls, and a call it does\n * list stays `preparing` without arguments. The step's own tool-call block still holds them.\n */\nexport function undispatchedCalls(chat: ChatSnapshot): UndispatchedCall[] {\n const turnNumber = chat.timeline.turnOrder.at(-1);\n const turn = turnNumber === undefined ? undefined : chat.timeline.turns.get(turnNumber);\n // Only a closed Turn is finished: a Turn whose start fell outside the loaded history window\n // reports `unknown` while it still runs. Callers pass the result only while the Session runs.\n if (turn === undefined || turn.status === \"closed\") return [];\n const calls: UndispatchedCall[] = [];\n for (const step of turn.steps) {\n const assistant: AssistantChatData | undefined = step.data.get(\"assistant-step\");\n if (assistant?.status !== \"settled\") continue;\n for (const block of assistant.blocks) {\n if (block.kind === \"tool-call\") calls.push({ callId: block.callId, name: block.name, argsRaw: block.argsRaw });\n }\n }\n if (calls.length === 0) return calls;\n const settled = new Set<string>();\n for (const node of chat.legacy.nodes as readonly unknown[]) {\n const value = node as { readonly kind?: unknown; readonly callId?: unknown };\n if (value.kind === \"tool-result\" && typeof value.callId === \"string\") settled.add(value.callId);\n }\n return calls.filter((call) => !settled.has(call.callId));\n}\n\nexport function sameUndispatchedCalls(left: readonly UndispatchedCall[], right: readonly UndispatchedCall[]): boolean {\n return left.length === right.length && left.every((call, index) => (\n call.callId === right[index]?.callId && call.argsRaw === right[index].argsRaw\n ));\n}\n\n/** Return every active file mutation in official DSH dispatch order, including nested Code Mode calls. */\nexport function fileMutations(\n runningCalls: readonly RunningToolCall[],\n partial: PartialAssistant | null = null,\n undispatched: readonly UndispatchedCall[] = []\n): FileMutationActivity[] {\n const values: FileMutationActivity[] = [];\n visitRunning(runningCalls, (call) => {\n // A preparing call has no arguments; they come from `partial` or its finished step below.\n if (call.phase !== \"start\") return;\n const mutation = mutationFromArgs(call.name, call.callId, call.argsRaw, \"running\");\n if (mutation !== undefined) values.push(mutation);\n });\n for (const call of undispatched) {\n if (values.some((candidate) => candidate.callId === call.callId)) continue;\n const mutation = mutationFromArgs(call.name, call.callId, call.argsRaw, \"running\");\n if (mutation !== undefined) values.push(mutation);\n }\n for (const block of partial?.blocks ?? []) {\n if (block.kind !== \"tool-call\") continue;\n const value = mutationFromArgs(block.name, block.callId, block.argsRaw, \"streaming\");\n if (value !== undefined && !values.some((candidate) => candidate.callId === value.callId)) values.push(value);\n }\n return values;\n}\n\n/** Running calls whose settlement may have changed creative files. */\nexport function mutatingCallIds(runningCalls: readonly RunningToolCall[]): ReadonlySet<string> {\n const ids = new Set<string>();\n visitRunning(runningCalls, (call) => { if (MUTATING_CALLS.has(call.name)) ids.add(call.callId); });\n return ids;\n}\n\nfunction settledMutationSignals(block: ToolCallBlock): string[] {\n const nested = block.subCalls.flatMap(settledMutationSignals);\n if (!(\"kind\" in block) || block.isError) return nested;\n if (block.call === null) return nested;\n const mutation = mutationFromArgs(block.call.name, block.callId, block.call.argsRaw, \"running\");\n return mutation?.path === undefined ? nested : [`${block.callId}\\0${mutation.path}`, ...nested];\n}\n\nfunction latestSettledWrite(chat: ChatSnapshot): { readonly signal: string; readonly turn: number | undefined } | undefined {\n for (const key of chat.order.toReversed()) {\n const node = chat.nodes.get(key);\n if (node?.kind !== \"tool-call\") continue;\n const root = (node.data as { readonly root?: ToolCallBlock }).root;\n const signal = root === undefined ? undefined : settledMutationSignals(root).at(-1);\n if (signal === undefined) continue;\n const location = node.location;\n return { signal, turn: location.kind === \"turn\" || location.kind === \"step\" ? location.turn.turn : undefined };\n }\n return undefined;\n}\n\n/** Latest durable successful mutation, used when a fast call skips the live render window. */\nexport function latestSettledMutation(chat: ChatSnapshot): string | undefined {\n return latestSettledWrite(chat)?.signal;\n}\n\n/** The Turn that produced {@link latestSettledMutation}, when the Chat still locates it. */\nexport function latestSettledMutationTurn(chat: ChatSnapshot): number | undefined {\n return latestSettledWrite(chat)?.turn;\n}\n\n/** The last Turn while it is open. A reloaded Session shows history Turns as closed. */\nexport function openTurn(chat: ChatSnapshot): number | undefined {\n const turnNumber = chat.timeline.turnOrder.at(-1);\n if (turnNumber === undefined) return undefined;\n return chat.timeline.turns.get(turnNumber)?.status === \"open\" ? turnNumber : undefined;\n}\n\n/** Convert a DSH tool path to the creative-relative path accepted by the narrow route. */\nexport function creativeRelativePath(path: string | undefined, cwd: string | undefined): string | undefined {\n if (path === undefined || path === \"\") return undefined;\n const normalized = path.replaceAll(\"\\\\\", \"/\");\n const root = cwd?.replaceAll(\"\\\\\", \"/\").replace(/\\/$/u, \"\");\n const insideRoot = root !== undefined && normalized.startsWith(`${root}/`);\n if ((normalized.startsWith(\"/\") || /^[a-z]:\\//iu.test(normalized) || normalized.startsWith(\"file:\")) && !insideRoot) return undefined;\n const relative = insideRoot ? normalized.slice(root.length + 1) : normalized.replace(/^\\.\\//u, \"\");\n const [directory] = relative.split(\"/\", 1);\n const creative = directory !== undefined && (STORY_DIRECTORIES.has(directory) || DRAMA_DIRECTORIES.has(directory) || directory === GAME_DIRECTORY || directory === VIDEO_DIRECTORY);\n if ((!creative && relative !== \"short-drama.json\") || !EDITABLE_EXTENSION.test(relative)) return undefined;\n if (relative.split(\"/\").some((part) => part === \"..\" || part === \".\" || part === \"\")) return undefined;\n return relative;\n}\n\nexport function workbenchModeForPath(path: string | undefined): WorkbenchMode | undefined {\n if (path === \"short-drama.json\") return \"drama\";\n const directory = path?.split(\"/\", 1)[0];\n if (directory !== undefined && STORY_DIRECTORIES.has(directory)) return \"story\";\n if (directory !== undefined && DRAMA_DIRECTORIES.has(directory)) return \"drama\";\n if (directory === GAME_DIRECTORY) return \"game\";\n if (directory === VIDEO_DIRECTORY) return \"video\";\n return undefined;\n}\n\n/** Choose the first useful document when a creative workbench opens. */\nexport function preferredWorkbenchFile(\n files: readonly WorkspaceFilePath[],\n mode: WorkbenchMode\n): string | undefined {\n const matching = files.filter((file) => workbenchModeForPath(file.path) === mode);\n const preferences = mode === \"story\"\n ? [/^\u6B63\u6587\\/.*\\.md$/u, /^\u5927\u7EB2\\/.*\\.md$/u, /\\.md$/u]\n : mode === \"drama\" ? [\n /^\u5267\u96C6\\/EP0*1\\/\u5267\u672C\\.md$/u,\n /^\u5267\u96C6\\/.*\\/\u5267\u672C\\.md$/u,\n /^\u5267\u96C6\\/EP0*1\\/screenplay\\.md$/iu,\n /^\u5267\u96C6\\/.*\\/screenplay\\.md$/iu,\n /^\u9879\u76EE\u5F00\u53D1\\/creative-brief\\.md$/u,\n /^\u8F93\u5165\\/.*\\.md$/u,\n /\\.md$/u,\n /^short-drama\\.json$/u\n ] : mode === \"game\" ? [\n /^game-adaptations\\/[^/]+\\/PRODUCT_BRIEF\\.md$/u,\n /^game-adaptations\\/[^/]+\\/design\\/GAME_DESIGN\\.md$/u,\n /^game-adaptations\\/[^/]+\\/qa\\/verification\\.json$/u,\n /^game-adaptations\\/[^/]+\\/build\\/app\\/index\\.html$/u,\n /\\.md$/u\n ] : [\n /^video-recaps\\/[^/]+\\/work\\/recap_story_plan\\.json$/u,\n /^video-recaps\\/[^/]+\\/work\\/narration\\.json$/u,\n /^video-recaps\\/[^/]+\\/work\\/assembly_manifest\\.json$/u\n ];\n for (const pattern of preferences) {\n const match = matching.find((file) => pattern.test(file.path));\n if (match !== undefined) return match.path;\n }\n return matching[0]?.path;\n}\n\n/** Project one streamed mutation over its immediate predecessor. */\nexport function previewMutation(activity: FileMutationActivity, base: string): string | undefined {\n if (activity.operation === \"replace-file\") return activity.newText;\n if (activity.operation === \"replace-text\") {\n if (activity.oldText === undefined || activity.newText === undefined || activity.oldText === \"\") return undefined;\n if (activity.replaceAll) return base.includes(activity.oldText) ? base.split(activity.oldText).join(activity.newText) : undefined;\n const at = base.indexOf(activity.oldText);\n return at < 0 ? undefined : `${base.slice(0, at)}${activity.newText}${base.slice(at + activity.oldText.length)}`;\n }\n if (activity.operation === \"insert-text\") {\n if (activity.newText === undefined) return undefined;\n const rawLine = /\"insert_line\"\\s*:\\s*(\\d+)/u.exec(activity.argsRaw)?.[1];\n if (rawLine === undefined) return undefined;\n const line = Number.parseInt(rawLine, 10);\n const parts = base.split(\"\\n\");\n const at = Math.max(0, Math.min(parts.length, line));\n parts.splice(at, 0, activity.newText);\n return parts.join(\"\\n\");\n }\n return undefined;\n}\n", "export interface FileTreeInput {\n readonly path: string;\n readonly bytes: number;\n}\n\nexport interface FileTreeFile {\n readonly kind: \"file\";\n readonly name: string;\n readonly path: string;\n readonly bytes: number;\n}\n\nexport interface FileTreeDirectory {\n readonly kind: \"directory\";\n readonly name: string;\n readonly path: string;\n readonly fileCount: number;\n readonly children: readonly FileTreeNode[];\n}\n\nexport type FileTreeNode = FileTreeFile | FileTreeDirectory;\n\ninterface MutableDirectory {\n readonly name: string;\n readonly path: string;\n readonly directories: Map<string, MutableDirectory>;\n readonly files: FileTreeFile[];\n}\n\nfunction directory(name: string, path: string): MutableDirectory {\n return { name, path, directories: new Map(), files: [] };\n}\n\nfunction compareNames(left: { readonly name: string }, right: { readonly name: string }): number {\n return left.name.localeCompare(right.name, \"zh-Hans-CN\", { numeric: true });\n}\n\nfunction freezeDirectory(value: MutableDirectory): FileTreeDirectory {\n const directories = [...value.directories.values()].map(freezeDirectory).sort(compareNames);\n const files = [...value.files].sort(compareNames);\n return {\n kind: \"directory\",\n name: value.name,\n path: value.path,\n fileCount: files.length + directories.reduce((sum, child) => sum + child.fileCount, 0),\n children: [...directories, ...files]\n };\n}\n\nexport function buildFileTree(files: readonly FileTreeInput[], group: string): readonly FileTreeNode[] {\n const root = directory(group, group);\n for (const file of files) {\n const relative = file.path.startsWith(`${group}/`) ? file.path.slice(group.length + 1) : file.path;\n const segments = relative.split(\"/\").filter((segment) => segment !== \"\");\n const name = segments.pop();\n if (name === undefined) continue;\n let parent = root;\n for (const segment of segments) {\n const path = `${parent.path}/${segment}`;\n const child = parent.directories.get(segment) ?? directory(segment, path);\n parent.directories.set(segment, child);\n parent = child;\n }\n parent.files.push({ kind: \"file\", name, path: file.path, bytes: file.bytes });\n }\n return freezeDirectory(root).children;\n}\n", "const TITLE_KEYS = [\n \"display_name\", \"title\", \"name\", \"shot_id\", \"scene_id\", \"episode_id\", \"character_id\",\n \"location_id\", \"view_id\", \"prop_id\", \"state_id\", \"decision_id\", \"occurrence_id\", \"record_id\", \"id\"\n] as const;\n\nexport interface JsonlRecord {\n readonly line: number;\n readonly raw: string;\n readonly value?: unknown;\n readonly title: string;\n readonly type?: string;\n readonly status?: string;\n readonly error?: string;\n}\n\nfunction objectRecord(value: unknown): Record<string, unknown> | undefined {\n return typeof value === \"object\" && value !== null && !Array.isArray(value) ? value as Record<string, unknown> : undefined;\n}\n\nfunction stringField(record: Record<string, unknown>, keys: readonly string[]): string | undefined {\n for (const key of keys) {\n const value = record[key];\n if (typeof value === \"string\" && value.trim() !== \"\") return value;\n }\n return undefined;\n}\n\nfunction metadata(value: unknown, line: number): Pick<JsonlRecord, \"title\" | \"type\" | \"status\"> {\n const record = objectRecord(value);\n if (record === undefined) return { title: typeof value === \"string\" ? value : JSON.stringify(value) ?? `\u7B2C ${String(line)} \u884C` };\n const type = stringField(record, [\"record_type\", \"type\", \"kind\"]);\n const acceptance = objectRecord(record.creator_acceptance);\n const status = stringField(record, [\"status\"]) ?? (acceptance === undefined ? undefined : stringField(acceptance, [\"status\"]));\n return {\n title: stringField(record, TITLE_KEYS) ?? `\u8BB0\u5F55 ${String(line)}`,\n ...(type === undefined ? {} : { type }),\n ...(status === undefined ? {} : { status })\n };\n}\n\nexport function parseJsonl(content: string): JsonlRecord[] {\n const records: JsonlRecord[] = [];\n const lines = content.replaceAll(\"\\r\\n\", \"\\n\").split(\"\\n\");\n for (const [index, raw] of lines.entries()) {\n if (raw.trim() === \"\") continue;\n try {\n const value = JSON.parse(raw) as unknown;\n records.push({ line: index + 1, raw, value, ...metadata(value, index + 1) });\n } catch (error) {\n records.push({\n line: index + 1,\n raw,\n title: `\u7B2C ${String(index + 1)} \u884C\u683C\u5F0F\u9519\u8BEF`,\n error: error instanceof Error ? error.message : String(error)\n });\n }\n }\n return records;\n}\n\nconst PREVIEW_LIMIT = 200;\n\nexport function JsonlPreview({ content, label }: { readonly content: string; readonly label: string }) {\n const records = parseJsonl(content);\n if (records.length === 0) return <div className=\"oh-story-markdown-empty\">\u8FD9\u4E2A JSONL \u6587\u4EF6\u8FD8\u662F\u7A7A\u7684\u3002</div>;\n const valid = records.filter((record) => record.error === undefined).length;\n const errors = records.length - valid;\n const visible = records.slice(0, PREVIEW_LIMIT);\n return <section className=\"oh-story-jsonl\" aria-label={`${label} \u7ED3\u6784\u5316\u9884\u89C8`}>\n <header className=\"oh-story-jsonl-summary\">\n <strong>{errors === 0 ? `${String(valid)} \u6761\u8BB0\u5F55` : `${String(valid)} \u6761\u6709\u6548\u8BB0\u5F55`}</strong>\n {errors > 0 && <span>{String(errors)} \u6761\u683C\u5F0F\u9519\u8BEF</span>}\n {records.length > PREVIEW_LIMIT && <span>\u4EC5\u663E\u793A\u524D {String(PREVIEW_LIMIT)} \u6761</span>}\n </header>\n <div className=\"oh-story-jsonl-records\">\n {visible.map((record) => record.error === undefined\n ? <details key={record.line} open={records.length <= 2}>\n <summary>\n <span>\u7B2C {String(record.line)} \u884C</span>\n <strong>{record.title}</strong>\n {record.type !== undefined && <code>{record.type}</code>}\n {record.status !== undefined && <em>{record.status}</em>}\n </summary>\n <pre><code>{JSON.stringify(record.value, null, 2)}</code></pre>\n </details>\n : <div className=\"oh-story-jsonl-error\" key={record.line} role=\"alert\">\n <strong>{record.title}</strong>\n <span>{record.error}</span>\n <pre>{record.raw}</pre>\n </div>)}\n </div>\n </section>;\n}\n", "import type { ReactNode } from \"react\";\n\nconst INLINE = /(`[^`\\n]+`|\\*\\*[^*\\n]+\\*\\*|~~[^~\\n]+~~|\\[[^\\]\\n]+\\]\\(https?:\\/\\/[^)\\s]+\\)|\\*[^*\\n]+\\*)/gu;\n\nfunction inline(source: string, key: string): ReactNode[] {\n const nodes: ReactNode[] = [];\n let cursor = 0;\n for (const match of source.matchAll(INLINE)) {\n const token = match[0];\n const index = match.index;\n if (index > cursor) nodes.push(source.slice(cursor, index));\n if (token.startsWith(\"`\")) nodes.push(<code key={`${key}-${String(index)}`}>{token.slice(1, -1)}</code>);\n else if (token.startsWith(\"**\")) nodes.push(<strong key={`${key}-${String(index)}`}>{token.slice(2, -2)}</strong>);\n else if (token.startsWith(\"~~\")) nodes.push(<del key={`${key}-${String(index)}`}>{token.slice(2, -2)}</del>);\n else if (token.startsWith(\"*\")) nodes.push(<em key={`${key}-${String(index)}`}>{token.slice(1, -1)}</em>);\n else {\n const link = /^\\[([^\\]]+)\\]\\((https?:\\/\\/[^)\\s]+)\\)$/u.exec(token);\n nodes.push(link === null ? token : <a key={`${key}-${String(index)}`} href={link[2]} target=\"_blank\" rel=\"noreferrer\">{link[1]}</a>);\n }\n cursor = index + token.length;\n }\n if (cursor < source.length) nodes.push(source.slice(cursor));\n return nodes;\n}\n\ntype Alignment = \"left\" | \"center\" | \"right\" | undefined;\ninterface ListItem { readonly text: string; readonly checked?: boolean }\n\nexport type MarkdownBlock =\n | { readonly kind: \"code\"; readonly lines: readonly string[]; readonly language?: string }\n | { readonly kind: \"heading\"; readonly text: string; readonly level: number }\n | { readonly kind: \"quote\"; readonly lines: readonly string[] }\n | { readonly kind: \"ul\" | \"ol\"; readonly items: readonly ListItem[]; readonly start?: number }\n | { readonly kind: \"table\"; readonly headers: readonly string[]; readonly rows: readonly (readonly string[])[]; readonly alignments: readonly Alignment[] }\n | { readonly kind: \"rule\" }\n | { readonly kind: \"paragraph\"; readonly lines: readonly string[] };\n\nfunction splitTableRow(line: string): string[] {\n let source = line.trim();\n if (source.startsWith(\"|\")) source = source.slice(1);\n if (source.endsWith(\"|\")) source = source.slice(0, -1);\n const cells: string[] = [];\n let cell = \"\";\n for (let index = 0; index < source.length; index += 1) {\n const character = source[index] ?? \"\";\n if (character === \"\\\\\" && source[index + 1] === \"|\") {\n cell += \"|\";\n index += 1;\n } else if (character === \"|\") {\n cells.push(cell.trim());\n cell = \"\";\n } else cell += character;\n }\n cells.push(cell.trim());\n return cells;\n}\n\nfunction tableAlignments(line: string): Alignment[] | undefined {\n const cells = splitTableRow(line);\n if (cells.length === 0 || !cells.every((cell) => /^:?-{3,}:?$/u.test(cell))) return undefined;\n return cells.map((cell) => {\n if (cell.startsWith(\":\") && cell.endsWith(\":\")) return \"center\";\n if (cell.endsWith(\":\")) return \"right\";\n if (cell.startsWith(\":\")) return \"left\";\n return undefined;\n });\n}\n\nfunction beginsBlock(lines: readonly string[], index: number): boolean {\n const line = lines[index] ?? \"\";\n return /^(`{3,}|~{3,})\\s*[\\w-]*\\s*$/u.test(line)\n || /^#{1,6}\\s+/u.test(line)\n || /^(?:-{3,}|\\*{3,}|_{3,})\\s*$/u.test(line)\n || /^>\\s?/u.test(line)\n || /^[-*+]\\s+/u.test(line)\n || /^\\d+[.)]\\s+/u.test(line)\n || (line.includes(\"|\") && tableAlignments(lines[index + 1] ?? \"\") !== undefined);\n}\n\nexport function parseMarkdownBlocks(markdown: string): MarkdownBlock[] {\n const lines = markdown.replaceAll(\"\\r\\n\", \"\\n\").split(\"\\n\");\n const result: MarkdownBlock[] = [];\n for (let index = 0; index < lines.length;) {\n const line = lines[index] ?? \"\";\n if (line.trim() === \"\") { index += 1; continue; }\n\n const fence = /^(`{3,}|~{3,})\\s*([\\w-]*)\\s*$/u.exec(line);\n if (fence !== null) {\n const marker = fence[1] ?? \"```\";\n const markerCharacter = marker[0] ?? \"`\";\n const closing = new RegExp(`^${markerCharacter}{${String(marker.length)},}\\\\s*$`, \"u\");\n const code: string[] = [];\n index += 1;\n while (index < lines.length && !closing.test(lines[index] ?? \"\")) { code.push(lines[index] ?? \"\"); index += 1; }\n if (index < lines.length) index += 1;\n result.push({ kind: \"code\", lines: code, ...(fence[2] === undefined || fence[2] === \"\" ? {} : { language: fence[2] }) });\n continue;\n }\n\n const heading = /^(#{1,6})\\s+(.+)$/u.exec(line);\n if (heading !== null) {\n result.push({ kind: \"heading\", text: heading[2] ?? \"\", level: heading[1]?.length ?? 1 });\n index += 1;\n continue;\n }\n if (/^(?:-{3,}|\\*{3,}|_{3,})\\s*$/u.test(line)) { result.push({ kind: \"rule\" }); index += 1; continue; }\n\n const alignments = line.includes(\"|\") ? tableAlignments(lines[index + 1] ?? \"\") : undefined;\n if (alignments !== undefined) {\n const headers = splitTableRow(line);\n const rows: string[][] = [];\n index += 2;\n while (index < lines.length && (lines[index] ?? \"\").includes(\"|\") && (lines[index] ?? \"\").trim() !== \"\") {\n rows.push(splitTableRow(lines[index] ?? \"\"));\n index += 1;\n }\n result.push({ kind: \"table\", headers, rows, alignments });\n continue;\n }\n\n if (/^>\\s?/u.test(line)) {\n const quote: string[] = [];\n while (index < lines.length && /^>\\s?/u.test(lines[index] ?? \"\")) {\n quote.push((lines[index] ?? \"\").replace(/^>\\s?/u, \"\"));\n index += 1;\n }\n result.push({ kind: \"quote\", lines: quote });\n continue;\n }\n\n const unordered = /^[-*+]\\s+(.+)$/u.exec(line);\n const ordered = /^(\\d+)[.)]\\s+(.+)$/u.exec(line);\n if (unordered !== null || ordered !== null) {\n const kind = unordered !== null ? \"ul\" : \"ol\";\n const items: ListItem[] = [];\n const pattern = kind === \"ul\" ? /^[-*+]\\s+(.+)$/u : /^\\d+[.)]\\s+(.+)$/u;\n const start = ordered === null ? undefined : Number(ordered[1]);\n while (index < lines.length) {\n const item = pattern.exec(lines[index] ?? \"\");\n if (item === null) break;\n const source = item[1] ?? \"\";\n const task = /^\\[([ xX])\\]\\s+(.+)$/u.exec(source);\n items.push(task === null ? { text: source } : { text: task[2] ?? \"\", checked: task[1]?.toLocaleLowerCase() === \"x\" });\n index += 1;\n }\n result.push({ kind, items, ...(start === undefined ? {} : { start }) });\n continue;\n }\n\n const paragraph: string[] = [line];\n index += 1;\n while (index < lines.length) {\n const next = lines[index] ?? \"\";\n if (next.trim() === \"\" || beginsBlock(lines, index)) break;\n paragraph.push(next);\n index += 1;\n }\n result.push({ kind: \"paragraph\", lines: paragraph });\n }\n return result;\n}\n\nfunction Heading({ block, blockKey }: { readonly block: Extract<MarkdownBlock, { readonly kind: \"heading\" }>; readonly blockKey: string }) {\n const children = inline(block.text, blockKey);\n switch (block.level) {\n case 1: return <h1>{children}</h1>;\n case 2: return <h2>{children}</h2>;\n case 3: return <h3>{children}</h3>;\n case 4: return <h4>{children}</h4>;\n case 5: return <h5>{children}</h5>;\n default: return <h6>{children}</h6>;\n }\n}\n\nexport function MarkdownPreview({ content, label }: { readonly content: string; readonly label: string }) {\n const parsed = parseMarkdownBlocks(content);\n if (parsed.length === 0) return <div className=\"oh-story-markdown-empty\">\u8FD9\u4E2A Markdown \u6587\u4EF6\u8FD8\u662F\u7A7A\u7684\u3002</div>;\n return <article className=\"oh-story-markdown\" aria-label={`${label} \u6E32\u67D3\u9884\u89C8`}>\n {parsed.map((block, index) => {\n const key = `block-${String(index)}`;\n if (block.kind === \"code\") return <pre key={key}><code data-language={block.language}>{block.lines.join(\"\\n\")}</code></pre>;\n if (block.kind === \"rule\") return <hr key={key} />;\n if (block.kind === \"quote\") return <blockquote key={key}>{block.lines.map((line, lineIndex) => <p key={`${key}-${String(lineIndex)}`}>{inline(line, `${key}-${String(lineIndex)}`)}</p>)}</blockquote>;\n if (block.kind === \"ul\" || block.kind === \"ol\") {\n const items = block.items.map((item, itemIndex) => <li key={`${key}-${String(itemIndex)}`} className={item.checked === undefined ? undefined : \"oh-story-task-item\"}>\n {item.checked === undefined ? null : <input type=\"checkbox\" checked={item.checked} readOnly disabled aria-label={item.checked ? \"\u5DF2\u5B8C\u6210\" : \"\u672A\u5B8C\u6210\"} />}\n {inline(item.text, `${key}-${String(itemIndex)}`)}\n </li>);\n return block.kind === \"ul\" ? <ul key={key}>{items}</ul> : <ol key={key} start={block.start}>{items}</ol>;\n }\n if (block.kind === \"table\") return <div className=\"oh-story-markdown-table\" key={key}>\n <table>\n <thead><tr>{block.headers.map((cell, cellIndex) => <th key={`${key}-h-${String(cellIndex)}`} style={{ textAlign: block.alignments[cellIndex] }}>{inline(cell, `${key}-h-${String(cellIndex)}`)}</th>)}</tr></thead>\n <tbody>{block.rows.map((row, rowIndex) => <tr key={`${key}-r-${String(rowIndex)}`}>{block.headers.map((_, cellIndex) => <td key={`${key}-r-${String(rowIndex)}-${String(cellIndex)}`} style={{ textAlign: block.alignments[cellIndex] }}>{inline(row[cellIndex] ?? \"\", `${key}-r-${String(rowIndex)}-${String(cellIndex)}`)}</td>)}</tr>)}</tbody>\n </table>\n </div>;\n if (block.kind === \"heading\") return <Heading key={key} block={block} blockKey={key} />;\n if (block.kind === \"paragraph\") return <p key={key}>{block.lines.map((line, lineIndex) => <span key={`${key}-${String(lineIndex)}`}>{lineIndex === 0 ? null : <br />}{inline(line, `${key}-${String(lineIndex)}`)}</span>)}</p>;\n return null;\n })}\n </article>;\n}\n", "export type DramaProductionSection = \"shots\" | \"assets\" | \"tasks\" | \"sequence\" | \"canvas\";\n\nexport type DramaAssetKind = \"character\" | \"scene\" | \"prop\" | \"state\" | \"unknown\";\nexport const PRODUCTION_PROTOCOL_VERSION = \"short-drama/v1\";\n\nexport interface DramaProductionDiagnostic {\n readonly severity: \"error\" | \"warning\";\n readonly code: string;\n readonly path: string;\n readonly offset: number;\n readonly line: number;\n readonly targetId?: string | undefined;\n readonly message: string;\n}\n\nexport interface DramaDocumentTarget {\n readonly path: string;\n readonly offset: number;\n readonly id: string;\n}\n\nexport interface DramaShot {\n readonly id: string;\n readonly title: string;\n readonly path: string;\n readonly offset: number;\n readonly source?: string | undefined;\n /** Screenplay scene IDs named by \u6765\u6E90, in document order; empty when the field names none. */\n readonly sceneIds: readonly string[];\n readonly durationSeconds?: number | undefined;\n readonly purpose?: string | undefined;\n readonly shotSpec?: string | undefined;\n readonly start?: string | undefined;\n readonly end?: string | undefined;\n readonly references: readonly string[];\n readonly keyframePrompt?: string | undefined;\n readonly motion?: DramaMotionPrompt | undefined;\n}\n\nexport interface DramaAsset {\n readonly id: string;\n readonly title: string;\n readonly kind: DramaAssetKind;\n readonly path: string;\n readonly offset: number;\n readonly purpose?: string | undefined;\n readonly reference?: string | undefined;\n readonly prompt?: string | undefined;\n readonly description?: string | undefined;\n}\n\nexport interface DramaMotionPrompt {\n readonly id: string;\n readonly title: string;\n readonly path: string;\n readonly offset: number;\n readonly shotId?: string | undefined;\n readonly durationSeconds?: number | undefined;\n readonly startFrame?: string | undefined;\n readonly end?: string | undefined;\n readonly prompt?: string | undefined;\n}\n\nexport interface DramaVisualAsset {\n readonly id: string;\n readonly title: string;\n readonly kind: DramaAssetKind;\n readonly path: string;\n readonly offset: number;\n readonly description: string;\n readonly stableId: boolean;\n readonly declaredId?: string | undefined;\n}\n\nexport interface DramaEpisodeProduction {\n readonly protocolVersion: typeof PRODUCTION_PROTOCOL_VERSION;\n readonly episodeDirectory: string;\n readonly shots: readonly DramaShot[];\n readonly assets: readonly DramaAsset[];\n readonly visualAssets: readonly DramaVisualAsset[];\n readonly motions: readonly DramaMotionPrompt[];\n readonly targets: ReadonlyMap<string, DramaDocumentTarget>;\n readonly documentPaths: readonly string[];\n readonly diagnostics: readonly DramaProductionDiagnostic[];\n}\n\ninterface MarkdownSection {\n readonly heading: string;\n readonly body: string;\n readonly offset: number;\n}\n\nconst CREATOR_DOCUMENT_NAMES = new Set([\"\u5267\u672C.md\", \"\u89C6\u89C9\u8BBE\u5B9A.md\", \"\u5206\u955C.md\", \"\u56FE\u7247\u63D0\u793A\u8BCD.md\", \"\u89C6\u9891\u63D0\u793A\u8BCD.md\"]);\n\nexport function episodeDirectoryForPath(path: string | undefined): string | undefined {\n if (path === undefined) return undefined;\n const match = /^(\u5267\u96C6\\/[^/]+)\\/[^/]+$/u.exec(path);\n return match?.[1];\n}\n\nexport function isCreatorDocumentPath(path: string): boolean {\n const directory = episodeDirectoryForPath(path);\n const name = path.split(\"/\").at(-1);\n return directory !== undefined && name !== undefined && CREATOR_DOCUMENT_NAMES.has(name);\n}\n\nexport function creatorDocumentPaths(files: readonly { readonly path: string }[], episodeDirectory: string): string[] {\n return files\n .map((file) => file.path)\n .filter((path) => path.startsWith(`${episodeDirectory}/`) && CREATOR_DOCUMENT_NAMES.has(path.slice(episodeDirectory.length + 1)))\n .sort((left, right) => creatorDocumentOrder(left) - creatorDocumentOrder(right) || left.localeCompare(right, \"zh-Hans-CN\"));\n}\n\nexport function parseEpisodeProduction(documents: Readonly<Record<string, string>>, episodeDirectory: string): DramaEpisodeProduction {\n const storyboardPath = `${episodeDirectory}/\u5206\u955C.md`;\n const imagePromptPath = `${episodeDirectory}/\u56FE\u7247\u63D0\u793A\u8BCD.md`;\n const videoPromptPath = `${episodeDirectory}/\u89C6\u9891\u63D0\u793A\u8BCD.md`;\n const visualPath = `${episodeDirectory}/\u89C6\u89C9\u8BBE\u5B9A.md`;\n const shots = parseStoryboard(storyboardPath, documents[storyboardPath] ?? \"\");\n const assets = parseImagePrompts(imagePromptPath, documents[imagePromptPath] ?? \"\");\n const motions = parseVideoPrompts(videoPromptPath, documents[videoPromptPath] ?? \"\");\n const visualAssets = parseVisualAssets(visualPath, documents[visualPath] ?? \"\");\n const motionByShot = new Map(motions.flatMap((motion) => motion.shotId === undefined ? [] : [[motion.shotId, motion] as const]));\n const linkedShots = shots.map((shot) => ({ ...shot, motion: motionByShot.get(shot.id) }));\n const targets = new Map<string, DramaDocumentTarget>();\n for (const item of [...linkedShots, ...assets, ...motions, ...visualAssets]) {\n targets.set(item.id, { path: item.path, offset: item.offset, id: item.id });\n }\n const screenplayPath = `${episodeDirectory}/\u5267\u672C.md`;\n for (const shot of linkedShots) {\n for (const id of sourceKeys(shot)) {\n const target = sectionTarget(screenplayPath, documents[screenplayPath] ?? \"\", id);\n if (target === undefined) continue;\n targets.set(id, target);\n }\n }\n const diagnostics = validateProductionProtocol({\n documents,\n episodeDirectory,\n shots: linkedShots,\n assets,\n visualAssets,\n motions\n });\n return {\n protocolVersion: PRODUCTION_PROTOCOL_VERSION,\n episodeDirectory,\n shots: linkedShots,\n assets,\n visualAssets,\n motions,\n targets,\n documentPaths: Object.keys(documents).filter((path) => path.startsWith(`${episodeDirectory}/`)),\n diagnostics\n };\n}\n\nexport function parseStoryboard(path: string, content: string): DramaShot[] {\n return levelTwoSections(content).flatMap((section) => {\n const match = /^(SHOT-[A-Z0-9-]+)\\s*(?:[\u00B7\uFF5C|]\\s*)?(.*)$/iu.exec(section.heading.trim());\n if (match === null || match[1] === undefined) return [];\n const fields = bulletFields(section.body);\n const id = match[1].toLocaleUpperCase();\n const source = firstField(fields, \"\u6765\u6E90\", \"\u573A\u6B21\");\n return [{\n id,\n title: match[2]?.trim() || id,\n path,\n offset: section.offset,\n source,\n sceneIds: sourceSceneIds(source),\n durationSeconds: seconds(firstField(fields, \"\u65F6\u957F\")),\n purpose: firstField(fields, \"\u76EE\u7684\", \"\u955C\u5934\u76EE\u7684\"),\n shotSpec: firstField(fields, \"\u666F\u522B/\u673A\u4F4D\", \"\u666F\u522B\", \"\u955C\u5934\u89C4\u683C\"),\n start: firstField(fields, \"\u8D77\u70B9\", \"\u8D77\u59CB\"),\n end: firstField(fields, \"\u7EC8\u70B9\", \"\u7ED3\u675F\"),\n references: splitReferences(firstField(fields, \"\u56FE\u7247\u63D0\u793A\u8BCD\u9879\", \"\u53C2\u8003\", \"\u5173\u8054\u8D44\u4EA7\")),\n keyframePrompt: quoteUnderHeading(section.body, \"\u51BB\u7ED3\u5173\u952E\u5E27\u63D0\u793A\u8BCD\")\n }];\n });\n}\n\nexport function parseImagePrompts(path: string, content: string): DramaAsset[] {\n return levelTwoSections(content).flatMap((section) => {\n const match = /^(IMG-[A-Z0-9-]+)\\s*(?:[\u00B7\uFF5C|]\\s*)?(.*)$/iu.exec(section.heading.trim());\n if (match === null || match[1] === undefined) return [];\n const fields = bulletFields(section.body);\n const id = match[1].toLocaleUpperCase();\n const title = match[2]?.trim() || id;\n return [{\n id,\n title,\n kind: inferAssetKind(`${id} ${title} ${firstField(fields, \"\u7528\u9014\") ?? \"\"}`),\n path,\n offset: section.offset,\n purpose: firstField(fields, \"\u7528\u9014\"),\n reference: firstField(fields, \"\u53C2\u8003\", \"\u53C2\u8003\u7EA6\u675F\"),\n prompt: quoteUnderHeading(section.body, \"\u53EF\u590D\u5236\u63D0\u793A\u8BCD\")\n }];\n });\n}\n\nexport function parseVideoPrompts(path: string, content: string): DramaMotionPrompt[] {\n return levelTwoSections(content).flatMap((section) => {\n const match = /^(MOTION-[A-Z0-9-]+)\\s*(?:[\u00B7\uFF5C|]\\s*)?(.*)$/iu.exec(section.heading.trim());\n if (match === null || match[1] === undefined) return [];\n const fields = bulletFields(section.body);\n const id = match[1].toLocaleUpperCase();\n const shotId = firstField(fields, \"\u5206\u955C\", \"\u955C\u5934\")?.match(/SHOT-[A-Z0-9-]+/iu)?.[0]?.toLocaleUpperCase();\n return [{\n id,\n title: match[2]?.trim() || id,\n path,\n offset: section.offset,\n shotId,\n durationSeconds: seconds(firstField(fields, \"\u65F6\u957F\")),\n startFrame: firstField(fields, \"\u8D77\u59CB\u5E27\", \"\u8D77\u70B9\"),\n end: firstField(fields, \"\u7EC8\u70B9\", \"\u7ED3\u675F\"),\n prompt: quoteUnderHeading(section.body, \"\u53EF\u590D\u5236\u63D0\u793A\u8BCD\")\n }];\n });\n}\n\nexport function parseVisualAssets(path: string, content: string): DramaVisualAsset[] {\n return levelTwoSections(content).flatMap((section) => {\n const match = /^(\u4EBA\u7269|\u89D2\u8272|\u9020\u578B|\u5730\u70B9|\u573A\u666F|\u9053\u5177|\u72B6\u6001)\\s*(?:[\u00B7\uFF5C|:]\\s*)?(.*)$/u.exec(section.heading.trim());\n if (match === null || match[1] === undefined) return [];\n const fields = bulletFields(section.body);\n const title = match[2]?.trim() || section.heading.trim();\n const declaredId = firstField(fields, \"ID\", \"\u8D44\u4EA7 ID\", \"\u8D44\u4EA7ID\")?.trim().toLocaleUpperCase();\n const stableId = declaredId !== undefined && /^VISUAL-[A-Z0-9-]+$/u.test(declaredId);\n const id = stableId ? declaredId : `VISUAL-${slug(`${match[1]}-${title}`)}`;\n return [{ id, title, kind: inferAssetKind(`${match[1]} ${title}`), path, offset: section.offset, description: section.body.trim(), stableId, declaredId }];\n });\n}\n\nfunction validateProductionProtocol(input: {\n readonly documents: Readonly<Record<string, string>>;\n readonly episodeDirectory: string;\n readonly shots: readonly DramaShot[];\n readonly assets: readonly DramaAsset[];\n readonly visualAssets: readonly DramaVisualAsset[];\n readonly motions: readonly DramaMotionPrompt[];\n}): DramaProductionDiagnostic[] {\n const diagnostics: DramaProductionDiagnostic[] = [];\n const add = (value: Omit<DramaProductionDiagnostic, \"line\">): void => {\n diagnostics.push({ ...value, line: lineAt(input.documents[value.path] ?? \"\", value.offset) });\n };\n const all = [...input.shots, ...input.assets, ...input.visualAssets, ...input.motions];\n const byId = new Map<string, typeof all>();\n for (const item of all) byId.set(item.id, [...(byId.get(item.id) ?? []), item]);\n for (const [id, items] of byId) {\n if (items.length < 2) continue;\n for (const item of items) add({ severity: \"error\", code: \"duplicate_id\", path: item.path, offset: item.offset, targetId: id, message: `${id} \u5728\u5F53\u524D\u96C6\u5185\u91CD\u590D\uFF0C\u540E\u51FA\u73B0\u7684\u6761\u76EE\u4F1A\u906E\u853D\u524D\u4E00\u6761\u3002` });\n }\n\n for (const visual of input.visualAssets) {\n if (visual.stableId) continue;\n add(visual.declaredId === undefined\n ? { severity: \"warning\", code: \"generated_visual_id\", path: visual.path, offset: visual.offset, targetId: visual.id, message: `${visual.title} \u7F3A\u5C11\u7A33\u5B9A\u7684 \u201C- ID\uFF1AVISUAL-*\u201D\uFF1B\u4FEE\u6539\u6807\u9898\u4F1A\u6539\u53D8\u753B\u5E03\u8282\u70B9\u8EAB\u4EFD\u3002` }\n : { severity: \"warning\", code: \"invalid_visual_id\", path: visual.path, offset: visual.offset, targetId: visual.id, message: `${visual.title} \u7684 \u201C- ID\uFF1A${visual.declaredId}\u201D \u4E0D\u662F\u53EF\u7528\u5F62\u5F0F\uFF0C\u5DF2\u56DE\u9000\u5230\u6807\u9898\u6D3E\u751F ID\uFF1B\u8BF7\u5199\u6210 VISUAL- \u52A0\u5927\u5199\u5B57\u6BCD\u3001\u6570\u5B57\u6216\u8FDE\u5B57\u7B26\u3002` });\n }\n\n const knownReferences = new Set([...input.assets, ...input.visualAssets, ...input.shots, ...input.motions].map((item) => item.id));\n const screenplayPath = `${input.episodeDirectory}/\u5267\u672C.md`;\n for (const shot of input.shots) {\n for (const reference of shot.references) {\n if (!knownReferences.has(reference)) add({ severity: \"warning\", code: \"unknown_reference\", path: shot.path, offset: shot.offset, targetId: shot.id, message: `${shot.id} \u5F15\u7528\u4E86\u672A\u89E3\u6790\u7684 ${reference}\u3002` });\n }\n for (const id of sourceKeys(shot)) {\n if (sectionTarget(screenplayPath, input.documents[screenplayPath] ?? \"\", id) === undefined) {\n add({ severity: \"warning\", code: \"unknown_source\", path: shot.path, offset: shot.offset, targetId: shot.id, message: `${shot.id} \u7684\u6765\u6E90 ${id} \u5728\u5267\u672C\u4E2D\u4E0D\u5B58\u5728\u3002` });\n }\n }\n }\n\n const shots = new Set(input.shots.map((shot) => shot.id));\n const motionsByShot = new Map<string, DramaMotionPrompt[]>();\n for (const motion of input.motions) {\n if (motion.shotId === undefined) {\n add({ severity: \"warning\", code: \"motion_without_shot\", path: motion.path, offset: motion.offset, targetId: motion.id, message: `${motion.id} \u6CA1\u6709\u53EF\u89E3\u6790\u7684 SHOT-* \u5206\u955C\u5B57\u6BB5\u3002` });\n continue;\n }\n if (!shots.has(motion.shotId)) add({ severity: \"error\", code: \"unknown_motion_shot\", path: motion.path, offset: motion.offset, targetId: motion.id, message: `${motion.id} \u6307\u5411\u4E0D\u5B58\u5728\u7684 ${motion.shotId}\u3002` });\n motionsByShot.set(motion.shotId, [...(motionsByShot.get(motion.shotId) ?? []), motion]);\n }\n for (const [shotId, motions] of motionsByShot) {\n if (motions.length < 2) continue;\n for (const motion of motions) add({ severity: \"error\", code: \"multiple_motions\", path: motion.path, offset: motion.offset, targetId: motion.id, message: `${shotId} \u540C\u65F6\u7ED1\u5B9A\u4E86\u591A\u4E2A MOTION\uFF0C\u753B\u5E03\u53EA\u80FD\u786E\u5B9A\u4E00\u4E2A\u3002` });\n }\n\n const parsedOffsets = new Set([...input.shots, ...input.assets, ...input.motions].map((item) => `${item.path}:${String(item.offset)}`));\n for (const [path, prefix] of [\n [`${input.episodeDirectory}/\u5206\u955C.md`, \"SHOT\"],\n [`${input.episodeDirectory}/\u56FE\u7247\u63D0\u793A\u8BCD.md`, \"IMG\"],\n [`${input.episodeDirectory}/\u89C6\u9891\u63D0\u793A\u8BCD.md`, \"MOTION\"]\n ] as const) {\n for (const section of levelTwoSections(input.documents[path] ?? \"\")) {\n if (section.heading.toLocaleUpperCase().startsWith(prefix) && !parsedOffsets.has(`${path}:${String(section.offset)}`)) {\n add({ severity: \"error\", code: \"malformed_heading\", path, offset: section.offset, message: `\u65E0\u6CD5\u89E3\u6790\u6807\u9898 \u201C${section.heading.trim()}\u201D\uFF0C\u9700\u8981\u7A33\u5B9A\u7684 ${prefix}-* ID\u3002` });\n }\n }\n }\n return diagnostics.sort((left, right) => left.path.localeCompare(right.path, \"zh-Hans-CN\") || left.offset - right.offset || left.code.localeCompare(right.code));\n}\n\nexport function productionCompleteness(shot: DramaShot): {\n readonly keyframe: boolean;\n readonly motion: boolean;\n readonly references: boolean;\n readonly complete: boolean;\n} {\n const keyframe = Boolean(shot.keyframePrompt?.trim());\n const motion = Boolean(shot.motion?.prompt?.trim());\n const references = shot.references.length > 0;\n return { keyframe, motion, references, complete: keyframe && motion };\n}\n\nfunction levelTwoSections(content: string): MarkdownSection[] {\n const matches = [...content.matchAll(/^##\\s+(.+)\\s*$/gmu)];\n return matches.map((match, index) => {\n const start = (match.index ?? 0) + match[0].length;\n const end = matches[index + 1]?.index ?? content.length;\n return { heading: match[1] ?? \"\", body: content.slice(start, end), offset: match.index ?? 0 };\n });\n}\n\nfunction bulletFields(body: string): Map<string, string> {\n const fields = new Map<string, string>();\n for (const match of body.matchAll(/^\\s*[-*]\\s+([^\uFF1A:\\n]+)[\uFF1A:]\\s*(.+?)\\s*$/gmu)) {\n const key = match[1]?.trim();\n const value = match[2]?.trim();\n if (key !== undefined && value !== undefined) fields.set(key, value);\n }\n return fields;\n}\n\nfunction firstField(fields: ReadonlyMap<string, string>, ...names: string[]): string | undefined {\n for (const name of names) {\n const value = fields.get(name);\n if (value !== undefined && value !== \"\") return value;\n }\n return undefined;\n}\n\nfunction quoteUnderHeading(body: string, heading: string): string | undefined {\n const escaped = heading.replace(/[.*+?^${}()|[\\]\\\\]/gu, \"\\\\$&\");\n const match = new RegExp(`^###\\\\s+${escaped}\\\\s*$([\\\\s\\\\S]*?)(?=^###\\\\s+|(?![\\\\s\\\\S]))`, \"imu\").exec(body);\n if (match?.[1] === undefined) return undefined;\n const lines = match[1].split(/\\r?\\n/u)\n .filter((line) => /^\\s*>/u.test(line))\n .map((line) => line.replace(/^\\s*>\\s?/u, \"\").trimEnd());\n const value = lines.join(\"\\n\").trim();\n return value === \"\" ? undefined : value;\n}\n\nfunction seconds(value: string | undefined): number | undefined {\n if (value === undefined) return undefined;\n const match = /([0-9]+(?:\\.[0-9]+)?)\\s*(?:s|\u79D2)/iu.exec(value);\n if (match?.[1] === undefined) return undefined;\n const parsed = Number(match[1]);\n return Number.isFinite(parsed) && parsed > 0 ? parsed : undefined;\n}\n\nfunction splitReferences(value: string | undefined): string[] {\n if (value === undefined) return [];\n const ids = value.match(/(?:IMG|SHOT|MOTION)-[A-Z0-9-]+/giu) ?? [];\n return [...new Set(ids.map((id) => id.toLocaleUpperCase()))];\n}\n\nfunction inferAssetKind(value: string): DramaAssetKind {\n if (/(\u4EBA\u7269|\u89D2\u8272|\u9020\u578B|character|portrait|sheet)/iu.test(value)) return \"character\";\n if (/(\u5730\u70B9|\u573A\u666F|\u73AF\u5883|scene|location|corridor|room)/iu.test(value)) return \"scene\";\n if (/(\u9053\u5177|\u7269\u4EF6|prop|object)/iu.test(value)) return \"prop\";\n if (/(\u72B6\u6001|state|look)/iu.test(value)) return \"state\";\n return \"unknown\";\n}\n\nfunction slug(value: string): string {\n return value.trim().toLocaleUpperCase().replace(/[^\\p{Letter}\\p{Number}]+/gu, \"-\").replace(/^-|-$/gu, \"\") || \"ITEM\";\n}\n\nfunction lineAt(content: string, offset: number): number {\n return content.slice(0, Math.max(0, offset)).split(/\\r?\\n/u).length;\n}\n\n// Drama Skills 0.6.5 (#100): \u6765\u6E90 starts with a screenplay scene ID and may\n// continue with a short quote or further IDs joined by \u3001. The ID shape is the\n// one creator_markdown_check.py uses; the checker additionally requires the\n// field to *start* with an ID, which the workbench leaves to it \u2014 here an ID\n// anywhere in the field still navigates.\nexport function sourceSceneIds(source: string | undefined): string[] {\n if (source === undefined) return [];\n return [...new Set([...source.matchAll(/(?:[A-Za-z0-9]+-)+SC[0-9]+/gu)].map((match) => match[0]))];\n}\n\n/** Scene IDs to resolve; a \u6765\u6E90 naming no ID falls back to matching the whole field. */\nfunction sourceKeys(shot: DramaShot): readonly string[] {\n if (shot.sceneIds.length > 0) return shot.sceneIds;\n return shot.source === undefined ? [] : [shot.source];\n}\n\nfunction sectionTarget(path: string, content: string, id: string): DramaDocumentTarget | undefined {\n const offset = content.search(new RegExp(`^##\\\\s+${id.replace(/[.*+?^${}()|[\\]\\\\]/gu, \"\\\\$&\")}(?:\\\\s|$)`, \"imu\"));\n return offset < 0 ? undefined : { path, offset, id };\n}\n\nfunction creatorDocumentOrder(path: string): number {\n const name = path.split(\"/\").at(-1);\n return [\"\u5267\u672C.md\", \"\u89C6\u89C9\u8BBE\u5B9A.md\", \"\u5206\u955C.md\", \"\u56FE\u7247\u63D0\u793A\u8BCD.md\", \"\u89C6\u9891\u63D0\u793A\u8BCD.md\"].indexOf(name ?? \"\");\n}\n", "import { useCallback, useEffect, useMemo, useRef, useState, type KeyboardEvent as ReactKeyboardEvent, type PointerEvent as ReactPointerEvent } from \"react\";\n// Type-only: erased from the browser bundle, but a modality added to the host registry\n// without a label below becomes a type error instead of an unlabelled chip.\nimport type { DramaAdapterModality, DramaAdapterStatus } from \"../drama-adapters.js\";\nimport { productionCompleteness, type DramaDocumentTarget, type DramaEpisodeProduction, type DramaProductionSection } from \"./drama-production.js\";\nimport { endpoint } from \"./workbench-ui.js\";\nimport { nativeBatchPrompt, nativeCompositionPrompt, nativeProductionPrompt } from \"./production-prompts.js\";\nimport { activeProductionJobId, compositionInFlight, createPendingJob, queuedItemForJob, reconcileProductionJobs, reconcileSequence, referencesForTarget, reorderSequence, sequenceIssues, selectedVersionForTarget, type CanvasPoint, type ProductionJob, type ProductionMediaVersion, type ProductionQueueEntry, type ProductionSequenceItem } from \"./production-runtime.js\";\n\ninterface Props {\n readonly sessionId: string;\n readonly production: DramaEpisodeProduction;\n readonly sessionRunning: boolean;\n readonly queue: readonly ProductionQueueEntry[];\n readonly section: DramaProductionSection;\n readonly selectedId: string | undefined;\n readonly jobs: readonly ProductionJob[];\n readonly versions: readonly ProductionMediaVersion[];\n readonly libraryVersions: readonly ProductionMediaVersion[];\n readonly selections: Readonly<Record<string, string>>;\n readonly manualReferences: Readonly<Record<string, readonly string[]>>;\n readonly sequence: readonly ProductionSequenceItem[];\n readonly canvas: Readonly<Record<string, CanvasPoint>>;\n readonly zoom: number;\n readonly onSectionChange: (section: DramaProductionSection) => void;\n readonly onSelect: (id: string | undefined) => void;\n readonly onNavigate: (target: DramaDocumentTarget) => void;\n readonly onJobsChange: (jobs: ProductionJob[]) => void;\n readonly onSelectionsChange: (selections: Record<string, string>) => void;\n readonly onManualReferencesChange: (references: Record<string, string[]>) => void;\n readonly onOpenMedia: (path: string) => void;\n readonly onSequenceChange: (sequence: ProductionSequenceItem[]) => void;\n readonly onCanvasChange: (canvas: Record<string, CanvasPoint>) => void;\n readonly onZoomChange: (zoom: number) => void;\n readonly onDispatchPrompt: (prompt: string) => Promise<void>;\n readonly onCancelTurn: () => Promise<void>;\n readonly onRemoveQueued: (itemId: string) => Promise<void>;\n readonly onRefresh: () => void;\n}\n\nconst SECTION_LABELS: Readonly<Record<DramaProductionSection, string>> = { shots: \"\u955C\u5934\", assets: \"\u7D20\u6750\", tasks: \"\u4EFB\u52A1\", sequence: \"\u6210\u7247\", canvas: \"\u753B\u5E03\" };\nconst SECTION_ORDER = Object.keys(SECTION_LABELS) as DramaProductionSection[];\nconst STATUS_LABELS: Readonly<Record<ProductionJob[\"status\"], string>> = { 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\" };\nconst ASSET_KIND_LABEL = { character: \"\u4EBA\u7269\", scene: \"\u573A\u666F\", prop: \"\u9053\u5177\", state: \"\u72B6\u6001\", unknown: \"\u8BBE\u5B9A\" } as const;\nconst JOB_KIND_LABEL = { image: \"\u56FE\u7247\", video: \"\u89C6\u9891\", composition: \"\u6210\u7247\" } as const;\n/** Where `short-drama-edit` renders the assembled cut, relative to the episode directory. */\nconst ASSEMBLED_CUT_PATH = \"\u5236\u4F5C\u6210\u679C/\u6210\u7247/\u6210\u7247.mp4\";\n\n/** Mirror of the host `/oh-story/drama-preflight` summary: presence only, never values. */\ninterface DramaPreflight {\n readonly python: { readonly ok: boolean; readonly version?: string };\n readonly adapterConfig: { readonly path: string; readonly generated: boolean; readonly ok: boolean };\n readonly adapters: readonly DramaAdapterStatus[];\n}\n\nconst MODALITY_LABEL: Readonly<Record<DramaAdapterModality, string>> = { image: \"\u56FE\u7247\", video: \"\u89C6\u9891\", tts: \"\u8BED\u97F3\", music: \"\u97F3\u4E50\" };\n\n/**\n * DeepSeek writes the prompts; the pictures, videos, speech and music come from\n * provider APIs that the produce Skill calls. Nothing in the conversation says so,\n * and the keys live in the host environment, so the \u751F\u4EA7 view states it up front.\n */\nfunction ProductionEnvironment({ sessionId }: { readonly sessionId: string }) {\n const [preflight, setPreflight] = useState<DramaPreflight | \"failed\">();\n const [attempt, setAttempt] = useState(0);\n // The summary is host-wide (the route ignores sessionId); the id only keeps\n // the URL shape shared with every other workbench endpoint.\n useEffect(() => {\n const controller = new AbortController();\n void fetch(endpoint(\"drama-preflight\", sessionId), { signal: controller.signal })\n .then(async (response) => {\n if (!response.ok) throw new Error(`HTTP ${String(response.status)}`);\n const summary = await response.json() as DramaPreflight;\n if (!controller.signal.aborted) setPreflight(summary);\n })\n .catch(() => { if (!controller.signal.aborted) setPreflight(\"failed\"); });\n return () => { controller.abort(); };\n }, [attempt, sessionId]);\n const unconfigured = typeof preflight === \"object\" ? preflight.adapters.filter((adapter) => !adapter.configured) : [];\n return <div className=\"oh-story-production-environment\" role=\"status\" aria-label=\"\u5A92\u4F53\u751F\u6210\u73AF\u5883\">\n <strong>\u751F\u6210\u73AF\u5883</strong>\n {preflight === undefined && <span data-pending>\u68C0\u67E5\u4E2D\u2026</span>}\n {preflight === \"failed\" && <button type=\"button\" onClick={() => { setPreflight(undefined); setAttempt((value) => value + 1); }}>\u73AF\u5883\u68C0\u67E5\u5931\u8D25 \u00B7 \u91CD\u8BD5</button>}\n {typeof preflight === \"object\" && <>\n <span data-ready={preflight.python.ok || undefined}>Python {preflight.python.version ?? \"\u672A\u627E\u5230\"}</span>\n {preflight.adapters.map((adapter) => <span key={adapter.name} data-ready={adapter.configured || undefined} title={adapter.configured ? `${adapter.name} \u5DF2\u914D\u7F6E` : `\u7F3A\u5C11\u73AF\u5883\u53D8\u91CF ${adapter.missing.join(\"\u3001\")}`}>{MODALITY_LABEL[adapter.modality]} {adapter.label}{adapter.configured ? \"\" : ` \u00B7 \u7F3A ${adapter.missing.join(\"\u3001\")}`}</span>)}\n <em>DeepSeek \u53EA\u8D1F\u8D23\u5199\u63D0\u793A\u8BCD\uFF1B\u56FE\u7247\u3001\u89C6\u9891\u3001\u8BED\u97F3\u3001\u97F3\u4E50\u7531\u4E0A\u9762\u7684\u4F9B\u5E94\u5546 API \u751F\u6210\uFF0CKey \u5728\u542F\u52A8 DSH \u524D\u5199\u5165\u5BBF\u4E3B\u673A\u73AF\u5883\u53D8\u91CF\u3002\n {unconfigured.length === preflight.adapters.length && \" \u5F53\u524D\u4E00\u4E2A\u90FD\u6CA1\u914D\u7F6E\uFF0C\u751F\u4EA7\u4EFB\u52A1\u4F1A\u505C\u5728 adapter \u4E4B\u524D\u3002\"}\n {\" \"}Adapter \u914D\u7F6E{preflight.adapterConfig.generated ? \"\u5DF2\u81EA\u52A8\u767B\u8BB0\" : \"\u4F7F\u7528\u81EA\u5B9A\u4E49\u6587\u4EF6\"}{preflight.adapterConfig.ok ? \"\" : \"\uFF08\u5199\u5165\u5931\u8D25\uFF09\"}\uFF1A<code>{preflight.adapterConfig.path}</code>\u3002\u8BE6\u89C1 README\u300C\u5A92\u4F53\u751F\u6210 API\u300D\u3002</em>\n </>}\n </div>;\n}\n\nfunction handleSectionKey(event: ReactKeyboardEvent<HTMLButtonElement>, current: DramaProductionSection, onChange: (section: DramaProductionSection) => void): void {\n const index = SECTION_ORDER.indexOf(current);\n const next = event.key === \"Home\" ? 0\n : event.key === \"End\" ? SECTION_ORDER.length - 1\n : event.key === \"ArrowRight\" ? (index + 1) % SECTION_ORDER.length\n : event.key === \"ArrowLeft\" ? (index - 1 + SECTION_ORDER.length) % SECTION_ORDER.length\n : undefined;\n if (next === undefined) return;\n event.preventDefault();\n onChange(SECTION_ORDER[next]!);\n event.currentTarget.parentElement?.querySelectorAll<HTMLButtonElement>(\"[role='tab']\")[next]?.focus();\n}\n\nexport function DramaProductionView(props: Props) {\n const [notice, setNotice] = useState<string>();\n const protocolErrors = props.production.diagnostics.filter((item) => item.severity === \"error\").length;\n const jobsRef = useRef(props.jobs);\n const commitJobs = useCallback((next: ProductionJob[]) => {\n jobsRef.current = next;\n props.onJobsChange(next);\n }, [props.onJobsChange]);\n useEffect(() => { jobsRef.current = props.jobs; }, [props.jobs]);\n\n useEffect(() => {\n const next = reconcileSequence(props.production.shots.map((shot) => shot.id), props.sequence, props.versions, props.selections);\n if (JSON.stringify(next) !== JSON.stringify(props.sequence)) props.onSequenceChange(next);\n }, [props.production.shots, props.selections, props.sequence, props.versions]);\n\n useEffect(() => {\n const next = reconcileProductionJobs(props.jobs, props.queue, props.sessionRunning, props.versions);\n if (JSON.stringify(next) !== JSON.stringify(props.jobs)) commitJobs(next);\n }, [commitJobs, props.jobs, props.queue, props.sessionRunning, props.versions]);\n\n const dispatchJob = async (job: ProductionJob, references: readonly ProductionMediaVersion[] = []) => {\n commitJobs([...jobsRef.current, { ...job, status: \"awaiting_confirmation\" }]);\n props.onSectionChange(\"tasks\");\n try {\n await props.onDispatchPrompt(nativeProductionPrompt(props.production, job, references));\n setNotice(`${job.targetId} \u6B63\u5728\u51C6\u5907\u5B8C\u6574\u9884\u68C0\uFF1B\u8BF7\u5728 Chat \u67E5\u770B\u5E76\u660E\u786E\u786E\u8BA4\u540E\u518D\u751F\u4EA7\u3002`);\n } catch (error) {\n commitJobs(jobsRef.current.map((item) => item.id === job.id ? { ...item, status: \"failed\", error: error instanceof Error ? error.message : String(error) } : item));\n }\n };\n\n const createJob = async (targetId: string, kind: \"image\" | \"video\", prompt: string) => {\n if (prompt.trim() === \"\") { setNotice(`${targetId} \u6CA1\u6709\u53EF\u6295\u4EA7\u63D0\u793A\u8BCD\u3002`); return; }\n const job = createPendingJob({ id: crypto.randomUUID(), targetId, kind, prompt });\n await dispatchJob(job, kind === \"video\" ? referencesForTarget(targetId, props.production, props.versions, props.selections, props.libraryVersions, props.manualReferences) : []);\n };\n\n const createBatch = async (kind: \"image\" | \"video\") => {\n const candidates = props.production.shots.flatMap((shot) => { const prompt = kind === \"image\" ? shot.keyframePrompt : shot.motion?.prompt; return prompt === undefined ? [] : [{ id: shot.id, prompt }]; });\n if (candidates.length === 0) { setNotice(kind === \"image\" ? \"\u6CA1\u6709\u53EF\u6295\u4EA7\u7684\u5173\u952E\u5E27\u63D0\u793A\u8BCD\u3002\" : \"\u6CA1\u6709\u53EF\u6295\u4EA7\u7684\u89C6\u9891\u63D0\u793A\u8BCD\u3002\"); return; }\n const job = createPendingJob({ id: crypto.randomUUID(), targetId: kind === \"image\" ? \"BATCH-KEYFRAMES\" : \"BATCH-VIDEOS\", kind, prompt: candidates.map((item) => `${item.id}\\n${item.prompt}`).join(\"\\n\\n\"), expectedOutputs: candidates.length });\n commitJobs([...jobsRef.current, { ...job, status: \"awaiting_confirmation\" }]); props.onSectionChange(\"tasks\");\n try { await props.onDispatchPrompt(nativeBatchPrompt(props.production, job, candidates)); setNotice(`${String(candidates.length)} \u4E2A\u955C\u5934\u6B63\u5728\u51C6\u5907\u540C\u4E00\u6279\u6B21\u9884\u68C0\uFF1B\u8BF7\u5728 Chat \u6838\u5BF9\u540E\u660E\u786E\u786E\u8BA4\u3002`); }\n catch (error) { commitJobs(jobsRef.current.map((item) => item.id === job.id ? { ...item, status: \"failed\", error: error instanceof Error ? error.message : String(error) } : item)); }\n };\n\n const dispatchComposition = async (job: ProductionJob) => {\n const versionById = new Map(props.versions.map((version) => [version.id, version]));\n const ordered = props.sequence.flatMap((item) => { const version = item.versionId === undefined ? undefined : versionById.get(item.versionId); return version === undefined ? [] : [version.path ?? version.url]; });\n commitJobs([...jobsRef.current, job]); props.onSectionChange(\"tasks\");\n try { await props.onDispatchPrompt(nativeCompositionPrompt(props.production, job, ordered)); setNotice(\"\u6210\u7247\u4EFB\u52A1\u5DF2\u8FDB\u5165 DSH \u539F\u751F\u961F\u5217\uFF1B\u6587\u4EF6\u3001FFmpeg \u548C\u5199\u5165\u7EE7\u7EED\u53D7 DSH \u6743\u9650\u4E0E\u5BA1\u6279\u63A7\u5236\u3002\"); }\n catch (error) { commitJobs(jobsRef.current.map((item) => item.id === job.id ? { ...item, status: \"failed\", error: error instanceof Error ? error.message : String(error) } : item)); }\n };\n\n const cancelJob = async (job: ProductionJob) => {\n try { await props.onCancelTurn(); commitJobs(jobsRef.current.map((item) => item.id === job.id ? { ...item, status: \"canceled\", progress: 0 } : item)); setNotice(\"\u5DF2\u8BF7\u6C42\u505C\u6B62\u5F53\u524D DSH Turn\uFF1BDSH Queue \u4E2D\u7684\u5176\u4ED6\u4EFB\u52A1\u4F1A\u4FDD\u7559\u3002\"); }\n catch (error) { setNotice(error instanceof Error ? error.message : String(error)); }\n };\n const removeQueuedJob = async (job: ProductionJob, itemId: string) => {\n try { await props.onRemoveQueued(itemId); commitJobs(jobsRef.current.map((item) => item.id === job.id ? { ...item, status: \"canceled\", progress: 0 } : item)); setNotice(`${job.targetId} \u5DF2\u4ECE DSH Queue \u79FB\u9664\u3002`); }\n catch (error) { setNotice(error instanceof Error ? error.message : String(error)); }\n };\n const composeSequence = () => {\n const issues = sequenceIssues(props.sequence, props.versions);\n if (issues.length > 0) { setNotice(issues[0]); return; }\n // short-drama-edit renders to this fixed path, so the job correlates on the deliverable\n // rather than on a job id in the filename, and ignores a cut that was already there.\n const outputPath = `${props.production.episodeDirectory}/${ASSEMBLED_CUT_PATH}`;\n void dispatchComposition(createPendingJob({\n id: crypto.randomUUID(),\n targetId: props.production.episodeDirectory,\n kind: \"composition\",\n prompt: \"\u6309\u6210\u7247\u987A\u5E8F\u5408\u6210\",\n outputPath,\n supersededOutputIds: props.libraryVersions.flatMap((version) => version.path === outputPath ? [version.id] : [])\n }));\n };\n\n return <div className=\"oh-story-production\">\n <div className=\"oh-story-production-bar\"><div className=\"oh-story-production-tabs\" role=\"tablist\" aria-label=\"\u77ED\u5267\u751F\u4EA7\u89C6\u56FE\">{SECTION_ORDER.map((item) => <button type=\"button\" role=\"tab\" tabIndex={props.section === item ? 0 : -1} aria-selected={props.section === item} key={item} onKeyDown={(event) => { handleSectionKey(event, item, props.onSectionChange); }} onClick={() => { props.onSectionChange(item); }}>{SECTION_LABELS[item]}</button>)}</div><div className=\"oh-story-production-meta\"><span className=\"oh-story-production-summary\">{props.production.shots.length} \u955C \u00B7 {props.production.assets.length + props.production.visualAssets.length} \u7D20\u6750 \u00B7 {props.jobs.filter((job) => job.status === \"awaiting_confirmation\" || job.status === \"running\" || job.status === \"pending\").length} \u4EFB\u52A1</span><button type=\"button\" onClick={props.onRefresh}>\u5237\u65B0</button></div></div>\n <ProductionEnvironment sessionId={props.sessionId} />\n {notice !== undefined && <div className=\"oh-story-production-notice\" role=\"status\"><span>{notice}</span><button type=\"button\" aria-label=\"\u5173\u95ED\u63D0\u793A\" onClick={() => { setNotice(undefined); }}>\u00D7</button></div>}\n {props.production.diagnostics.length > 0 && <details className=\"oh-story-production-diagnostics\"><summary>{protocolErrors > 0 ? `${String(protocolErrors)} \u4E2A\u534F\u8BAE\u9519\u8BEF` : `${String(props.production.diagnostics.length)} \u4E2A\u683C\u5F0F\u63D0\u9192`}</summary><ul>{props.production.diagnostics.slice(0, 8).map((item) => <li data-severity={item.severity} key={`${item.path}:${String(item.offset)}:${item.code}`}><button type=\"button\" onClick={() => { props.onNavigate({ path: item.path, offset: item.offset, id: item.targetId ?? item.code }); }}>{item.path.split(\"/\").at(-1)}:{item.line}</button><span>{item.message}</span></li>)}</ul>{props.production.diagnostics.length > 8 && <p>\u53E6\u6709 {props.production.diagnostics.length - 8} \u9879\uFF0C\u8BF7\u6309\u6587\u6863\u4F4D\u7F6E\u4FEE\u590D\u3002</p>}</details>}\n {props.section === \"shots\" && <ShotBoard {...props} onCreateJob={createJob} onBatch={createBatch} />}\n {props.section === \"assets\" && <AssetBoard {...props} onCreateJob={createJob} />}\n {props.section === \"tasks\" && <TaskBoard jobs={props.jobs} queue={props.queue} sessionRunning={props.sessionRunning} onCancel={cancelJob} onRemoveQueued={removeQueuedJob} />}\n {props.section === \"sequence\" && <SequenceBoard {...props} onCompose={composeSequence} />}\n {props.section === \"canvas\" && <ProductionCanvas {...props} />}\n </div>;\n}\n\nfunction ShotBoard(props: Props & { readonly onCreateJob: (targetId: string, kind: \"image\" | \"video\", prompt: string) => Promise<void>; readonly onBatch: (kind: \"image\" | \"video\") => Promise<void> }) {\n const selectedRef = useScrollIntoView(props.selectedId);\n if (props.production.shots.length === 0) return <section className=\"oh-story-shot-board\"><MissingDocument document={`${props.production.episodeDirectory}/\u5206\u955C.md`} documentPaths={props.production.documentPaths} what=\"\u955C\u5934\" skill=\"/short-drama-storyboard\" onNavigate={props.onNavigate} /></section>;\n return <section className=\"oh-story-shot-board\"><div className=\"oh-story-production-actions\"><button type=\"button\" onClick={() => { void props.onBatch(\"image\"); }}>\u51C6\u5907\u6279\u91CF\u5173\u952E\u5E27</button><button type=\"button\" onClick={() => { void props.onBatch(\"video\"); }}>\u51C6\u5907\u6279\u91CF\u89C6\u9891</button></div><div className=\"oh-story-shot-grid\">{props.production.shots.map((shot) => {\n const completeness = productionCompleteness(shot); const versions = props.versions.filter((version) => version.targetId === shot.id); const selected = selectedVersionForTarget(shot.id, props.versions, props.selections, \"image\") ?? selectedVersionForTarget(shot.id, props.versions, props.selections, \"video\");\n return <article className=\"oh-story-shot-card\" role=\"button\" tabIndex={0} aria-pressed={props.selectedId === shot.id} aria-label={`\u9009\u4E2D\u955C\u5934 ${shot.id} ${shot.title}`} ref={props.selectedId === shot.id ? selectedRef : undefined} data-selected={props.selectedId === shot.id || undefined} key={shot.id} onKeyDown={(event) => { if (event.key === \"Enter\" || event.key === \" \") { event.preventDefault(); props.onSelect(shot.id); } }} onClick={() => { props.onSelect(shot.id); }}>\n {selected === undefined ? <div className=\"oh-story-shot-placeholder\"><strong>{shot.id.split(\"-\").at(-1)}</strong><span>\u7B49\u5F85\u5173\u952E\u5E27\u6210\u679C</span></div> : <MediaPreview version={selected} />}<header><button type=\"button\" onClick={(event) => { event.stopPropagation(); props.onNavigate({ path: shot.path, offset: shot.offset, id: shot.id }); }}>{shot.id}</button><span>{shot.durationSeconds === undefined ? \"\u2014\" : `${String(shot.durationSeconds)}s`}</span></header><h3>{shot.title}</h3>{shot.shotSpec !== undefined && <p>{shot.shotSpec}</p>}<dl><dt>\u8D77</dt><dd>{shot.start ?? \"\u672A\u586B\u5199\"}</dd><dt>\u7EC8</dt><dd>{shot.end ?? \"\u672A\u586B\u5199\"}</dd></dl>\n <div className=\"oh-story-shot-status\"><ReadinessBadge label=\"\u5173\u952E\u5E27\" ready={completeness.keyframe} /><ReadinessBadge label=\"\u8FD0\u52A8\" ready={completeness.motion} /><ReadinessBadge label=\"\u53C2\u8003\" ready={completeness.references} /><span>{versions.length} \u7248\u672C</span></div><div className=\"oh-story-reference-links\">{shot.sceneIds.length > 0 ? shot.sceneIds.map((sceneId) => <ReferenceButton key={sceneId} id={sceneId} production={props.production} onNavigate={props.onNavigate} />) : shot.source !== undefined && <ReferenceButton id={shot.source} production={props.production} onNavigate={props.onNavigate} />}{shot.references.map((id) => <ReferenceButton id={id} production={props.production} onNavigate={props.onNavigate} key={id} />)}</div>\n <div className=\"oh-story-card-actions\">{shot.keyframePrompt !== undefined && <button type=\"button\" onClick={(event) => { event.stopPropagation(); void props.onCreateJob(shot.id, \"image\", shot.keyframePrompt ?? \"\"); }}>\u51C6\u5907\u5173\u952E\u5E27</button>}{shot.motion?.prompt !== undefined && <button type=\"button\" onClick={(event) => { event.stopPropagation(); void props.onCreateJob(shot.id, \"video\", shot.motion?.prompt ?? \"\"); }}>\u51C6\u5907\u89C6\u9891</button>}</div>{versions.length > 1 && <VersionStrip targetId={shot.id} versions={versions} selections={props.selections} onSelectionsChange={props.onSelectionsChange} />}\n </article>;\n })}</div></section>;\n}\n\nfunction AssetBoard(props: Props & { readonly onCreateJob: (targetId: string, kind: \"image\" | \"video\", prompt: string) => Promise<void> }) {\n const [query, setQuery] = useState(\"\");\n const [kind, setKind] = useState<\"all\" | \"image\" | \"video\">(\"all\");\n const assets = [...props.production.assets, ...props.production.visualAssets.filter((visual) => !props.production.assets.some((asset) => asset.title === visual.title))];\n const needle = query.trim().toLocaleLowerCase();\n const library = props.libraryVersions.filter((version) => (kind === \"all\" || version.kind === kind) && (needle === \"\" || `${version.targetId} ${version.path ?? \"\"}`.toLocaleLowerCase().includes(needle)));\n const selectedRef = useScrollIntoView(props.selectedId);\n const referenceTarget = props.selectedId?.startsWith(\"SHOT-\") === true ? props.selectedId : undefined;\n const toggleReference = (versionId: string) => {\n if (referenceTarget === undefined) return;\n const current = props.manualReferences[referenceTarget] ?? [];\n const next = current.includes(versionId) ? current.filter((id) => id !== versionId) : [...current, versionId];\n const mutable = Object.fromEntries(Object.entries(props.manualReferences).map(([target, ids]) => [target, [...ids]]));\n props.onManualReferencesChange({ ...mutable, [referenceTarget]: next });\n };\n if (assets.length === 0 && props.libraryVersions.length === 0) return <section className=\"oh-story-assets\"><MissingDocument document={`${props.production.episodeDirectory}/\u56FE\u7247\u63D0\u793A\u8BCD.md`} documentPaths={props.production.documentPaths} what=\"\u7D20\u6750\" skill=\"/short-drama-image-prompts\" onNavigate={props.onNavigate} /></section>;\n return <section className=\"oh-story-assets\"><div className=\"oh-story-asset-grid\">{assets.map((asset) => { const prompt = \"prompt\" in asset ? asset.prompt : asset.description; const versions = props.versions.filter((version) => version.targetId === asset.id); const selected = selectedVersionForTarget(asset.id, props.versions, props.selections, \"image\"); return <article className=\"oh-story-asset-card\" ref={props.selectedId === asset.id ? selectedRef : undefined} data-selected={props.selectedId === asset.id || undefined} key={asset.id}>{selected === undefined ? <div className=\"oh-story-asset-placeholder\">{asset.kind === \"character\" ? \"\u4EBA\" : asset.kind === \"scene\" ? \"\u666F\" : asset.kind === \"prop\" ? \"\u7269\" : \"\u8BBE\"}</div> : <MediaPreview version={selected} />}<div><small>{ASSET_KIND_LABEL[asset.kind]}</small><h3>{asset.title}</h3><button type=\"button\" onClick={() => { props.onNavigate({ path: asset.path, offset: asset.offset, id: asset.id }); }}>{asset.id}</button></div>{prompt !== undefined && <p className=\"oh-story-asset-description\">{prompt}</p>}<div className=\"oh-story-card-actions\">{prompt !== undefined && <button type=\"button\" onClick={() => { void props.onCreateJob(asset.id, \"image\", prompt); }}>\u51C6\u5907\u7D20\u6750</button>}</div>{versions.length > 0 && <VersionStrip targetId={asset.id} versions={versions} selections={props.selections} onSelectionsChange={props.onSelectionsChange} />}</article>; })}</div><div className=\"oh-story-media-library\"><header><div><strong>\u9879\u76EE\u5A92\u4F53\u5E93</strong><span>{library.length}/{props.libraryVersions.length} \u9879 \u00B7 \u53EF\u8DE8\u96C6\u590D\u7528</span></div><div><input aria-label=\"\u641C\u7D22\u9879\u76EE\u5A92\u4F53\" value={query} placeholder=\"\u641C\u7D22 ID \u6216\u8DEF\u5F84\" onChange={(event) => { setQuery(event.target.value); }} /><select aria-label=\"\u7B5B\u9009\u5A92\u4F53\u7C7B\u578B\" value={kind} onChange={(event) => { setKind(event.target.value as typeof kind); }}><option value=\"all\">\u5168\u90E8</option><option value=\"image\">\u56FE\u7247</option><option value=\"video\">\u89C6\u9891</option></select></div></header><p className=\"oh-story-projection-note\">{referenceTarget === undefined ? \"\u5148\u5728\u955C\u5934\u9875\u9009\u4E2D\u4E00\u4E2A\u955C\u5934\uFF0C\u518D\u56DE\u5230\u8FD9\u91CC\u628A\u5DF2\u6709\u56FE\u7247\u8BBE\u4E3A\u8BE5\u955C\u5934\u7684\u8865\u5145\u53C2\u8003\u3002\" : `\u53EF\u628A\u4E0B\u9762\u7684\u56FE\u7247\u8BBE\u4E3A ${referenceTarget} \u7684\u8865\u5145\u53C2\u8003\u3002`}\u8865\u5145\u53C2\u8003\u53EA\u63D0\u793A Agent \u6838\u5BF9\uFF1B\u5199\u8FDB\u6765\u6E90\u6761\u76EE\u7684\u300C\u8F93\u5165\u53C2\u8003\u56FE\u300D\u540E\u624D\u4F1A\u9001\u8FDB\u751F\u4EA7\u3002</p><div className=\"oh-story-media-library-grid\">{library.map((version) => { const selected = referenceTarget !== undefined && (props.manualReferences[referenceTarget] ?? []).includes(version.id); return <article key={version.id}><MediaPreview version={version} /><strong>{version.targetId}</strong><span title={version.path}>{version.path}</span><footer>{version.path !== undefined && <button type=\"button\" onClick={() => { props.onOpenMedia(version.path!); }}>\u6253\u5F00\u6587\u4EF6</button>}{referenceTarget !== undefined && version.kind === \"image\" && <button type=\"button\" aria-pressed={selected} aria-label={`${selected ? \"\u53D6\u6D88\" : \"\u8BBE\u4E3A\"} ${referenceTarget} \u53C2\u8003 ${version.targetId}`} title=\"\u63D0\u793A Agent \u6838\u5BF9\uFF1B\u5199\u8FDB\u300C\u8F93\u5165\u53C2\u8003\u56FE\u300D\u540E\u624D\u4F1A\u9001\u8FDB\u751F\u4EA7\" onClick={() => { toggleReference(version.id); }}>{selected ? \"\u5DF2\u8BBE\u8865\u5145\u53C2\u8003\" : \"\u8BBE\u4E3A\u8865\u5145\u53C2\u8003\"}</button>}</footer></article>; })}</div></div></section>;\n}\n\nfunction TaskBoard({ jobs, queue, sessionRunning, onCancel, onRemoveQueued }: {\n readonly jobs: readonly ProductionJob[];\n readonly queue: readonly ProductionQueueEntry[];\n readonly sessionRunning: boolean;\n readonly onCancel: (job: ProductionJob) => Promise<void>;\n readonly onRemoveQueued: (job: ProductionJob, itemId: string) => Promise<void>;\n}) {\n const activeJobId = activeProductionJobId(jobs, queue, sessionRunning);\n return <section className=\"oh-story-task-board\">\n <div className=\"oh-story-projection-note\">\u56FE\u7247\u3001\u89C6\u9891\u3001\u8BED\u97F3\u3001\u97F3\u4E50\u90FD\u5148\u9884\u68C0\u3001\u540E\u786E\u8BA4\u3002\u8FD9\u91CC\u8DDF\u8E2A\u56FE\u7247\u3001\u89C6\u9891\u4E0E\u6210\u7247\u4EFB\u52A1\uFF1B\u8BED\u97F3\u548C\u97F3\u4E50\u5728 Chat \u91CC\u5B8C\u6210\uFF0C\u7ED3\u679C\u76F4\u63A5\u843D\u5728\u5236\u4F5C\u6210\u679C\u76EE\u5F55\u3002\u4F9B\u5E94\u5546\u89C1\u4E0A\u65B9\u300C\u751F\u6210\u73AF\u5883\u300D\uFF0C\u5B9E\u9645\u8D26\u53F7\u3001\u6A21\u578B\u4E0E\u53EF\u7528\u6027\u7531\u5F53\u524D DSH \u8FD0\u884C\u73AF\u5883\u51B3\u5B9A\u3002</div>\n {jobs.length === 0 ? <div className=\"oh-story-production-empty\">\u8FD8\u6CA1\u6709\u751F\u4EA7\u4EFB\u52A1\u3002\u53EF\u4ECE\u955C\u5934\u6216\u7D20\u6750\u9875\u63D0\u4EA4\u5355\u4E2A\u6216\u6279\u91CF\u4EFB\u52A1\u3002</div> : [...jobs].reverse().map((job) => {\n const queued = queuedItemForJob(job.id, queue);\n const displayStatus = queued === undefined ? STATUS_LABELS[job.status] : \"DSH Queue\";\n return <article key={job.id} data-job-id={job.id} data-status={job.status}><header><strong title={job.targetId}>{job.targetId}</strong><span>{JOB_KIND_LABEL[job.kind]}</span><span>{displayStatus}</span></header><div className=\"oh-story-task-progress\"><i style={{ width: `${String(job.progress)}%` }} /></div><details><summary>\u67E5\u770B\u6295\u4EA7\u63D0\u793A\u8BCD</summary><p>{job.prompt}</p></details>{job.expectedOutputs > 1 && <small>{job.completedOutputs}/{job.expectedOutputs} \u9879\u6210\u679C</small>}{job.error !== undefined && <div className=\"oh-story-error\">{job.error}</div>}{job.output !== undefined && <MediaPreview version={job.output} />}<footer>{queued !== undefined && (job.status === \"awaiting_confirmation\" || job.status === \"pending\" || job.status === \"running\") && <button type=\"button\" onClick={() => { void onRemoveQueued(job, queued.id); }}>\u4ECE DSH Queue \u79FB\u9664</button>}{activeJobId === job.id && <button type=\"button\" onClick={() => { void onCancel(job); }}>\u505C\u6B62\u5F53\u524D DSH Turn</button>}</footer></article>;\n })}\n </section>;\n}\n\nfunction SequenceBoard(props: Props & { readonly onCompose: () => void }) {\n const composing = compositionInFlight(props.jobs);\n const issues = sequenceIssues(props.sequence, props.versions); const versionById = new Map(props.versions.map((version) => [version.id, version])); const move = (index: number, delta: number) => { const source = props.sequence[index]; const target = props.sequence[index + delta]; if (source !== undefined && target !== undefined) props.onSequenceChange(reorderSequence(props.sequence, index, index + delta)); };\n return <section className=\"oh-story-sequence\"><div className=\"oh-story-sequence-summary\"><strong>{props.sequence.length} \u4E2A\u955C\u5934</strong><span>{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`}</span><button type=\"button\" disabled={composing || issues.length > 0 || props.sequence.length < 2} onClick={props.onCompose}>\u5408\u6210\u6210\u7247</button></div>{issues.length > 0 && <ul className=\"oh-story-sequence-issues\">{issues.slice(0, 3).map((issue) => <li key={issue}>{issue}</li>)}{issues.length > 3 && <li>\u53E6\u6709 {issues.length - 3} \u4E2A\u963B\u585E\u9879\uFF0C\u8BF7\u5728\u4E0B\u65B9\u955C\u5934\u884C\u8865\u9F50\u89C6\u9891\u3002</li>}</ul>}<ol>{props.sequence.map((item, index) => { const version = item.versionId === undefined ? undefined : versionById.get(item.versionId); return <li key={item.shotId}><span>{String(index + 1).padStart(2, \"0\")}</span>{version === undefined ? <div className=\"oh-story-sequence-missing\">\u7F3A\u5C11\u89C6\u9891</div> : <MediaPreview version={version} interactive={false} />}<strong>{item.shotId}</strong><div><button type=\"button\" aria-label={`\u4E0A\u79FB ${item.shotId}`} disabled={index === 0} onClick={() => { move(index, -1); }}>\u2191</button><button type=\"button\" aria-label={`\u4E0B\u79FB ${item.shotId}`} disabled={index === props.sequence.length - 1} onClick={() => { move(index, 1); }}>\u2193</button></div></li>; })}</ol></section>;\n}\n\nfunction ProductionCanvas(props: Props) {\n const nodes = useMemo(() => { const sourceAssets = [...props.production.assets, ...props.production.visualAssets]; const assets = sourceAssets.map((asset, index) => ({ id: asset.id, label: asset.title, type: \"asset\", initial: { x: 80, y: 80 + index * 150 } })); const shots = props.production.shots.map((shot, index) => ({ id: shot.id, label: shot.title, type: \"shot\", initial: { x: 640, y: 80 + index * 180 } })); return [...assets, ...shots]; }, [props.production.assets, props.production.shots, props.production.visualAssets]);\n const positions = Object.fromEntries(nodes.map((node) => [node.id, props.canvas[node.id] ?? node.initial]));\n const startDrag = (event: ReactPointerEvent<HTMLElement>, id: string) => { event.currentTarget.setPointerCapture(event.pointerId); const origin = positions[id] ?? { x: 0, y: 0 }; const start = { x: event.clientX, y: event.clientY }; const move = (moveEvent: PointerEvent) => { props.onCanvasChange({ ...props.canvas, [id]: { x: origin.x + (moveEvent.clientX - start.x) / props.zoom, y: origin.y + (moveEvent.clientY - start.y) / props.zoom } }); }; const end = () => { globalThis.removeEventListener(\"pointermove\", move); globalThis.removeEventListener(\"pointerup\", end); }; globalThis.addEventListener(\"pointermove\", move); globalThis.addEventListener(\"pointerup\", end); };\n const moveNode = (id: string, x: number, y: number) => { const origin = positions[id] ?? { x: 0, y: 0 }; props.onCanvasChange({ ...props.canvas, [id]: { x: origin.x + x, y: origin.y + y } }); };\n const connections = props.production.shots.flatMap((shot) => shot.references.map((reference) => [reference, shot.id] as const));\n if (nodes.length === 0) return <section className=\"oh-story-canvas-shell\" aria-label=\"\u77ED\u5267\u7D20\u6750\u4E0E\u955C\u5934\u5173\u7CFB\u753B\u5E03\"><MissingDocument document={`${props.production.episodeDirectory}/\u5206\u955C.md`} documentPaths={props.production.documentPaths} what=\"\u5173\u7CFB\" skill=\"/short-drama-storyboard\" onNavigate={props.onNavigate} /></section>;\n return <section className=\"oh-story-canvas-shell\" aria-label=\"\u77ED\u5267\u7D20\u6750\u4E0E\u955C\u5934\u5173\u7CFB\u753B\u5E03\"><div className=\"oh-story-projection-note\">\u6587\u6863\u5173\u7CFB \u00B7 \u5E03\u5C40\u4EC5\u4FDD\u5B58\u5728\u5F53\u524D DSH Session</div><div className=\"oh-story-canvas-controls\"><button type=\"button\" aria-label=\"\u7F29\u5C0F\u753B\u5E03\" onClick={() => { props.onZoomChange(Math.max(.5, props.zoom - .1)); }}>\u2212</button><span>{Math.round(props.zoom * 100)}%</span><button type=\"button\" aria-label=\"\u653E\u5927\u753B\u5E03\" onClick={() => { props.onZoomChange(Math.min(1.8, props.zoom + .1)); }}>\uFF0B</button><button type=\"button\" onClick={() => { props.onCanvasChange({}); props.onZoomChange(.65); }}>\u590D\u4F4D</button></div><div className=\"oh-story-canvas-viewport\"><div className=\"oh-story-canvas\" style={{ transform: `scale(${String(props.zoom)})` }}><svg aria-hidden=\"true\">{connections.map(([from, to]) => { const a = positions[from]; const b = positions[to]; if (a === undefined || b === undefined) return null; return <path key={`${from}:${to}`} data-active={to === props.selectedId || undefined} d={`M ${String(a.x + 180)} ${String(a.y + 50)} C ${String(a.x + 360)} ${String(a.y + 50)}, ${String(b.x - 180)} ${String(b.y + 50)}, ${String(b.x)} ${String(b.y + 50)}`} />; })}</svg>{nodes.map((node) => <article key={node.id} tabIndex={0} aria-label={`${node.type === \"asset\" ? \"\u7D20\u6750\" : \"\u955C\u5934\"} ${node.label}`} data-node-type={node.type} data-selected={node.id === props.selectedId || undefined} style={{ left: positions[node.id]?.x, top: positions[node.id]?.y }} onKeyDown={(event) => { const step = event.shiftKey ? 40 : 10; const delta: readonly [number, number] | undefined = event.key === \"ArrowLeft\" ? [-step, 0] : event.key === \"ArrowRight\" ? [step, 0] : event.key === \"ArrowUp\" ? [0, -step] : event.key === \"ArrowDown\" ? [0, step] : undefined; if (delta !== undefined) { event.preventDefault(); moveNode(node.id, delta[0], delta[1]); } }} onPointerDown={(event) => { startDrag(event, node.id); }} onDoubleClick={() => { const target = props.production.targets.get(node.id); if (target !== undefined) props.onNavigate(target); }}><small>{node.type === \"asset\" ? \"\u7D20\u6750\" : \"\u955C\u5934\"}</small><strong>{node.label}</strong><span>{node.id}</span></article>)}</div></div></section>;\n}\n\n/** Scroll the card an Agent focus_target selected into view; without it the tab switches but the card stays off-screen. */\nfunction useScrollIntoView(selectedId: string | undefined) {\n const ref = useRef<HTMLElement | null>(null);\n useEffect(() => { ref.current?.scrollIntoView({ block: \"nearest\" }); }, [selectedId]);\n return ref;\n}\n\nfunction ReadinessBadge({ label, ready }: { readonly label: string; readonly ready: boolean }) {\n return <span data-ready={ready} aria-label={`${label}${ready ? \"\u5DF2\u5907\" : \"\u5F85\u8865\"}`}><i aria-hidden=\"true\">{ready ? \"\u2713\" : \"\u2014\"}</i>{label}</span>;\n}\n\nfunction MissingDocument({ document, documentPaths, what, skill, onNavigate }: {\n readonly document: string;\n readonly documentPaths: readonly string[];\n readonly what: string;\n readonly skill: string;\n readonly onNavigate: (target: DramaDocumentTarget) => void;\n}) {\n const present = documentPaths.includes(document);\n return <div className=\"oh-story-production-empty\">\n <strong>\u8FD8\u6CA1\u6709\u53EF\u6295\u5F71\u7684{what}\u3002</strong>\n <p>{present\n ? `${document} \u5DF2\u5B58\u5728\uFF0C\u4F46\u6CA1\u6709\u89E3\u6790\u51FA\u6761\u76EE\u3002\u8BF7\u68C0\u67E5\u4E8C\u7EA7\u6807\u9898\u662F\u5426\u4E3A\u7A33\u5B9A\u7684 ID \u5F62\u5F0F\u3002`\n : `\u672C\u96C6\u8FD8\u6CA1\u6709 ${document}\u3002\u5728\u53F3\u4FA7 Chat \u7528 ${skill} \u5199\u597D\u8FD9\u4EFD\u6587\u6863\u540E\uFF0C\u8FD9\u91CC\u4F1A\u81EA\u52A8\u51FA\u73B0\u3002`}</p>\n {present && <button type=\"button\" onClick={() => { onNavigate({ path: document, offset: 0, id: document }); }}>\u6253\u5F00 {document.split(\"/\").at(-1)}</button>}\n </div>;\n}\n\nfunction ReferenceButton({ id, production, onNavigate }: { readonly id: string; readonly production: DramaEpisodeProduction; readonly onNavigate: (target: DramaDocumentTarget) => void }) { const target = production.targets.get(id); return <button type=\"button\" disabled={target === undefined} onClick={(event) => { event.stopPropagation(); if (target !== undefined) onNavigate(target); }}>{id}</button>; }\nfunction MediaPreview({ version, interactive = true }: { readonly version: ProductionMediaVersion; readonly interactive?: boolean }) { return version.kind === \"image\" ? <img className=\"oh-story-media-preview\" src={version.url} alt={version.targetId} loading=\"lazy\" /> : <video className=\"oh-story-media-preview\" src={version.url} controls={interactive} muted={!interactive} preload=\"metadata\" />; }\nfunction VersionStrip({ targetId, versions, selections, onSelectionsChange }: { readonly targetId: string; readonly versions: readonly ProductionMediaVersion[]; readonly selections: Readonly<Record<string, string>>; readonly onSelectionsChange: (value: Record<string, string>) => void }) { const selected = selectedVersionForTarget(targetId, versions, selections)?.id; return <div className=\"oh-story-version-strip\" aria-label={`${targetId} \u6210\u679C\u7248\u672C`}>{versions.map((version, index) => <button type=\"button\" aria-pressed={version.id === selected} aria-label={`\u9009\u62E9 ${targetId} \u7248\u672C ${String(index + 1)}`} data-selected={version.id === selected || undefined} key={version.id} onClick={(event) => { event.stopPropagation(); onSelectionsChange({ ...selections, [targetId]: version.id }); }}><MediaPreview version={version} interactive={false} /><span>V{String(index + 1)}</span></button>)}</div>; }\n", "import type { KeyboardEvent as ReactKeyboardEvent } from \"react\";\n\n/** Roving-focus keyboard contract shared by every workbench tablist. */\nexport function handleTabKey<T extends string>(\n event: ReactKeyboardEvent<HTMLButtonElement>,\n values: readonly T[],\n current: T,\n select: (value: T) => void\n): void {\n let index: number | undefined;\n if (event.key === \"Home\") index = 0;\n else if (event.key === \"End\") index = values.length - 1;\n else if (event.key === \"ArrowRight\") index = (values.indexOf(current) + 1) % values.length;\n else if (event.key === \"ArrowLeft\") index = (values.indexOf(current) - 1 + values.length) % values.length;\n if (index === undefined) return;\n event.preventDefault();\n const value = values[index];\n if (value === undefined) return;\n select(value);\n event.currentTarget.parentElement?.querySelectorAll<HTMLButtonElement>(\"[role='tab']\")[index]?.focus();\n}\n\nexport function endpoint(path: string, sessionId: string, file?: string): string {\n const url = new URL(`/oh-story/${path}`, globalThis.location.origin);\n url.searchParams.set(\"sessionId\", sessionId);\n if (file !== undefined) url.searchParams.set(\"path\", file);\n return url.toString();\n}\n", "import type { DramaEpisodeProduction } from \"./drama-production.js\";\nimport type { ProductionJob, ProductionMediaVersion } from \"./production-runtime.js\";\n\nconst authorityBoundary = \"\u53EA\u4F7F\u7528\u5F53\u524D DSH Preset \u53EF\u89C1\u7684\u5DE5\u5177\uFF1B\u6240\u6709\u6587\u4EF6\u3001\u7F51\u7EDC\u3001\u751F\u6210\u548C\u547D\u4EE4\u64CD\u4F5C\u7EE7\u7EED\u9075\u5B88 DSH \u6743\u9650\u4E0E\u5BA1\u6279\u3002\";\n\n/**\n * The listed references are what the workbench can see, not what the job sends: upstream\n * `prepare` requires `reference_bindings` to equal the source entry's own declaration slot for\n * slot, and a frame's role comes from the \u7528\u9014 that entry's \u8F93\u5165\u53C2\u8003\u56FE records (\u5206\u955C.md for SHOT-*,\n * \u89C6\u9891\u63D0\u793A\u8BCD.md for MOTION-*), never from this list. How a \u7ED3\u675F\u5E27 travels depends on the dialect:\n * frame positions keep it in last_frame, but MiniMax H3 cannot mix frame and reference inputs, so a\n * mixed group goes out whole as full-reference reference_image (upstream minimax-h3.md, and\n * target-model-profile.md \u53C2\u8003\u6761\u4EF6\u65B9\u5F0F).\n */\nconst referenceRules = \"\u53C2\u8003\u56FE\u4EE5\u6765\u6E90\u6761\u76EE\u81EA\u5DF1\u7684\u58F0\u660E\u4E3A\u51C6\uFF08IMG-* \u7684\u300C\u53C2\u8003\u300D\uFF0CSHOT-*\uFF0FMOTION-* \u7684\u300C\u8F93\u5165\u53C2\u8003\u56FE\u300D\uFF09\uFF1Areference_bindings \u5FC5\u987B\u4E0E\u8BE5\u6761\u76EE\u9010\u69FD\u4E00\u81F4\uFF0C\u5DE5\u4F5C\u53F0\u5217\u51FA\u7684\u8865\u5145\u53C2\u8003\u53EA\u4F5C\u6838\u5BF9\uFF0C\u6761\u76EE\u91CC\u6CA1\u6709\u58F0\u660E\u7684\u4E0D\u8981\u76F4\u63A5\u52A0\u8FDB job\uFF0C\u786E\u9700\u4F7F\u7528\u65F6\u5148\u8BF7\u62E5\u6709\u8BE5\u6761\u76EE\u7684\u9636\u6BB5\u4FEE\u8BA2\u6587\u6863\u3002\u8D77\u59CB\u5E27\u4E0E\u7ED3\u675F\u5E27\u7684\u89D2\u8272\u53EA\u53D6\u81EA\u6765\u6E90\u6761\u76EE\u81EA\u5DF1\u300C\u8F93\u5165\u53C2\u8003\u56FE\u300D\u5404\u69FD\u4F4D\u8BB0\u5F55\u7684\u7528\u9014\uFF08\u8D77\u59CB\u5E27\uFF0F\u7ED3\u675F\u5E27\uFF09\uFF1ASHOT-* \u770B\u300A\u5206\u955C.md\u300B\uFF0CMOTION-* \u770B\u300A\u89C6\u9891\u63D0\u793A\u8BCD.md\u300B\uFF1B\u518D\u7531\u76EE\u6807\u6A21\u578B\u65B9\u8A00\u7FFB\u6210 adapter \u7684 role\uFF0C\u4E0D\u6309\u6587\u4EF6\u540D\u6216\u5DE5\u4F5C\u53F0\u6E05\u5355\u63A8\u65AD\u3002\u76EE\u6807\u65B9\u8A00\u7528 first_frame\uFF0Flast_frame \u4F4D\u7F6E\u627F\u63A5\u8FD9\u7EC4\u8F93\u5165\u65F6\uFF0C\u7ED3\u675F\u5E27\u53EA\u8FDB last_frame\uFF0C\u7EDD\u4E0D\u964D\u7EA7\u6210\u666E\u901A\u53C2\u8003\u56FE\uFF1B\u65B9\u8A00\u8981\u6C42\u6574\u7EC4\u8D70\u591A\u69FD\u53C2\u8003\u65F6\uFF08\u5982 MiniMax H3 \u7684 full-reference\uFF1A\u9996\u5C3E\u5E27\u8F93\u5165\u4E0E\u53C2\u8003\u8F93\u5165\u4E92\u65A5\uFF0C\u8D77\u59CB\u5E27\u3001\u7ED3\u675F\u5E27\u90FD\u968F\u6574\u7EC4\u4EE5 reference_image \u9001\u5165\uFF09\uFF0C\u6309\u65B9\u8A00\u7FFB\u8BD1\uFF0C\u5E76\u5728\u9884\u89C8\u91CC\u5199\u660E\u7ED3\u675F\u5E27\u5C06\u4F5C\u4E3A\u53C2\u8003\u56FE\u9001\u5165\uFF0C\u6216\u5148\u8BF7\u5206\u955C owner \u53D6\u820D\u3002\";\n/** Upstream's SHOT-* selector extracts only the start frame, so the note belongs to image jobs alone. */\nconst shotStartFrameNote = \"\u5206\u955C.md \u7684 SHOT-* \u53EA\u4EA7\u51FA\u8D77\u59CB\u5E27\uFF1B\u8981\u4EA7\u51FA\u7ED3\u675F\u5E27\uFF0C\u5148\u7531\u56FE\u7247\u63D0\u793A\u8BCD\u9636\u6BB5\u5EFA\u7ACB\u72EC\u7ACB\u7684 IMG-* \u6761\u76EE\u518D\u6295\u4EA7\u3002\";\n\nfunction referenceParagraph(kind: ProductionJob[\"kind\"]): string {\n return kind === \"image\" ? `${referenceRules}${shotStartFrameNote}` : referenceRules;\n}\n\nexport function nativeProductionPrompt(\n production: DramaEpisodeProduction,\n job: ProductionJob,\n references: readonly ProductionMediaVersion[]\n): string {\n const referenceText = references.length === 0\n ? \"\u65E0\"\n : references.map((item) => `${item.targetId}: ${item.path ?? item.url}`).join(\"\\n\");\n return `/short-drama-produce\n\n\u53EA\u51C6\u5907\u5F53\u524D\u5355\u9879\u751F\u4EA7\u4EFB\u52A1\uFF0C\u4E0D\u8FD0\u884C Provider\u3002\n- \u4EFB\u52A1 ID\uFF1A${job.id}\n- \u4EFB\u52A1\u7C7B\u578B\uFF1A${job.kind === \"image\" ? \"\u56FE\u7247/\u5173\u952E\u5E27\" : \"\u955C\u5934\u89C6\u9891\"}\n- \u5EFA\u8BAE adapter \u5951\u7EA6\uFF1A${job.kind === \"image\" ? \"gpt-image-2\" : \"seedance\"}\uFF08\u5B9E\u9645\u914D\u7F6E\u4E0E\u6A21\u578B\u4EE5\u5F53\u524D DSH \u8FD0\u884C\u73AF\u5883\u4E3A\u51C6\uFF09\n- \u6295\u4EA7\u5BF9\u8C61\uFF1A${job.targetId}\n- \u521B\u4F5C\u6587\u6863\u76EE\u5F55\uFF1A${production.episodeDirectory}\n- \u5DE5\u4F5C\u53F0\u5217\u51FA\u7684\u8865\u5145\u53C2\u8003\uFF08\u4E0D\u662F\u751F\u4EA7\u8F93\u5165\u5FEB\u7167\uFF09\uFF1A\n${referenceText}\n- \u8F93\u51FA\u76EE\u5F55\uFF1A${production.episodeDirectory}/\u5236\u4F5C\u6210\u679C/${job.targetId}\n- \u8F93\u51FA\u6587\u4EF6\u540D\u5FC5\u987B\u540C\u65F6\u5305\u542B\u6295\u4EA7\u5BF9\u8C61 ID \u4E0E\u4EFB\u52A1 ID ${job.id}\uFF0C\u4EE5\u4FBF DSH \u5DE5\u4F5C\u53F0\u5173\u8054\u7248\u672C\u3002\n\n\u5F85\u9884\u68C0\u63D0\u793A\u8BCD\uFF1A\n${job.prompt}\n\n${referenceParagraph(job.kind)}\n\n\u6309 short-drama-produce \u7684\u786C\u95F8\u95E8\u5EFA\u7ACB\u4E34\u65F6 job \u5E76\u6267\u884C prepare\uFF0C\u5728 Chat \u4E2D\u5B8C\u6574\u5C55\u793A adapter\u3001\u6A21\u578B/profile\u3001\u6570\u91CF\u3001\u53C2\u6570\u3001references\u3001outputs \u4E0E overwrite\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\u4EFB\u52A1 ID\uFF0C\u5E76\u8FD0\u884C Provider\u3002${authorityBoundary}`;\n}\n\nexport function nativeBatchPrompt(\n production: DramaEpisodeProduction,\n job: ProductionJob,\n candidates: readonly { readonly id: string; readonly prompt: string }[]\n): string {\n return `/short-drama-produce\n\n\u53EA\u51C6\u5907\u5F53\u524D\u6279\u91CF\u751F\u4EA7\u4EFB\u52A1\uFF0C\u4E0D\u8FD0\u884C Provider\u3002\n- \u6279\u6B21\u4EFB\u52A1 ID\uFF1A${job.id}\n- \u4EFB\u52A1\u7C7B\u578B\uFF1A${job.kind === \"image\" ? \"\u6279\u91CF\u5173\u952E\u5E27\" : \"\u6279\u91CF\u955C\u5934\u89C6\u9891\"}\n- \u5EFA\u8BAE adapter \u5951\u7EA6\uFF1A${job.kind === \"image\" ? \"gpt-image-2\" : \"seedance\"}\uFF08\u5B9E\u9645\u914D\u7F6E\u4E0E\u6A21\u578B\u4EE5\u5F53\u524D DSH \u8FD0\u884C\u73AF\u5883\u4E3A\u51C6\uFF09\n- \u521B\u4F5C\u6587\u6863\u76EE\u5F55\uFF1A${production.episodeDirectory}\n- \u8F93\u51FA\u6839\u76EE\u5F55\uFF1A${production.episodeDirectory}/\u5236\u4F5C\u6210\u679C\n- \u6BCF\u4E2A\u8F93\u51FA\u6587\u4EF6\u540D\u5FC5\u987B\u5305\u542B\u5BF9\u5E94\u955C\u5934 ID \u4E0E\u6279\u6B21\u4EFB\u52A1 ID ${job.id}\u3002\n\n${candidates.map((item) => `## ${item.id}\\n${item.prompt}`).join(\"\\n\\n\")}\n\n${referenceParagraph(job.kind)}\n\n\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}`;\n}\n\n/**\n * Upstream's edit stage owns only the \u526A\u8F91\u5355 CUT items, the delivery spec, and what it writes under\n * \u5236\u4F5C\u6210\u679C/\u6210\u7247/ (short-drama-edit stage-contract.md). Normalised clips therefore go to \u6210\u7247/\u89C4\u683C\u7EDF\u4E00/,\n * which mediaTargetFromPath keeps out of the shot versions, and carry no job id that could correlate\n * them with a production job. An external mix ends with the loudnorm pass render itself runs\n * (edit_tool.py `_loudnorm_filter`, then AAC 192k at 48 kHz).\n */\nexport function nativeCompositionPrompt(\n production: DramaEpisodeProduction,\n job: ProductionJob,\n orderedPaths: readonly string[]\n): string {\n return `/short-drama-edit\n\n\u6267\u884C\u521B\u4F5C\u8005\u5DF2\u660E\u786E\u786E\u8BA4\u7684\u6210\u7247\u88C5\u914D\u4EFB\u52A1\u3002\n- \u4EFB\u52A1 ID\uFF1A${job.id}\n- \u5267\u96C6\uFF1A${production.episodeDirectory}\n- \u521B\u4F5C\u8005\u5728\u6210\u7247\u89C6\u56FE\u6392\u5B9A\u7684\u955C\u5E8F\uFF0C\u4E0D\u5F97\u81EA\u884C\u6362\u5E8F\uFF1A\n${orderedPaths.map((path, index) => `${String(index + 1)}. ${path}`).join(\"\\n\")}\n- \u526A\u8F91\u5355\uFF1A${production.episodeDirectory}/\u526A\u8F91\u5355.md\n- \u8F93\u51FA\uFF1A${production.episodeDirectory}/\u5236\u4F5C\u6210\u679C/\u6210\u7247/\n\n\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\u8BB0\u5F55\u7D20\u6750\u53D6\u820D\u3001\u5165\u51FA\u70B9\u3001\u540E\u671F\u5904\u7406\u4E0E\u4EA4\u4ED8\u89C4\u683C\uFF0C\u4E0D\u6539\u5199\u5267\u672C\u3001\u5206\u955C\u6216\u89C6\u9891\u63D0\u793A\u8BCD\u7684\u8BED\u4E49\uFF1B\u4E0D\u8981\u9000\u56DE\u53BB\u751F\u6210\u65B0\u7D20\u6750\u3002\n\n\u89C6\u9891\u63D0\u793A\u8BCD.md \u91CC\u7684\u6BCF\u4E2A\u300C## MOTION-*\u300D\u90FD\u5FC5\u987B\u4F5C\u4E3A\u67D0\u4E2A CUT \u7684\u300C\u6765\u6E90\u300D\uFF0C\u5426\u5219\u5199\u8FDB\u526A\u8F91\u5355\u5F00\u5934\uFF08\u4EA4\u4ED8\u89C4\u683C\u6240\u5728\u5904\u3001\u7B2C\u4E00\u4E2A\u300C## CUT-\u300D\u4E4B\u524D\uFF09\u7684\u4E00\u884C\uFF1A\u300C- \u672A\u91C7\u7528\u955C\u5934\uFF1AMOTION-\u2026\uFF08\u7406\u7531\uFF1A\u6587\u4EF6\u7F3A\u5931\u2014\u2014\u2026\uFF09\uFF1BMOTION-\u2026\uFF08\u7406\u7531\uFF1A\u8D28\u91CF\u4E0D\u53EF\u7528\u2014\u2014\u2026\uFF09\u300D\u3002\u591A\u9879\u7528\u5168\u89D2\u300C\uFF1B\u300D\u8FDE\u63A5\uFF0C\u7406\u7531\u4E0D\u80FD\u4E3A\u7A7A\u3001\u81EA\u8EAB\u4E0D\u542B\u300C\uFF1B\u300D\uFF0C\u5E76\u5199\u660E\u5C5E\u4E8E\u6587\u4EF6\u7F3A\u5931\u3001\u8D28\u91CF\u4E0D\u53EF\u7528\u8FD8\u662F\u53D9\u4E8B\u53D6\u820D\uFF1B\u6F0F\u6389\u4EFB\u4F55\u4E00\u4E2A\uFF0Ccheck \u90FD\u4F1A\u963B\u65AD\u3002\n\n\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\u6240\u6709 CUT \u7684\u7D20\u6750\u5FC5\u987B\u540C\u5BBD\u3001\u540C\u9AD8\u3001\u540C\u5E27\u7387\uFF1Arender \u53EA\u786C\u62FC\u63A5\uFF0C\u4E0D\u7F29\u653E\u4E5F\u4E0D\u6539\u5E27\u7387\u3002check \u62A5\u51FA\u753B\u5E45\u6216\u5E27\u7387\u4E0D\u4E00\u81F4\u65F6\uFF0C\u5728\u5F53\u524D DSH \u6267\u884C\u73AF\u5883\u91CC\u7ECF\u5BA1\u6279\u7528 ffmpeg \u6309\u4EA4\u4ED8\u89C4\u683C\u7EDF\u4E00\u3001\u4FDD\u7559\u6784\u56FE\uFF0C\u65B0\u6587\u4EF6\u5199\u5230 ${production.episodeDirectory}/\u5236\u4F5C\u6210\u679C/\u6210\u7247/\u89C4\u683C\u7EDF\u4E00/\u2014\u2014\u8FD9\u662F\u526A\u8F91\u9636\u6BB5\u81EA\u5DF1\u7684\u4E2D\u95F4\u6587\u4EF6\uFF0C\u4E0D\u653E\u5728\u751F\u4EA7\u9636\u6BB5\u7684\u539F\u7D20\u6750\u65C1\u8FB9\u3001\u4E0D\u8986\u76D6\u5DF2\u751F\u4EA7\u7684\u7D20\u6750\uFF0C\u6587\u4EF6\u540D\u4E5F\u4E0D\u6CBF\u7528\u539F\u6587\u4EF6\u91CC\u7684\u4EFB\u52A1 ID\uFF08\u53EF\u76F4\u63A5\u7528 MOTION ID\uFF09\uFF1B\u5728\u8BE5 CUT \u4E0B\u8BB0\u5F55\u88C1\u5207\u6216\u7559\u8FB9\uFF08\u4E0D\u8981\u5199\u8FDB\u300C\u753B\u9762\u300D\u884C\uFF0C\u5B83\u53EA\u8BA4\u4EAE\u5EA6\u3001\u9971\u548C\u3001\u8272\u6E29\u6216\u300C\u65E0\u300D\u300C\u4E0D\u6821\u300D\uFF09\uFF0C\u628A\u300C\u6765\u6E90\u300D\u6539\u6307\u65B0\u6587\u4EF6\uFF0C\u5165\u51FA\u70B9\u968F\u8F6C\u6362\u53D8\u5316\u65F6\u540C\u6B65\u4FEE\u6539\uFF0C\u518D\u91CD\u8DD1 check\u3002\n\n\u9ED8\u8BA4\u7684\u786C\u5B57\u5E55\u8DEF\u7EBF\u9700\u8981\u5E26 libass \u7684 ffmpeg\uFF0C\u7F3A libass \u65F6\u5982\u5B9E\u62A5\u51FA\uFF0C\u4E0D\u8981\u6084\u6084\u53BB\u6389\u5B57\u5E55\u3002Remotion \u5728\u9879\u76EE\u5916\u7684 ~/.cache/short-drama-edit/remotion \u91CC\u88C5 Node \u4F9D\u8D56\u3001\u9010\u5E27\u8FC7\u65E0\u5934\u6D4F\u89C8\u5668\uFF1A\u53EF\u9009\u7684 Remotion \u5B57\u5E55\u8DEF\u7EBF\u8981\u5B83\uFF0C\u526A\u8F91\u5355\u91CC\u53EA\u8981\u6709\u300C\u753B\u9762\u6587\u5B57\u300D\u884C\u4E5F\u5FC5\u987B\u8981\u5B83\uFF1B\u53EA\u6709\u521B\u4F5C\u8005\u660E\u786E\u540C\u610F\u8FD9\u6B21\u5B89\u88C5\uFF08\u5728\u8BE5\u76EE\u5F55 npm install\uFF0C0.8 \u4E4B\u524D\u88C5\u8FC7\u7684\u8981\u91CD\u88C5\u4E00\u6B21\uFF09\u65F6\u624D\u8D70\uFF0C\u672A\u540C\u610F\u5C31\u4E0D\u5199\u300C\u753B\u9762\u6587\u5B57\u300D\u884C\uFF0C\u5E76\u544A\u8BC9\u521B\u4F5C\u8005\u753B\u9762\u91CC\u7559\u7ED9\u9762\u677F\u7684\u7A7A\u767D\u4F1A\u4FDD\u6301\u7A7A\u767D\u3002\u526A\u8F91\u5355\u7684\u300C\u58F0\u97F3\u300D\u884C\u53EA\u662F\u8BB0\u5F55\uFF0Crender \u4E0D\u6267\u884C\u5B83\uFF1Arender \u5207\u6BB5\u3001\u540C\u573A\u666F\u81EA\u52A8\u63A5\u955C\uFF08CUT \u5199\u4E86\u300C\u753B\u9762\u300D\u6821\u6B63\u5C31\u66FF\u4EE3\u5B83\uFF0C\u300C\u753B\u9762\uFF1A\u4E0D\u6821\u300D\u8DF3\u8FC7\u5B83\uFF0C\u4EA4\u4ED8\u89C4\u683C\u5199\u300C\u63A5\u955C\u5339\u914D\uFF1A\u65E0\u300D\u6574\u96C6\u5173\u95ED\uFF09\u3001\u786C\u62FC\u63A5\u3001\u6DF7\u5165\u300C\u97F3\u6548\u300D\u884C\u3001\u70E7\u5B57\u5E55\u4E0E\u753B\u9762\u6587\u5B57\u3001\u53EF\u9009\u9897\u7C92\u3001\u7EDF\u4E00\u54CD\u5EA6\u3002\u300C\u97F3\u6548\u300D\u884C\u4E4B\u5916\u7684\u6DF7\u97F3\u3001\u4EA4\u53C9\u6DE1\u5165\u3001\u914D\u4E50\u3001\u8F6C\u573A\u6216\u683C\u5F0F\u8F6C\u6362\u90FD\u662F\u53E6\u4E00\u6B65\u7ECF\u5BA1\u6279\u7684\u5916\u90E8 ffmpeg \u5904\u7406\uFF0C\u5148\u5199\u5230\u4E34\u65F6\u6587\u4EF6\uFF1B\u8FD9\u4E00\u6B65\u6700\u540E\u8981\u50CF render \u4E00\u6837\u6309\u526A\u8F91\u5355\u7684\u300C\u4EA4\u4ED8\u54CD\u5EA6\u300D\u5BF9\u6574\u7247\u505A\u4E24\u904D loudnorm\uFF08I=\u4EA4\u4ED8\u54CD\u5EA6\u3001TP=-1.5\u3001LRA=11\uFF0C\u7B2C\u4E8C\u904D\u4EE3\u5165\u7B2C\u4E00\u904D\u7684\u5B9E\u6D4B\u503C\u5E76\u7528 linear=true\uFF09\uFF0C\u97F3\u9891\u7F16\u7801\u4E3A AAC 192k\u300148 kHz\uFF0C\u7136\u540E\u624D\u66FF\u6362 ${production.episodeDirectory}/\u5236\u4F5C\u6210\u679C/\u6210\u7247/\u6210\u7247.mp4\uFF0C\u5E76\u628A\u547D\u4EE4\u8BB0\u8FDB\u526A\u8F91\u5355\uFF1B\u91CD\u65B0 render \u4F1A\u8986\u76D6\u6210\u7247\uFF0C\u8FD9\u4E9B\u6B65\u9AA4\u8981\u91CD\u505A\u3002\u6700\u540E\u5BF9\u4EA4\u4ED8\u7684\u8FD9\u4EFD\u6210\u7247.mp4 \u8FD0\u884C edit_tool.py verify \u5E76\u62A5\u544A\u5B9E\u6D4B\u6570\u5B57\uFF0C\u300C\u672A\u6D4B\u300D\u9879\u7167\u5B9E\u5199\u672A\u6D4B\u3002\n\nffmpeg \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`;\n}\n", "export type ProductionJobKind = \"image\" | \"video\" | \"composition\";\nexport type ProductionJobStatus = \"awaiting_confirmation\" | \"pending\" | \"running\" | \"dispatched_unknown\" | \"succeeded\" | \"failed\" | \"canceled\";\n\nexport interface ProductionMediaVersion {\n readonly id: string;\n readonly targetId: string;\n readonly kind: \"image\" | \"video\";\n readonly url: string;\n /** Workspace-relative path when the result is owned by the DSH FileSystem. */\n readonly path?: string | undefined;\n}\n\nexport interface ProductionJob {\n readonly id: string;\n readonly targetId: string;\n readonly kind: ProductionJobKind;\n readonly status: ProductionJobStatus;\n readonly progress: number;\n readonly prompt: string;\n readonly error?: string | undefined;\n readonly output?: ProductionMediaVersion | undefined;\n readonly expectedOutputs: number;\n readonly completedOutputs: number;\n /**\n * Deliverable whose name the job cannot influence. Drama Skills 0.7 renders the\n * assembled cut to a fixed path, so it carries no job id to correlate on.\n */\n readonly outputPath?: string | undefined;\n /** Versions already at `outputPath` when the job was dispatched, so an earlier cut never completes it. */\n readonly supersededOutputIds?: readonly string[] | undefined;\n}\n\nexport interface ProductionSequenceItem {\n readonly shotId: string;\n readonly versionId?: string | undefined;\n}\n\nexport interface CanvasPoint {\n readonly x: number;\n readonly y: number;\n}\n\nexport interface ProductionQueueEntry {\n readonly id: string;\n readonly preview: string;\n}\n\nfunction record(value: unknown): Record<string, unknown> | undefined {\n return typeof value === \"object\" && value !== null && !Array.isArray(value) ? value as Record<string, unknown> : undefined;\n}\n\n/**\n * DSH Queue rows from the host `inbox` projection's `next-turn` list. DSH 0.1.7 removed\n * `SessionSnapshot.queue`; reading it threw and blanked the whole workbench (#50). The\n * projection is wire JSON and absent without agent-loop, so every row is checked rather than\n * trusted. Like DSH's own QueueDock, a row whose prompt RPC already has a transcript echo is\n * a turn being claimed, not a queued one. The preview is the row's full text: the job-id label\n * is matched against it, and the old 200-character preview could cut that label off.\n */\nexport function productionQueueFromInbox(rows: unknown, claimedRequestIds: ReadonlySet<string> = new Set()): ProductionQueueEntry[] {\n if (!Array.isArray(rows)) return [];\n return rows.flatMap((row) => {\n const item = record(row);\n if (item === undefined || typeof item.id !== \"string\" || !Array.isArray(item.content)) return [];\n const source = record(item.source);\n if (source?.kind === \"user\" && typeof source.rpcId === \"string\" && claimedRequestIds.has(source.rpcId)) return [];\n const preview = item.content.flatMap((block) => {\n const value = record(block);\n return value?.type === \"text\" && typeof value.text === \"string\" ? [value.text] : [];\n }).join(\" \");\n return [{ id: item.id, preview }];\n });\n}\n\nexport function createPendingJob(input: {\n readonly id: string;\n readonly targetId: string;\n readonly kind: ProductionJobKind;\n readonly prompt: string;\n readonly expectedOutputs?: number | undefined;\n readonly outputPath?: string | undefined;\n readonly supersededOutputIds?: readonly string[] | undefined;\n}): ProductionJob {\n return {\n id: input.id,\n targetId: input.targetId,\n kind: input.kind,\n status: \"pending\",\n progress: 0,\n prompt: input.prompt,\n expectedOutputs: Math.max(1, Math.floor(input.expectedOutputs ?? 1)),\n completedOutputs: 0,\n outputPath: input.outputPath,\n supersededOutputIds: input.supersededOutputIds\n };\n}\n\nexport function selectedVersionForTarget(\n targetId: string,\n versions: readonly ProductionMediaVersion[],\n selections: Readonly<Record<string, string>>,\n kind?: ProductionMediaVersion[\"kind\"]\n): ProductionMediaVersion | undefined {\n const candidates = versions.filter((version) => version.targetId === targetId && (kind === undefined || version.kind === kind));\n return candidates.find((version) => version.id === selections[targetId]) ?? candidates.at(-1);\n}\n\n/**\n * Upstream's edit stage owns what it writes under \u5236\u4F5C\u6210\u679C/\u6210\u7247/ \u2014 the cut, its segments, and clips\n * normalised into \u6210\u7247/\u89C4\u683C\u7EDF\u4E00/ \u2014 so none of it is a new version of a shot or asset, even when a\n * filename carries that shot's or MOTION's ID.\n */\nconst EDIT_OUTPUT_DIRECTORY = /(?:^|\\/)\u5236\u4F5C\u6210\u679C\\/\u6210\u7247\\//u;\n\nexport function mediaTargetFromPath(path: string, knownTargets: readonly string[]): string | undefined {\n if (EDIT_OUTPUT_DIRECTORY.test(path)) return undefined;\n const upper = path.toLocaleUpperCase();\n const segments = upper.split(\"/\");\n const filename = segments.at(-1) ?? \"\";\n return [...knownTargets].sort((left, right) => right.length - left.length).find((target) => {\n const canonical = target.toLocaleUpperCase();\n return segments.includes(canonical)\n || filename === canonical\n || filename.startsWith(`${canonical}.`)\n || filename.startsWith(`${canonical}-`);\n });\n}\n\nexport function mediaVersionMatchesJob(version: ProductionMediaVersion, jobId: string): boolean {\n if (version.path === undefined || jobId.trim() === \"\") return false;\n const escaped = jobId.replace(/[.*+?^${}()|[\\]\\\\]/gu, \"\\\\$&\");\n const basename = version.path.split(\"/\").at(-1) ?? \"\";\n return new RegExp(`(?:^|[-_.])${escaped}(?:[-_.]|$)`, \"u\").test(basename);\n}\n\nexport function outputsForJob(job: ProductionJob, versions: readonly ProductionMediaVersion[]): ProductionMediaVersion[] {\n if (job.outputPath === undefined) return versions.filter((version) => mediaVersionMatchesJob(version, job.id));\n const superseded = new Set(job.supersededOutputIds ?? []);\n return versions.filter((version) => version.path === job.outputPath && !superseded.has(version.id));\n}\n\n/**\n * True while a composition the creator already dispatched has not settled. Every composition\n * for an episode renders to the same upstream path, so a second one dispatched now would be\n * completed by the first one's cut \u2014 and, once marked succeeded, could no longer be removed\n * from the DSH Queue.\n */\nexport function compositionInFlight(jobs: readonly ProductionJob[]): boolean {\n return jobs.some((job) => job.kind === \"composition\"\n && (job.status === \"awaiting_confirmation\" || job.status === \"pending\" || job.status === \"running\"));\n}\n\n/**\n * A composition whose Turn ended without a cut stays dispatched_unknown so a late cut can still\n * complete it, and compositionInFlight lets the creator compose again. Both render to the same\n * upstream path, so once a new composition is dispatched its cut would complete the old job too.\n * Fail the old one instead, keeping the check findings its error already reports.\n */\nexport function settleSupersededCompositions(jobs: readonly ProductionJob[], next: ProductionJob): ProductionJob[] {\n if (next.kind !== \"composition\") return [...jobs];\n return jobs.map((job) => (\n job.id !== next.id\n && job.kind === \"composition\"\n && job.status === \"dispatched_unknown\"\n && (job.targetId === next.targetId || (job.outputPath !== undefined && job.outputPath === next.outputPath))\n ? { ...job, status: \"failed\" }\n : job\n ));\n}\n\nexport function referencesForTarget(\n targetId: string,\n production: { readonly shots: readonly { readonly id: string; readonly references: readonly string[] }[] },\n versions: readonly ProductionMediaVersion[],\n selections: Readonly<Record<string, string>>,\n libraryVersions: readonly ProductionMediaVersion[] = versions,\n manualReferences: Readonly<Record<string, readonly string[]>> = {}\n): ProductionMediaVersion[] {\n const shot = production.shots.find((item) => item.id === targetId);\n if (shot === undefined) return [];\n const declared = shot.references.flatMap((id) => {\n const version = selectedVersionForTarget(id, versions, selections, \"image\");\n return version === undefined ? [] : [version];\n });\n const manual = (manualReferences[targetId] ?? []).flatMap((id) => {\n const version = libraryVersions.find((item) => item.id === id && item.kind === \"image\");\n return version === undefined ? [] : [version];\n });\n return [...new Map([...declared, ...manual].map((version) => [version.id, version])).values()];\n}\n\nexport function queuedItemForJob(jobId: string, queue: readonly ProductionQueueEntry[]): ProductionQueueEntry | undefined {\n if (jobId.trim() === \"\") return undefined;\n const escaped = jobId.replace(/[.*+?^${}()|[\\]\\\\]/gu, \"\\\\$&\");\n // The prompts label the id as \u300C\u4EFB\u52A1 ID\uFF1A<id>\u300D / \u300C\u6279\u6B21\u4EFB\u52A1 ID\uFF1A<id>\u300D. Anchor on that label so an\n // id merely quoted inside another job's output paths cannot mark this job as queued.\n const labelled = new RegExp(`\u4EFB\u52A1\\\\s*ID\\\\s*[\uFF1A:]\\\\s*${escaped}(?:[\\\\s.,;\u3001\u3002]|$)`, \"u\");\n return queue.find((item) => labelled.test(item.preview));\n}\n\nexport function activeProductionJobId(\n jobs: readonly ProductionJob[],\n queue: readonly ProductionQueueEntry[],\n sessionRunning: boolean\n): string | undefined {\n if (!sessionRunning) return undefined;\n return [...jobs].reverse().find((job) => (\n (job.status === \"awaiting_confirmation\" || job.status === \"pending\" || job.status === \"running\")\n && queuedItemForJob(job.id, queue) === undefined\n ))?.id;\n}\n\n/** Reconcile the lightweight Session projection against DSH Queue/Turn state and real workspace outputs. */\nexport function reconcileProductionJobs(\n jobs: readonly ProductionJob[],\n queue: readonly ProductionQueueEntry[],\n sessionRunning: boolean,\n versions: readonly ProductionMediaVersion[]\n): ProductionJob[] {\n const latestPending = [...jobs].reverse().find((job) => (\n job.status === \"pending\" && queuedItemForJob(job.id, queue) === undefined\n ));\n\n // Retire an unfinished composition only once a newer one actually runs, and before outputs are\n // matched, so the newer cut cannot complete it. A dispatch that fails or is withdrawn from the\n // Queue leaves the older one to be finished in Chat.\n const settleCompositions = (list: readonly ProductionJob[]): ProductionJob[] => list\n .filter((job) => job.kind === \"composition\" && job.status === \"running\")\n .reduce((current, running) => settleSupersededCompositions(current, running), [...list]);\n const reconciled = settleCompositions(jobs).map((job): ProductionJob => {\n const queued = queuedItemForJob(job.id, queue) !== undefined;\n // A terminal job is never revived by a result that arrived later. This matters most for\n // `outputPath`: a shared deliverable name carries no job identity, so without this guard\n // the next cut would complete a job the creator canceled, and bury the error a failed one\n // reported. A job-id correlated failure keeps its old behaviour \u2014 that output really is its own.\n if (job.status === \"canceled\" || job.status === \"succeeded\") return job;\n if (job.status === \"failed\" && job.outputPath !== undefined) return job;\n const outputs = outputsForJob(job, versions);\n\n if (outputs.length >= job.expectedOutputs) {\n return {\n ...job,\n status: \"succeeded\",\n progress: 100,\n completedOutputs: outputs.length,\n output: outputs[0],\n error: undefined\n };\n }\n if (job.status === \"awaiting_confirmation\" && outputs.length === 0) return job;\n if (job.status === \"running\" && queued) return { ...job, status: \"pending\", progress: 0 };\n if (job.status === \"pending\" && sessionRunning && !queued && job === latestPending) {\n return { ...job, status: \"running\", progress: Math.max(10, job.progress), error: undefined };\n }\n if (!sessionRunning && !queued && (job.status === \"running\" || job.status === \"dispatched_unknown\")) {\n return {\n ...job,\n status: \"dispatched_unknown\",\n progress: Math.round(outputs.length / job.expectedOutputs * 100),\n completedOutputs: outputs.length,\n // Assembly is local ffmpeg, so nothing was billed: a missing cut usually means edit_tool\n // check blocked the render, and those findings \u2014 not a billing warning \u2014 are what to show.\n error: outputs.length > 0\n ? `DSH Turn \u5DF2\u7ED3\u675F\uFF0C\u5DF2\u53D1\u73B0 ${String(outputs.length)}/${String(job.expectedOutputs)} \u9879\u6210\u679C\uFF1B\u8BF7\u5237\u65B0\u6838\u5BF9\u5269\u4F59\u8F93\u51FA\u3002`\n : job.kind === \"composition\"\n ? \"\u6210\u7247\u672A\u751F\u6210\uFF1A\u8BF7\u5728 Chat \u67E5\u770B edit_tool check \u7684\u963B\u65AD\u9879\uFF08\u672A\u91C7\u7528\u955C\u5934\u7406\u7531\u3001\u753B\u5E45/\u5E27\u7387\u4E0D\u4E00\u81F4\u7B49\uFF09\uFF0C\u4FEE\u6B63\u540E\u518D\u5408\u6210\u3002\"\n : \"DSH Turn \u5DF2\u7ED3\u675F\uFF0C\u5C1A\u672A\u53D1\u73B0\u5173\u8054\u6210\u679C\u3002\u4EFB\u52A1\u53EF\u80FD\u5DF2\u6D3E\u53D1\uFF0C\u8BF7\u5148\u5237\u65B0\u6210\u679C\uFF0C\u907F\u514D\u91CD\u590D\u8BA1\u8D39\u3002\"\n };\n }\n if (outputs.length > 0) {\n return {\n ...job,\n status: job.status === \"failed\" ? \"failed\" : \"running\",\n progress: Math.max(10, Math.round(outputs.length / job.expectedOutputs * 100)),\n completedOutputs: outputs.length,\n error: job.status === \"failed\" ? job.error : undefined\n };\n }\n return job;\n });\n return settleCompositions(reconciled);\n}\n\nexport function reconcileSequence(\n shotIds: readonly string[],\n current: readonly ProductionSequenceItem[],\n versions: readonly ProductionMediaVersion[],\n selections: Readonly<Record<string, string>>\n): ProductionSequenceItem[] {\n const shotSet = new Set(shotIds);\n const preserved = current.filter((item) => shotSet.has(item.shotId));\n const present = new Set(preserved.map((item) => item.shotId));\n const appended = shotIds.filter((shotId) => !present.has(shotId)).map((shotId) => ({ shotId }));\n return [...preserved, ...appended].map((item) => ({\n shotId: item.shotId,\n versionId: selectedVersionForTarget(item.shotId, versions, selections, \"video\")?.id\n }));\n}\n\nexport function sequenceIssues(sequence: readonly ProductionSequenceItem[], versions: readonly ProductionMediaVersion[]): string[] {\n const versionById = new Map(versions.map((version) => [version.id, version]));\n const issues: string[] = [];\n for (const item of sequence) {\n const version = item.versionId === undefined ? undefined : versionById.get(item.versionId);\n if (version === undefined || version.kind !== \"video\") issues.push(`${item.shotId} \u7F3A\u5C11\u5DF2\u9009\u89C6\u9891\u7248\u672C`);\n else if (version.path === undefined) issues.push(`${item.shotId} \u7684\u89C6\u9891\u6CA1\u6709\u53EF\u4F9B DSH \u8BFB\u53D6\u7684\u5DE5\u4F5C\u533A\u8DEF\u5F84`);\n }\n return issues;\n}\n\nexport function reorderSequence(sequence: readonly ProductionSequenceItem[], source: number, target: number): ProductionSequenceItem[] {\n if (!Number.isInteger(source) || !Number.isInteger(target)) return [...sequence];\n if (source < 0 || target < 0 || source >= sequence.length || target >= sequence.length || source === target) return [...sequence];\n const next = [...sequence];\n const [item] = next.splice(source, 1);\n if (item !== undefined) next.splice(target, 0, item);\n return next;\n}\n", "export const OH_STORY_PRODUCTION_TOOL_NAME = \"oh_story_production\";\n\nexport const PRODUCTION_INTENT_ACTIONS = [\n \"open_section\",\n \"focus_target\",\n \"set_sequence\",\n \"track_job\"\n] as const;\n\nexport const PRODUCTION_INTENT_SECTIONS = [\"shots\", \"assets\", \"tasks\", \"sequence\", \"canvas\"] as const;\nexport const PRODUCTION_INTENT_JOB_KINDS = [\"image\", \"video\", \"composition\"] as const;\n\nexport type ProductionIntentAction = typeof PRODUCTION_INTENT_ACTIONS[number];\nexport type ProductionIntentSection = typeof PRODUCTION_INTENT_SECTIONS[number];\nexport type ProductionIntentJobKind = typeof PRODUCTION_INTENT_JOB_KINDS[number];\n\nexport interface ProductionIntentArgs {\n readonly action: ProductionIntentAction;\n readonly episode: string;\n readonly section?: ProductionIntentSection | undefined;\n readonly targetId?: string | undefined;\n readonly shotIds?: readonly string[] | undefined;\n readonly jobId?: string | undefined;\n readonly jobKind?: ProductionIntentJobKind | undefined;\n readonly expectedOutputs?: number | undefined;\n readonly prompt?: string | undefined;\n}\n\nfunction requiredText(value: string | undefined, field: string): string {\n const normalized = value?.trim();\n if (!normalized) throw new Error(`oh_story_production ${field} is required for this action.`);\n if (normalized.length > 512) throw new Error(`oh_story_production ${field} is too long.`);\n return normalized;\n}\n\n/** Validate the cross-runtime UI intent without reading or mutating workspace state. */\nexport function validateProductionIntent(args: ProductionIntentArgs): ProductionIntentArgs {\n const episode = args.episode.trim().replaceAll(\"\\\\\", \"/\").replace(/\\/$/u, \"\");\n if (!/^\u5267\u96C6\\/EP\\d{3,}$/u.test(episode)) {\n throw new Error(\"oh_story_production episode must use the creator path form \u5267\u96C6/EP001.\");\n }\n if (args.action === \"open_section\") {\n if (args.section === undefined) throw new Error(\"oh_story_production section is required for open_section.\");\n return { action: args.action, episode, section: args.section };\n }\n if (args.action === \"focus_target\") {\n return { action: args.action, episode, targetId: requiredText(args.targetId, \"targetId\"), section: args.section };\n }\n if (args.action === \"set_sequence\") {\n const shotIds = args.shotIds?.map((value) => value.trim()).filter((value) => value !== \"\") ?? [];\n if (shotIds.length === 0) throw new Error(\"oh_story_production shotIds must contain at least one shot for set_sequence.\");\n if (shotIds.length > 500 || new Set(shotIds).size !== shotIds.length || shotIds.some((value) => !/^SHOT-[A-Z0-9-]+$/u.test(value))) {\n throw new Error(\"oh_story_production shotIds must be unique canonical SHOT-* identifiers.\");\n }\n return { action: args.action, episode, shotIds };\n }\n // Leave expectedOutputs/prompt undefined when the caller omits them: track_job re-registers a job the\n // workbench already created, and defaulting here would silently reset a batch's count to 1.\n const expectedOutputs = args.expectedOutputs;\n if (expectedOutputs !== undefined && (!Number.isInteger(expectedOutputs) || expectedOutputs < 1 || expectedOutputs > 500)) {\n throw new Error(\"oh_story_production expectedOutputs must be an integer between 1 and 500.\");\n }\n if (args.jobKind === undefined) throw new Error(\"oh_story_production jobKind is required for track_job.\");\n const prompt = args.prompt?.trim();\n return {\n action: args.action,\n episode,\n jobId: requiredText(args.jobId, \"jobId\"),\n targetId: requiredText(args.targetId, \"targetId\"),\n jobKind: args.jobKind,\n expectedOutputs,\n prompt: prompt === \"\" ? undefined : prompt\n };\n}\n", "import type { ChatSnapshot } from \"@deepseek-ai/dsh-client-ui-chat/client\";\nimport type { ToolCallBlock } from \"@deepseek-ai/dsh-client-ui-conversation/client\";\nimport {\n OH_STORY_PRODUCTION_TOOL_NAME,\n validateProductionIntent,\n type ProductionIntentArgs\n} from \"../production-intent.js\";\n\nexport interface SettledProductionIntent {\n readonly callId: string;\n readonly intent: ProductionIntentArgs;\n}\n\nfunction parsedIntent(block: ToolCallBlock): SettledProductionIntent | undefined {\n if (!(\"kind\" in block) || block.isError || block.call?.name !== OH_STORY_PRODUCTION_TOOL_NAME) return undefined;\n try {\n const args = JSON.parse(block.call.argsRaw) as ProductionIntentArgs;\n return { callId: block.callId, intent: validateProductionIntent(args) };\n } catch {\n return undefined;\n }\n}\n\nfunction visit(block: ToolCallBlock, output: SettledProductionIntent[]): void {\n const direct = parsedIntent(block);\n if (direct !== undefined) output.push(direct);\n for (const child of block.subCalls) visit(child, output);\n}\n\n/** Replay durable successful Agent UI intents in official DSH Chat order. */\nexport function settledProductionIntents(chat: ChatSnapshot): SettledProductionIntent[] {\n const output: SettledProductionIntent[] = [];\n for (const key of chat.order) {\n const node = chat.nodes.get(key);\n if (node?.kind !== \"tool-call\") continue;\n const root = (node.data as { readonly root?: ToolCallBlock }).root;\n if (root !== undefined) visit(root, output);\n }\n return output;\n}\n", "import { useEffect, useId, useRef, useState } from \"react\";\nimport { workbenchLabel, type WorkbenchMode } from \"./file-activity.js\";\nimport { endpoint, handleTabKey } from \"./workbench-ui.js\";\n\nexport interface VideoPreviewAsset {\n readonly role: \"source\" | \"edited\" | \"final\";\n readonly label: string;\n readonly path: string;\n readonly bytes: number;\n readonly version: string;\n readonly mimeType: string;\n}\n\nexport interface VideoArtifactSummary {\n readonly label: string;\n readonly path: string;\n readonly version: string;\n readonly kind: \"plan\" | \"script\" | \"subtitle\" | \"quality\" | \"manifest\";\n}\n\nexport interface VideoProject {\n readonly id: string;\n readonly root: string;\n readonly title: string;\n readonly state: \"not-started\" | \"working\" | \"waiting\" | \"ready\";\n readonly stage: string;\n readonly stageLabel: string;\n readonly nextArtifact?: string | undefined;\n readonly previews: readonly VideoPreviewAsset[];\n readonly artifacts: readonly VideoArtifactSummary[];\n}\n\ninterface FilePayload { readonly content: string }\ninterface VideoPreflight {\n readonly python: { readonly ok: boolean; readonly version?: string };\n readonly ffmpeg: { readonly ok: boolean; readonly subtitles: boolean };\n readonly ffprobe: { readonly ok: boolean };\n readonly credentials: { readonly mimo: boolean; readonly fish: boolean; readonly indexTts: boolean; readonly ttsProvider: string };\n}\n\nfunction preferredPreview(project: VideoProject): VideoPreviewAsset | undefined {\n return project.previews.find((item) => item.role === \"final\")\n ?? project.previews.find((item) => item.role === \"edited\")\n ?? project.previews.find((item) => item.role === \"source\");\n}\n\nfunction readableBytes(bytes: number): string {\n if (bytes < 1_024 * 1_024) return `${(bytes / 1_024).toFixed(1)} KB`;\n if (bytes < 1_024 * 1_024 * 1_024) return `${(bytes / (1_024 * 1_024)).toFixed(1)} MB`;\n return `${(bytes / (1_024 * 1_024 * 1_024)).toFixed(2)} GB`;\n}\n\nfunction ActionIcon({ name }: { readonly name: \"reload\" | \"fullscreen\" | \"external\" }) {\n const paths = {\n reload: <><path d=\"M20 11a8 8 0 1 0-2.34 5.66\"/><path d=\"M20 4v7h-7\"/></>,\n fullscreen: <><path d=\"M8 3H3v5M16 3h5v5M8 21H3v-5M16 21h5v-5\"/></>,\n external: <><path d=\"M14 3h7v7M21 3l-9 9\"/><path d=\"M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6\"/></>\n };\n return <svg aria-hidden viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.8\" strokeLinecap=\"round\" strokeLinejoin=\"round\">{paths[name]}</svg>;\n}\n\nfunction preferredArtifact(project: VideoProject): VideoArtifactSummary | undefined {\n return project.artifacts.find((item) => item.path.endsWith(\"final_qc.json\"))\n ?? project.artifacts.find((item) => item.path.endsWith(\"assembly_qc.json\"))\n ?? project.artifacts.find((item) => item.kind === \"quality\")\n ?? project.artifacts.at(-1);\n}\n\nfunction artifactKindLabel(kind: VideoArtifactSummary[\"kind\"]): string {\n return { plan: \"\u65B9\u6848\", script: \"\u6587\u7A3F\", subtitle: \"\u5B57\u5E55\", quality: \"\u8D28\u68C0\", manifest: \"\u6E05\u5355\" }[kind];\n}\n\nfunction VideoPreview({ project, sessionId, running }: { readonly project: VideoProject; readonly sessionId: string; readonly running: boolean }) {\n const shellRef = useRef<HTMLDivElement>(null);\n const initial = preferredPreview(project);\n const [role, setRole] = useState<VideoPreviewAsset[\"role\"] | undefined>(initial?.role);\n const selected = project.previews.find((item) => item.role === role) ?? preferredPreview(project);\n const [loaded, setLoaded] = useState(initial);\n const [revision, setRevision] = useState(0);\n const [ready, setReady] = useState(false);\n const [error, setError] = useState(false);\n if (selected === undefined || loaded === undefined) return <div className=\"oh-video-preview-empty\">\n <span aria-hidden>\u25B6</span>\n <strong>\u8FD8\u6CA1\u6709\u53EF\u9884\u89C8\u7684\u89C6\u9891</strong>\n <p>\u628A\u539F\u7247\u5BFC\u5165 <code>video-recaps/&lt;\u9879\u76EE&gt;/sources/</code>\uFF0C\u7136\u540E\u5728\u53F3\u4FA7 Chat \u4F7F\u7528 <code>/video-recap</code>\u3002\u526A\u540E\u7247\u548C\u6700\u7EC8\u6210\u7247\u4F1A\u81EA\u52A8\u51FA\u73B0\u5728\u8FD9\u91CC\u3002</p>\n <div className=\"oh-video-prompt-example\"><span>\u63CF\u8FF0\u793A\u4F8B</span><q>\u628A\u8FD9\u6BB5\u89C6\u9891\u505A\u6210 3 \u5206\u949F\u4E2D\u6587\u89E3\u8BF4\uFF0C\u4FDD\u7559\u5173\u952E\u539F\u58F0\uFF0C\u5B57\u5E55\u70E7\u8FDB\u753B\u9762\u3002</q></div>\n </div>;\n const pending = selected.path !== loaded.path || selected.version !== loaded.version;\n const load = (asset: VideoPreviewAsset): void => {\n setRole(asset.role);\n setLoaded(asset);\n setReady(false);\n setError(false);\n setRevision((value) => value + 1);\n };\n const runtimeState = error ? \"\u89C6\u9891\u8F7D\u5165\u5931\u8D25 \u00B7 \u53EF\u91CD\u65B0\u8F7D\u5165\"\n : running ? \"Agent \u6B63\u5728\u66F4\u65B0\u9879\u76EE \u00B7 \u5F53\u524D\u64AD\u653E\u4FDD\u6301\u4E0D\u53D8\"\n : pending ? \"\u65B0\u7248\u672C\u5DF2\u5C31\u7EEA \u00B7 \u7531\u4F60\u51B3\u5B9A\u4F55\u65F6\u8F7D\u5165\"\n : ready ? `${loaded.label}\u5DF2\u8F7D\u5165 \u00B7 ${readableBytes(loaded.bytes)}` : \"\u6B63\u5728\u8BFB\u53D6\u89C6\u9891\u4FE1\u606F\u2026\";\n const mediaUrl = `${endpoint(\"media\", sessionId, loaded.path)}&version=${encodeURIComponent(loaded.version)}&reload=${String(revision)}`;\n return <div ref={shellRef} className=\"oh-video-preview-shell\" data-state={error ? \"error\" : running ? \"building\" : ready ? \"ready\" : \"loading\"}>\n <div className=\"oh-video-stagebar\">\n <div className=\"oh-video-version-tabs\" role=\"tablist\" aria-label=\"\u9884\u89C8\u7248\u672C\">\n {project.previews.map((asset) => <button\n type=\"button\"\n role=\"tab\"\n key={asset.role}\n aria-selected={asset.role === selected.role}\n tabIndex={asset.role === selected.role ? 0 : -1}\n onKeyDown={(event) => { handleTabKey(event, project.previews.map((item) => item.role), selected.role, (next) => {\n const asset = project.previews.find((item) => item.role === next);\n if (asset !== undefined) load(asset);\n }); }}\n onClick={() => { load(asset); }}\n >{asset.label}</button>)}\n </div>\n <span className=\"oh-video-runtime-state\" role=\"status\" aria-live=\"polite\"><i aria-hidden /><em>{runtimeState}</em></span>\n <div className=\"oh-video-preview-actions\">\n {pending && <button type=\"button\" onClick={() => { load(selected); }}>\u8F7D\u5165\u65B0\u7248\u672C</button>}\n <button type=\"button\" title=\"\u91CD\u65B0\u8F7D\u5165\" aria-label=\"\u91CD\u65B0\u8F7D\u5165\u89C6\u9891\" onClick={() => { load(loaded); }}><ActionIcon name=\"reload\" /></button>\n <button type=\"button\" title=\"\u5168\u5C4F\" aria-label=\"\u5168\u5C4F\u9884\u89C8\" onClick={() => { void shellRef.current?.requestFullscreen(); }}><ActionIcon name=\"fullscreen\" /></button>\n <a href={mediaUrl} target=\"_blank\" rel=\"noreferrer\" title=\"\u5728\u65B0\u7A97\u53E3\u6253\u5F00\" aria-label=\"\u5728\u65B0\u7A97\u53E3\u6253\u5F00\u89C6\u9891\"><ActionIcon name=\"external\" /></a>\n </div>\n </div>\n <div className=\"oh-video-player-stage\">\n <video\n key={`${loaded.path}:${loaded.version}:${String(revision)}`}\n src={mediaUrl}\n controls\n preload=\"metadata\"\n playsInline\n onLoadedMetadata={() => { setReady(true); setError(false); }}\n onError={() => { setError(true); setReady(false); }}\n />\n </div>\n </div>;\n}\n\nfunction VideoArtifacts({ project, sessionId }: { readonly project: VideoProject; readonly sessionId: string }) {\n const [selected, setSelected] = useState(preferredArtifact(project)?.path);\n const [content, setContent] = useState<string>();\n const [error, setError] = useState<string>();\n const [preflight, setPreflight] = useState<VideoPreflight | \"failed\">();\n useEffect(() => { setSelected(preferredArtifact(project)?.path); }, [project.id]);\n useEffect(() => {\n if (selected === undefined) { setContent(undefined); return; }\n const controller = new AbortController();\n setContent(undefined);\n setError(undefined);\n void fetch(endpoint(\"file\", sessionId, selected), { signal: controller.signal })\n .then(async (response) => {\n const payload = await response.json() as FilePayload & { readonly error?: string };\n if (!response.ok) throw new Error(payload.error ?? `HTTP ${String(response.status)}`);\n setContent(payload.content);\n })\n .catch((reason: unknown) => { if (!controller.signal.aborted) setError(reason instanceof Error ? reason.message : String(reason)); });\n return () => { controller.abort(); };\n }, [selected, sessionId]);\n const selectedArtifact = project.artifacts.find((item) => item.path === selected);\n return <div className=\"oh-video-artifacts\">\n <aside aria-label=\"\u89C6\u9891\u9879\u76EE\u4EA7\u7269\">\n <div className=\"oh-video-artifacts-heading\"><strong>\u9879\u76EE\u4EA7\u7269</strong><span>{project.artifacts.length}</span></div>\n <div className=\"oh-video-environment\">\n <strong>\u8FD0\u884C\u73AF\u5883</strong>\n {typeof preflight === \"object\" ? <>\n <span data-ready={preflight.python.ok || undefined}>Python {preflight.python.version ?? \"\u672A\u627E\u5230\"}</span>\n <span data-ready={(preflight.ffmpeg.ok && preflight.ffmpeg.subtitles) || undefined}>ffmpeg {preflight.ffmpeg.subtitles ? \"\u00B7 libass\" : \"\u00B7 \u7F3A\u5B57\u5E55\u6EE4\u955C\"}</span>\n <span data-ready={preflight.ffprobe.ok || undefined}>ffprobe {preflight.ffprobe.ok ? \"\u53EF\u7528\" : \"\u672A\u627E\u5230\"}</span>\n <span data-ready={preflight.credentials.mimo || undefined}>MiMo Key {preflight.credentials.mimo ? \"\u5DF2\u914D\u7F6E\" : \"\u672A\u914D\u7F6E\"}</span>\n {/* auto voices with MiMo when its key is set and falls back to Fish Audio otherwise. */}\n {(preflight.credentials.ttsProvider === \"fish-audio\" || (preflight.credentials.ttsProvider === \"auto\" && !preflight.credentials.mimo))\n && <span data-ready={preflight.credentials.fish || undefined}>Fish Key {preflight.credentials.fish ? \"\u5DF2\u914D\u7F6E\" : \"\u672A\u914D\u7F6E\"}</span>}\n {preflight.credentials.ttsProvider === \"index-tts\"\n && <span data-ready={preflight.credentials.indexTts || undefined}>IndexTTS {preflight.credentials.indexTts ? \"\u5DF2\u914D\u7F6E\" : \"\u7F3A INDEX_TTS_ENDPOINT / INDEX_TTS_VOICE\"}</span>}\n <em>DSH Host \u8FDB\u7A0B\u73AF\u5883\uFF1BAgent \u6267\u884C\u4E16\u754C\u4EE5 <code>video-recap --doctor</code> \u4E3A\u51C6\u3002</em>\n </> : <button type=\"button\" onClick={() => {\n void fetch(endpoint(\"video-preflight\", sessionId)).then(async (response) => {\n if (!response.ok) throw new Error(`HTTP ${String(response.status)}`);\n setPreflight(await response.json() as VideoPreflight);\n }).catch(() => { setPreflight(\"failed\"); });\n }}>{preflight === \"failed\" ? \"\u73AF\u5883\u68C0\u67E5\u5931\u8D25 \u00B7 \u91CD\u8BD5\" : \"\u68C0\u67E5\u73AF\u5883\"}</button>}\n </div>\n <nav>\n {project.artifacts.length === 0 && <p>\u6D41\u6C34\u7EBF\u542F\u52A8\u540E\uFF0C\u5173\u952E\u4EA7\u7269\u4F1A\u51FA\u73B0\u5728\u8FD9\u91CC\u3002</p>}\n {project.artifacts.map((artifact) => <button\n type=\"button\"\n key={artifact.path}\n aria-current={artifact.path === selected ? \"page\" : undefined}\n onClick={() => { setSelected(artifact.path); }}\n ><span>{artifact.label}</span><small>{artifact.path.split(\"/\").at(-1)}</small></button>)}\n </nav>\n </aside>\n <section>\n {selectedArtifact !== undefined && <header className=\"oh-video-artifact-header\">\n <div><strong>{selectedArtifact.label}</strong><span>{selectedArtifact.path.split(\"/\").at(-1)}</span></div>\n <em>{artifactKindLabel(selectedArtifact.kind)}</em>\n </header>}\n <div className=\"oh-video-artifact-content\">{project.artifacts.length === 0 ? <div className=\"oh-video-artifacts-empty\">\u6545\u4E8B\u65B9\u6848\u3001\u89E3\u8BF4\u8BCD\u3001\u5B57\u5E55\u548C\u8D28\u68C0\u62A5\u544A\u4F1A\u6309\u4E0A\u6E38\u6D41\u6C34\u7EBF\u5199\u5165\u8FD9\u91CC\u3002</div>\n : error !== undefined ? <div className=\"oh-story-error\">{error}</div>\n : content === undefined ? <div className=\"oh-video-artifacts-empty\">\u6B63\u5728\u8F7D\u5165\u4EA7\u7269\u2026</div>\n : <pre>{content}</pre>}</div>\n </section>\n </div>;\n}\n\nexport function VideoStudio({\n sessionId,\n projects,\n running,\n projectId,\n tab,\n hidden,\n workbenches,\n paneId,\n labelledBy,\n onProject,\n onTab,\n onWorkbench,\n onCollapse\n}: {\n readonly sessionId: string;\n readonly projects: readonly VideoProject[];\n readonly running: boolean;\n readonly projectId: string | undefined;\n readonly tab: \"preview\" | \"artifacts\";\n readonly hidden: boolean;\n readonly workbenches: readonly WorkbenchMode[];\n readonly paneId: string;\n readonly labelledBy: string;\n readonly onProject: (id: string) => void;\n readonly onTab: (tab: \"preview\" | \"artifacts\") => void;\n readonly onWorkbench: (mode: WorkbenchMode) => void;\n readonly onCollapse: () => void;\n}) {\n const project = projects.find((item) => item.id === projectId) ?? projects[0];\n const tabsId = useId();\n useEffect(() => { if (project !== undefined && project.id !== projectId) onProject(project.id); }, [onProject, project, projectId]);\n const tabs = [\"preview\", \"artifacts\"] as const;\n return <main id={paneId} className=\"oh-video-studio\" role=\"tabpanel\" aria-labelledby={labelledBy} hidden={hidden}>\n <header className=\"oh-video-toolbar\">\n <div className=\"oh-workbench-cluster\">\n <div className=\"oh-video-mode-tabs\" role=\"tablist\" aria-label=\"\u521B\u4F5C\u5DE5\u4F5C\u53F0\">{workbenches.map((mode) => <button\n type=\"button\" role=\"tab\" key={mode} aria-selected={mode === \"video\"} tabIndex={mode === \"video\" ? 0 : -1}\n onKeyDown={(event) => { handleTabKey(event, workbenches, \"video\", onWorkbench); }} onClick={() => { onWorkbench(mode); }}\n >{workbenchLabel(mode)}</button>)}</div>\n <button className=\"oh-workbench-collapse\" type=\"button\" title=\"\u6536\u8D77\u521B\u4F5C\u5DE5\u4F5C\u53F0\" aria-label=\"\u6536\u8D77\u521B\u4F5C\u5DE5\u4F5C\u53F0\" onClick={onCollapse}>\u00D7</button>\n </div>\n <label className=\"oh-video-project\"><span>\u89C6\u9891\u9879\u76EE</span><select aria-label=\"\u89C6\u9891\u9879\u76EE\" value={project?.id ?? \"\"} disabled={project === undefined} onChange={(event) => { onProject(event.target.value); }}>\n {projects.map((item) => <option key={item.id} value={item.id}>{item.title}</option>)}\n </select></label>\n {project !== undefined && <span className=\"oh-video-stage\" data-state={project.state}><i aria-hidden />{project.stageLabel}</span>}\n <div className=\"oh-video-tabs\" role=\"tablist\" aria-label=\"\u89C6\u9891\u5DE5\u4F5C\u53F0\">{tabs.map((item) => <button\n type=\"button\" role=\"tab\" key={item} id={`${tabsId}-${item}-tab`} aria-controls={`${tabsId}-${item}-panel`}\n aria-selected={tab === item} tabIndex={tab === item ? 0 : -1}\n onKeyDown={(event) => { handleTabKey(event, tabs, tab, onTab); }} onClick={() => { onTab(item); }}\n >{item === \"preview\" ? \"\u9884\u89C8\" : \"\u4EA7\u7269\"}</button>)}</div>\n </header>\n {project === undefined ? <div className=\"oh-video-preview-empty\"><span aria-hidden>\u25B6</span><strong>\u8FD8\u6CA1\u6709\u89C6\u9891\u9879\u76EE</strong><p>\u5728\u53F3\u4FA7 Chat \u544A\u8BC9 Agent \u8981\u5904\u7406\u7684\u89C6\u9891\uFF1B\u9879\u76EE\u4F1A\u521B\u5EFA\u5728 <code>video-recaps/&lt;\u9879\u76EE&gt;/</code>\u3002</p></div> : <div className=\"oh-video-panels\">\n <div role=\"tabpanel\" id={`${tabsId}-preview-panel`} aria-labelledby={`${tabsId}-preview-tab`} hidden={tab !== \"preview\"}><VideoPreview key={project.id} project={project} sessionId={sessionId} running={running} /></div>\n <div role=\"tabpanel\" id={`${tabsId}-artifacts-panel`} aria-labelledby={`${tabsId}-artifacts-tab`} hidden={tab !== \"artifacts\"}><VideoArtifacts project={project} sessionId={sessionId} /></div>\n </div>}\n </main>;\n}\n", "/**\n * DSH is a general Harness: one installed plugin must not turn every Session\n * into a writing surface. The workbench claims the conversation layout only for\n * a workspace that actually holds creative work, and the creator can always\n * take the layout back.\n */\n\nexport type WorkbenchPreference = \"open\" | \"closed\";\n\nexport interface WorkbenchWorkspace {\n readonly files: readonly unknown[];\n readonly games: readonly { readonly source: \"workspace\" | \"example\" }[];\n readonly videos: readonly unknown[];\n}\n\nexport interface WorkbenchPreferenceStorage {\n getItem: (key: string) => string | null;\n setItem: (key: string, value: string) => void;\n}\n\n/** The bundled game example ships with the plugin, so it never marks a workspace as creative. */\nexport function hasCreativeProject(workspace: WorkbenchWorkspace | undefined): boolean {\n if (workspace === undefined) return false;\n return workspace.files.length > 0\n || workspace.videos.length > 0\n || workspace.games.some((game) => game.source === \"workspace\");\n}\n\n/** An explicit creator choice always wins over what the workspace happens to contain. */\nexport function resolveWorkbenchOpen(preference: WorkbenchPreference | undefined, creativeProject: boolean): boolean {\n return preference === undefined ? creativeProject : preference === \"open\";\n}\n\nexport function workbenchPreferenceKey(cwd: string): string {\n return `oh-story.workbench.${cwd}`;\n}\n\n/** The DSH Session Store is not persisted, so the choice is kept per workspace instead. */\nexport function readWorkbenchPreference(storage: WorkbenchPreferenceStorage | undefined, cwd: string | undefined): WorkbenchPreference | undefined {\n if (storage === undefined || cwd === undefined) return undefined;\n let value: string | null;\n try { value = storage.getItem(workbenchPreferenceKey(cwd)); }\n catch { return undefined; }\n return value === \"open\" || value === \"closed\" ? value : undefined;\n}\n\nexport function writeWorkbenchPreference(storage: WorkbenchPreferenceStorage | undefined, cwd: string | undefined, preference: WorkbenchPreference): void {\n if (storage === undefined || cwd === undefined) return;\n // Private windows and blocked site data refuse to persist; the Session still keeps the choice.\n try { storage.setItem(workbenchPreferenceKey(cwd), preference); }\n catch { /* the Session Store remains the in-session authority */ }\n}\n\n/** Reading the property itself throws when the browser blocks site data. */\nexport function workbenchPreferenceStorage(): WorkbenchPreferenceStorage | undefined {\n try { return globalThis.localStorage; }\n catch { return undefined; }\n}\n", ".oh-story-bridge-marker { display: none; }\n.oh-story-welcome {\n box-sizing: border-box;\n order: -1;\n flex-shrink: 0;\n width: min(640px, calc(100% - 32px));\n margin: 24px auto;\n padding: 20px 24px;\n border: 1px solid var(--dsw-alias-border-l2);\n border-radius: 12px;\n color: var(--dsw-alias-label-primary);\n background: var(--dsw-alias-bg-base);\n font: 14px/1.7 var(--dsw-font-family);\n overflow-wrap: anywhere;\n}\n.oh-story-welcome h2 { margin: 0 0 8px; font-size: 20px; }\n.oh-story-welcome p { margin: 8px 0 0; }\n.oh-story-welcome ol { margin: 12px 0; padding-left: 24px; }\n.oh-story-split-surface { display: contents; font-family: var(--dsw-font-family); }\n\n/* Collapsed, the plugin owns nothing but this control: DSH renders the\n conversation exactly as it does without the plugin installed. The launcher is\n fixed to the conversation column's own corner, which the bridge publishes,\n because the surrounding shell is not ours to place things in. */\n.oh-story-launcher {\n box-sizing: border-box;\n display: flex;\n position: fixed;\n z-index: 9;\n top: calc(var(--oh-story-seam-top, 0px) + 10px);\n right: calc(var(--oh-story-seam-right, 0px) + 14px);\n min-height: 28px;\n align-items: center;\n gap: 6px;\n border: 1px solid var(--dsw-alias-border-l2);\n border-radius: 999px;\n color: var(--dsw-alias-label-secondary);\n background: var(--dsw-alias-bg-base);\n padding: 3px 11px;\n cursor: pointer;\n font-family: var(--dsw-font-family);\n font-size: 12px;\n line-height: 20px;\n}\n.oh-story-launcher b { font-weight: 500; }\n.oh-story-launcher:hover { color: var(--dsw-alias-label-primary); background: var(--dsw-alias-interactive-bg-hover); }\n.oh-story-launcher:focus-visible { outline: 2px solid var(--dsw-alias-state-business-primary); outline-offset: 2px; }\n\n/* DSH documents every [data-slot] wrapper as a stable addressable styling\n seam. The official Session body and composer stay mounted; this only turns\n their scroll host into a three-column writing surface. */\n[data-conversation-scroll]:has(> [data-slot=\"conversation.session\"] > .oh-story-split-surface[data-open=\"true\"]) {\n --os-border: var(--dsw-alias-border-l2);\n --os-muted: var(--dsw-alias-label-secondary);\n display: grid;\n grid-template-columns: clamp(184px, 16%, 200px) minmax(240px, 1fr) clamp(408px, 40%, 520px);\n grid-template-rows: minmax(0, 1fr);\n min-height: 0;\n overflow-x: hidden;\n overflow-y: auto;\n position: relative;\n scrollbar-gutter: stable;\n scroll-padding-bottom: calc(max(var(--dsh-composer-height, 152px), var(--oh-story-composer-height, 0px)) + 16px);\n}\n\n/* Keep the final Chat flow above the overlapping official Composer. */\n[data-conversation-scroll]:has(> [data-slot=\"conversation.session\"] > .oh-story-split-surface[data-open=\"true\"])\n > [data-slot=\"conversation.session\"] > :not(.oh-story-split-surface) {\n grid-column: 3;\n grid-row: 1;\n min-width: 0;\n min-height: 100%;\n border-left: 1px solid var(--os-border);\n}\n\n/* DSH 0.1.7 nests a data-chat-flow inside every step-process group; only the top-level flow needs room. */\n[data-conversation-scroll]:has(> [data-slot=\"conversation.session\"] > .oh-story-split-surface[data-open=\"true\"])\n [data-chat-flow]:not([data-step-process-content]) {\n padding-bottom: calc(max(var(--dsh-composer-height, 152px), var(--oh-story-composer-height, 0px)) + 16px);\n}\n\n[data-conversation-scroll]:has(> [data-slot=\"conversation.session\"] > .oh-story-split-surface[data-open=\"true\"])\n > [data-composer-seat] {\n grid-column: 3;\n grid-row: 1;\n align-self: start;\n min-width: 0;\n width: 100%;\n position: sticky;\n top: calc(var(--oh-story-scroll-height, 720px) - max(var(--dsh-composer-height, 152px), var(--oh-story-composer-height, 0px)));\n bottom: auto;\n}\n\n/* Game mode keeps the official Conversation on the right but merges the two\n creator columns into one playable Studio. */\n[data-conversation-scroll][data-oh-story-workbench=\"game\"]:has(> [data-slot=\"conversation.session\"] > .oh-story-split-surface[data-open=\"true\"]) {\n --game-stage: #0d100e;\n --game-stage-raised: #161a17;\n --game-accent: var(--dsw-alias-state-business-primary);\n --game-warning: #f4bd55;\n --game-danger: #f06b63;\n grid-template-columns: minmax(0, 1fr) clamp(400px, 34%, 520px);\n overflow: hidden;\n}\n\n[data-conversation-scroll][data-oh-story-workbench=\"game\"]:has(> [data-slot=\"conversation.session\"] > .oh-story-split-surface[data-open=\"true\"])\n > [data-slot=\"conversation.session\"] > :not(.oh-story-split-surface),\n[data-conversation-scroll][data-oh-story-workbench=\"game\"]:has(> [data-slot=\"conversation.session\"] > .oh-story-split-surface[data-open=\"true\"])\n > [data-composer-seat] { grid-column: 2; }\n\n/* DSH 0.1.2 lays two 40px column-resize strips (z-index 8) over the whole\n conversation area. The workbench replaces that column geometry, so the strip\n no longer marks a real column seam here \u2014 it just swallows clicks on the\n right edge of the file tree. The creator panes take the clicks back. */\n.oh-story-tree,\n.oh-story-editor {\n box-sizing: border-box;\n grid-row: 1;\n position: sticky;\n z-index: 9;\n top: 0;\n align-self: start;\n min-width: 0;\n min-height: 0;\n height: 100%;\n color: inherit;\n background: var(--dsw-alias-bg-base);\n}\n\n.oh-game-studio {\n box-sizing: border-box;\n display: flex;\n grid-column: 1;\n grid-row: 1;\n position: sticky;\n z-index: 9;\n top: 0;\n min-width: 0;\n min-height: 0;\n height: 100%;\n align-self: start;\n overflow: hidden;\n flex-direction: column;\n border-right: 1px solid var(--os-border);\n color: var(--dsw-alias-label-primary);\n background: var(--dsw-alias-bg-base);\n}\n.oh-game-studio[hidden] { display: none; }\n\n.oh-game-toolbar {\n box-sizing: border-box;\n display: grid;\n min-height: 56px;\n flex: none;\n grid-template-columns: auto minmax(160px, 1fr) auto;\n align-items: center;\n gap: 9px;\n padding: 8px 12px;\n border-bottom: 1px solid var(--os-border);\n background: var(--dsw-alias-bg-base);\n}\n\n.oh-game-mode-tabs {\n display: flex;\n margin-right: 2px;\n padding-right: 9px;\n border-right: 1px solid var(--os-border);\n}\n.oh-game-mode-tabs button {\n min-width: 42px;\n min-height: 36px;\n border: 0;\n border-radius: 5px;\n color: var(--os-muted);\n background: transparent;\n padding: 4px 7px;\n cursor: pointer;\n white-space: nowrap;\n font: 11px/1 var(--dsw-font-family);\n}\n.oh-game-mode-tabs button:hover { color: var(--dsw-alias-label-primary); }\n.oh-game-mode-tabs button[aria-selected=\"true\"] { color: var(--dsw-alias-label-primary); background: var(--dsw-alias-button-ghost-active-fill); font-weight: 500; }\n\n.oh-game-project { display: flex; min-width: 0; align-items: center; gap: 7px; color: var(--os-muted); font-size: 11px; }\n.oh-game-project > span { flex: none; }\n.oh-game-project select,\n.oh-game-design select {\n min-width: 0;\n border: 1px solid var(--os-border);\n border-radius: 8px;\n color: var(--dsw-alias-label-primary);\n background: var(--dsw-alias-bg-base);\n padding: 6px 28px 6px 9px;\n font: inherit;\n}\n.oh-game-project select { max-width: 360px; min-height: 36px; flex: 1; overflow: hidden; text-overflow: ellipsis; font-weight: 500; }\n.oh-game-design select { min-height: 36px; }\n.oh-game-project select:focus-visible,\n.oh-game-design select:focus-visible,\n.oh-game-mode-tabs button:focus-visible,\n.oh-game-tabs button:focus-visible,\n.oh-game-preview-status button:focus-visible,\n.oh-game-mobile-switcher button:focus-visible { outline: 2px solid var(--dsw-alias-state-business-primary); outline-offset: 1px; }\n\n.oh-game-tabs,\n.oh-game-mobile-switcher {\n display: flex;\n padding: 2px;\n border: 1px solid var(--os-border);\n border-radius: 9px;\n background: var(--dsw-alias-bg-base);\n}\n.oh-game-tabs button,\n.oh-game-mobile-switcher button {\n min-width: 56px;\n min-height: 36px;\n border: 0;\n border-radius: 6px;\n color: var(--os-muted);\n background: transparent;\n cursor: pointer;\n font: 12px/1 var(--dsw-font-family);\n}\n.oh-game-tabs button:hover,\n.oh-game-mobile-switcher button:hover { color: var(--dsw-alias-label-primary); }\n.oh-game-tabs button[aria-selected=\"true\"],\n.oh-game-mobile-switcher button[aria-selected=\"true\"] { color: var(--dsw-alias-label-primary); background: var(--dsw-alias-button-ghost-active-fill); box-shadow: 0 1px 2px rgb(0 0 0 / 7%); font-weight: 600; }\n.oh-game-panels,\n.oh-game-panel {\n display: flex;\n min-width: 0;\n min-height: 0;\n flex: 1;\n overflow: hidden;\n flex-direction: column;\n}\n.oh-game-panel[hidden] { display: none; }\n\n.oh-game-preview-shell {\n display: grid;\n min-width: 0;\n min-height: 0;\n flex: 1;\n grid-template-rows: 40px minmax(0, 1fr);\n position: relative;\n overflow: hidden;\n border-top: 2px solid var(--game-accent);\n background-color: var(--game-stage);\n}\n.oh-game-preview-shell[data-state=\"building\"] { border-top-color: var(--game-warning); animation: oh-game-build-line 1.4s linear infinite; }\n.oh-game-preview-shell[data-state=\"error\"] { border-top-color: var(--game-danger); }\n.oh-game-preview-status {\n display: flex;\n min-width: 0;\n align-items: center;\n justify-content: space-between;\n gap: 12px;\n padding: 0 10px 0 12px;\n color: rgb(244 248 240 / 76%);\n background: var(--game-stage-raised);\n font-size: 11px;\n}\n.oh-game-runtime-state { display: inline-flex; overflow: hidden; min-width: 0; align-items: center; gap: 7px; text-overflow: ellipsis; white-space: nowrap; }\n.oh-game-runtime-state > i { width: 6px; height: 6px; flex: none; border-radius: 50%; background: var(--dsw-alias-state-success-primary, #45b96f); }\n.oh-game-preview-shell[data-state=\"loading\"] .oh-game-runtime-state > i { background: rgb(255 255 255 / 42%); box-shadow: none; }\n.oh-game-preview-shell[data-state=\"building\"] .oh-game-runtime-state > i { background: var(--game-warning); }\n.oh-game-preview-shell[data-state=\"error\"] .oh-game-runtime-state > i { background: var(--game-danger); }\n.oh-game-preview-status > div { display: flex; flex: none; gap: 6px; }\n.oh-game-preview-status button {\n min-height: 36px;\n border: 1px solid rgb(255 255 255 / 14%);\n border-radius: 6px;\n color: rgb(255 255 255 / 84%);\n background: rgb(255 255 255 / 5%);\n padding: 3px 8px;\n cursor: pointer;\n font: inherit;\n}\n.oh-game-preview-status button:hover { background: rgb(255 255 255 / 11%); }\n.oh-game-reload { display: inline-flex; align-items: center; gap: 5px; }\n.oh-game-reload b { font: inherit; font-weight: 500; }\n.oh-game-preview-shell iframe { width: 100%; height: 100%; min-width: 0; min-height: 0; border: 0; background: var(--game-stage); }\n.oh-game-focus-hint {\n position: absolute;\n right: 10px;\n bottom: 10px;\n z-index: 2;\n padding: 4px 8px;\n border: 1px solid rgb(255 255 255 / 12%);\n border-radius: 6px;\n color: rgb(255 255 255 / 62%);\n background: rgb(8 10 9 / 82%);\n pointer-events: none;\n font-size: 10px;\n}\n.oh-game-focus-hint[data-focused] { color: var(--game-accent); }\n\n.oh-game-preview-empty,\n.oh-game-design-empty {\n display: grid;\n max-width: 560px;\n margin: auto;\n padding: 36px;\n place-items: center;\n gap: 8px;\n color: var(--os-muted);\n text-align: center;\n line-height: 1.65;\n}\n.oh-game-preview-empty { width: 100%; max-width: none; min-height: 0; flex: 1; box-sizing: border-box; align-content: center; color: rgb(244 248 240 / 70%); background: var(--game-stage); }\n.oh-game-preview-empty > span { color: var(--game-accent); font-size: 30px; }\n.oh-game-preview-empty strong,\n.oh-game-design-empty strong { color: inherit; font-size: 15px; }\n.oh-game-preview-empty p,\n.oh-game-design-empty p { margin: 0; }\n.oh-game-preview-empty code,\n.oh-game-design-empty code { font: 11px/1.5 ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace; }\n.oh-game-prompt-example { display: grid; max-width: 560px; gap: 4px; margin-top: 8px; padding: 10px 12px; border: 1px solid rgb(255 255 255 / 12%); border-radius: 8px; text-align: left; }\n.oh-game-prompt-example span { color: var(--game-accent); font-size: 10px; font-weight: 600; }\n.oh-game-prompt-example q { color: rgb(244 248 240 / 72%); quotes: none; font-size: 11px; }\n\n.oh-game-design { display: flex; min-height: 0; flex: 1; overflow: hidden; flex-direction: column; }\n.oh-game-design > label { display: flex; min-height: 42px; flex: none; align-items: center; gap: 10px; padding: 0 14px; border-bottom: 1px solid var(--os-border); color: var(--os-muted); font-size: 11px; }\n.oh-game-design select { max-width: min(560px, 75%); }\n.oh-game-source { box-sizing: border-box; min-height: 0; flex: 1; overflow: auto; margin: 0; padding: 18px 22px 48px; color: var(--dsw-alias-label-secondary); background: var(--dsw-alias-markdown-code-block); white-space: pre-wrap; overflow-wrap: anywhere; font: 12px/1.65 ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace; }\n\n.oh-game-mobile-switcher { display: none; }\n\n@keyframes oh-game-build-line { 50% { border-top-color: var(--game-accent); } }\n\n.oh-story-tree {\n grid-column: 1;\n overflow: auto;\n padding: 14px 10px 24px;\n border-right: 1px solid var(--os-border);\n background: var(--dsw-specific-sidebar-fill);\n}\n\n.oh-story-editor {\n display: flex;\n grid-column: 2;\n overflow: hidden;\n flex-direction: column;\n}\n\n.oh-story-brand,\n.oh-story-editor header,\n.oh-story-role summary {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 12px;\n}\n\n.oh-story-brand { min-height: 28px; gap: 8px; padding: 0 5px 8px 7px; font-size: 14px; font-weight: 500; white-space: nowrap; }\n.oh-story-brand-cluster { display: flex; min-width: 0; align-items: center; gap: 6px; }\n.oh-story-brand-cluster strong { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font: inherit; }\n.oh-story-kind { flex: none; padding: 1px 6px; border-radius: 5px; color: var(--dsw-alias-label-secondary); background: var(--dsw-alias-button-ghost-active-fill); font-size: 11px; line-height: 16px; font-weight: 500; }\n\n.oh-story-brand button,\n.oh-story-save,\n.oh-story-role button {\n border: 1px solid var(--dsw-alias-border-l2);\n border-radius: 999px;\n color: var(--dsw-alias-label-secondary);\n background: var(--dsw-alias-bg-base);\n padding: 3px 9px;\n cursor: pointer;\n font: inherit;\n}\n\n.oh-story-brand button { display: grid; width: 28px; height: 28px; place-items: center; border: 0; padding: 0; background: transparent; font-size: 16px; }\n.oh-story-brand button:hover,\n.oh-story-save:hover:not(:disabled),\n.oh-story-role button:hover { color: var(--dsw-alias-label-primary); background: var(--dsw-alias-interactive-bg-hover); }\n.oh-story-brand button:focus-visible,\n.oh-story-save:focus-visible,\n.oh-story-mode-tabs button:focus-visible,\n.oh-story-editor-tabs button:focus-visible,\n.oh-story-tree nav button:focus-visible,\n.oh-story-role button:focus-visible { outline: 2px solid var(--dsw-alias-state-business-primary); outline-offset: -2px; }\n.oh-story-save:disabled { opacity: .48; cursor: default; }\n\n.oh-story-brand-actions { display: flex; flex: none; align-items: center; gap: 2px; }\n\n.oh-workbench-cluster { display: flex; min-width: 0; align-items: center; gap: 6px; }\n.oh-workbench-collapse {\n display: grid;\n width: 28px;\n height: 28px;\n flex: none;\n place-items: center;\n border: 0;\n border-radius: 5px;\n color: var(--os-muted);\n background: transparent;\n padding: 0;\n cursor: pointer;\n font: inherit;\n font-size: 16px;\n}\n.oh-workbench-collapse:hover { color: var(--dsw-alias-label-primary); background: var(--dsw-alias-interactive-bg-hover); }\n.oh-workbench-collapse:focus-visible { outline: 2px solid var(--dsw-alias-state-business-primary); outline-offset: -2px; }\n\n.oh-story-mode-tabs { display: flex; margin: 0 4px 8px; padding: 2px; border: 1px solid var(--os-border); border-radius: 7px; background: var(--dsw-alias-bg-layer-1); }\n\n.oh-story-mode-tabs button,\n.oh-story-editor-tabs button {\n position: relative;\n min-height: 24px;\n flex: 1;\n border: 0;\n color: var(--os-muted);\n background: transparent;\n border-radius: 5px;\n cursor: pointer;\n font: inherit;\n font-size: 11px;\n}\n\n.oh-story-mode-tabs button:hover,\n.oh-story-editor-tabs button:hover { color: var(--dsw-alias-label-primary); }\n.oh-story-mode-tabs button[aria-selected=\"true\"],\n.oh-story-editor-tabs button[aria-selected=\"true\"] { color: var(--dsw-alias-label-primary); background: var(--dsw-alias-bg-base); box-shadow: 0 1px 2px rgb(0 0 0 / 8%); font-weight: 500; }\n\n.oh-story-file-group,\n.oh-story-file-folder { margin: 0; }\n.oh-story-file-group > summary,\n.oh-story-file-folder > summary {\n display: flex;\n align-items: center;\n gap: 5px;\n min-height: 26px;\n padding: 0 7px;\n border-radius: 6px;\n color: var(--os-muted);\n cursor: pointer;\n list-style: none;\n font-size: 11px;\n font-weight: 600;\n}\n.oh-story-file-folder > summary { padding-left: min(calc(7px + var(--oh-story-indent, 0px)), 49px); }\n.oh-story-file-group > summary { margin-top: 3px; }\n.oh-story-file-group > summary::-webkit-details-marker,\n.oh-story-file-folder > summary::-webkit-details-marker { display: none; }\n.oh-story-file-group > summary::before,\n.oh-story-file-folder > summary::before { width: 8px; content: \"\u203A\"; transform: rotate(0); transition: transform .12s ease; }\n.oh-story-file-group[open] > summary::before,\n.oh-story-file-folder[open] > summary::before { transform: rotate(90deg); }\n.oh-story-file-group > summary:hover,\n.oh-story-file-folder > summary:hover { color: var(--dsw-alias-label-primary); background: var(--dsw-alias-interactive-bg-hover); }\n.oh-story-file-group > summary span,\n.oh-story-file-folder > summary span { margin-left: auto; color: var(--dsw-alias-label-secondary); font-weight: 400; }\n\n.oh-story-tree nav button {\n display: block;\n width: 100%;\n overflow: hidden;\n padding: 6px 8px 6px min(calc(14px + var(--oh-story-indent, 0px)), 56px);\n border: 0;\n border-radius: 6px;\n color: inherit;\n background: transparent;\n text-align: left;\n text-overflow: ellipsis;\n white-space: nowrap;\n cursor: pointer;\n font: inherit;\n font-size: 12px;\n}\n.oh-story-tree nav button:hover { background: var(--dsw-alias-interactive-bg-hover); }\n.oh-story-tree nav button[aria-current=\"page\"] { background: var(--dsw-alias-button-ghost-active-fill); color: var(--dsw-alias-label-primary); }\n.oh-story-tree nav button[data-agent-target] { box-shadow: inset 2px 0 var(--dsw-alias-state-business-primary); }\n\n.oh-story-editor > header {\n min-height: 44px;\n flex: none;\n padding: 0 14px;\n border-bottom: 1px solid var(--os-border);\n}\n\n.oh-story-editor-path {\n overflow: hidden;\n min-width: 0;\n flex: 1;\n text-overflow: ellipsis;\n white-space: nowrap;\n font-size: 12px;\n color: var(--os-muted);\n}\n.oh-story-editor-path > span { overflow: hidden; display: block; text-overflow: ellipsis; }\n.oh-story-editor-path > strong { display: none; overflow: hidden; text-overflow: ellipsis; font: inherit; }\n\n.oh-story-editor-actions { display: flex; flex: none; align-items: center; gap: 8px; }\n.oh-story-editor-tabs {\n display: flex;\n padding: 2px;\n border: 1px solid var(--os-border);\n border-radius: 7px;\n background: var(--dsw-alias-bg-layer-1);\n}\n.oh-story-editor-tabs button { min-height: 24px; padding: 0 9px; border-radius: 5px; font-size: 11px; }\n.oh-story-save { min-height: 28px; }\n\n.oh-story-editor textarea {\n box-sizing: border-box;\n width: 100%;\n min-height: 0;\n flex: 1;\n resize: none;\n border: 0;\n outline: 0;\n padding: clamp(20px, 6%, 48px) clamp(22px, 10%, 84px) 48px;\n color: var(--dsw-alias-label-primary);\n background: transparent;\n font: 16px/1.9 ui-serif, \"Songti SC\", \"STSong\", Georgia, serif;\n}\n.oh-story-editor textarea[data-format=\"structured\"] {\n tab-size: 2;\n font: 13px/1.65 ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;\n}\n\n.oh-story-markdown {\n box-sizing: border-box;\n width: 100%;\n min-height: 0;\n flex: 1;\n overflow: auto;\n padding: clamp(24px, 8%, 56px) clamp(24px, 10%, 92px) 64px;\n color: var(--dsw-alias-label-primary);\n font: 16px/1.85 ui-serif, \"Songti SC\", \"STSong\", Georgia, serif;\n overflow-wrap: anywhere;\n}\n.oh-story-markdown > :first-child { margin-top: 0; }\n.oh-story-markdown > :last-child { margin-bottom: 0; }\n.oh-story-markdown h1,\n.oh-story-markdown h2,\n.oh-story-markdown h3,\n.oh-story-markdown h4,\n.oh-story-markdown h5,\n.oh-story-markdown h6 { margin: 1.45em 0 .6em; font-family: var(--dsw-font-family); line-height: 1.35; letter-spacing: -.01em; }\n.oh-story-markdown h1 { font-size: 1.75em; }\n.oh-story-markdown h2 { padding-bottom: .35em; border-bottom: 1px solid var(--os-border); font-size: 1.35em; }\n.oh-story-markdown h3 { font-size: 1.15em; }\n.oh-story-markdown p { margin: .75em 0; }\n.oh-story-markdown ul,\n.oh-story-markdown ol { margin: .75em 0; padding-left: 1.6em; }\n.oh-story-markdown li { margin: .28em 0; }\n.oh-story-markdown .oh-story-task-item { list-style: none; margin-left: -1.35em; }\n.oh-story-task-item input { margin: 0 .55em 0 0; accent-color: var(--dsw-alias-state-business-primary); }\n.oh-story-markdown blockquote { margin: 1em 0; padding: .1em 1em; border-left: 3px solid var(--dsw-alias-state-business-primary); color: var(--dsw-alias-label-secondary); }\n/* DSH gives inline code its own alias; the block fill is a different surface. */\n.oh-story-markdown code { padding: .15em .4em; border-radius: 4px; background: var(--dsw-alias-markdown-inline-code); font: .86em/1.6 ui-monospace, SFMono-Regular, Menlo, monospace; }\n.oh-story-markdown pre { overflow: auto; margin: 1em 0; padding: 14px 16px; border: 1px solid var(--dsw-alias-border-l1); border-radius: 10px; background: var(--dsw-alias-markdown-code-block); }\n.oh-story-markdown pre code { padding: 0; background: transparent; }\n.oh-story-markdown a { color: var(--dsw-alias-state-business-primary); text-decoration-thickness: 1px; text-underline-offset: 3px; }\n.oh-story-markdown del { color: var(--os-muted); }\n.oh-story-markdown-table { overflow-x: auto; margin: 1em 0; border: 1px solid var(--os-border); border-radius: 10px; }\n.oh-story-markdown table { width: 100%; border-collapse: collapse; font-family: ui-sans-serif, system-ui, \"PingFang SC\", sans-serif; font-size: 13px; line-height: 1.55; }\n.oh-story-markdown th,\n.oh-story-markdown td { min-width: 96px; padding: 9px 12px; border-right: 1px solid var(--os-border); border-bottom: 1px solid var(--os-border); vertical-align: top; }\n.oh-story-markdown th:last-child,\n.oh-story-markdown td:last-child { border-right: 0; }\n.oh-story-markdown tbody tr:last-child td { border-bottom: 0; }\n.oh-story-markdown th { background: var(--dsw-alias-bg-layer-1); font-weight: 600; }\n.oh-story-markdown hr { margin: 2em 0; border: 0; border-top: 1px solid var(--os-border); }\n.oh-story-markdown-empty { margin: auto; color: var(--os-muted); font-size: 13px; }\n\n.oh-story-jsonl {\n box-sizing: border-box;\n display: flex;\n width: 100%;\n min-height: 0;\n flex: 1;\n overflow: hidden;\n flex-direction: column;\n color: var(--dsw-alias-label-primary);\n background: var(--dsw-alias-bg-base);\n}\n.oh-story-jsonl-summary { display: flex; min-height: 42px; flex: none; align-items: center; gap: 10px; padding: 0 18px; border-bottom: 1px solid var(--os-border); font-size: 12px; }\n.oh-story-jsonl-summary strong { font-weight: 600; }\n.oh-story-jsonl-summary span { color: var(--os-muted); }\n.oh-story-jsonl-records { overflow: auto; padding: 14px 18px 36px; }\n.oh-story-jsonl details,\n.oh-story-jsonl-error { overflow: hidden; margin-bottom: 10px; border: 1px solid var(--os-border); border-radius: 10px; background: var(--dsw-alias-bg-layer-1); }\n.oh-story-jsonl summary { display: flex; min-height: 42px; align-items: center; gap: 9px; padding: 0 12px; cursor: pointer; list-style: none; font: 12px/1.4 var(--dsw-font-family); }\n.oh-story-jsonl summary::-webkit-details-marker { display: none; }\n.oh-story-jsonl summary::before { content: \"\u203A\"; color: var(--os-muted); font-size: 16px; transition: transform .12s ease; }\n.oh-story-jsonl details[open] summary::before { transform: rotate(90deg); }\n.oh-story-jsonl summary > span { flex: none; color: var(--os-muted); font-variant-numeric: tabular-nums; }\n.oh-story-jsonl summary > strong { overflow: hidden; min-width: 80px; flex: 1; text-overflow: ellipsis; white-space: nowrap; font-weight: 600; }\n.oh-story-jsonl summary > code,\n.oh-story-jsonl summary > em { flex: none; padding: 2px 6px; border-radius: 5px; background: var(--dsw-alias-button-ghost-active-fill); color: var(--dsw-alias-label-secondary); font: 11px/1.35 ui-monospace, SFMono-Regular, Menlo, monospace; font-style: normal; }\n.oh-story-jsonl pre { overflow: auto; max-height: 520px; margin: 0; padding: 14px 16px; border-top: 1px solid var(--os-border); background: var(--dsw-alias-markdown-code-block); color: var(--dsw-alias-label-secondary); white-space: pre-wrap; overflow-wrap: anywhere; font: 12px/1.6 ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace; }\n.oh-story-jsonl-error { display: grid; gap: 5px; padding: 12px; border-color: var(--dsw-alias-state-error-primary); font-size: 12px; }\n.oh-story-jsonl-error > strong { color: var(--dsw-alias-state-error-primary); }\n.oh-story-jsonl-error > span { color: var(--os-muted); }\n.oh-story-jsonl-error pre { margin: 3px -12px -12px; }\n\n.oh-story-stream,\n.oh-story-conflict,\n.oh-story-warning {\n flex: none;\n padding: 7px 12px;\n border-bottom: 1px solid var(--os-border);\n font-size: 11px;\n line-height: 1.4;\n}\n\n.oh-story-stream { color: var(--dsw-alias-state-business-primary); background: var(--dsw-alias-button-ghost-active-fill); }\n.oh-story-stream[data-stage=\"streaming\"] { animation: oh-story-pulse 1.2s ease-in-out infinite alternate; }\n.oh-story-conflict { color: var(--dsw-alias-state-warn-label); background: var(--dsw-specific-tip); }\n.oh-story-conflict > div { display: flex; gap: 6px; margin-top: 6px; }\n.oh-story-conflict button,\n.oh-story-empty button {\n border: 1px solid var(--os-border);\n border-radius: 6px;\n color: inherit;\n background: var(--dsw-alias-bg-base);\n padding: 3px 8px;\n cursor: pointer;\n font: inherit;\n}\n.oh-story-warning { color: var(--dsw-alias-state-warn-label); background: var(--dsw-specific-tip); }\n\n@keyframes oh-story-pulse { to { opacity: .62; } }\n@media (prefers-reduced-motion: reduce) { .oh-story-stream[data-stage=\"streaming\"] { animation: none; } }\n\n.oh-story-empty { margin: auto; max-width: 480px; padding: 30px; color: var(--os-muted); line-height: 1.7; text-align: center; }\n.oh-story-error { margin: 8px; padding: 8px 10px; border-radius: 8px; color: var(--dsw-alias-state-error-primary); background: var(--dsw-specific-tip); font-size: 12px; }\n\n.oh-story-role { display: flex; flex-direction: column; margin: 0; overflow: hidden; }\n.oh-story-role summary { min-height: 24px; padding: 0; cursor: pointer; list-style: none; font-size: 14px; line-height: 24px; }\n.oh-story-role summary::-webkit-details-marker { display: none; }\n.oh-story-role summary span { color: var(--dsw-alias-state-business-primary); }\n.oh-story-role summary strong { margin-right: auto; color: var(--dsw-alias-label-secondary); font-weight: 500; }\n.oh-story-role summary em { color: var(--dsw-alias-label-caption); font-style: normal; font-size: 12px; }\n.oh-story-role[data-state=\"error\"] summary em { color: var(--dsw-alias-state-error-primary); }\n.oh-story-role pre { max-height: 260px; overflow: auto; margin: 4px 0 4px 4px; padding: 12px 16px; border: 1px solid var(--dsw-alias-border-l1); border-radius: 12px; color: var(--dsw-alias-label-secondary); background: var(--dsw-alias-markdown-code-block); white-space: pre-wrap; font: var(--dsw-font-markdown-code-block-small); }\n.oh-story-role > button { align-self: flex-start; margin: 4px 0 2px 4px; font-size: 11px; }\n\n/* Short-drama production views are projections of the creator Markdown and\n DSH Session state. They intentionally use only DSH semantic tokens. */\n.oh-story-production { min-height: 0; flex: 1; overflow: auto; background: var(--dsw-alias-bg-base); font: 12px/1.5 var(--dsw-font-family); }\n.oh-story-production button,\n.oh-story-production select { border: 1px solid var(--os-border); border-radius: 6px; color: inherit; background: var(--dsw-alias-bg-base); padding: 4px 8px; cursor: pointer; font: inherit; }\n.oh-story-production button:hover:not(:disabled) { background: var(--dsw-alias-interactive-bg-hover); }\n.oh-story-production button:disabled { opacity: .45; cursor: default; }\n.oh-story-production button:focus-visible,\n.oh-story-canvas article:focus-visible { outline: 2px solid var(--dsw-alias-state-business-primary); outline-offset: 2px; }\n.oh-story-production-bar,\n.oh-story-production-notice,\n.oh-story-production-actions,\n.oh-story-sequence-summary { display: flex; align-items: center; gap: 8px; }\n.oh-story-production-bar { position: sticky; z-index: 5; top: 0; justify-content: space-between; min-height: 44px; box-sizing: border-box; padding: 6px 12px; border-bottom: 1px solid var(--os-border); background: color-mix(in srgb, var(--dsw-alias-bg-base) 94%, transparent); backdrop-filter: blur(12px); }\n.oh-story-production-tabs { display: flex; align-self: stretch; gap: 16px; }\n.oh-story-production-tabs button { position: relative; border: 0; border-radius: 0; padding: 0; background: transparent; color: var(--os-muted); }\n.oh-story-production-tabs button[aria-selected=\"true\"] { color: var(--dsw-alias-label-primary); }\n.oh-story-production-tabs button[aria-selected=\"true\"]::after { position: absolute; right: 0; bottom: -6px; left: 0; height: 2px; border-radius: 2px; background: var(--dsw-alias-state-business-primary); content: \"\"; }\n.oh-story-production-meta { display: flex; align-items: center; gap: 8px; }\n.oh-story-production-meta > button { padding-block: 2px; color: var(--os-muted); }\n.oh-story-production-summary { color: var(--os-muted); white-space: nowrap; }\n.oh-story-production-notice { justify-content: space-between; margin: 8px 12px 0; padding: 7px 9px; border: 1px solid var(--os-border); border-radius: 7px; color: var(--dsw-alias-label-secondary); background: var(--dsw-alias-bg-layer-1); }\n.oh-story-production-notice button { border: 0; background: transparent; }\n.oh-story-production-environment { display: flex; min-width: 0; flex-wrap: wrap; align-items: center; gap: 5px 10px; margin: 8px 12px 0; padding: 7px 9px; border: 1px solid var(--os-border); border-radius: 7px; color: var(--os-muted); background: var(--dsw-alias-bg-layer-1); font-size: 10px; }\n/* Environment names such as MINIMAX_VIDEO_RESOLUTIONS and the temp-dir path are longer than the 500 px editor column; let them break rather than widen the view. */\n.oh-story-production-environment > * { min-width: 0; max-width: 100%; overflow-wrap: anywhere; }\n.oh-story-production-environment strong { color: var(--dsw-alias-label-secondary); font-size: 11px; }\n.oh-story-production-environment span::before { content: \"\u25CF\"; margin-right: 4px; color: var(--video-danger, #d9534f); }\n.oh-story-production-environment span[data-ready]::before { color: var(--dsw-alias-state-success-primary, #45b96f); }\n.oh-story-production-environment span[data-pending]::before { color: var(--os-muted); }\n.oh-story-production-environment em { flex-basis: 100%; font-style: normal; line-height: 1.5; }\n.oh-story-production-environment code { font-size: 10px; overflow-wrap: anywhere; }\n.oh-story-production-environment button { min-height: 24px; border: 1px solid var(--os-border); border-radius: 6px; padding: 0 8px; color: inherit; background: var(--dsw-alias-bg-base); cursor: pointer; font: inherit; }\n.oh-story-production-diagnostics { margin: 8px 12px 0; padding: 7px 9px; border: 1px solid var(--dsw-alias-state-warn-label); border-radius: 7px; background: var(--dsw-specific-tip); }\n.oh-story-production-diagnostics summary { color: var(--dsw-alias-state-warn-label); cursor: pointer; }\n.oh-story-production-diagnostics ul { display: grid; gap: 4px; margin: 8px 0 0; padding: 0; list-style: none; }\n.oh-story-production-diagnostics li { display: grid; grid-template-columns: auto minmax(0, 1fr); align-items: start; gap: 6px; color: var(--dsw-alias-label-secondary); }\n.oh-story-production-diagnostics li[data-severity=\"error\"] { color: var(--dsw-alias-state-error-primary); }\n.oh-story-production-diagnostics li button { border: 0; padding: 0; color: inherit; background: transparent; text-align: left; }\n.oh-story-production-diagnostics p { margin: 6px 0 0; color: var(--os-muted); }\n.oh-story-production-actions { justify-content: flex-end; margin-bottom: 12px; }\n.oh-story-production-actions button:last-child,\n.oh-story-sequence-summary button { color: var(--dsw-alias-state-business-primary); border-color: var(--dsw-alias-state-business-primary); }\n.oh-story-shot-board { padding: 16px 12px; }\n.oh-story-shot-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); align-items: start; gap: 12px; }\n.oh-story-shot-card,\n.oh-story-asset-card,\n.oh-story-task-board > article { min-width: 0; overflow: hidden; border: 1px solid var(--os-border); border-radius: 10px; background: var(--dsw-alias-bg-layer-1); }\n.oh-story-shot-card { padding: 10px; cursor: default; transition: border-color .15s ease, background-color .15s ease; }\n.oh-story-shot-card:hover { border-color: var(--dsw-alias-border-l2); }\n.oh-story-shot-card { cursor: pointer; }\n.oh-story-shot-card:focus-visible,\n.oh-story-asset-card:focus-visible { outline: 2px solid var(--dsw-alias-state-business-primary); outline-offset: 2px; }\n.oh-story-shot-card[data-selected],\n.oh-story-asset-card[data-selected] { border-color: var(--dsw-alias-state-business-primary); background: color-mix(in srgb, var(--dsw-alias-state-business-primary) 4%, var(--dsw-alias-bg-layer-1)); }\n.oh-story-shot-card > header,\n.oh-story-task-board article > header { display: flex; min-height: 0; align-items: center; gap: 8px; padding: 0; border: 0; }\n.oh-story-shot-card > header > button { overflow: hidden; min-width: 0; flex: 1; border: 0; padding: 0; color: var(--dsw-alias-state-business-primary); background: transparent; text-align: left; text-overflow: ellipsis; white-space: nowrap; }\n.oh-story-shot-card > header > span { color: var(--os-muted); font-variant-numeric: tabular-nums; }\n.oh-story-shot-card h3,\n.oh-story-asset-card h3 { margin: 7px 0 4px; font-size: 13px; font-weight: 600; }\n.oh-story-shot-card > p,\n.oh-story-asset-card > p,\n.oh-story-task-board article > p { margin: 5px 0; color: var(--os-muted); }\n.oh-story-shot-placeholder { display: grid; height: 132px; place-content: center; gap: 3px; margin-bottom: 8px; border-radius: 7px; color: var(--os-muted); background: var(--dsw-alias-button-ghost-active-fill); text-align: center; }\n.oh-story-shot-placeholder strong { color: var(--dsw-alias-label-secondary); font-size: 22px; font-variant-numeric: tabular-nums; }\n.oh-story-shot-card dl { display: grid; grid-template-columns: 20px minmax(0, 1fr); margin: 7px 0; }\n.oh-story-shot-card dt { color: var(--dsw-alias-state-business-primary); }\n.oh-story-shot-card dd { min-width: 0; margin: 0; overflow-wrap: anywhere; }\n.oh-story-shot-status,\n.oh-story-reference-links,\n.oh-story-card-actions { display: flex; flex-wrap: wrap; gap: 5px; margin-top: 7px; }\n.oh-story-shot-status span { padding: 1px 5px; border-radius: 5px; color: var(--os-muted); background: var(--dsw-alias-button-ghost-active-fill); }\n.oh-story-shot-status span[data-ready=\"true\"] { color: var(--dsw-alias-state-business-primary); }\n.oh-story-shot-status span > i { margin-right: 3px; font-style: normal; }\n.oh-story-reference-links button { max-width: 100%; overflow: hidden; padding: 1px 5px; border: 0; color: var(--dsw-alias-state-business-primary); background: transparent; text-overflow: ellipsis; }\n.oh-story-card-actions { padding-top: 8px; border-top: 1px solid var(--os-border); }\n.oh-story-card-actions button { flex: 1; padding-block: 4px; }\n.oh-story-card-actions button:last-child { color: var(--dsw-alias-state-business-primary); border-color: color-mix(in srgb, var(--dsw-alias-state-business-primary) 45%, var(--os-border)); }\n.oh-story-media-preview { display: block; width: 100%; height: 168px; border-radius: 7px; background: var(--dsw-alias-bg-base); object-fit: contain; }\n.oh-story-media-document { display: grid; min-height: 0; flex: 1; overflow: auto; place-items: center; padding: 24px; }\n.oh-story-media-document img,\n.oh-story-media-document video { display: block; max-width: 100%; max-height: 100%; object-fit: contain; }\n.oh-story-media-document audio { width: min(520px, 100%); }\n.oh-story-version-strip { display: flex; gap: 5px; overflow-x: auto; margin-top: 8px; padding-top: 8px; border-top: 1px solid var(--os-border); }\n.oh-story-version-strip > button { position: relative; width: 64px; min-width: 64px; padding: 2px; }\n.oh-story-version-strip > button[data-selected] { border-color: var(--dsw-alias-state-business-primary); }\n.oh-story-version-strip .oh-story-media-preview { height: 72px; }\n.oh-story-version-strip span { position: absolute; right: 3px; bottom: 3px; padding: 0 3px; border-radius: 3px; background: var(--dsw-alias-bg-base); font-size: 10px; }\n.oh-story-asset-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: 12px; padding: 16px 12px; }\n.oh-story-asset-card { padding: 10px; }\n.oh-story-asset-card > div:nth-child(2) > button { overflow: hidden; max-width: 100%; border: 0; padding: 0; color: var(--dsw-alias-state-business-primary); background: transparent; text-overflow: ellipsis; }\n.oh-story-asset-card small { color: var(--os-muted); text-transform: uppercase; }\n.oh-story-asset-placeholder { display: grid; height: 112px; place-items: center; border-radius: 7px; color: var(--os-muted); background: var(--dsw-alias-button-ghost-active-fill); font-size: 28px; }\n.oh-story-asset-description { display: -webkit-box; overflow: hidden; -webkit-box-orient: vertical; -webkit-line-clamp: 5; line-clamp: 5; }\n.oh-story-media-library { margin: 0 12px 14px; padding-top: 12px; border-top: 1px solid var(--os-border); }\n.oh-story-media-library > header { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-bottom: 10px; }\n.oh-story-media-library > header > div { display: flex; align-items: center; gap: 7px; }\n.oh-story-media-library > header span { color: var(--os-muted); }\n.oh-story-media-library input { width: 180px; box-sizing: border-box; border: 1px solid var(--os-border); border-radius: 6px; padding: 5px 8px; color: inherit; background: var(--dsw-alias-bg-base); font: inherit; }\n.oh-story-media-library > .oh-story-projection-note { margin-bottom: 10px; }\n.oh-story-media-library-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(160px, 1fr)); gap: 8px; }\n.oh-story-media-library-grid > article { display: flex; min-width: 0; flex-direction: column; gap: 5px; padding: 7px; border: 1px solid var(--os-border); border-radius: 8px; background: var(--dsw-alias-bg-layer-1); }\n.oh-story-media-library-grid .oh-story-media-preview { height: 116px; }\n.oh-story-media-library-grid > article > span { overflow: hidden; color: var(--os-muted); font-size: 10px; text-overflow: ellipsis; white-space: nowrap; }\n.oh-story-media-library-grid footer { display: flex; gap: 4px; margin-top: auto; }\n.oh-story-media-library-grid footer button { min-width: 0; flex: 1; padding-inline: 4px; }\n.oh-story-media-library-grid footer button[aria-pressed=\"true\"] { color: var(--dsw-alias-state-business-primary); border-color: var(--dsw-alias-state-business-primary); }\n.oh-story-task-board { display: grid; gap: 10px; padding: 12px; }\n.oh-story-task-board > article { padding: 11px; }\n.oh-story-task-board > article[data-status=\"dispatched_unknown\"] { border-color: var(--dsw-alias-state-warn-label); }\n.oh-story-task-board > article[data-status=\"dispatched_unknown\"] .oh-story-error { color: var(--dsw-alias-state-warn-label); background: var(--dsw-specific-tip); }\n.oh-story-task-board article > header strong { min-width: 0; flex: 1; overflow: hidden; text-overflow: ellipsis; }\n.oh-story-task-board article > header span { padding: 1px 5px; border-radius: 5px; color: var(--os-muted); background: var(--dsw-alias-button-ghost-active-fill); }\n.oh-story-task-progress { height: 3px; overflow: hidden; margin-top: 8px; border-radius: 3px; background: var(--os-border); }\n.oh-story-task-progress i { display: block; height: 100%; background: var(--dsw-alias-state-business-primary); transition: width .2s ease; }\n.oh-story-task-board details { margin-top: 8px; color: var(--os-muted); }\n.oh-story-task-board details summary { cursor: pointer; }\n.oh-story-task-board details p { max-height: 120px; overflow: auto; margin: 6px 0; padding: 8px; border-radius: 6px; background: var(--dsw-alias-bg-base); white-space: pre-wrap; }\n.oh-story-task-board footer { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: 5px; margin-top: 8px; }\n.oh-story-projection-note { padding: 7px 10px; border: 1px solid var(--os-border); border-radius: 7px; color: var(--os-muted); background: var(--dsw-alias-bg-layer-1); }\n.oh-story-task-board > .oh-story-projection-note { margin-bottom: 0; }\n.oh-story-production-empty { padding: 48px 20px; color: var(--os-muted); text-align: center; }\n.oh-story-production-empty strong { display: block; margin-bottom: 6px; color: var(--dsw-alias-text-1); font-size: 13px; }\n.oh-story-production-empty p { margin: 0 auto; max-width: 44em; line-height: 1.6; }\n.oh-story-production-empty button { margin-top: 12px; }\n.oh-story-sequence { padding: 12px; }\n.oh-story-sequence-summary { justify-content: space-between; margin-bottom: 10px; }\n.oh-story-sequence-summary span { margin-left: auto; color: var(--os-muted); }\n.oh-story-sequence-issues { margin: 0 0 10px; padding: 8px 8px 8px 28px; border-radius: 7px; color: var(--dsw-alias-state-warn-label); background: var(--dsw-specific-tip); }\n.oh-story-sequence-issues li + li { margin-top: 2px; }\n.oh-story-sequence ol { display: grid; gap: 6px; margin: 0; padding: 0; list-style: none; }\n.oh-story-sequence > ol > li { display: grid; min-height: 70px; grid-template-columns: 28px 96px minmax(0, 1fr) auto; align-items: center; gap: 8px; padding: 7px; border: 1px solid var(--os-border); border-radius: 8px; background: var(--dsw-alias-bg-layer-1); }\n.oh-story-sequence > ol > li > span { color: var(--os-muted); font-variant-numeric: tabular-nums; }\n.oh-story-sequence > ol > li .oh-story-media-preview,\n.oh-story-sequence-missing { width: 96px; height: 54px; }\n.oh-story-sequence-missing { display: grid; place-items: center; border-radius: 5px; color: var(--os-muted); background: var(--dsw-alias-button-ghost-active-fill); }\n.oh-story-sequence > ol > li > div:last-child { display: flex; gap: 3px; }\n.oh-story-canvas-shell { position: relative; display: flex; height: max(580px, calc(100% - 84px)); min-height: 580px; flex-direction: column; overflow: hidden; }\n.oh-story-canvas-shell > .oh-story-projection-note { z-index: 3; flex: none; margin: 8px 168px 8px 8px; }\n.oh-story-canvas-controls { position: absolute; z-index: 4; top: 8px; right: 8px; display: flex; align-items: center; gap: 3px; padding: 3px; border: 1px solid var(--os-border); border-radius: 8px; background: var(--dsw-alias-bg-base); }\n.oh-story-canvas-controls span { min-width: 44px; color: var(--os-muted); text-align: center; }\n.oh-story-canvas-viewport { width: 100%; min-height: 0; flex: 1; overflow: auto; background-color: var(--dsw-alias-bg-base); background-image: radial-gradient(var(--os-border) 1px, transparent 1px); background-size: 20px 20px; }\n.oh-story-canvas { position: relative; width: 1800px; height: 1800px; transform-origin: 0 0; }\n.oh-story-canvas svg { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; pointer-events: none; }\n.oh-story-canvas path { fill: none; opacity: .35; stroke: var(--dsw-alias-border-l2); stroke-width: 1.5; }\n.oh-story-canvas path[data-active] { opacity: .8; stroke: var(--dsw-alias-state-business-primary); }\n.oh-story-canvas article { position: absolute; display: flex; width: 180px; min-height: 76px; box-sizing: border-box; flex-direction: column; gap: 4px; padding: 10px; border: 1px solid var(--os-border); border-radius: 8px; background: var(--dsw-alias-bg-layer-1); box-shadow: 0 4px 14px rgb(0 0 0 / 8%); cursor: grab; user-select: none; touch-action: none; }\n.oh-story-canvas article:active { cursor: grabbing; }\n.oh-story-canvas article[data-node-type=\"shot\"] { border-color: var(--dsw-alias-state-business-primary); }\n.oh-story-canvas article[data-selected] { box-shadow: 0 0 0 2px color-mix(in srgb, var(--dsw-alias-state-business-primary) 28%, transparent), 0 4px 14px rgb(0 0 0 / 8%); }\n.oh-story-canvas article small { color: var(--os-muted); text-transform: uppercase; }\n.oh-story-canvas article strong,\n.oh-story-canvas article span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\n.oh-story-canvas article span { color: var(--os-muted); font-size: 10px; }\n\n[data-conversation-scroll][data-oh-story-layout=\"medium\"]:has(> [data-slot=\"conversation.session\"] > .oh-story-split-surface[data-open=\"true\"]) {\n grid-template-columns: clamp(104px, 18%, 184px) minmax(200px, 1fr) clamp(300px, 45%, 408px);\n}\n\n[data-conversation-scroll][data-oh-story-layout=\"compact\"]:has(> [data-slot=\"conversation.session\"] > .oh-story-split-surface[data-open=\"true\"]) {\n grid-template-columns: clamp(80px, 16%, 104px) minmax(0, 1fr) clamp(228px, 48%, 300px);\n}\n\n[data-oh-story-layout=\"medium\"] .oh-story-file-folder > summary { padding-left: min(calc(7px + var(--oh-story-indent, 0px)), 35px); }\n[data-oh-story-layout=\"medium\"] .oh-story-tree nav button { padding-left: min(calc(14px + var(--oh-story-indent, 0px)), 42px); }\n[data-oh-story-layout=\"medium\"] .oh-story-editor textarea { padding-right: 28px; padding-left: 28px; }\n\n[data-oh-story-layout=\"compact\"] .oh-story-tree { padding-inline: 4px; }\n[data-oh-story-layout=\"compact\"] .oh-story-brand { gap: 4px; padding-inline: 2px; font-size: 11px; }\n[data-oh-story-layout=\"compact\"] .oh-story-brand-cluster { gap: 4px; }\n[data-oh-story-layout=\"compact\"] .oh-story-brand-cluster strong > span { display: none; }\n[data-oh-story-layout=\"compact\"] .oh-story-kind { padding-inline: 4px; font-size: 11px; }\n[data-oh-story-layout=\"compact\"] .oh-story-brand button { width: 24px; height: 24px; }\n[data-oh-story-layout=\"compact\"] .oh-story-mode-tabs { margin-inline: 0; }\n[data-oh-story-layout=\"compact\"] .oh-story-mode-tabs button { padding-inline: 3px; font-size: 11px; }\n[data-oh-story-layout=\"compact\"] .oh-story-file-folder > summary { padding-left: min(calc(5px + var(--oh-story-indent, 0px)), 19px); }\n[data-oh-story-layout=\"compact\"] .oh-story-tree nav button { padding-right: 4px; padding-left: min(calc(7px + var(--oh-story-indent, 0px)), 21px); }\n[data-oh-story-layout=\"compact\"] .oh-story-editor > header {\n display: grid;\n min-height: 68px;\n grid-template-columns: minmax(0, 1fr);\n grid-template-rows: 24px 36px;\n align-content: center;\n gap: 0;\n padding: 4px 3px;\n}\n[data-oh-story-layout=\"compact\"] .oh-story-editor-path > span { display: none; }\n[data-oh-story-layout=\"compact\"] .oh-story-editor-path > strong { display: block; font-size: 11px; line-height: 24px; }\n[data-oh-story-layout=\"compact\"] .oh-story-editor-actions { width: 100%; min-width: 0; justify-content: flex-end; gap: 4px; }\n[data-oh-story-layout=\"compact\"] .oh-story-editor-tabs { min-width: 0; flex: 1; }\n[data-oh-story-layout=\"compact\"] .oh-story-editor-tabs button { min-width: 0; padding-inline: 2px; white-space: nowrap; }\n[data-oh-story-layout=\"compact\"] .oh-story-save { flex: none; padding-inline: 4px; white-space: nowrap; font-size: 11px; }\n[data-oh-story-layout=\"compact\"] .oh-story-editor textarea { padding: 16px 12px 40px; }\n[data-oh-story-layout=\"compact\"] .oh-story-markdown { padding: 18px 12px 48px; }\n[data-oh-story-layout=\"compact\"] .oh-story-jsonl-summary { padding-inline: 10px; }\n[data-oh-story-layout=\"compact\"] .oh-story-jsonl-records { padding: 8px 7px 28px; }\n[data-oh-story-layout=\"compact\"] .oh-story-jsonl summary { gap: 6px; padding-inline: 7px; }\n[data-oh-story-layout=\"compact\"] .oh-story-jsonl summary > span { display: none; }\n[data-oh-story-layout=\"compact\"] .oh-story-jsonl summary > strong { min-width: 32px; }\n[data-oh-story-layout=\"compact\"] .oh-story-jsonl summary > code,\n[data-oh-story-layout=\"compact\"] .oh-story-jsonl summary > em { display: none; }\n\n[data-conversation-scroll][data-oh-story-workbench=\"game\"][data-oh-story-layout=\"medium\"]:has(> [data-slot=\"conversation.session\"] > .oh-story-split-surface[data-open=\"true\"]) {\n grid-template-columns: minmax(0, 1fr) clamp(360px, 42%, 440px);\n}\n[data-oh-story-workbench=\"game\"][data-oh-story-layout=\"medium\"] .oh-game-toolbar { grid-template-columns: auto minmax(140px, 1fr) auto; }\n\n[data-conversation-scroll][data-oh-story-workbench=\"game\"][data-oh-story-layout=\"compact\"]:has(> [data-slot=\"conversation.session\"] > .oh-story-split-surface[data-open=\"true\"]) {\n display: grid;\n grid-template-columns: minmax(0, 1fr);\n overflow: hidden;\n}\n[data-conversation-scroll][data-oh-story-workbench=\"game\"][data-oh-story-layout=\"compact\"]\n > [data-slot=\"conversation.session\"] > :not(.oh-story-split-surface),\n[data-conversation-scroll][data-oh-story-workbench=\"game\"][data-oh-story-layout=\"compact\"]\n > [data-composer-seat],\n[data-conversation-scroll][data-oh-story-workbench=\"game\"][data-oh-story-layout=\"compact\"] .oh-game-studio {\n grid-column: 1;\n}\n[data-conversation-scroll][data-oh-story-workbench=\"game\"][data-oh-story-layout=\"compact\"][data-oh-studio-pane=\"studio\"]\n > [data-slot=\"conversation.session\"] > :not(.oh-story-split-surface),\n[data-conversation-scroll][data-oh-story-workbench=\"game\"][data-oh-story-layout=\"compact\"][data-oh-studio-pane=\"studio\"]\n > [data-composer-seat],\n[data-conversation-scroll][data-oh-story-workbench=\"game\"][data-oh-story-layout=\"compact\"][data-oh-studio-pane=\"chat\"] .oh-game-studio { display: none; }\n[data-conversation-scroll][data-oh-story-workbench=\"game\"][data-oh-story-layout=\"compact\"] .oh-game-mobile-switcher {\n display: flex;\n position: absolute;\n top: 8px;\n right: 8px;\n z-index: 20;\n border-color: var(--dsw-alias-border-l1);\n box-shadow: 0 4px 14px rgb(0 0 0 / 12%);\n}\n[data-conversation-scroll][data-oh-story-workbench=\"game\"][data-oh-story-layout=\"compact\"] .oh-game-mobile-switcher button { min-width: 52px; min-height: 32px; }\n[data-conversation-scroll][data-oh-story-workbench=\"game\"][data-oh-story-layout=\"compact\"] .oh-game-toolbar {\n min-height: 101px;\n grid-template-columns: auto minmax(0, 1fr) 112px;\n grid-template-rows: 44px 44px;\n align-content: center;\n gap: 5px;\n padding: 4px 8px;\n}\n[data-conversation-scroll][data-oh-story-workbench=\"game\"][data-oh-story-layout=\"compact\"] .oh-game-toolbar > .oh-workbench-cluster { grid-column: 1; grid-row: 1; width: fit-content; }\n[data-conversation-scroll][data-oh-story-workbench=\"game\"][data-oh-story-layout=\"compact\"] .oh-game-project > span { display: none; }\n[data-conversation-scroll][data-oh-story-workbench=\"game\"][data-oh-story-layout=\"compact\"] .oh-game-project { grid-column: 1 / -1; grid-row: 2; }\n[data-conversation-scroll][data-oh-story-workbench=\"game\"][data-oh-story-layout=\"compact\"] .oh-game-project select { max-width: none; width: 100%; min-height: 44px; }\n[data-conversation-scroll][data-oh-story-workbench=\"game\"][data-oh-story-layout=\"compact\"] .oh-game-tabs { grid-column: 2; grid-row: 1; width: fit-content; justify-self: end; }\n[data-conversation-scroll][data-oh-story-workbench=\"game\"][data-oh-story-layout=\"compact\"] .oh-game-mode-tabs button,\n[data-conversation-scroll][data-oh-story-workbench=\"game\"][data-oh-story-layout=\"compact\"] .oh-game-tabs button,\n[data-conversation-scroll][data-oh-story-workbench=\"game\"][data-oh-story-layout=\"compact\"] .oh-game-mobile-switcher button { min-height: 44px; }\n[data-conversation-scroll][data-oh-story-workbench=\"game\"][data-oh-story-layout=\"compact\"] .oh-game-preview-shell { grid-template-rows: 46px minmax(0, 1fr); }\n[data-conversation-scroll][data-oh-story-workbench=\"game\"][data-oh-story-layout=\"compact\"] .oh-game-preview-status button { min-height: 36px; }\n[data-conversation-scroll][data-oh-story-workbench=\"game\"][data-oh-story-layout=\"compact\"] .oh-game-reload b { display: none; }\n[data-conversation-scroll][data-oh-story-workbench=\"game\"][data-oh-story-layout=\"compact\"] .oh-game-preview-status { padding-left: 8px; }\n[data-conversation-scroll][data-oh-story-workbench=\"game\"][data-oh-story-layout=\"compact\"] .oh-game-preview-status > span { max-width: 40%; }\n.oh-game-runtime-state > em { display: block; overflow: hidden; min-width: 0; font-style: normal; text-overflow: ellipsis; white-space: nowrap; }\n\n/* DSH may keep its navigation drawer open at a 500 px browser viewport,\n leaving the conversation center close to 212 px wide. The Studio publishes\n its measured width because a container style query cannot style the\n container itself. Row one stays clear for the \u5236\u4F5C / \u5BF9\u8BDD switch. */\n[data-conversation-scroll][data-oh-story-workbench=\"game\"][data-oh-story-layout=\"compact\"] .oh-game-studio[data-oh-game-narrow] .oh-game-toolbar {\n min-height: 193px;\n grid-template-columns: minmax(0, 1fr);\n grid-template-rows: repeat(4, 44px);\n align-content: center;\n padding: 4px 8px;\n}\n[data-conversation-scroll][data-oh-story-workbench=\"game\"][data-oh-story-layout=\"compact\"] .oh-game-studio[data-oh-game-narrow] .oh-game-toolbar > .oh-workbench-cluster {\n grid-column: 1;\n grid-row: 2;\n justify-self: start;\n}\n[data-conversation-scroll][data-oh-story-workbench=\"game\"][data-oh-story-layout=\"compact\"] .oh-game-studio[data-oh-game-narrow] .oh-game-tabs {\n grid-column: 1;\n grid-row: 3;\n justify-self: start;\n}\n[data-conversation-scroll][data-oh-story-workbench=\"game\"][data-oh-story-layout=\"compact\"] .oh-game-studio[data-oh-game-narrow] .oh-game-project {\n grid-column: 1;\n grid-row: 4;\n}\n[data-conversation-scroll][data-oh-story-workbench=\"game\"][data-oh-story-layout=\"compact\"] .oh-game-studio[data-oh-game-narrow] .oh-game-project select {\n width: 100%;\n max-width: none;\n min-height: 44px;\n}\n[data-conversation-scroll][data-oh-story-workbench=\"game\"][data-oh-story-layout=\"compact\"] .oh-game-studio[data-oh-game-narrow] .oh-game-preview-status {\n gap: 4px;\n padding-right: 6px;\n padding-left: 6px;\n}\n[data-conversation-scroll][data-oh-story-workbench=\"game\"][data-oh-story-layout=\"compact\"] .oh-game-studio[data-oh-game-narrow] .oh-game-preview-status > span { max-width: 36%; }\n\n@media (prefers-reduced-motion: reduce) {\n .oh-game-preview-shell[data-state=\"building\"] { animation: none; }\n}\n\n@media (prefers-contrast: more) {\n .oh-game-preview-status button,\n .oh-game-tabs,\n .oh-game-mode-tabs,\n .oh-game-mobile-switcher { border-width: 2px; }\n}\n[data-oh-story-layout=\"compact\"] .oh-story-production-summary { display: none; }\n[data-oh-story-layout=\"compact\"] .oh-story-production-bar { flex-wrap: wrap; padding-inline: 4px; }\n[data-oh-story-layout=\"compact\"] .oh-story-production-tabs { width: 100%; gap: 0; }\n[data-oh-story-layout=\"compact\"] .oh-story-production-tabs button { min-width: 0; flex: 1; padding-inline: 0; font-size: 11px; }\n[data-oh-story-layout=\"compact\"] .oh-story-production-meta { width: 100%; justify-content: flex-end; }\n[data-oh-story-layout=\"compact\"] .oh-story-shot-grid,\n[data-oh-story-layout=\"compact\"] .oh-story-asset-grid { grid-template-columns: minmax(0, 1fr); }\n[data-oh-story-layout=\"compact\"] .oh-story-media-library > header { align-items: stretch; flex-direction: column; }\n[data-oh-story-layout=\"compact\"] .oh-story-media-library > header > div:last-child { display: grid; grid-template-columns: minmax(0, 1fr) auto; }\n[data-oh-story-layout=\"compact\"] .oh-story-media-library input { width: 100%; }\n[data-oh-story-layout=\"compact\"] .oh-story-sequence { padding-inline: 6px; }\n[data-oh-story-layout=\"compact\"] .oh-story-sequence-summary { flex-wrap: wrap; }\n[data-oh-story-layout=\"compact\"] .oh-story-sequence-summary span { display: none; }\n[data-oh-story-layout=\"compact\"] .oh-story-sequence > ol > li { grid-template-columns: 24px 64px minmax(0, 1fr); gap: 5px; }\n[data-oh-story-layout=\"compact\"] .oh-story-sequence > ol > li .oh-story-media-preview,\n[data-oh-story-layout=\"compact\"] .oh-story-sequence-missing { width: 64px; height: 40px; }\n[data-oh-story-layout=\"compact\"] .oh-story-sequence > ol > li > div:last-child { grid-column: 2 / 4; justify-content: flex-end; }\n[data-oh-story-layout=\"compact\"] .oh-story-canvas-shell > .oh-story-projection-note { overflow: hidden; max-height: 48px; margin: 8px; }\n[data-oh-story-layout=\"compact\"] .oh-story-canvas-controls { position: static; flex: none; align-self: flex-end; margin: 0 8px 8px; }\n\n/* Video mode intentionally stays a preview surface: one player, a read-only artifact view,\n and the official DSH Conversation. It shares no nonlinear-editor or timeline runtime. */\n[data-conversation-scroll][data-oh-story-workbench=\"video\"]:has(> [data-slot=\"conversation.session\"] > .oh-story-split-surface[data-open=\"true\"]) {\n --video-stage: #0b0d10;\n --video-stage-raised: #15181d;\n --video-accent: var(--dsw-alias-state-business-primary);\n --video-warning: #f4bd55;\n --video-danger: #f06b63;\n grid-template-columns: minmax(0, 1fr) clamp(400px, 34%, 520px);\n overflow: hidden;\n}\n[data-conversation-scroll][data-oh-story-workbench=\"video\"]:has(> [data-slot=\"conversation.session\"] > .oh-story-split-surface[data-open=\"true\"])\n > [data-slot=\"conversation.session\"] > :not(.oh-story-split-surface),\n[data-conversation-scroll][data-oh-story-workbench=\"video\"]:has(> [data-slot=\"conversation.session\"] > .oh-story-split-surface[data-open=\"true\"])\n > [data-composer-seat] { grid-column: 2; }\n\n.oh-video-studio {\n box-sizing: border-box;\n display: flex;\n grid-column: 1;\n grid-row: 1;\n position: sticky;\n top: 0;\n min-width: 0;\n min-height: 0;\n height: 100%;\n align-self: start;\n overflow: hidden;\n flex-direction: column;\n border-right: 1px solid var(--os-border);\n color: var(--dsw-alias-label-primary);\n background: var(--dsw-alias-bg-base);\n}\n.oh-video-studio[hidden] { display: none; }\n.oh-video-toolbar {\n box-sizing: border-box;\n display: grid;\n min-height: 100px;\n flex: none;\n grid-template-columns: minmax(0, 1fr) auto;\n grid-template-rows: 40px 40px;\n align-items: center;\n gap: 4px 12px;\n padding: 8px 12px 9px;\n border-bottom: 1px solid var(--os-border);\n background: var(--dsw-alias-bg-base);\n}\n.oh-video-mode-tabs { display: flex; width: fit-content; grid-column: 1; grid-row: 1; padding: 2px; border: 1px solid var(--os-border); border-radius: 9px; background: var(--dsw-alias-bg-layer-1); }\n.oh-video-mode-tabs button,\n.oh-video-tabs button,\n.oh-video-version-tabs button {\n min-height: 36px;\n border: 0;\n border-radius: 6px;\n padding: 4px 8px;\n color: var(--os-muted);\n background: transparent;\n cursor: pointer;\n white-space: nowrap;\n font: 12px/1 var(--dsw-font-family);\n}\n.oh-video-mode-tabs button { min-width: 48px; }\n.oh-video-mode-tabs button:hover,\n.oh-video-tabs button:hover,\n.oh-video-version-tabs button:hover { color: var(--dsw-alias-label-primary); }\n.oh-video-mode-tabs button[aria-selected=\"true\"],\n.oh-video-tabs button[aria-selected=\"true\"],\n.oh-video-version-tabs button[aria-selected=\"true\"] { color: var(--dsw-alias-label-primary); background: var(--dsw-alias-bg-base); box-shadow: 0 1px 2px rgb(0 0 0 / 9%); font-weight: 600; }\n.oh-video-project { display: flex; min-width: 0; grid-column: 1; grid-row: 2; align-items: center; gap: 9px; color: var(--os-muted); font-size: 11px; }\n.oh-video-project > span { flex: none; }\n.oh-video-project select {\n width: min(100%, 440px);\n min-width: 0;\n min-height: 36px;\n border: 1px solid var(--os-border);\n border-radius: 8px;\n padding: 6px 28px 6px 9px;\n color: var(--dsw-alias-label-primary);\n background: var(--dsw-alias-bg-base);\n overflow: hidden;\n text-overflow: ellipsis;\n font: inherit;\n font-weight: 500;\n}\n.oh-video-stage { display: inline-flex; grid-column: 2; grid-row: 2; align-items: center; gap: 7px; border: 1px solid var(--os-border); border-radius: 999px; padding: 5px 9px; color: var(--os-muted); background: var(--dsw-alias-bg-layer-1); white-space: nowrap; font-size: 11px; }\n.oh-video-stage > i { width: 7px; height: 7px; border-radius: 50%; background: var(--video-warning); }\n.oh-video-stage[data-state=\"ready\"] > i { background: var(--dsw-alias-state-success-primary, #45b96f); }\n.oh-video-stage[data-state=\"not-started\"] > i { background: var(--os-muted); }\n.oh-video-tabs,\n.oh-video-version-tabs { display: flex; padding: 2px; border: 1px solid var(--os-border); border-radius: 9px; }\n.oh-video-tabs { grid-column: 2; grid-row: 1; }\n.oh-video-tabs button { min-width: 56px; }\n.oh-video-panels,\n.oh-video-panels > [role=\"tabpanel\"] { display: flex; min-width: 0; min-height: 0; flex: 1; overflow: hidden; flex-direction: column; }\n.oh-video-panels > [hidden] { display: none; }\n\n.oh-video-preview-shell { display: grid; min-width: 0; min-height: 0; flex: 1; grid-template-rows: 48px minmax(0, 1fr); overflow: hidden; border-top: 2px solid var(--video-accent); background: var(--video-stage); }\n.oh-video-preview-shell[data-state=\"building\"] { border-top-color: var(--video-warning); }\n.oh-video-preview-shell[data-state=\"error\"] { border-top-color: var(--video-danger); }\n.oh-video-stagebar { display: grid; min-width: 0; grid-template-columns: auto minmax(80px, 1fr) auto; align-items: center; gap: 10px; padding: 0 10px; color: rgb(244 248 255 / 74%); background: var(--video-stage-raised); font-size: 11px; }\n.oh-video-version-tabs { border-color: rgb(255 255 255 / 13%); }\n.oh-video-version-tabs button[aria-selected=\"true\"] { color: #fff; background: rgb(255 255 255 / 12%); }\n.oh-video-runtime-state { display: flex; min-width: 0; align-items: center; justify-content: center; gap: 7px; overflow: hidden; }\n.oh-video-runtime-state > i { width: 6px; height: 6px; flex: none; border-radius: 50%; background: var(--dsw-alias-state-success-primary, #45b96f); }\n.oh-video-preview-shell[data-state=\"building\"] .oh-video-runtime-state > i { background: var(--video-warning); }\n.oh-video-preview-shell[data-state=\"error\"] .oh-video-runtime-state > i { background: var(--video-danger); }\n.oh-video-runtime-state > em { overflow: hidden; font-style: normal; text-overflow: ellipsis; white-space: nowrap; }\n.oh-video-preview-actions { display: flex; gap: 5px; }\n.oh-video-preview-actions button,\n.oh-video-preview-actions a { display: grid; min-width: 34px; min-height: 34px; box-sizing: border-box; place-items: center; border: 1px solid rgb(255 255 255 / 14%); border-radius: 6px; padding: 3px 8px; color: rgb(255 255 255 / 84%); background: rgb(255 255 255 / 5%); cursor: pointer; text-decoration: none; font: inherit; }\n.oh-video-preview-actions svg { width: 16px; height: 16px; }\n.oh-video-preview-actions button:hover,\n.oh-video-preview-actions a:hover { background: rgb(255 255 255 / 11%); }\n.oh-video-player-stage { display: grid; min-width: 0; min-height: 0; place-items: center; overflow: hidden; padding: 14px; background: radial-gradient(circle at 50% 40%, #1b2027, var(--video-stage) 62%); }\n.oh-video-player-stage video { display: block; width: min(100%, 1200px); height: auto; max-width: 100%; max-height: 100%; border-radius: 4px; object-fit: contain; background: #000; box-shadow: 0 16px 50px rgb(0 0 0 / 32%); }\n.oh-video-preview-shell:fullscreen { width: 100vw; height: 100vh; }\n\n.oh-video-preview-empty,\n.oh-video-artifacts-empty { display: grid; max-width: 620px; margin: auto; place-items: center; gap: 9px; padding: 36px; color: var(--os-muted); text-align: center; line-height: 1.65; }\n.oh-video-preview-empty { width: 100%; max-width: none; min-height: 0; box-sizing: border-box; flex: 1; align-content: center; color: rgb(244 248 255 / 70%); background: var(--video-stage); }\n.oh-video-preview-empty > span { color: var(--video-accent); font-size: 32px; }\n.oh-video-preview-empty strong { color: rgb(255 255 255 / 92%); }\n.oh-video-preview-empty p { max-width: 560px; margin: 0; }\n.oh-video-preview-empty code { color: rgb(255 255 255 / 88%); }\n.oh-video-prompt-example { max-width: 560px; margin-top: 10px; padding: 12px 14px; border: 1px solid rgb(255 255 255 / 11%); border-radius: 9px; background: rgb(255 255 255 / 4%); text-align: left; }\n.oh-video-prompt-example span { display: block; margin-bottom: 4px; color: var(--video-accent); font-size: 10px; font-weight: 600; }\n.oh-video-prompt-example q { quotes: none; }\n\n.oh-video-artifacts { display: grid; min-width: 0; min-height: 0; flex: 1; grid-template-columns: minmax(150px, 220px) minmax(0, 1fr); overflow: hidden; }\n.oh-video-artifacts > aside { display: flex; min-height: 0; flex-direction: column; overflow: hidden; padding: 8px; border-right: 1px solid var(--os-border); background: var(--dsw-alias-bg-layer-1); }\n.oh-video-artifacts-heading { display: flex; min-height: 30px; flex: none; align-items: center; justify-content: space-between; padding: 0 7px; }\n.oh-video-artifacts-heading strong { font-size: 11px; }\n.oh-video-artifacts-heading span { min-width: 20px; border-radius: 999px; padding: 1px 5px; color: var(--os-muted); background: var(--dsw-alias-button-ghost-active-fill); text-align: center; font-size: 10px; }\n.oh-video-artifacts > aside nav { min-height: 0; flex: 1; overflow: auto; }\n.oh-video-artifacts > aside nav button { display: flex; width: 100%; min-width: 0; position: relative; flex-direction: column; align-items: flex-start; gap: 3px; border: 0; border-radius: 7px; padding: 9px; color: inherit; background: transparent; cursor: pointer; text-align: left; }\n.oh-video-artifacts > aside nav button:hover,\n.oh-video-artifacts > aside nav button[aria-current=\"page\"] { background: var(--dsw-alias-button-ghost-active-fill); }\n.oh-video-artifacts > aside nav button[aria-current=\"page\"]::before { content: \"\"; width: 2px; position: absolute; inset-block: 8px; left: 2px; border-radius: 2px; background: var(--video-accent); }\n.oh-video-artifacts > aside nav small { width: 100%; overflow: hidden; color: var(--os-muted); text-overflow: ellipsis; white-space: nowrap; }\n.oh-video-artifacts > aside nav > p { margin: 10px 4px; color: var(--os-muted); font-size: 11px; line-height: 1.5; }\n.oh-video-environment { display: grid; gap: 5px; margin-bottom: 8px; padding: 8px; border: 1px solid var(--os-border); border-radius: 8px; background: var(--dsw-alias-bg-layer-1); }\n.oh-video-environment strong { font-size: 11px; }\n.oh-video-environment span { color: var(--os-muted); font-size: 10px; }\n.oh-video-environment em { color: var(--os-muted); font-size: 10px; font-style: normal; line-height: 1.5; }\n.oh-video-environment code { font-size: 10px; }\n.oh-video-environment span::before { content: \"\u25CF\"; margin-right: 5px; color: var(--video-danger); }\n.oh-video-environment span[data-ready]::before { color: var(--dsw-alias-state-success-primary, #45b96f); }\n.oh-video-environment button { min-height: 30px; border: 1px solid var(--os-border); border-radius: 6px; color: inherit; background: var(--dsw-alias-bg-base); cursor: pointer; font: inherit; }\n.oh-video-artifacts > section { display: flex; min-width: 0; min-height: 0; overflow: hidden; flex-direction: column; }\n.oh-video-artifact-header { display: flex; min-height: 54px; box-sizing: border-box; flex: none; align-items: center; justify-content: space-between; gap: 12px; padding: 8px 16px; border-bottom: 1px solid var(--os-border); }\n.oh-video-artifact-header > div { display: flex; min-width: 0; flex-direction: column; gap: 3px; }\n.oh-video-artifact-header strong { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 12px; }\n.oh-video-artifact-header span { overflow: hidden; color: var(--os-muted); text-overflow: ellipsis; white-space: nowrap; font-size: 10px; }\n.oh-video-artifact-header em { flex: none; border: 1px solid var(--os-border); border-radius: 999px; padding: 3px 7px; color: var(--os-muted); background: var(--dsw-alias-bg-layer-1); font-size: 10px; font-style: normal; }\n.oh-video-artifact-content { min-width: 0; min-height: 0; flex: 1; overflow: auto; }\n.oh-video-artifact-content pre { min-width: 0; min-height: 100%; box-sizing: border-box; margin: 0; padding: 20px; color: inherit; background: var(--dsw-alias-bg-base); white-space: pre-wrap; overflow-wrap: anywhere; font: 12px/1.65 var(--dsw-font-family-mono, ui-monospace, monospace); }\n\n[data-conversation-scroll][data-oh-story-workbench=\"video\"][data-oh-story-layout=\"medium\"]:has(> [data-slot=\"conversation.session\"] > .oh-story-split-surface[data-open=\"true\"]) { grid-template-columns: minmax(0, 1fr) clamp(360px, 42%, 440px); }\n[data-oh-story-workbench=\"video\"][data-oh-story-layout=\"medium\"] .oh-video-project select { width: 100%; }\n\n[data-conversation-scroll][data-oh-story-workbench=\"video\"][data-oh-story-layout=\"compact\"]:has(> [data-slot=\"conversation.session\"] > .oh-story-split-surface[data-open=\"true\"]) { display: grid; grid-template-columns: minmax(0, 1fr); overflow: hidden; }\n[data-conversation-scroll][data-oh-story-workbench=\"video\"][data-oh-story-layout=\"compact\"]\n > [data-slot=\"conversation.session\"] > :not(.oh-story-split-surface),\n[data-conversation-scroll][data-oh-story-workbench=\"video\"][data-oh-story-layout=\"compact\"]\n > [data-composer-seat],\n[data-conversation-scroll][data-oh-story-workbench=\"video\"][data-oh-story-layout=\"compact\"] .oh-video-studio { grid-column: 1; }\n[data-conversation-scroll][data-oh-story-workbench=\"video\"][data-oh-story-layout=\"compact\"][data-oh-studio-pane=\"studio\"]\n > [data-slot=\"conversation.session\"] > :not(.oh-story-split-surface),\n[data-conversation-scroll][data-oh-story-workbench=\"video\"][data-oh-story-layout=\"compact\"][data-oh-studio-pane=\"studio\"]\n > [data-composer-seat],\n[data-conversation-scroll][data-oh-story-workbench=\"video\"][data-oh-story-layout=\"compact\"][data-oh-studio-pane=\"chat\"] .oh-video-studio { display: none; }\n[data-conversation-scroll][data-oh-story-workbench=\"video\"][data-oh-story-layout=\"compact\"] .oh-game-mobile-switcher { display: flex; position: absolute; top: 8px; right: 8px; z-index: 20; border-color: var(--dsw-alias-border-l1); box-shadow: 0 4px 14px rgb(0 0 0 / 12%); }\n[data-conversation-scroll][data-oh-story-workbench=\"video\"][data-oh-story-layout=\"compact\"] .oh-video-toolbar { min-height: 142px; grid-template-columns: minmax(0, 1fr) auto; grid-template-rows: 44px 44px 38px; align-content: center; gap: 2px 6px; padding: 4px 8px; }\n[data-conversation-scroll][data-oh-story-workbench=\"video\"][data-oh-story-layout=\"compact\"] .oh-video-toolbar > .oh-workbench-cluster { grid-column: 1 / -1; grid-row: 1; width: fit-content; }\n[data-conversation-scroll][data-oh-story-workbench=\"video\"][data-oh-story-layout=\"compact\"] .oh-video-tabs { grid-column: 2; grid-row: 2; justify-self: end; }\n[data-conversation-scroll][data-oh-story-workbench=\"video\"][data-oh-story-layout=\"compact\"] .oh-video-project { grid-column: 1; grid-row: 2; }\n[data-conversation-scroll][data-oh-story-workbench=\"video\"][data-oh-story-layout=\"compact\"] .oh-video-project > span { display: none; }\n[data-conversation-scroll][data-oh-story-workbench=\"video\"][data-oh-story-layout=\"compact\"] .oh-video-stage { grid-column: 1 / -1; grid-row: 3; justify-self: start; }\n[data-conversation-scroll][data-oh-story-workbench=\"video\"][data-oh-story-layout=\"compact\"] .oh-video-stagebar { grid-template-columns: minmax(0, 1fr) auto; grid-template-rows: 42px 38px; gap: 2px 6px; padding: 3px 7px; }\n[data-conversation-scroll][data-oh-story-workbench=\"video\"][data-oh-story-layout=\"compact\"] .oh-video-preview-shell { grid-template-rows: 86px minmax(0, 1fr); }\n[data-conversation-scroll][data-oh-story-workbench=\"video\"][data-oh-story-layout=\"compact\"] .oh-video-version-tabs { grid-column: 1; grid-row: 1; }\n[data-conversation-scroll][data-oh-story-workbench=\"video\"][data-oh-story-layout=\"compact\"] .oh-video-runtime-state { grid-column: 1; grid-row: 2; justify-content: flex-start; }\n[data-conversation-scroll][data-oh-story-workbench=\"video\"][data-oh-story-layout=\"compact\"] .oh-video-preview-actions { grid-column: 2; grid-row: 1 / 3; }\n[data-conversation-scroll][data-oh-story-workbench=\"video\"][data-oh-story-layout=\"compact\"] .oh-video-preview-actions button:first-child { max-width: 70px; }\n[data-conversation-scroll][data-oh-story-workbench=\"video\"][data-oh-story-layout=\"compact\"] .oh-video-artifacts { grid-template-columns: minmax(105px, 35%) minmax(0, 1fr); }\n"],
5
- "mappings": "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A,EAAkB;AAC5B;;;ACzDA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAA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",
6
- "names": ["import_react", "name", "visit", "directory", "name", "record", "import_jsx_runtime", "directory", "name", "import_jsx_runtime", "import_react", "import_jsx_runtime", "name", "asset", "import_jsx_runtime", "activity", "name", "directory", "open"]
4
+ "sourcesContent": ["import type { Context as ClientContext } from \"@deepseek-ai/cordis\";\nimport type { ISessions } from \"@deepseek-ai/dsh-api-session-controller/client\";\nimport { defineStore } from \"@deepseek-ai/dsh-client-store\";\nimport type { IConversation, PartialAssistant, RunningToolCall } from \"@deepseek-ai/dsh-client-ui-conversation/client\";\nimport type {} from \"@deepseek-ai/dsh-client-ui-chat/client\";\nimport type {} from \"@deepseek-ai/dsh-client-ui-layout/client\";\nimport type {} from \"@deepseek-ai/dsh-client-ui-renderer/client\";\nimport type {} from \"@deepseek-ai/dsh-client-ui-session/client\";\nimport type { PropsRenderSlots, PropsRuntime, PropsStore } from \"@deepseek-ai/dsh-client-ui-slots\";\nimport type { ToolCallViewProps } from \"@deepseek-ai/dsh-client-ui-tool/client\";\nimport { useCallback, useEffect, useId, useLayoutEffect, useMemo, useRef, useState, type CSSProperties } from \"react\";\nimport { createPortal } from \"react-dom\";\nimport {\n creativeRelativePath,\n fileMutations,\n latestSettledMutation,\n latestSettledMutationTurn,\n mutatingCallIds,\n openTurn,\n preferredWorkbenchFile,\n previewMutation,\n sameUndispatchedCalls,\n streamingAssistant,\n undispatchedCalls,\n workbenchLabel,\n workbenchModeForPath,\n type UndispatchedCall,\n type WorkbenchMode\n} from \"./file-activity.js\";\nimport { buildFileTree, type FileTreeNode } from \"./file-tree.js\";\nimport { JsonlPreview } from \"./jsonl-preview.js\";\nimport { MarkdownPreview } from \"./markdown-preview.js\";\nimport {\n creatorDocumentPaths,\n episodeDirectoryForPath,\n isCreatorDocumentPath,\n parseEpisodeProduction,\n type DramaDocumentTarget,\n type DramaProductionSection\n} from \"./drama-production.js\";\nimport { DramaProductionView } from \"./drama-production-view.js\";\nimport { createPendingJob, type\n CanvasPoint,\n mediaTargetFromPath,\n productionQueueFromInbox,\n type ProductionJob,\n type ProductionMediaVersion,\n type ProductionQueueEntry,\n type ProductionSequenceItem\n} from \"./production-runtime.js\";\nimport { settledProductionIntents, type SettledProductionIntent } from \"./production-intents.js\";\nimport { OH_STORY_PRODUCTION_TOOL_NAME } from \"../production-intent.js\";\nimport { VideoStudio, type VideoProject } from \"./video-studio.js\";\nimport {\n hasCreativeProject,\n readWorkbenchPreference,\n resolveWorkbenchOpen,\n workbenchPreferenceStorage,\n writeWorkbenchPreference,\n type WorkbenchPreference\n} from \"./workbench-presence.js\";\nimport { endpoint, handleTabKey } from \"./workbench-ui.js\";\nimport styles from \"./plugin.css?inline\";\n\nexport const name = \"oh-story\";\nexport const inject = [\"slots\", \"sessions\", \"conversation\"];\n\ndeclare module \"@deepseek-ai/dsh-client-ui-slots\" {\n interface SlotMap {\n \"oh-story.workspace\": { kind: \"single\"; scope: \"session\" };\n }\n}\n\ninterface WorkspaceFile {\n readonly path: string;\n readonly bytes: number;\n readonly version: string;\n readonly kind: \"text\" | \"media\";\n readonly mimeType?: string | undefined;\n}\ninterface WorkspacePayload {\n readonly cwd: string;\n readonly files: readonly WorkspaceFile[];\n readonly games: readonly GameProject[];\n readonly videos: readonly VideoProject[];\n readonly shortDrama: Record<string, unknown> | null;\n readonly metadataErrors: readonly string[];\n readonly mode: \"dsh-session\";\n}\ninterface GameProject {\n readonly id: string;\n readonly root: string;\n readonly title: string;\n readonly source: \"workspace\" | \"example\";\n readonly previewReady: boolean;\n readonly previewUrl?: string | undefined;\n readonly previewVersion: string;\n}\ninterface FilePayload {\n readonly path: string;\n readonly content: string;\n readonly bytes: number;\n readonly version: string;\n}\ninterface FileBuffer {\n readonly content: string;\n readonly saved: string;\n readonly source: \"disk\" | \"human\" | \"agent\";\n readonly version: string;\n readonly saving?: boolean | undefined;\n readonly error?: string | undefined;\n readonly missing?: boolean | undefined;\n readonly conflict?: {\n readonly message: string;\n readonly theirs?: string | undefined;\n readonly theirsVersion?: string | undefined;\n } | undefined;\n}\n\ninterface WorkbenchMemory {\n buffers: Record<string, FileBuffer>;\n workbenchPreference: WorkbenchPreference | undefined;\n editorMode: \"preview\" | \"source\" | \"production\";\n expanded: Record<string, boolean>;\n selected: string | undefined;\n workbench: WorkbenchMode;\n gameTab: \"preview\" | \"design\";\n gameProjectId: string | undefined;\n gamePane: \"studio\" | \"chat\";\n videoTab: \"preview\" | \"artifacts\";\n videoProjectId: string | undefined;\n videoPane: \"studio\" | \"chat\";\n productionSection: DramaProductionSection;\n productionSelectedIds: Record<string, string | undefined>;\n productionJobs: Record<string, ProductionJob[]>;\n productionSelections: Record<string, Record<string, string>>;\n productionReferences: Record<string, Record<string, string[]>>;\n productionSequence: Record<string, ProductionSequenceItem[]>;\n productionCanvas: Record<string, Record<string, CanvasPoint>>;\n productionZoom: Record<string, number>;\n productionIntentCalls: Record<string, boolean>;\n /** Latest settled Agent write the workbench has already followed or taken as history. */\n settledMutation: string | undefined;\n /** False only in a Store instance the plugin has not restored this Session's memory into yet. */\n hydrated: boolean;\n}\n\ntype Update<T> = T | ((current: T) => T);\n\nfunction applyUpdate<T>(current: T, update: Update<T>): T {\n return typeof update === \"function\" ? (update as (value: T) => T)(current) : update;\n}\n\n/**\n * DSH 0.1.7 binds session-scoped Store instances to the Session binding's generation and drops\n * them when that generation is released or rebound, which a Session switch is enough to do, and\n * a mounted slot can be handed a fresh instance. The workbench keeps unsaved drafts, production\n * jobs and layout in its Store, and those lived for the page before, so the plugin holds its own\n * page-lifetime copy and restores it into every fresh instance.\n */\nconst workbenchMemoryBySession = new Map<string, WorkbenchMemory>();\n\nconst NO_UNDISPATCHED_CALLS: readonly UndispatchedCall[] = [];\n\nfunction createWorkbenchStore() {\n return defineStore({\n init: (): WorkbenchMemory => ({\n buffers: {},\n workbenchPreference: undefined,\n editorMode: \"preview\",\n expanded: {},\n selected: undefined,\n workbench: \"story\",\n gameTab: \"preview\",\n gameProjectId: undefined,\n gamePane: \"studio\",\n videoTab: \"preview\",\n videoProjectId: undefined,\n videoPane: \"studio\",\n productionSection: \"shots\",\n productionSelectedIds: {},\n productionJobs: {},\n productionSelections: {},\n productionReferences: {},\n productionSequence: {},\n productionCanvas: {},\n productionZoom: {},\n productionIntentCalls: {},\n settledMutation: undefined,\n hydrated: false\n }),\n actions: {\n restore: (draft, memory: WorkbenchMemory | undefined) => {\n if (memory !== undefined) {\n Object.assign(draft, memory);\n // A save in flight belonged to the dropped instance; its completion never lands here.\n draft.buffers = Object.fromEntries(Object.entries(memory.buffers).map(([path, buffer]) => [path, { ...buffer, saving: undefined }]));\n }\n draft.hydrated = true;\n },\n setSettledMutation: (draft, value: string | undefined) => {\n draft.settledMutation = value;\n },\n setBuffers: (draft, update: Update<Record<string, FileBuffer>>) => {\n draft.buffers = applyUpdate(draft.buffers, update);\n },\n setWorkbenchPreference: (draft, update: Update<WorkbenchPreference | undefined>) => {\n draft.workbenchPreference = applyUpdate(draft.workbenchPreference, update);\n },\n setEditorMode: (draft, update: Update<WorkbenchMemory[\"editorMode\"]>) => {\n draft.editorMode = applyUpdate(draft.editorMode, update);\n },\n setExpanded: (draft, update: Update<Record<string, boolean>>) => {\n draft.expanded = applyUpdate(draft.expanded, update);\n },\n setSelected: (draft, update: Update<string | undefined>) => {\n draft.selected = applyUpdate(draft.selected, update);\n },\n setWorkbench: (draft, update: Update<WorkbenchMode>) => {\n draft.workbench = applyUpdate(draft.workbench, update);\n },\n setGameTab: (draft, update: Update<WorkbenchMemory[\"gameTab\"]>) => {\n draft.gameTab = applyUpdate(draft.gameTab, update);\n },\n setGameProjectId: (draft, update: Update<string | undefined>) => {\n draft.gameProjectId = applyUpdate(draft.gameProjectId, update);\n },\n setGamePane: (draft, update: Update<WorkbenchMemory[\"gamePane\"]>) => {\n draft.gamePane = applyUpdate(draft.gamePane, update);\n },\n setVideoTab: (draft, update: Update<WorkbenchMemory[\"videoTab\"]>) => {\n draft.videoTab = applyUpdate(draft.videoTab, update);\n },\n setVideoProjectId: (draft, update: Update<string | undefined>) => {\n draft.videoProjectId = applyUpdate(draft.videoProjectId, update);\n },\n setVideoPane: (draft, update: Update<WorkbenchMemory[\"videoPane\"]>) => {\n draft.videoPane = applyUpdate(draft.videoPane, update);\n },\n setProductionSection: (draft, update: Update<DramaProductionSection>) => {\n draft.productionSection = applyUpdate(draft.productionSection, update);\n },\n setProductionSelectedIds: (draft, update: Update<Record<string, string | undefined>>) => {\n draft.productionSelectedIds = applyUpdate(draft.productionSelectedIds, update);\n },\n setProductionJobs: (draft, update: Update<Record<string, ProductionJob[]>>) => {\n draft.productionJobs = applyUpdate(draft.productionJobs, update);\n },\n setProductionSelections: (draft, update: Update<Record<string, Record<string, string>>>) => {\n draft.productionSelections = applyUpdate(draft.productionSelections, update);\n },\n setProductionReferences: (draft, update: Update<Record<string, Record<string, string[]>>>) => {\n draft.productionReferences = applyUpdate(draft.productionReferences, update);\n },\n setProductionSequence: (draft, update: Update<Record<string, ProductionSequenceItem[]>>) => {\n draft.productionSequence = applyUpdate(draft.productionSequence, update);\n },\n setProductionCanvas: (draft, update: Update<Record<string, Record<string, CanvasPoint>>>) => {\n draft.productionCanvas = applyUpdate(draft.productionCanvas, update);\n },\n setProductionZoom: (draft, update: Update<Record<string, number>>) => {\n draft.productionZoom = applyUpdate(draft.productionZoom, update);\n },\n setProductionIntentCalls: (draft, update: Update<Record<string, boolean>>) => {\n draft.productionIntentCalls = applyUpdate(draft.productionIntentCalls, update);\n }\n }\n });\n}\n\nclass WorkspaceRequestError extends Error {\n constructor(readonly status: number, message: string) { super(message); }\n}\n\nconst GROUP_ORDER: Readonly<Record<WorkbenchMode, readonly string[]>> = {\n story: [\"\u6B63\u6587\", \"\u5927\u7EB2\", \"\u8BBE\u5B9A\", \"\u8FFD\u8E2A\", \"\u5BF9\u6807\", \"\u53C2\u8003\u8D44\u6599\"],\n drama: [\"\u9879\u76EE\", \"\u8F93\u5165\", \"\u9879\u76EE\u5F00\u53D1\", \"\u8BBE\u5B9A\u96C6\", \"\u5267\u96C6\", \"\u5BA1\u67E5\", \"\u521B\u4F5C\u8005\u51B3\u7B56\", \"\u4EA4\u4ED8\"],\n game: [\"game-adaptations\"],\n video: [\"video-recaps\"]\n};\n\nconst WORKBENCH_MODES = [\"story\", \"drama\", \"game\", \"video\"] as const;\nconst EDITOR_MODES = [\"preview\", \"source\", \"production\"] as const;\n\nfunction groupForPath(path: string): string {\n return path === \"short-drama.json\" ? \"\u9879\u76EE\" : path.split(\"/\", 1)[0] ?? \"\u5176\u4ED6\";\n}\n\nasync function json<T>(response: Response): Promise<T> {\n const value = await response.json() as T & { readonly error?: string };\n if (!response.ok) throw new WorkspaceRequestError(response.status, value.error ?? `HTTP ${String(response.status)}`);\n return value;\n}\n\nfunction FileTreeNodes({\n nodes,\n depth,\n expanded,\n selected,\n activityPath,\n onToggle,\n onSelect\n}: {\n readonly nodes: readonly FileTreeNode[];\n readonly depth: number;\n readonly expanded: Readonly<Record<string, boolean>>;\n readonly selected: string | undefined;\n readonly activityPath: string | undefined;\n readonly onToggle: (path: string, open: boolean) => void;\n readonly onSelect: (path: string) => void;\n}) {\n return <>{nodes.map((node) => {\n if (node.kind === \"file\") return <button\n type=\"button\"\n key={node.path}\n style={{ \"--oh-story-indent\": `${String(depth * 14)}px` } as CSSProperties}\n title={node.path}\n aria-label={node.path}\n data-file-path={node.path}\n data-agent-target={node.path === activityPath || undefined}\n aria-current={node.path === selected ? \"page\" : undefined}\n onClick={() => { onSelect(node.path); }}\n >{node.name}</button>;\n const open = selected?.startsWith(`${node.path}/`) === true || expanded[node.path] === true;\n return <details className=\"oh-story-file-folder\" key={node.path} open={open} onToggle={(event) => { onToggle(node.path, event.currentTarget.open); }}>\n <summary style={{ \"--oh-story-indent\": `${String(depth * 14)}px` } as CSSProperties} title={node.path}>{node.name}<span>{node.fileCount}</span></summary>\n <FileTreeNodes\n nodes={node.children}\n depth={depth + 1}\n expanded={expanded}\n selected={selected}\n activityPath={activityPath}\n onToggle={onToggle}\n onSelect={onSelect}\n />\n </details>;\n })}</>;\n}\n\nfunction useWorkspace(sessionId: string): {\n readonly workspace: WorkspacePayload | undefined;\n readonly error: string | undefined;\n readonly loading: boolean;\n readonly reload: () => void;\n} {\n const [version, setVersion] = useState(0);\n const [workspace, setWorkspace] = useState<WorkspacePayload>();\n const [error, setError] = useState<string>();\n const [loading, setLoading] = useState(true);\n const reload = useCallback(() => {\n setLoading(true);\n setVersion((value) => value + 1);\n }, []);\n useEffect(() => {\n const controller = new AbortController();\n setError(undefined);\n void fetch(endpoint(\"workspace\", sessionId), { signal: controller.signal })\n .then((response) => json<WorkspacePayload>(response))\n .then(setWorkspace)\n .catch((reason: unknown) => {\n if (!controller.signal.aborted) setError(reason instanceof Error ? reason.message : String(reason));\n })\n .finally(() => { if (!controller.signal.aborted) setLoading(false); });\n return () => { controller.abort(); };\n }, [sessionId, version]);\n return { workspace, error, loading, reload };\n}\n\nfunction isolatedPreviewUrl(path: string, version: string, revision: number): { readonly href: string; readonly isolated: boolean } {\n const url = new URL(path, globalThis.location.origin);\n if (url.hostname === \"127.0.0.1\") url.hostname = \"localhost\";\n else if (url.hostname === \"localhost\") url.hostname = \"127.0.0.1\";\n url.searchParams.set(\"build\", version);\n url.searchParams.set(\"reload\", String(revision));\n return { href: url.toString(), isolated: url.origin !== globalThis.location.origin };\n}\n\n/**\n * An iframe fires `load`, not `error`, when a navigation commits an HTTP error response, so the\n * frame's own events cannot tell a working preview from the route's JSON error body. Probe the\n * same URL out of band and report a non-OK or non-HTML answer as a real failure.\n */\nfunction PreviewProbe({ href, onFailed }: { readonly href: string; readonly onFailed: () => void }) {\n // Hold the callback in a ref so an inline arrow from the caller cannot re-trigger the probe.\n const failedRef = useRef(onFailed);\n useEffect(() => { failedRef.current = onFailed; }, [onFailed]);\n useEffect(() => {\n const controller = new AbortController();\n void fetch(href, { signal: controller.signal })\n .then((response) => {\n if (controller.signal.aborted) return;\n const type = response.headers.get(\"content-type\") ?? \"\";\n if (!response.ok || !type.includes(\"text/html\")) failedRef.current();\n })\n .catch(() => { if (!controller.signal.aborted) failedRef.current(); });\n return () => { controller.abort(); };\n }, [href]);\n return null;\n}\n\nfunction GamePreview({ project, building }: { readonly project: GameProject; readonly building: boolean }) {\n const shellRef = useRef<HTMLDivElement>(null);\n const fullscreenButtonRef = useRef<HTMLButtonElement>(null);\n const restoreFullscreenFocus = useRef(false);\n const [focused, setFocused] = useState(false);\n const [loaded, setLoaded] = useState(false);\n const [loadError, setLoadError] = useState(false);\n const [revision, setRevision] = useState(0);\n const [loadedVersion, setLoadedVersion] = useState(project.previewVersion);\n useEffect(() => {\n const document = shellRef.current?.ownerDocument;\n if (document === undefined) return;\n const restore = (): void => {\n if (document.fullscreenElement !== null || !restoreFullscreenFocus.current) return;\n restoreFullscreenFocus.current = false;\n fullscreenButtonRef.current?.focus();\n };\n document.addEventListener(\"fullscreenchange\", restore);\n return () => { document.removeEventListener(\"fullscreenchange\", restore); };\n }, []);\n if (!project.previewReady || project.previewUrl === undefined) return <div className=\"oh-game-preview-empty\">\n <span aria-hidden>\u25EB</span>\n <strong>\u8FD8\u6CA1\u6709\u53EF\u8BD5\u73A9\u7248\u672C</strong>\n <p>\u5728\u53F3\u4FA7 Chat \u4F7F\u7528 <code>/novel-to-game quick</code>\uFF0C\u4EA7\u7269\u5199\u5165 <code>game-adaptations/&lt;project&gt;/build/app/</code> \u540E\u4F1A\u81EA\u52A8\u51FA\u73B0\u5728\u8FD9\u91CC\u3002</p>\n <div className=\"oh-game-prompt-example\"><span>\u63CF\u8FF0\u793A\u4F8B</span><q>\u628A\u300A\u4F5C\u54C1\u540D\u300B\u6539\u7F16\u6210\u7F51\u9875\u4E92\u52A8\u6E38\u620F\uFF0C\u76EE\u6807\u73A9\u5BB6\u662F\u2026\u2026\uFF0C\u6838\u5FC3\u73A9\u6CD5\u662F\u2026\u2026\uFF0C\u5E0C\u671B\u6574\u4F53\u98CE\u683C\u2026\u2026</q></div>\n </div>;\n const preview = isolatedPreviewUrl(project.previewUrl, loadedVersion, revision);\n const pending = project.previewVersion !== loadedVersion;\n /** Accept the newer build the creator just chose. */\n const reload = (): void => {\n setLoaded(false);\n setLoadError(false);\n setLoadedVersion(project.previewVersion);\n setRevision((value) => value + 1);\n };\n /** Re-run the build the creator already accepted; never silently adopt a newer one. */\n const refresh = (): void => {\n setLoaded(false);\n setLoadError(false);\n setRevision((value) => value + 1);\n };\n const runtimeState = loadError ? \"\u9884\u89C8\u8F7D\u5165\u5931\u8D25 \u00B7 \u53EF\u91CD\u65B0\u8F7D\u5165\"\n : building ? \"Agent \u6B63\u5728\u66F4\u65B0\u6E38\u620F\u6587\u4EF6 \u00B7 \u5F53\u524D\u9884\u89C8\u4FDD\u6301\u4E0D\u53D8\"\n : pending ? \"\u65B0\u7248\u672C\u5DF2\u5C31\u7EEA \u00B7 \u7531\u4F60\u51B3\u5B9A\u4F55\u65F6\u8F7D\u5165\"\n : loaded ? (preview.isolated ? \"\u9884\u89C8\u5DF2\u8F7D\u5165\" : \"\u9884\u89C8\u5DF2\u8F7D\u5165 \u00B7 \u5F53\u524D\u90E8\u7F72\u65E0\u6CD5\u9694\u79BB\u6765\u6E90\uFF0C\u5B58\u6863\u529F\u80FD\u4E0D\u53EF\u7528\")\n : \"\u6B63\u5728\u8F7D\u5165\u9884\u89C8\u2026\";\n const fullscreen = (): void => {\n const shell = shellRef.current;\n if (shell === null) return;\n restoreFullscreenFocus.current = true;\n void shell.requestFullscreen().catch(() => { restoreFullscreenFocus.current = false; });\n };\n return <div ref={shellRef} className=\"oh-game-preview-shell\" data-state={loadError ? \"error\" : building ? \"building\" : loaded ? \"ready\" : \"loading\"}>\n <div className=\"oh-game-preview-status\">\n <span className=\"oh-game-runtime-state\" role=\"status\" aria-live=\"polite\" title={runtimeState}><i aria-hidden /><em>{runtimeState}</em></span>\n <div>\n {pending && !building && <button type=\"button\" onClick={reload}>\u8F7D\u5165\u65B0\u7248\u672C</button>}\n <button className=\"oh-game-reload\" type=\"button\" onClick={refresh} aria-label=\"\u91CD\u65B0\u8F7D\u5165\u6E38\u620F\"><span aria-hidden>\u21BB</span><b>\u5237\u65B0</b></button>\n <button ref={fullscreenButtonRef} type=\"button\" onClick={fullscreen}>\u5168\u5C4F\u8BD5\u73A9</button>\n </div>\n </div>\n <PreviewProbe href={preview.href} onFailed={() => { setLoaded(false); setLoadError(true); }} />\n <iframe\n key={`${project.id}:${loadedVersion}:${String(revision)}`}\n src={preview.href}\n title={`\u300A${project.title}\u300B\u53EF\u8BD5\u73A9\u9884\u89C8`}\n sandbox={preview.isolated\n ? \"allow-scripts allow-same-origin allow-forms allow-modals allow-downloads\"\n : \"allow-scripts allow-forms allow-modals allow-downloads\"}\n allow=\"autoplay; fullscreen; gamepad\"\n allowFullScreen\n referrerPolicy=\"no-referrer\"\n onLoad={() => { setLoadError(false); setLoaded(true); }}\n onError={() => { setLoaded(false); setLoadError(true); }}\n onFocus={() => { setFocused(true); }}\n onBlur={() => { setFocused(false); }}\n />\n <div className=\"oh-game-focus-hint\" data-focused={focused || undefined}>{focused ? \"\u6E38\u620F\u6B63\u5728\u63A5\u6536\u952E\u9F20\u8F93\u5165\" : \"\u70B9\u51FB\u753B\u9762\u8FDB\u5165\u8BD5\u73A9\"}</div>\n </div>;\n}\n\nfunction GameDesign({\n project,\n files,\n selected,\n sessionId,\n onSelect\n}: {\n readonly project: GameProject;\n readonly files: readonly WorkspaceFile[];\n readonly selected: string | undefined;\n readonly sessionId: string;\n readonly onSelect: (path: string) => void;\n}) {\n const documents = useMemo(() => files.filter((file) => file.path.startsWith(`${project.root}/`) && (\n /\\.(?:md|txt|json|jsonl|html|css|[cm]?js|tsx?|jsx)$/iu.test(file.path)\n )), [files, project.root]);\n const preferred = selected !== undefined && documents.some((file) => file.path === selected)\n ? selected\n : documents.find((file) => file.path === `${project.root}/PRODUCT_BRIEF.md`)?.path ?? documents[0]?.path;\n const [path, setPath] = useState(preferred);\n const [content, setContent] = useState<string>();\n const [error, setError] = useState<string>();\n useEffect(() => { setPath(preferred); }, [preferred, project.id]);\n useEffect(() => {\n if (path === undefined || project.source === \"example\") { setContent(undefined); return; }\n const controller = new AbortController();\n setContent(undefined);\n setError(undefined);\n void fetch(endpoint(\"file\", sessionId, path), { signal: controller.signal })\n .then((response) => json<FilePayload>(response))\n .then((file) => { setContent(file.content); })\n .catch((reason: unknown) => { if (!controller.signal.aborted) setError(reason instanceof Error ? reason.message : String(reason)); });\n return () => { controller.abort(); };\n }, [path, project.source, sessionId]);\n if (project.source === \"example\") return <div className=\"oh-game-design-empty\">\n <strong>\u5185\u7F6E\u5B8C\u6574\u793A\u4F8B</strong>\n <p>\u300A\u91D1\u74F6\u6885 \u00B7 \u98CE\u6708\u603B\u8D26\u300B\u7684\u5B8C\u6574\u53EF\u73A9\u6784\u5EFA\u4E0E QA \u6821\u9A8C\u7ED3\u679C\u968F\u63D2\u4EF6\u6253\u5305\uFF0C\u53EF\u76F4\u63A5\u5728\u5DE6\u4FA7\u8BD5\u73A9\u3002\u4E0A\u6E38\u7684\u4EA7\u54C1\u7B80\u62A5\u3001\u5206\u6790\u3001\u6982\u5FF5\u3001\u8BBE\u8BA1\u4E0E\u6E90\u5C0F\u8BF4\u4E0D\u968F\u5305\u5206\u53D1\uFF0C\u53EF\u5728 novel-to-game \u4ED3\u5E93\u67E5\u770B\u5B8C\u6574\u521B\u4F5C\u8FC7\u7A0B\u3002</p>\n <code>novel-to-game/examples/jin-ping-mei</code>\n </div>;\n if (documents.length === 0 || path === undefined) return <div className=\"oh-game-design-empty\">\u5F53\u524D\u9879\u76EE\u8FD8\u6CA1\u6709\u53EF\u68C0\u67E5\u7684\u8BBE\u8BA1\u6216\u6E90\u6587\u4EF6\u3002</div>;\n const markdown = path.toLocaleLowerCase().endsWith(\".md\");\n return <div className=\"oh-game-design\">\n <label>\u9879\u76EE\u6587\u4EF6<select value={path} onChange={(event) => {\n setPath(event.target.value);\n onSelect(event.target.value);\n }}>{documents.map((file) => <option value={file.path} key={file.path}>{file.path.slice(project.root.length + 1)}</option>)}</select></label>\n {error !== undefined ? <div className=\"oh-story-error\">{error}</div>\n : content === undefined ? <div className=\"oh-game-design-empty\">\u6B63\u5728\u8F7D\u5165\u6587\u4EF6\u2026</div>\n : markdown ? <MarkdownPreview content={content} label={path} />\n : <pre className=\"oh-game-source\" aria-label={`${path} \u6E90\u7801`}>{content}</pre>}\n </div>;\n}\n\nfunction GameStudio({\n sessionId,\n workspace,\n building,\n selected,\n gameTab,\n gameProjectId,\n hidden,\n onGameTab,\n onGameProject,\n workbenches,\n paneId,\n labelledBy,\n onWorkbench,\n onCollapse,\n onSelect\n}: {\n readonly sessionId: string;\n readonly workspace: WorkspacePayload;\n readonly building: boolean;\n readonly selected: string | undefined;\n readonly gameTab: WorkbenchMemory[\"gameTab\"];\n readonly gameProjectId: string | undefined;\n readonly hidden: boolean;\n readonly onGameTab: (tab: WorkbenchMemory[\"gameTab\"]) => void;\n readonly onGameProject: (id: string) => void;\n readonly workbenches: readonly WorkbenchMode[];\n readonly paneId: string;\n readonly labelledBy: string;\n readonly onWorkbench: (mode: WorkbenchMode) => void;\n readonly onCollapse: () => void;\n readonly onSelect: (path: string) => void;\n}) {\n const project = workspace.games.find((value) => value.id === gameProjectId) ?? workspace.games[0];\n const studioRef = useRef<HTMLElement>(null);\n const tabsId = useId();\n useLayoutEffect(() => {\n const studio = studioRef.current;\n if (studio === null) return;\n const publishWidth = () => {\n studio.toggleAttribute(\"data-oh-game-narrow\", studio.clientWidth <= 300);\n };\n publishWidth();\n const observer = new ResizeObserver(publishWidth);\n observer.observe(studio);\n return () => { observer.disconnect(); };\n }, []);\n useEffect(() => {\n if (project !== undefined && project.id !== gameProjectId) onGameProject(project.id);\n }, [gameProjectId, onGameProject, project]);\n if (project === undefined) return <main ref={studioRef} id={paneId} className=\"oh-game-studio\" role=\"tabpanel\" aria-labelledby={labelledBy} hidden={hidden}><div className=\"oh-game-design-empty\">\u6E38\u620F\u80FD\u529B\u6B63\u5728\u8F7D\u5165\u2026</div></main>;\n const tabs = [\"preview\", \"design\"] as const;\n return <main ref={studioRef} id={paneId} className=\"oh-game-studio\" data-source={project.source} role=\"tabpanel\" aria-labelledby={labelledBy} hidden={hidden}>\n <header className=\"oh-game-toolbar\">\n <div className=\"oh-workbench-cluster\">\n {workbenches.length > 1 && <div className=\"oh-game-mode-tabs\" role=\"tablist\" aria-label=\"\u521B\u4F5C\u5DE5\u4F5C\u53F0\">\n {workbenches.map((mode) => <button\n type=\"button\"\n role=\"tab\"\n key={mode}\n aria-selected={mode === \"game\"}\n tabIndex={mode === \"game\" ? 0 : -1}\n onKeyDown={(event) => { handleTabKey(event, workbenches, \"game\", onWorkbench); }}\n onClick={() => { onWorkbench(mode); }}\n >{workbenchLabel(mode)}</button>)}\n </div>}\n <button className=\"oh-workbench-collapse\" type=\"button\" title=\"\u6536\u8D77\u521B\u4F5C\u5DE5\u4F5C\u53F0\" aria-label=\"\u6536\u8D77\u521B\u4F5C\u5DE5\u4F5C\u53F0\" onClick={onCollapse}>\u00D7</button>\n </div>\n <label className=\"oh-game-project\" title=\"\u5207\u6362\u9879\u76EE\u5C06\u91CD\u65B0\u8F7D\u5165\u8BD5\u73A9\"><span>\u6E38\u620F\u9879\u76EE</span><select aria-label=\"\u6E38\u620F\u9879\u76EE\uFF1B\u5207\u6362\u5C06\u91CD\u65B0\u8F7D\u5165\u8BD5\u73A9\" value={project.id} onChange={(event) => { onGameProject(event.target.value); }}>\n {workspace.games.some((item) => item.source === \"workspace\") && <optgroup label=\"\u6211\u7684\u9879\u76EE\">{workspace.games.filter((item) => item.source === \"workspace\").map((item) => <option value={item.id} key={item.id}>{`\u6211\u7684\u9879\u76EE \u00B7 ${item.title}`}</option>)}</optgroup>}\n {workspace.games.some((item) => item.source === \"example\") && <optgroup label=\"\u5185\u7F6E\u793A\u4F8B\">{workspace.games.filter((item) => item.source === \"example\").map((item) => <option value={item.id} key={item.id}>{`\u5185\u7F6E\u793A\u4F8B \u00B7 ${item.title}`}</option>)}</optgroup>}\n </select></label>\n <div className=\"oh-game-tabs\" role=\"tablist\" aria-label=\"\u6E38\u620F\u5DE5\u4F5C\u53F0\">\n {tabs.map((tab) => <button\n key={tab}\n type=\"button\"\n role=\"tab\"\n tabIndex={gameTab === tab ? 0 : -1}\n aria-selected={gameTab === tab}\n id={`${tabsId}-${tab}-tab`}\n aria-controls={`${tabsId}-${tab}-panel`}\n onKeyDown={(event) => { handleTabKey(event, tabs, gameTab, onGameTab); }}\n onClick={() => { onGameTab(tab); }}\n >{tab === \"preview\" ? \"\u8BD5\u73A9\" : project.source === \"example\" ? \"\u8BF4\u660E\" : \"\u9879\u76EE\u6587\u4EF6\"}</button>)}\n </div>\n </header>\n <div className=\"oh-game-panels\">\n <div className=\"oh-game-panel\" role=\"tabpanel\" id={`${tabsId}-preview-panel`} aria-labelledby={`${tabsId}-preview-tab`} hidden={gameTab !== \"preview\"}>\n <GamePreview key={`${project.id}:${String(project.previewReady)}`} project={project} building={building} />\n </div>\n <div className=\"oh-game-panel\" role=\"tabpanel\" id={`${tabsId}-design-panel`} aria-labelledby={`${tabsId}-design-tab`} hidden={gameTab !== \"design\"}>\n <GameDesign project={project} files={workspace.files} selected={selected} sessionId={sessionId} onSelect={onSelect} />\n </div>\n </div>\n </main>;\n}\n\nfunction CreativeWorkbench({\n sessionId,\n runningCalls,\n partial,\n undispatched,\n settledMutation,\n settledMutationTurn,\n liveTurn,\n sessionRunning,\n productionQueue,\n productionIntents,\n sendProductionPrompt,\n cancelProduction,\n removeQueuedProduction,\n workspace,\n error,\n workspaceLoading,\n reload,\n open,\n creativeProject,\n welcome,\n useStore,\n actions\n}: {\n readonly sessionId: string;\n readonly runningCalls: readonly RunningToolCall[];\n readonly partial: PartialAssistant | null;\n readonly undispatched: readonly UndispatchedCall[];\n readonly settledMutation: string | undefined;\n /** Turn of {@link settledMutation}; only a write from a Turn this mount saw open is followed. */\n readonly settledMutationTurn: number | undefined;\n /** The Session's last Turn while it is open. */\n readonly liveTurn: number | undefined;\n readonly sessionRunning: boolean;\n readonly productionQueue: readonly ProductionQueueEntry[];\n readonly productionIntents: readonly SettledProductionIntent[];\n readonly workspace: WorkspacePayload | undefined;\n readonly error: string | undefined;\n readonly workspaceLoading: boolean;\n readonly reload: () => void;\n readonly open: boolean;\n readonly creativeProject: boolean;\n /** A blank Session over a workspace without creative work: the first thing a fresh DSH shows. */\n readonly welcome: boolean;\n} & Pick<WorkbenchSlotProps, \"useStore\" | \"actions\" | \"sendProductionPrompt\" | \"cancelProduction\" | \"removeQueuedProduction\">) {\n const activities = useMemo(\n () => fileMutations(runningCalls, partial, undispatched),\n [partial, runningCalls, undispatched]\n );\n const normalizedActivities = useMemo(() => activities.flatMap((activity) => {\n const path = creativeRelativePath(activity.path, workspace?.cwd);\n return path === undefined ? [] : [{ activity, path }];\n }), [activities, workspace?.cwd]);\n const primaryActivity = normalizedActivities.at(-1);\n const activityPaths = useMemo(() => new Set(normalizedActivities.map((value) => value.path)), [normalizedActivities]);\n const settledPath = settledMutation === undefined\n ? undefined\n : creativeRelativePath(settledMutation.slice(settledMutation.indexOf(\"\\0\") + 1), workspace?.cwd);\n const activity = primaryActivity?.activity;\n const activityPath = primaryActivity?.path;\n const workbench = useStore((memory) => memory.workbench);\n const setWorkbench = actions.setWorkbench;\n const gameTab = useStore((memory) => memory.gameTab);\n const setGameTab = actions.setGameTab;\n const gameProjectId = useStore((memory) => memory.gameProjectId);\n const setGameProjectId = actions.setGameProjectId;\n const gamePane = useStore((memory) => memory.gamePane);\n const setGamePane = actions.setGamePane;\n const videoTab = useStore((memory) => memory.videoTab);\n const setVideoTab = actions.setVideoTab;\n const videoProjectId = useStore((memory) => memory.videoProjectId);\n const setVideoProjectId = actions.setVideoProjectId;\n const videoPane = useStore((memory) => memory.videoPane);\n const setVideoPane = actions.setVideoPane;\n const selected = useStore((memory) => memory.selected);\n const setSelected = actions.setSelected;\n const buffers = useStore((memory) => memory.buffers);\n const setBuffers = actions.setBuffers;\n const buffersRef = useRef<Record<string, FileBuffer>>({});\n const expanded = useStore((memory) => memory.expanded);\n const setExpanded = actions.setExpanded;\n const productionSection = useStore((memory) => memory.productionSection);\n const setProductionSection = actions.setProductionSection;\n const productionSelectedIds = useStore((memory) => memory.productionSelectedIds);\n const productionJobsByEpisode = useStore((memory) => memory.productionJobs);\n const productionSelectionsByEpisode = useStore((memory) => memory.productionSelections);\n const productionReferencesByEpisode = useStore((memory) => memory.productionReferences);\n const productionSequenceByEpisode = useStore((memory) => memory.productionSequence);\n const productionCanvasByEpisode = useStore((memory) => memory.productionCanvas);\n const productionZoomByEpisode = useStore((memory) => memory.productionZoom);\n const productionIntentCalls = useStore((memory) => memory.productionIntentCalls);\n const surfaceRef = useRef<HTMLDivElement>(null);\n const setWorkbenchPreference = actions.setWorkbenchPreference;\n const applyWorkbenchPreference = useCallback((preference: WorkbenchPreference): void => {\n setWorkbenchPreference(preference);\n writeWorkbenchPreference(workbenchPreferenceStorage(), workspace?.cwd, preference);\n }, [setWorkbenchPreference, workspace?.cwd]);\n const compactTabsId = useId();\n const compactStudioId = `${compactTabsId}-studio-panel`;\n const compactVideoStudioId = `${compactTabsId}-video-studio-panel`;\n const compactChatId = `${compactTabsId}-chat-panel`;\n const navRef = useRef<HTMLElement>(null);\n const activityBases = useRef(new Map<string, { readonly path: string; readonly base: string }>());\n const previousSignals = useRef<ReadonlySet<string>>(new Set());\n // The consumed signal lives in the Store so it survives a remount: DSH 0.1.7 reloads a Session's\n // Chat after a switch, and replaying its history must not look like a fresh Agent write.\n const consumedSettledMutation = useStore((memory) => memory.settledMutation);\n // A reloaded Session shows its history as closed Turns; only a Turn seen open is live work.\n const liveTurns = useRef(new Set<number>());\n if (liveTurn !== undefined) liveTurns.current.add(liveTurn);\n const saveLocks = useRef(new Set<string>());\n const buffer = selected === undefined ? undefined : buffers[selected];\n const selectedFile = workspace?.files.find((file) => file.path === selected);\n const selectedMedia = selectedFile?.kind === \"media\";\n const dirty = buffer?.source === \"human\" && buffer.content !== buffer.saved;\n const saving = buffer?.saving === true;\n const fileError = buffer?.error;\n const conflict = buffer?.conflict;\n const selectedLower = selected?.toLocaleLowerCase();\n const markdown = selectedLower?.endsWith(\".md\") === true;\n const jsonl = selectedLower?.endsWith(\".jsonl\") === true;\n const structured = jsonl || selectedLower?.endsWith(\".json\") === true;\n const previewable = markdown || jsonl;\n const episodeDirectory = episodeDirectoryForPath(selected);\n const productionAvailable = selected !== undefined && isCreatorDocumentPath(selected) && episodeDirectory !== undefined;\n const editorModes = productionAvailable ? EDITOR_MODES : EDITOR_MODES.filter((mode) => mode !== \"production\");\n const episodeDocumentPaths = useMemo(\n () => episodeDirectory === undefined ? [] : creatorDocumentPaths(workspace?.files.filter((file) => file.kind === \"text\") ?? [], episodeDirectory),\n [episodeDirectory, workspace?.files]\n );\n const episodeDocuments = useMemo(() => Object.fromEntries(episodeDocumentPaths.flatMap((path) => {\n const current = buffers[path];\n return current === undefined || current.missing === true ? [] : [[path, current.content] as const];\n })), [buffers, episodeDocumentPaths]);\n const episodeProduction = useMemo(\n () => episodeDirectory === undefined ? undefined : parseEpisodeProduction(episodeDocuments, episodeDirectory),\n [episodeDirectory, episodeDocuments]\n );\n const productionLibrary = useMemo(() => (workspace?.files ?? []).flatMap((file): ProductionMediaVersion[] => {\n if (file.kind !== \"media\" || file.mimeType?.startsWith(\"audio/\") === true) return [];\n if (!file.path.startsWith(\"\u5267\u96C6/\") && !file.path.startsWith(\"\u4EA4\u4ED8/\")) return [];\n const targetId = file.path.toLocaleUpperCase().match(/(?:SHOT|IMG|MOTION|VISUAL)-[A-Z0-9-]+/u)?.[0] ?? file.path.split(\"/\").at(-2) ?? \"PROJECT-MEDIA\";\n return [{\n id: `workspace:${file.path}:${file.version}`,\n targetId,\n kind: file.mimeType?.startsWith(\"image/\") === true ? \"image\" : \"video\",\n url: endpoint(\"media\", sessionId, file.path),\n path: file.path\n }];\n }), [sessionId, workspace?.files]);\n const productionVersions = useMemo(() => {\n if (episodeProduction === undefined) return [];\n const episodeName = episodeProduction.episodeDirectory.split(\"/\").at(-1) ?? \"\";\n const knownTargets = [\n ...episodeProduction.shots.map((shot) => shot.id),\n ...episodeProduction.assets.map((asset) => asset.id),\n ...episodeProduction.visualAssets.map((asset) => asset.id),\n ...episodeProduction.motions.map((motion) => motion.id)\n ].sort((left, right) => right.length - left.length);\n const motionTargets = new Map(episodeProduction.motions.flatMap((motion) => motion.shotId === undefined ? [] : [[motion.id, motion.shotId] as const]));\n const fromWorkspace = productionLibrary.flatMap((version) => {\n if (version.path === undefined || (!version.path.startsWith(`${episodeProduction.episodeDirectory}/`) && !version.path.startsWith(`\u4EA4\u4ED8/${episodeName}/`))) return [];\n const matched = mediaTargetFromPath(version.path, knownTargets);\n // Drama Skills 0.7 renders the assembled cut into \u5236\u4F5C\u6210\u679C/\u6210\u7247/; earlier native\n // compositions wrote \u6210\u7247-<job>.mp4 beside the per-shot results.\n const composition = /(?:^|\\/)\u6210\u7247-[^/]+\\.mp4$/iu.test(version.path)\n || /(?:^|\\/)\u5236\u4F5C\u6210\u679C\\/\u6210\u7247\\//u.test(version.path);\n if (matched === undefined && !composition) return [];\n const targetId = matched === undefined ? episodeProduction.episodeDirectory : motionTargets.get(matched) ?? matched;\n return [{ ...version, targetId }];\n });\n const byId = new Map<string, ProductionMediaVersion>();\n for (const version of fromWorkspace) byId.set(version.id, version);\n return [...byId.values()];\n }, [episodeProduction, productionLibrary]);\n const productionSelectedId = episodeDirectory === undefined ? undefined : productionSelectedIds[episodeDirectory];\n const productionJobs = episodeDirectory === undefined ? [] : productionJobsByEpisode[episodeDirectory] ?? [];\n const productionSelections = episodeDirectory === undefined ? {} : productionSelectionsByEpisode[episodeDirectory] ?? {};\n const productionReferences = episodeDirectory === undefined ? {} : productionReferencesByEpisode[episodeDirectory] ?? {};\n const productionSequence = episodeDirectory === undefined ? [] : productionSequenceByEpisode[episodeDirectory] ?? [];\n const productionCanvas = episodeDirectory === undefined ? {} : productionCanvasByEpisode[episodeDirectory] ?? {};\n const productionZoom = episodeDirectory === undefined ? .65 : productionZoomByEpisode[episodeDirectory] ?? .65;\n const setProductionSelectedId = useCallback((selectedId: string | undefined) => {\n if (episodeDirectory !== undefined) actions.setProductionSelectedIds((current) => ({ ...current, [episodeDirectory]: selectedId }));\n }, [actions, episodeDirectory]);\n const setProductionJobs = useCallback((jobs: ProductionJob[]) => {\n if (episodeDirectory !== undefined) actions.setProductionJobs((current) => ({ ...current, [episodeDirectory]: jobs }));\n }, [actions, episodeDirectory]);\n const setProductionSelections = useCallback((selections: Record<string, string>) => {\n if (episodeDirectory !== undefined) actions.setProductionSelections((current) => ({ ...current, [episodeDirectory]: selections }));\n }, [actions, episodeDirectory]);\n const setProductionReferences = useCallback((references: Record<string, string[]>) => {\n if (episodeDirectory !== undefined) actions.setProductionReferences((current) => ({ ...current, [episodeDirectory]: references }));\n }, [actions, episodeDirectory]);\n const setProductionSequence = useCallback((sequence: ProductionSequenceItem[]) => {\n if (episodeDirectory !== undefined) actions.setProductionSequence((current) => ({ ...current, [episodeDirectory]: sequence }));\n }, [actions, episodeDirectory]);\n const setProductionCanvas = useCallback((canvas: Record<string, CanvasPoint>) => {\n if (episodeDirectory !== undefined) actions.setProductionCanvas((current) => ({ ...current, [episodeDirectory]: canvas }));\n }, [actions, episodeDirectory]);\n const setProductionZoom = useCallback((zoom: number) => {\n if (episodeDirectory !== undefined) actions.setProductionZoom((current) => ({ ...current, [episodeDirectory]: zoom }));\n }, [actions, episodeDirectory]);\n const editorMode = useStore((memory) => memory.editorMode);\n const setEditorMode = actions.setEditorMode;\n const modeSelection = useRef(selected);\n const textareaRef = useRef<HTMLTextAreaElement>(null);\n const editorPositions = useRef(new Map<string, { readonly scrollTop: number; readonly selectionStart: number; readonly selectionEnd: number }>());\n const editorReady = buffer !== undefined && buffer.missing !== true;\n const workspaceKind = workbench === \"game\" || workbench === \"video\" ? undefined : workbench;\n const gameBuilding = normalizedActivities.some(({ path }) => path.startsWith(\"game-adaptations/\"));\n const videoBuilding = normalizedActivities.some(({ path }) => path.startsWith(\"video-recaps/\"));\n\n useEffect(() => { buffersRef.current = buffers; }, [buffers]);\n\n const rememberEditorPosition = useCallback((): void => {\n const element = textareaRef.current;\n if (element === null || selected === undefined || element.getAttribute(\"aria-label\") !== selected) return;\n editorPositions.current.set(selected, {\n scrollTop: element.scrollTop,\n selectionStart: element.selectionStart,\n selectionEnd: element.selectionEnd\n });\n }, [selected]);\n\n useLayoutEffect(() => {\n if (editorMode !== \"source\" || selected === undefined || !editorReady) return;\n const element = textareaRef.current;\n const position = editorPositions.current.get(selected);\n if (element === null || position === undefined) return;\n const end = Math.min(position.selectionEnd, element.value.length);\n element.setSelectionRange(Math.min(position.selectionStart, end), end);\n element.scrollTop = position.scrollTop;\n }, [editorMode, editorReady, selected]);\n\n useEffect(() => {\n const warn = (event: BeforeUnloadEvent): void => {\n if (!Object.values(buffersRef.current).some((value) => value.source === \"human\" && value.content !== value.saved)) return;\n event.preventDefault();\n };\n globalThis.addEventListener(\"beforeunload\", warn);\n return () => { globalThis.removeEventListener(\"beforeunload\", warn); };\n }, []);\n\n const expandPath = useCallback((path: string): void => {\n const segments = path.split(\"/\");\n const ancestors = [groupForPath(path)];\n for (let index = 1; index < segments.length - 1; index += 1) ancestors.push(segments.slice(0, index + 1).join(\"/\"));\n setExpanded((current) => {\n const next = { ...current };\n for (const ancestor of ancestors) next[ancestor] = true;\n return next;\n });\n }, []);\n\n const revealPath = useCallback((path: string): void => {\n rememberEditorPosition();\n const nextWorkbench = workbenchModeForPath(path) ?? \"story\";\n setWorkbench(nextWorkbench);\n if (nextWorkbench === \"game\" && !path.includes(\"/build/app/\")) setGameTab(\"design\");\n setSelected(path);\n expandPath(path);\n }, [expandPath, rememberEditorPosition]);\n\n useEffect(() => {\n if (workspace === undefined) return;\n const pending = productionIntents.filter(({ callId }) => productionIntentCalls[callId] !== true);\n if (pending.length === 0) return;\n for (const { intent } of pending) {\n if (intent.action === \"open_section\" || intent.action === \"focus_target\") {\n const documentPath = [\"\u5206\u955C.md\", \"\u56FE\u7247\u63D0\u793A\u8BCD.md\", \"\u89C6\u89C9\u8BBE\u5B9A.md\", \"\u5267\u672C.md\", \"\u89C6\u9891\u63D0\u793A\u8BCD.md\"]\n .map((name) => `${intent.episode}/${name}`)\n .find((path) => workspace.files.some((file) => file.path === path));\n if (documentPath !== undefined) {\n setWorkbench(\"drama\");\n setSelected(documentPath);\n expandPath(documentPath);\n globalThis.setTimeout(() => { setEditorMode(\"production\"); }, 0);\n }\n }\n if (intent.action === \"open_section\") setProductionSection(intent.section ?? \"shots\");\n else if (intent.action === \"focus_target\") {\n actions.setProductionSelectedIds((current) => ({ ...current, [intent.episode]: intent.targetId }));\n setProductionSection(intent.section ?? (intent.targetId?.startsWith(\"SHOT-\") === true ? \"shots\" : \"assets\"));\n } else if (intent.action === \"set_sequence\") {\n actions.setProductionSequence((current) => ({\n ...current,\n [intent.episode]: (intent.shotIds ?? []).map((shotId) => ({ shotId }))\n }));\n } else if (intent.action === \"track_job\" && intent.jobId !== undefined && intent.targetId !== undefined && intent.jobKind !== undefined) {\n const { jobId, targetId, jobKind } = intent;\n actions.setProductionJobs((current) => {\n const jobs = current[intent.episode] ?? [];\n if (jobs.some((job) => job.id === jobId)) {\n return {\n ...current,\n [intent.episode]: jobs.map((job) => job.id === jobId ? {\n ...job,\n targetId,\n kind: jobKind,\n status: \"running\",\n progress: Math.max(10, job.progress),\n prompt: intent.prompt ?? job.prompt,\n expectedOutputs: intent.expectedOutputs ?? job.expectedOutputs,\n error: undefined\n } : job)\n };\n }\n return {\n ...current,\n [intent.episode]: [...jobs, {\n ...createPendingJob({\n id: jobId,\n targetId,\n kind: jobKind,\n prompt: intent.prompt ?? \"\",\n expectedOutputs: intent.expectedOutputs\n }),\n status: \"running\",\n progress: 10\n }]\n };\n });\n }\n }\n actions.setProductionIntentCalls((current) => ({\n ...current,\n ...Object.fromEntries(pending.map(({ callId }) => [callId, true]))\n }));\n }, [actions, expandPath, productionIntentCalls, productionIntents, setEditorMode, setProductionSection, setSelected, setWorkbench, workspace]);\n\n // Latch first entry into the game workbench: before that the Studio must not mount, or every\n // session downloads and runs the bundled example in a display:none iframe. Once mounted it\n // stays mounted so the running game survives later navigation.\n const openedGame = useRef(false);\n if (workbench === \"game\") openedGame.current = true;\n const gameStudioMounted = openedGame.current;\n const openedVideo = useRef(false);\n if (workbench === \"video\") openedVideo.current = true;\n const videoStudioMounted = openedVideo.current;\n\n const followAgentPath = useCallback((path: string): void => {\n expandPath(path);\n const current = selected === undefined ? undefined : buffersRef.current[selected];\n const preserveFocusedDraft = path !== selected\n && current?.source === \"human\"\n && current.content !== current.saved\n && surfaceRef.current?.ownerDocument.activeElement === textareaRef.current;\n if (preserveFocusedDraft) return;\n // The editor textarea is not mounted in the Game Studio, so the draft guard above can never\n // fire there. Never preempt a running game: agent writes may expand the tree, not navigate.\n if ((workbench === \"game\" && gameTab === \"preview\") || (workbench === \"video\" && videoTab === \"preview\")) return;\n revealPath(path);\n }, [expandPath, gameTab, revealPath, selected, videoTab, workbench]);\n\n useEffect(() => {\n if (activityPath !== undefined && activityPath === selected && !selectedMedia) setEditorMode(\"source\");\n }, [activityPath, selected, selectedMedia]);\n\n useEffect(() => {\n if (modeSelection.current === selected) return;\n modeSelection.current = selected;\n setEditorMode(selected !== undefined && activityPaths.has(selected) ? \"source\" : selectedMedia || previewable ? \"preview\" : \"source\");\n }, [activityPaths, previewable, selected, selectedMedia]);\n\n useEffect(() => {\n if (workspaceLoading) return;\n if (activityPath !== undefined) return;\n if (selected !== undefined && (\n (workspace?.files.some((file) => file.path === selected) ?? false)\n || buffers[selected] !== undefined\n ) && workbenchModeForPath(selected) === workbench) return;\n setSelected(workspace === undefined ? undefined : preferredWorkbenchFile(workspace.files, workbench));\n }, [activityPath, buffers, selected, workbench, workspace, workspaceLoading]);\n\n useEffect(() => {\n if (workspace === undefined || workspaceLoading) return;\n const paths = new Set(workspace.files.map((file) => file.path));\n setBuffers((current) => {\n let changed = false;\n const next = { ...current };\n for (const [path, value] of Object.entries(current)) {\n if (paths.has(path) || activityPaths.has(path)) continue;\n // A write that just settled is on disk before the workspace reload lists it; keep its\n // preview (and so the selection) until then. A denied write never settles and is pruned.\n if (value.source === \"agent\" && sessionRunning && path === settledPath) continue;\n if (value.source === \"human\" && value.content !== value.saved) {\n if (value.missing !== true) {\n next[path] = { ...value, missing: true, error: \"\u6587\u4EF6\u5DF2\u4ECE workspace \u79FB\u9664\u3002\u672C\u5730\u8349\u7A3F\u4ECD\u4FDD\u7559\uFF0C\u53EF\u590D\u5236\u540E\u653E\u5F03\u8349\u7A3F\u3002\" };\n changed = true;\n }\n } else {\n delete next[path];\n changed = true;\n }\n }\n return changed ? next : current;\n });\n }, [activityPaths, sessionRunning, settledPath, workspace, workspaceLoading]);\n\n useEffect(() => {\n if (selected === undefined || selectedMedia || activityPaths.has(selected)) return;\n if (!(workspace?.files.some((file) => file.path === selected) ?? false)) return;\n const controller = new AbortController();\n setBuffers((current) => {\n const existing = current[selected];\n return existing === undefined ? current : { ...current, [selected]: { ...existing, error: undefined } };\n });\n void fetch(endpoint(\"file\", sessionId, selected), { signal: controller.signal })\n .then((response) => json<FilePayload>(response))\n .then((file) => {\n setBuffers((current) => {\n const existing = current[file.path];\n if (existing?.source === \"human\" && existing.content !== existing.saved) {\n if (existing.version === file.version) return { ...current, [file.path]: { ...existing, missing: false, error: undefined } };\n return {\n ...current,\n [file.path]: {\n ...existing,\n missing: false,\n error: undefined,\n conflict: {\n message: `${file.path} \u5DF2\u5728\u78C1\u76D8\u4E0A\u66F4\u65B0\uFF1B\u4F60\u7684\u672C\u5730\u8349\u7A3F\u6CA1\u6709\u88AB\u8986\u76D6\u3002`,\n theirs: file.content,\n theirsVersion: file.version\n }\n }\n };\n }\n return {\n ...current,\n [file.path]: { content: file.content, saved: file.content, source: \"disk\", version: file.version }\n };\n });\n })\n .catch((reason: unknown) => {\n if (controller.signal.aborted) return;\n setBuffers((current) => {\n const existing = current[selected];\n return existing === undefined ? current : {\n ...current,\n [selected]: { ...existing, error: reason instanceof Error ? reason.message : String(reason) }\n };\n });\n });\n return () => { controller.abort(); };\n }, [activityPaths, selected, selectedMedia, sessionId, workspace?.files]);\n\n useEffect(() => {\n if (!productionAvailable) return;\n const missing = episodeDocumentPaths.filter((path) => buffersRef.current[path] === undefined && !activityPaths.has(path));\n if (missing.length === 0) return;\n const controller = new AbortController();\n void Promise.all(missing.map((path) => fetch(endpoint(\"file\", sessionId, path), { signal: controller.signal }).then((response) => json<FilePayload>(response))))\n .then((files) => {\n setBuffers((current) => {\n const next = { ...current };\n for (const file of files) {\n const existing = next[file.path];\n if (existing?.source === \"human\" && existing.content !== existing.saved) continue;\n next[file.path] = { content: file.content, saved: file.content, source: \"disk\", version: file.version };\n }\n return next;\n });\n })\n .catch((reason: unknown) => {\n if (!controller.signal.aborted) {\n setBuffers((current) => {\n const next = { ...current };\n for (const path of missing) {\n const existing = next[path];\n if (existing !== undefined) next[path] = { ...existing, error: reason instanceof Error ? reason.message : String(reason) };\n }\n return next;\n });\n }\n });\n return () => { controller.abort(); };\n }, [activityPaths, episodeDocumentPaths, productionAvailable, sessionId]);\n\n useEffect(() => {\n if (normalizedActivities.length === 0) return;\n for (const { path } of normalizedActivities) expandPath(path);\n if (activityPath !== undefined) followAgentPath(activityPath);\n setBuffers((current) => {\n let next = current;\n for (const { activity: currentActivity, path } of normalizedActivities) {\n const existing = next[path];\n if (existing?.source === \"human\" && existing.content !== existing.saved) {\n next = {\n ...next,\n [path]: {\n ...existing,\n conflict: { message: `${path} \u6B63\u7531 Agent \u4FEE\u6539\uFF1B\u4F60\u7684\u672C\u5730\u8349\u7A3F\u5DF2\u9501\u5B9A\uFF0C\u4E0D\u4F1A\u88AB\u8986\u76D6\u3002` }\n }\n };\n continue;\n }\n let basis = activityBases.current.get(currentActivity.callId);\n if (basis === undefined || basis.path !== path) {\n basis = { path, base: existing?.content ?? \"\" };\n activityBases.current.set(currentActivity.callId, basis);\n }\n const preview = previewMutation(currentActivity, basis.base);\n if (preview === undefined || (existing?.source === \"agent\" && existing.content === preview)) continue;\n next = {\n ...next,\n [path]: {\n content: preview,\n saved: existing?.saved ?? \"\",\n source: \"agent\",\n version: existing?.version ?? \"\"\n }\n };\n }\n return next;\n });\n }, [activityPath, expandPath, followAgentPath, normalizedActivities]);\n\n useEffect(() => {\n const signals = new Set(mutatingCallIds(runningCalls));\n for (const { activity: currentActivity } of normalizedActivities) signals.add(currentActivity.callId.split(\":\", 1)[0] ?? currentActivity.callId);\n const settled = [...previousSignals.current].some((callId) => !signals.has(callId));\n for (const callId of activityBases.current.keys()) {\n if (!signals.has(callId.split(\":\", 1)[0] ?? callId)) activityBases.current.delete(callId);\n }\n previousSignals.current = signals;\n if (!settled) return;\n reload();\n }, [normalizedActivities, reload, runningCalls]);\n\n useEffect(() => {\n if (settledMutation === undefined || settledMutation === consumedSettledMutation) return;\n // History replayed after a reload or a Session switch is not a fresh Agent write.\n if (settledMutationTurn === undefined || !liveTurns.current.has(settledMutationTurn)) {\n actions.setSettledMutation(settledMutation);\n return;\n }\n // The signal carries an absolute path, so creativeRelativePath cannot resolve it until the\n // workspace (and its cwd) has loaded. Consuming the signal first would burn it: the effect\n // re-runs when cwd arrives, but the guard above then short-circuits and the agent's file is\n // never selected. Wait for cwd instead of dropping the follow.\n if (workspace?.cwd === undefined) return;\n actions.setSettledMutation(settledMutation);\n const path = creativeRelativePath(settledMutation.slice(settledMutation.indexOf(\"\\0\") + 1), workspace.cwd);\n if (path !== undefined) followAgentPath(path);\n reload();\n }, [actions, consumedSettledMutation, followAgentPath, reload, settledMutation, settledMutationTurn, workspace?.cwd]);\n\n useEffect(() => {\n if (selected === undefined) return;\n for (const button of navRef.current?.querySelectorAll<HTMLButtonElement>(\"button[data-file-path]\") ?? []) {\n if (button.dataset.filePath === selected) {\n button.scrollIntoView({ block: \"nearest\" });\n break;\n }\n }\n }, [selected]);\n\n useEffect(() => {\n if (!open || normalizedActivities.length > 0 || workspace === undefined) return;\n const sessionSurface = surfaceRef.current?.parentElement;\n if (sessionSurface === undefined || sessionSurface === null) return;\n const knownPaths = new Set(workspace.files.map((file) => file.path));\n const followOfficialFileLink = (event: MouseEvent): void => {\n const origin = event.target;\n if (!(origin instanceof Element)) return;\n const control = origin.closest<HTMLElement>(\"button, a\");\n if (control === null || control.closest(\".oh-story-split-surface\") !== null) return;\n const candidates = [control.title, control.getAttribute(\"aria-label\"), control.textContent];\n for (const candidate of candidates) {\n const path = creativeRelativePath(candidate?.trim().replace(/^(?:Open|\u6253\u5F00)\\s+/u, \"\"), workspace.cwd);\n if (path === undefined || !knownPaths.has(path)) continue;\n event.preventDefault();\n event.stopPropagation();\n revealPath(path);\n break;\n }\n };\n sessionSurface.addEventListener(\"click\", followOfficialFileLink, true);\n return () => { sessionSurface.removeEventListener(\"click\", followOfficialFileLink, true); };\n }, [normalizedActivities.length, open, revealPath, workspace]);\n\n useEffect(() => {\n if (workbench !== \"game\" && workbench !== \"video\") return;\n const surface = surfaceRef.current;\n const sessionSurface = surface?.parentElement;\n const chat = Array.from(sessionSurface?.children ?? []).find((child) => child !== surface && child instanceof HTMLElement);\n if (!(chat instanceof HTMLElement)) return;\n const previous = {\n id: chat.id,\n role: chat.getAttribute(\"role\"),\n labelledBy: chat.getAttribute(\"aria-labelledby\")\n };\n chat.id = compactChatId;\n chat.setAttribute(\"role\", \"tabpanel\");\n chat.setAttribute(\"aria-labelledby\", `${compactTabsId}-chat-tab`);\n return () => {\n chat.id = previous.id;\n if (previous.role === null) chat.removeAttribute(\"role\");\n else chat.setAttribute(\"role\", previous.role);\n if (previous.labelledBy === null) chat.removeAttribute(\"aria-labelledby\");\n else chat.setAttribute(\"aria-labelledby\", previous.labelledBy);\n };\n }, [compactChatId, compactTabsId, workbench]);\n\n const savePath = useCallback(async (path: string) => {\n if (saveLocks.current.has(path)) return;\n const submitted = buffersRef.current[path];\n if (submitted === undefined || submitted.missing === true || submitted.content === submitted.saved) return;\n saveLocks.current.add(path);\n setBuffers((current) => {\n const existing = current[path];\n return existing === undefined ? current : { ...current, [path]: { ...existing, saving: true, error: undefined } };\n });\n try {\n const file = await json<FilePayload>(await fetch(endpoint(\"file\", sessionId, path), {\n method: \"PUT\",\n headers: { \"content-type\": \"application/json\" },\n body: JSON.stringify({ content: submitted.content, baseVersion: submitted.version })\n }));\n setBuffers((current) => {\n const latest = current[path];\n if (latest === undefined) return current;\n const unchanged = latest.content === submitted.content;\n return {\n ...current,\n [path]: {\n content: unchanged ? file.content : latest.content,\n saved: file.content,\n source: unchanged ? \"disk\" : \"human\",\n version: file.version,\n saving: false\n }\n };\n });\n reload();\n } catch (reason) {\n if (reason instanceof WorkspaceRequestError && reason.status === 412) {\n try {\n const theirs = await json<FilePayload>(await fetch(endpoint(\"file\", sessionId, path)));\n setBuffers((current) => {\n const latest = current[path];\n if (latest === undefined) return current;\n return {\n ...current,\n [path]: {\n ...latest,\n saving: false,\n conflict: {\n message: `${path} \u5DF2\u5728\u78C1\u76D8\u4E0A\u66F4\u65B0\uFF1B\u8BF7\u9009\u62E9\u4FDD\u7559\u54EA\u4E00\u7248\u3002`,\n theirs: theirs.content,\n theirsVersion: theirs.version\n }\n }\n };\n });\n } catch (refreshError) {\n setBuffers((current) => {\n const existing = current[path];\n return existing === undefined ? current : {\n ...current,\n [path]: { ...existing, saving: false, error: refreshError instanceof Error ? refreshError.message : String(refreshError) }\n };\n });\n }\n } else {\n setBuffers((current) => {\n const existing = current[path];\n return existing === undefined ? current : {\n ...current,\n [path]: { ...existing, saving: false, error: reason instanceof Error ? reason.message : String(reason) }\n };\n });\n }\n } finally {\n saveLocks.current.delete(path);\n }\n }, [reload, sessionId]);\n\n useEffect(() => {\n if (!open) return;\n const saveShortcut = (event: KeyboardEvent): void => {\n if (!(event.metaKey || event.ctrlKey) || event.key.toLocaleLowerCase() !== \"s\") return;\n event.preventDefault();\n if (selected !== undefined) void savePath(selected);\n };\n globalThis.addEventListener(\"keydown\", saveShortcut);\n return () => { globalThis.removeEventListener(\"keydown\", saveShortcut); };\n }, [open, savePath, selected]);\n\n const groups = useMemo(() => {\n const value = new Map<string, WorkspaceFile[]>();\n const all = [...(workspace?.files ?? [])].filter((file) => workbenchModeForPath(file.path) === workbench);\n if (activityPath !== undefined && !all.some((file) => file.path === activityPath)) all.push({ path: activityPath, bytes: 0, version: \"\", kind: \"text\" });\n all.sort((left, right) => left.path.localeCompare(right.path, \"zh-Hans-CN\"));\n for (const file of all) {\n const directory = groupForPath(file.path);\n const files = value.get(directory) ?? [];\n files.push(file);\n value.set(directory, files);\n }\n const order = GROUP_ORDER[workbench];\n return [...value.entries()].sort(([left], [right]) => {\n const leftIndex = order.indexOf(left);\n const rightIndex = order.indexOf(right);\n return (leftIndex < 0 ? order.length : leftIndex) - (rightIndex < 0 ? order.length : rightIndex)\n || left.localeCompare(right, \"zh-Hans-CN\");\n });\n }, [activityPath, workbench, workspace]);\n\n const selectWorkbench = (next: WorkbenchMode): void => {\n setWorkbench(next);\n if (next === \"game\" || next === \"video\") {\n if (next === \"game\") setGameTab(\"preview\");\n else setVideoTab(\"preview\");\n setSelected(undefined);\n return;\n }\n const target = workspace === undefined ? undefined : preferredWorkbenchFile(workspace.files, next);\n if (target === undefined) setSelected(undefined);\n else revealPath(target);\n };\n const selectEditorMode = (next: WorkbenchMemory[\"editorMode\"]): void => {\n if (next === \"preview\") rememberEditorPosition();\n setEditorMode(next);\n };\n const navigateProductionTarget = (target: DramaDocumentTarget): void => {\n const content = buffersRef.current[target.path]?.content ?? \"\";\n const before = content.slice(0, target.offset);\n const approximateScrollTop = Math.max(0, before.split(/\\r?\\n/u).length * 28 - 96);\n editorPositions.current.set(target.path, { scrollTop: approximateScrollTop, selectionStart: target.offset, selectionEnd: target.offset });\n modeSelection.current = target.path;\n revealPath(target.path);\n setEditorMode(\"source\");\n };\n const selectedLabel = selected ?? `\u5728\u5F53\u524D DSH workspace \u4E2D\u9009\u62E9${workbenchLabel(workbench)}\u6587\u4EF6`;\n const selectedBasename = selected?.split(\"/\").at(-1) ?? selectedLabel;\n const selectedGroup = selected === undefined ? undefined : groupForPath(selected);\n const toggleGroup = (key: string, open: boolean): void => {\n setExpanded((current) => ({ ...current, [key]: open }));\n };\n const resolveConflict = (keepLocal: boolean): void => {\n if (selected === undefined || conflict?.theirs === undefined || conflict.theirsVersion === undefined) return;\n const theirs = conflict.theirs;\n const theirsVersion = conflict.theirsVersion;\n setBuffers((current) => {\n const existing = current[selected];\n if (existing === undefined) return current;\n return {\n ...current,\n [selected]: keepLocal\n ? { ...existing, saved: theirs, version: theirsVersion, source: \"human\", conflict: undefined }\n : { content: theirs, saved: theirs, source: \"disk\", version: theirsVersion }\n };\n });\n };\n\n if (!open) {\n // Without creative work there is nothing to reveal, so the plugin leaves the\n // official conversation exactly as DSH renders it. A failed workspace request\n // still offers the way in, because that error is only readable inside the workbench.\n if (!creativeProject && error === undefined) return welcome ? <WelcomeGuide /> : null;\n return <div ref={surfaceRef} className=\"oh-story-split-surface\" data-open=\"false\">\n <style>{styles}</style>\n <button className=\"oh-story-launcher\" type=\"button\" title={error ?? \"\u6253\u5F00\u521B\u4F5C\u5DE5\u4F5C\u53F0\"} aria-label=\"\u6253\u5F00\u521B\u4F5C\u5DE5\u4F5C\u53F0\" onClick={() => { applyWorkbenchPreference(\"open\"); }}>\n <span aria-hidden>\u2726</span><b>\u521B\u4F5C\u5DE5\u4F5C\u53F0</b>\n </button>\n </div>;\n }\n\n return <div ref={surfaceRef} className=\"oh-story-split-surface\" data-open=\"true\" data-workbench={workbench}>\n <style>{styles}</style>\n {(workbench === \"game\" || workbench === \"video\") && <div className=\"oh-game-mobile-switcher\" role=\"tablist\" aria-label={workbench === \"game\" ? \"\u7A84\u5C4F\u6E38\u620F\u5DE5\u4F5C\u53F0\" : \"\u7A84\u5C4F\u89C6\u9891\u5DE5\u4F5C\u53F0\"}>\n {([\"studio\", \"chat\"] as const).map((pane) => <button\n type=\"button\"\n role=\"tab\"\n key={pane}\n id={`${compactTabsId}-${pane}-tab`}\n aria-controls={pane === \"chat\" ? compactChatId : workbench === \"game\" ? compactStudioId : compactVideoStudioId}\n aria-selected={(workbench === \"game\" ? gamePane : videoPane) === pane}\n tabIndex={(workbench === \"game\" ? gamePane : videoPane) === pane ? 0 : -1}\n onKeyDown={(event) => { handleTabKey(event, [\"studio\", \"chat\"] as const, workbench === \"game\" ? gamePane : videoPane, workbench === \"game\" ? setGamePane : setVideoPane); }}\n onClick={() => { if (workbench === \"game\") setGamePane(pane); else setVideoPane(pane); }}\n >{pane === \"studio\" ? \"\u5236\u4F5C\" : \"\u5BF9\u8BDD\"}</button>)}\n </div>}\n {workbench === \"game\" && workspace === undefined && <main id={compactStudioId} className=\"oh-game-studio\" role=\"tabpanel\" aria-labelledby={`${compactTabsId}-studio-tab`}><div className=\"oh-game-design-empty\">{error ?? \"\u6B63\u5728\u8FDE\u63A5\u6E38\u620F\u5DE5\u4F5C\u53F0\u2026\"}</div></main>}\n {workspace !== undefined && gameStudioMounted && <GameStudio\n sessionId={sessionId}\n workspace={workspace}\n building={gameBuilding}\n selected={selected}\n gameTab={gameTab}\n gameProjectId={gameProjectId}\n hidden={workbench !== \"game\"}\n onGameTab={setGameTab}\n onGameProject={setGameProjectId}\n workbenches={WORKBENCH_MODES}\n paneId={compactStudioId}\n labelledBy={`${compactTabsId}-studio-tab`}\n onWorkbench={selectWorkbench}\n onCollapse={() => { applyWorkbenchPreference(\"closed\"); }}\n onSelect={revealPath}\n />}\n {workbench === \"video\" && workspace === undefined && <main id={compactVideoStudioId} className=\"oh-video-studio\" role=\"tabpanel\" aria-labelledby={`${compactTabsId}-studio-tab`}><div className=\"oh-video-preview-empty\">{error ?? \"\u6B63\u5728\u8FDE\u63A5\u89C6\u9891\u5DE5\u4F5C\u53F0\u2026\"}</div></main>}\n {workspace !== undefined && videoStudioMounted && <VideoStudio\n sessionId={sessionId}\n projects={workspace.videos}\n running={videoBuilding}\n projectId={videoProjectId}\n tab={videoTab}\n hidden={workbench !== \"video\"}\n workbenches={WORKBENCH_MODES}\n paneId={compactVideoStudioId}\n labelledBy={`${compactTabsId}-studio-tab`}\n onProject={setVideoProjectId}\n onTab={setVideoTab}\n onWorkbench={selectWorkbench}\n onCollapse={() => { applyWorkbenchPreference(\"closed\"); }}\n />}\n {workbench !== \"game\" && workbench !== \"video\" && <>\n <aside className=\"oh-story-tree\">\n <div className=\"oh-story-brand\">\n <span className=\"oh-story-brand-cluster\"><strong>\u2726 <span>Oh Story</span></strong>{workspaceKind !== undefined && <span className=\"oh-story-kind\">{workspaceKind === \"story\" ? \"\u5C0F\u8BF4\" : \"\u77ED\u5267\"}</span>}</span>\n <span className=\"oh-story-brand-actions\">\n <button type=\"button\" onClick={reload} title=\"\u5237\u65B0\" aria-label=\"\u5237\u65B0\u9879\u76EE\u6587\u4EF6\">\u21BB</button>\n <button type=\"button\" onClick={() => { applyWorkbenchPreference(\"closed\"); }} title=\"\u6536\u8D77\u521B\u4F5C\u5DE5\u4F5C\u53F0\" aria-label=\"\u6536\u8D77\u521B\u4F5C\u5DE5\u4F5C\u53F0\">\u00D7</button>\n </span>\n </div>\n {workspace !== undefined && <div className=\"oh-story-mode-tabs\" role=\"tablist\" aria-label=\"\u521B\u4F5C\u5DE5\u4F5C\u53F0\">\n {WORKBENCH_MODES.map((mode) => <button\n type=\"button\"\n role=\"tab\"\n key={mode}\n tabIndex={workbench === mode ? 0 : -1}\n aria-selected={workbench === mode}\n onKeyDown={(event) => { handleTabKey(event, WORKBENCH_MODES, workbench, selectWorkbench); }}\n onClick={() => { selectWorkbench(mode); }}\n >{workbenchLabel(mode)}</button>)}\n </div>}\n {error !== undefined && <div className=\"oh-story-error\">{error}</div>}\n {workspace?.metadataErrors.map((message) => <div className=\"oh-story-warning\" key={message}>{message}</div>)}\n <nav ref={navRef} aria-label={workbench === \"story\" ? \"\u5C0F\u8BF4\u9879\u76EE\u6587\u4EF6\" : \"\u77ED\u5267\u9879\u76EE\u6587\u4EF6\"}>\n {groups.map(([directory, files]) => {\n const groupOpen = selectedGroup === directory || expanded[directory] === true;\n return <details className=\"oh-story-file-group\" key={directory} open={groupOpen} onToggle={(event) => { toggleGroup(directory, event.currentTarget.open); }}>\n <summary>{directory}<span>{files.length}</span></summary>\n <FileTreeNodes\n nodes={buildFileTree(files, directory)}\n depth={1}\n expanded={expanded}\n selected={selected}\n activityPath={activityPath}\n onToggle={toggleGroup}\n onSelect={revealPath}\n />\n </details>;\n })}\n </nav>\n </aside>\n <main className=\"oh-story-editor\">\n <header>\n <span className=\"oh-story-editor-path\" title={selected}><span>{selectedLabel}</span><strong>{selectedBasename}</strong></span>\n <div className=\"oh-story-editor-actions\">\n {(previewable || productionAvailable) && !selectedMedia && <div className=\"oh-story-editor-tabs\" role=\"tablist\" aria-label={productionAvailable ? \"\u77ED\u5267\u6587\u6863\u67E5\u770B\u65B9\u5F0F\" : markdown ? \"Markdown \u67E5\u770B\u65B9\u5F0F\" : \"JSONL \u67E5\u770B\u65B9\u5F0F\"}>\n {editorModes.map((mode) => <button\n type=\"button\"\n role=\"tab\"\n key={mode}\n tabIndex={editorMode === mode ? 0 : -1}\n aria-selected={editorMode === mode}\n onKeyDown={(event) => { handleTabKey(event, editorModes, editorMode, selectEditorMode); }}\n onClick={() => { selectEditorMode(mode); }}\n >{mode === \"preview\" ? \"\u9884\u89C8\" : mode === \"source\" ? \"\u6E90\u7801\" : \"\u751F\u4EA7\"}</button>)}\n </div>}\n {(dirty || saving) && selected !== undefined && <button className=\"oh-story-save\" type=\"button\" disabled={saving || buffer?.missing === true} onClick={() => { void savePath(selected); }}>\n {saving ? \"\u4FDD\u5B58\u4E2D\u2026\" : \"\u4FDD\u5B58\"}\n </button>}\n </div>\n </header>\n {activity !== undefined && activityPath !== undefined && activityPath === selected && <div className=\"oh-story-stream\" data-stage={activity.stage} role=\"status\" aria-live=\"polite\">\u25CF {activity.stage === \"running\" ? \"Agent \u6B63\u5728\u5E94\u7528\u4FEE\u6539\" : \"Agent \u6B63\u5728\u751F\u6210\u6587\u4EF6\u5185\u5BB9\"}</div>}\n {conflict !== undefined && <div className=\"oh-story-conflict\" role=\"alert\">\n <span>{conflict.message}</span>\n {conflict.theirs !== undefined && conflict.theirsVersion !== undefined && selected !== undefined && <div>\n <button type=\"button\" onClick={() => { resolveConflict(false); }}>\u8F7D\u5165\u78C1\u76D8\u7248\u672C</button>\n <button type=\"button\" onClick={() => { resolveConflict(true); }}>\u4FDD\u7559\u672C\u5730\u8349\u7A3F</button>\n </div>}\n </div>}\n {fileError !== undefined && <div className=\"oh-story-error\">{fileError}</div>}\n {selected === undefined\n ? <div className=\"oh-story-empty\">{workbench === \"story\"\n ? <>\u5F53\u524D workspace \u8FD8\u6CA1\u6709\u5C0F\u8BF4\u6587\u4EF6\u3002\u53EF\u5728\u53F3\u4FA7 Chat \u4E2D\u8FD0\u884C <code>/story-setup</code>\u3002</>\n : <>\u5F53\u524D workspace \u8FD8\u6CA1\u6709\u77ED\u5267\u9879\u76EE\u3002\u53EF\u5728\u53F3\u4FA7 Chat \u4E2D\u8FD0\u884C <code>/short-drama</code>\u3002</>}</div>\n : selectedMedia && selectedFile !== undefined\n ? <div className=\"oh-story-media-document\">{selectedFile.mimeType?.startsWith(\"image/\") === true\n ? <img src={endpoint(\"media\", sessionId, selectedFile.path)} alt={selectedFile.path} />\n : selectedFile.mimeType?.startsWith(\"audio/\") === true\n ? <audio src={endpoint(\"media\", sessionId, selectedFile.path)} controls />\n : <video src={endpoint(\"media\", sessionId, selectedFile.path)} controls preload=\"metadata\" />}</div>\n : buffer === undefined\n ? <div className=\"oh-story-empty\">\u6B63\u5728\u52A0\u8F7D {selected}\u2026</div>\n : buffer.missing === true\n ? <div className=\"oh-story-empty\">\u6587\u4EF6\u5DF2\u4ECE workspace \u79FB\u9664\uFF0C\u672C\u5730\u8349\u7A3F\u4ECD\u4FDD\u7559\u3002\u8BF7\u5148\u590D\u5236\u9700\u8981\u7684\u5185\u5BB9\uFF0C\u518D\u653E\u5F03\u8349\u7A3F\u3002<button type=\"button\" onClick={() => {\n setBuffers((current) => {\n const next = { ...current };\n delete next[selected];\n return next;\n });\n setSelected(workspace === undefined ? undefined : preferredWorkbenchFile(workspace.files, workbench));\n }}>\u653E\u5F03\u672C\u5730\u8349\u7A3F</button></div>\n : editorMode === \"production\" && productionAvailable && episodeProduction !== undefined\n ? <DramaProductionView\n sessionId={sessionId}\n production={episodeProduction}\n sessionRunning={sessionRunning}\n queue={productionQueue}\n section={productionSection}\n selectedId={productionSelectedId}\n jobs={productionJobs}\n versions={productionVersions}\n libraryVersions={productionLibrary}\n selections={productionSelections}\n manualReferences={productionReferences}\n sequence={productionSequence}\n canvas={productionCanvas}\n zoom={productionZoom}\n onSectionChange={setProductionSection}\n onSelect={setProductionSelectedId}\n onNavigate={navigateProductionTarget}\n onJobsChange={setProductionJobs}\n onSelectionsChange={setProductionSelections}\n onManualReferencesChange={setProductionReferences}\n onOpenMedia={(path) => { revealPath(path); }}\n onSequenceChange={setProductionSequence}\n onCanvasChange={setProductionCanvas}\n onZoomChange={setProductionZoom}\n onDispatchPrompt={sendProductionPrompt}\n onCancelTurn={cancelProduction}\n onRemoveQueued={removeQueuedProduction}\n onRefresh={reload}\n />\n : previewable && editorMode === \"preview\"\n ? markdown\n ? <MarkdownPreview content={buffer.content} label={selected} />\n : <JsonlPreview content={buffer.content} label={selected} />\n : <textarea\n ref={textareaRef}\n value={buffer.content}\n data-format={structured ? \"structured\" : \"prose\"}\n onBlur={rememberEditorPosition}\n onScroll={rememberEditorPosition}\n onSelect={rememberEditorPosition}\n onChange={(event) => {\n const content = event.target.value;\n setBuffers((current) => ({\n ...current,\n [selected]: {\n content,\n saved: current[selected]?.saved ?? \"\",\n source: \"human\",\n version: current[selected]?.version ?? \"\",\n conflict: current[selected]?.conflict,\n saving: current[selected]?.saving\n }\n }));\n }}\n spellCheck={!structured}\n aria-label={selected}\n />}\n </main>\n </>}\n </div>;\n}\n\ninterface ProductionConversationFace {\n readonly sendProductionPrompt: (prompt: string) => Promise<void>;\n readonly cancelProduction: () => Promise<void>;\n readonly removeQueuedProduction: (itemId: string) => Promise<void>;\n}\n\ntype WorkbenchSlotProps = PropsRuntime<\"oh-story.workspace\"> & PropsStore<ReturnType<typeof createWorkbenchStore>> & ProductionConversationFace;\n\n/**\n * DSH 0.1.7's SessionProvider stopped keying its subtree by Session, so switching Sessions\n * would carry one Session's selection, drafts and dedup guards into the next. Keep the\n * one-mount-per-Session contract the workbench was written against.\n */\nfunction CreativeSplitBridge(props: WorkbenchSlotProps) {\n return <SessionWorkbenchMemory key={props.sessionId} {...props} />;\n}\n\n/** Restore this Session's workbench memory into a fresh Store before anything reads it. */\nfunction SessionWorkbenchMemory(props: WorkbenchSlotProps) {\n const { sessionId, useStore, actions } = props;\n const hydrated = useStore((state) => state.hydrated);\n // Nothing renders from a fresh instance: its initial state would be mirrored over the saved\n // copy, and the workbench's own effects would act on an empty selection.\n useLayoutEffect(() => {\n if (!hydrated) actions.restore(workbenchMemoryBySession.get(sessionId));\n }, [actions, hydrated, sessionId]);\n return hydrated ? <>\n <WorkbenchMemoryMirror sessionId={sessionId} useStore={useStore} />\n <SessionWorkbenchBridge {...props} />\n </> : null;\n}\n\n/** Keeps the page-lifetime copy current without re-rendering the workbench on every edit. */\nfunction WorkbenchMemoryMirror({ sessionId, useStore }: Pick<WorkbenchSlotProps, \"sessionId\" | \"useStore\">) {\n const memory = useStore((state) => state);\n useEffect(() => {\n workbenchMemoryBySession.set(sessionId, memory);\n }, [memory, sessionId]);\n return null;\n}\n\n/** Mount beside the official conversation without replacing Chat or Composer. */\nfunction SessionWorkbenchBridge({ sessionId, useSession, useSessions, useProjection, useChat, useStore, actions, sendProductionPrompt, cancelProduction, removeQueuedProduction }: WorkbenchSlotProps) {\n const marker = useRef<HTMLSpanElement>(null);\n const [target, setTarget] = useState<HTMLElement>();\n const runningCalls = useChat((snapshot) => snapshot.legacy.runningCalls);\n const partial = useChat((snapshot) => streamingAssistant(snapshot.timeline));\n const undispatched = useChat((snapshot) => undispatchedCalls(snapshot), sameUndispatchedCalls);\n const settledMutation = useChat((snapshot) => latestSettledMutation(snapshot));\n const settledMutationTurn = useChat((snapshot) => latestSettledMutationTurn(snapshot));\n const liveTurn = useChat((snapshot) => openTurn(snapshot));\n const workbench = useStore((memory) => memory.workbench);\n const gamePane = useStore((memory) => memory.gamePane);\n const videoPane = useStore((memory) => memory.videoPane);\n const sessionRunning = useSession((snapshot) => snapshot.running);\n const inboxRows = useProjection(\"inbox\", (inbox) => inbox?.[\"next-turn\"]);\n const pendingSubmissions = useSession((snapshot) => snapshot.pendingSubmissions);\n const productionQueue = useMemo(() => productionQueueFromInbox(\n inboxRows,\n new Set(pendingSubmissions.filter((item) => item.placement === \"transcript\").map((item) => item.requestId))\n ), [inboxRows, pendingSubmissions]);\n const chat = useChat((snapshot) => snapshot);\n const productionIntents = useMemo(() => settledProductionIntents(chat), [chat]);\n const { workspace, error, loading: workspaceLoading, reload } = useWorkspace(sessionId);\n const chosenPreference = useStore((memory) => memory.workbenchPreference);\n const creativeProject = hasCreativeProject(workspace);\n // DSH 0.1.7 opens a fresh home straight into a blank Session in its default workspace, so\n // \"no Session yet\" no longer marks a first launch. A blank Session without creative work does.\n const sessionBlank = useSessions((state) => state.byId[sessionId]?.blank === true);\n const welcome = sessionBlank && workspace !== undefined && !workspaceLoading && !creativeProject;\n // The Session Store holds this Session's choice; localStorage carries the workspace's\n // last choice across restarts. Reading it here keeps the decision in the same render\n // that learns the workspace, so a collapsed workbench never flashes the layout open.\n const storedPreference = useMemo(\n () => readWorkbenchPreference(workbenchPreferenceStorage(), workspace?.cwd),\n [workspace?.cwd]\n );\n const preference = chosenPreference ?? storedPreference;\n const open = resolveWorkbenchOpen(preference, creativeProject);\n useLayoutEffect(() => {\n const document = marker.current?.ownerDocument;\n if (document === undefined) return;\n const locate = (): void => {\n // DSH 0.1.7 renders the same conversation content inside the right sidebar's subagent\n // chats, so only this Session's main column is a valid seat.\n const anchor = document.querySelector<HTMLElement>(\n `[data-conversation-content][data-conversation-session=\"${CSS.escape(sessionId)}\"]:not([data-sidebar-chat] *) > [data-conversation-scroll] > [data-slot='conversation.session']`\n );\n setTarget((current) => current === anchor ? current : anchor ?? undefined);\n };\n locate();\n const observer = new MutationObserver(locate);\n observer.observe(document.body, { childList: true, subtree: true });\n return () => { observer.disconnect(); };\n }, [sessionId]);\n useLayoutEffect(() => {\n const scroller = target?.parentElement;\n if (scroller === undefined || scroller === null) return;\n if (!open) {\n // A collapsed workbench returns the conversation to DSH untouched, so the only\n // measurement left is where that column sits: the launcher floats over its corner.\n const publishSeam = (): void => {\n const box = scroller.getBoundingClientRect();\n scroller.style.setProperty(\"--oh-story-seam-top\", `${String(box.top)}px`);\n scroller.style.setProperty(\"--oh-story-seam-right\", `${String(scroller.ownerDocument.documentElement.clientWidth - box.right)}px`);\n };\n publishSeam();\n const seams = new ResizeObserver(publishSeam);\n seams.observe(scroller);\n const view = scroller.ownerDocument.defaultView;\n view?.addEventListener(\"resize\", publishSeam);\n return () => {\n seams.disconnect();\n view?.removeEventListener(\"resize\", publishSeam);\n scroller.style.removeProperty(\"--oh-story-seam-top\");\n scroller.style.removeProperty(\"--oh-story-seam-right\");\n };\n }\n const composerSeat = (): HTMLElement | null => scroller.querySelector(\":scope > [data-composer-seat]\");\n // The seat overlaps the Chat column here, so a reader parked at the tail has\n // to be carried across every layout pass; losing the tail does not merely\n // scroll it out of sight, it leaves the last lines behind the Composer.\n // Being parked cannot be read inside the pass \u2014 a reflow moves the tail\n // before the observer runs \u2014 and it cannot be read from scroll events alone\n // either: the Chat settles over several frames after a resize and every one\n // of those frames scrolls without the reader asking. So only a scroll the\n // reader actually drove releases the tail; reaching the bottom always\n // reclaims it.\n const parkedAtTail = (): boolean => scroller.scrollHeight - scroller.scrollTop - scroller.clientHeight <= 8;\n let parked = parkedAtTail();\n let drivenAt = 0;\n const markDriven = (event: Event): void => {\n if (event.target instanceof Node && composerSeat()?.contains(event.target) === true) return;\n // A button click (for example switching the editor preview) is not a\n // scrollbar drag. Its subsequent reflow must not release the Chat tail.\n if (event.type === \"pointerdown\" && event.target !== scroller) return;\n drivenAt = performance.now();\n };\n const trackParked = (): void => {\n if (parkedAtTail()) parked = true;\n else if (performance.now() - drivenAt < 400) parked = false;\n };\n const publishLayout = (): void => {\n scroller.style.setProperty(\"--oh-story-scroll-height\", `${String(scroller.clientHeight)}px`);\n // DSH 0.1.2 grows the seat with the streaming Todo panel while\n // --dsh-composer-height keeps reporting the bare input height. Publish the\n // measurement beside it rather than over it: the CSS takes the larger, so\n // writing the variable DSH also owns can never turn into a resize duel.\n scroller.style.setProperty(\"--oh-story-composer-height\", `${String(composerSeat()?.getBoundingClientRect().height ?? 0)}px`);\n scroller.dataset.ohStoryWorkbench = workbench;\n const studioPane = workbench === \"video\" ? videoPane : gamePane;\n scroller.dataset.ohStudioPane = studioPane;\n const compactAt = workbench === \"game\" || workbench === \"video\" ? 720 : 620;\n const mediumAt = workbench === \"game\" || workbench === \"video\" ? 960 : 900;\n const layout = scroller.clientWidth < compactAt ? \"compact\" : scroller.clientWidth < mediumAt ? \"medium\" : \"wide\";\n if (scroller.dataset.ohStoryLayout !== layout) scroller.dataset.ohStoryLayout = layout;\n if (parked) scroller.scrollTop = scroller.scrollHeight - scroller.clientHeight;\n };\n const observer = new ResizeObserver(publishLayout);\n const observed = new WeakSet<Element>();\n // The official seat and Chat flow mount and remount independently of this\n // bridge. The flow is observed because a resized Chat keeps re-wrapping for\n // several frames afterwards: pinning once against the height the first frame\n // reports leaves the reader behind the Composer again once it settles.\n let flowObserved = false;\n const observePanes = (): void => {\n const flow = scroller.querySelector(\"[data-chat-flow]:not([data-step-process-content])\");\n flowObserved = flow !== null;\n for (const pane of [composerSeat(), flow]) {\n if (pane === null || observed.has(pane)) continue;\n observed.add(pane);\n observer.observe(pane);\n }\n };\n publishLayout();\n scroller.addEventListener(\"scroll\", trackParked, { passive: true });\n for (const driven of [\"wheel\", \"touchmove\", \"pointerdown\", \"keydown\"]) {\n scroller.addEventListener(driven, markDriven, { passive: true });\n }\n observer.observe(scroller);\n observePanes();\n const seats = new MutationObserver(() => { observePanes(); publishLayout(); });\n seats.observe(scroller, { childList: true });\n // The flow mounts below the seat's level, and streaming mutates it token by\n // token: watch the subtree only until it has been found once.\n const panes = new MutationObserver(() => { if (!flowObserved) observePanes(); });\n panes.observe(scroller, { childList: true, subtree: true });\n return () => {\n panes.disconnect();\n scroller.removeEventListener(\"scroll\", trackParked);\n for (const driven of [\"wheel\", \"touchmove\", \"pointerdown\", \"keydown\"]) {\n scroller.removeEventListener(driven, markDriven);\n }\n observer.disconnect();\n seats.disconnect();\n scroller.style.removeProperty(\"--oh-story-scroll-height\");\n scroller.style.removeProperty(\"--oh-story-composer-height\");\n delete scroller.dataset.ohStoryLayout;\n delete scroller.dataset.ohStoryWorkbench;\n delete scroller.dataset.ohStudioPane;\n };\n }, [gamePane, open, target, videoPane, workbench]);\n return <>\n <span ref={marker} className=\"oh-story-bridge-marker\" aria-hidden />\n {target === undefined ? null : createPortal(<CreativeWorkbench\n sessionId={sessionId}\n runningCalls={runningCalls}\n partial={partial}\n undispatched={sessionRunning ? undispatched : NO_UNDISPATCHED_CALLS}\n settledMutation={settledMutation}\n settledMutationTurn={settledMutationTurn}\n liveTurn={liveTurn}\n sessionRunning={sessionRunning}\n productionQueue={productionQueue}\n productionIntents={productionIntents}\n workspace={workspace}\n error={error}\n workspaceLoading={workspaceLoading}\n reload={reload}\n open={open}\n creativeProject={creativeProject}\n welcome={welcome}\n sendProductionPrompt={sendProductionPrompt}\n cancelProduction={cancelProduction}\n removeQueuedProduction={removeQueuedProduction}\n useStore={useStore}\n actions={actions}\n />, target)}\n </>;\n}\n\ntype WorkbenchSeatProps = PropsRuntime<\"shell.overlay\"> & PropsRenderSlots<\"oh-story.workspace\">;\n\n/** How to reach the workbench from a DSH that has no creative work open yet. */\nfunction WelcomeGuide() {\n return <section className=\"oh-story-welcome\" aria-label=\"Oh Story \u4F7F\u7528\u5F15\u5BFC\">\n <style>{styles}</style>\n <h2>Oh Story \u5DF2\u52A0\u8F7D</h2>\n <p>\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</p>\n <ol>\n <li>\u70B9\u51FB\u5DE6\u4FA7\u300C\u5DE5\u4F5C\u533A / Workspaces\u300D\u65C1\u7684\u300C\u6DFB\u52A0\u5DE5\u4F5C\u533A / Add workspace\u300D\uFF0C\u9009\u62E9\u5B58\u653E\u4F5C\u54C1\u7684\u6587\u4EF6\u5939\u3002</li>\n <li>\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</li>\n <li>\u7A7A\u76EE\u5F55\uFF08\u5305\u62EC DSH \u81EA\u52A8\u5EFA\u7ACB\u7684\u300C\u9ED8\u8BA4\u5DE5\u4F5C\u533A / Default workspace\u300D\uFF09\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</li>\n </ol>\n <p>\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 <code>/story</code>\u3001<code>/short-drama</code>\u3001<code>/novel-to-game quick</code> \u6216 <code>/video-recap</code>\u3002</p>\n </section>;\n}\n\n/** Without any Session the session-scoped workbench cannot mount, so the guide mounts on its own. */\nfunction WorkbenchWelcome() {\n const marker = useRef<HTMLSpanElement>(null);\n const [target, setTarget] = useState<HTMLElement>();\n useLayoutEffect(() => {\n const document = marker.current?.ownerDocument;\n if (document === undefined) return;\n const locate = (): void => {\n const anchor = document.querySelector<HTMLElement>(\"[data-conversation-content]:not([data-sidebar-chat] *) > [data-conversation-scroll]\");\n setTarget((current) => current === anchor ? current : anchor ?? undefined);\n };\n locate();\n const observer = new MutationObserver(locate);\n observer.observe(document.body, { childList: true, subtree: true });\n return () => { observer.disconnect(); };\n }, []);\n return <>\n <span ref={marker} className=\"oh-story-bridge-marker\" aria-hidden />\n {target === undefined ? null : createPortal(<WelcomeGuide />, target)}\n </>;\n}\n\nfunction WorkbenchSeat({ SessionProvider, renderSlot }: WorkbenchSeatProps) {\n return <SessionProvider empty={() => <WorkbenchWelcome />}>{renderSlot(\"oh-story.workspace\", {})}</SessionProvider>;\n}\n\nfunction argsOf(block: ToolCallViewProps[\"block\"]): Record<string, unknown> {\n const raw = (\"kind\" in block ? block.call?.argsRaw : block.phase === \"start\" ? block.argsRaw : undefined) ?? \"{}\";\n try {\n const value = JSON.parse(raw) as unknown;\n return typeof value === \"object\" && value !== null && !Array.isArray(value) ? value as Record<string, unknown> : {};\n } catch { return {}; }\n}\n\nfunction resultOf(block: ToolCallViewProps[\"block\"]): string | undefined {\n if (!(\"kind\" in block)) return undefined;\n return block.content.map((item) => item.type === \"text\" ? item.text : JSON.stringify(item, null, 2)).join(\"\\n\");\n}\n\nfunction RoleToolView({ block, inspect }: ToolCallViewProps) {\n const args = argsOf(block);\n const role = typeof args.role === \"string\" ? args.role : \"story-role\";\n const output = resultOf(block);\n const state = !(\"kind\" in block) ? \"running\" : block.isError ? \"error\" : \"done\";\n return <details className=\"oh-story-role\" data-state={state}>\n <style>{styles}</style>\n <summary><span>\u2726 Role</span><strong>{role}</strong><em>{state === \"running\" ? \"\u8FD0\u884C\u4E2D\" : state === \"error\" ? \"\u5931\u8D25\" : \"\u5B8C\u6210\"}</em></summary>\n {output !== undefined && <pre>{output}</pre>}\n {inspect !== undefined && <button type=\"button\" onClick={inspect}>\u5728\u8F68\u8FF9\u4E2D\u68C0\u67E5</button>}\n </details>;\n}\n\nfunction ProductionToolView({ block, inspect }: ToolCallViewProps) {\n const args = argsOf(block);\n const action = typeof args.action === \"string\" ? args.action : \"production\";\n const episode = typeof args.episode === \"string\" ? args.episode : \"\u77ED\u5267\";\n const state = !(\"kind\" in block) ? \"running\" : block.isError ? \"error\" : \"done\";\n return <details className=\"oh-story-role\" data-state={state}>\n <style>{styles}</style>\n <summary><span>\u25A6 \u751F\u4EA7</span><strong>{episode} \u00B7 {action}</strong><em>{state === \"running\" ? \"\u6267\u884C\u4E2D\" : state === \"error\" ? \"\u5931\u8D25\" : \"\u5DF2\u5E94\u7528\"}</em></summary>\n {resultOf(block) !== undefined && <pre>{resultOf(block)}</pre>}\n {inspect !== undefined && <button type=\"button\" onClick={inspect}>\u5728\u8F68\u8FF9\u4E2D\u68C0\u67E5</button>}\n </details>;\n}\n\n/** Register only official DSH surfaces; the split bridge never replaces Chat. */\nexport function apply(context: ClientContext): void {\n context.slots.inject(\"shell.overlay\", () => {\n const disposeSeat = context.slots.register({\n name: \"shell.overlay\",\n id: \"oh-story-workspace\",\n order: -100,\n children: { \"oh-story.workspace\": { kind: \"single\", scope: \"session\" } }\n }, WorkbenchSeat);\n const disposeWorkbench = context.slots.register({\n name: \"oh-story.workspace\",\n store: createWorkbenchStore,\n inject: (sessionId) => {\n const binding = (context.sessions as unknown as ISessions).binding(sessionId);\n const conversation = binding?.ctx.get(\"conversation\");\n if (binding === undefined || conversation === undefined) {\n return {\n sendProductionPrompt: () => Promise.reject(new Error(\"DSH \u4F1A\u8BDD\u5F53\u524D\u4E0D\u53EF\u7528\u3002\")),\n cancelProduction: () => Promise.reject(new Error(\"DSH \u4F1A\u8BDD\u5F53\u524D\u4E0D\u53EF\u7528\u3002\")),\n removeQueuedProduction: () => Promise.reject(new Error(\"DSH \u4F1A\u8BDD\u5F53\u524D\u4E0D\u53EF\u7528\u3002\"))\n };\n }\n return {\n sendProductionPrompt: (prompt: string) => conversation.send(prompt),\n cancelProduction: () => conversation.cancel(),\n removeQueuedProduction: (itemId: string) => conversation.updateQueue(itemId as Parameters<IConversation[\"updateQueue\"]>[0], { kind: \"remove\" })\n };\n }\n }, CreativeSplitBridge);\n return [disposeSeat, disposeWorkbench];\n });\n context.slots.inject(\"tool.call.toolview\", () => context.slots.register({\n name: \"tool.call.toolview\",\n key: \"oh_story_role\"\n }, RoleToolView));\n context.slots.inject(\"tool.call.toolview\", () => context.slots.register({\n name: \"tool.call.toolview\",\n key: OH_STORY_PRODUCTION_TOOL_NAME\n }, ProductionToolView));\n}\n\nexport default { name, inject, apply };\n", "import type { AssistantChatData, ChatSnapshot } from \"@deepseek-ai/dsh-client-ui-chat/client\";\nimport type {\n ConversationTimelineSnapshot,\n PartialAssistant,\n RunningToolCall,\n ToolCallBlock\n} from \"@deepseek-ai/dsh-client-ui-conversation/client\";\n\nexport type MutationToolName = \"write\" | \"edit\" | \"str_replace_editor\";\n\nexport interface FileMutationActivity {\n readonly callId: string;\n readonly name: MutationToolName;\n readonly argsRaw: string;\n readonly stage: \"streaming\" | \"running\";\n readonly path: string | undefined;\n readonly operation: \"replace-file\" | \"replace-text\" | \"insert-text\" | undefined;\n readonly oldText: string | undefined;\n readonly newText: string | undefined;\n readonly replaceAll: boolean;\n}\n\ninterface JsonStringPrefix {\n readonly value: string;\n readonly complete: boolean;\n}\n\nexport type WorkbenchMode = \"story\" | \"drama\" | \"game\" | \"video\";\n\nconst WORKBENCH_LABELS: Readonly<Record<WorkbenchMode, string>> = {\n story: \"\u5C0F\u8BF4\",\n drama: \"\u77ED\u5267\",\n game: \"\u6E38\u620F\",\n video: \"\u89C6\u9891\"\n};\n\nexport function workbenchLabel(mode: WorkbenchMode): string {\n return WORKBENCH_LABELS[mode];\n}\n\nexport interface WorkspaceFilePath {\n readonly path: string;\n}\n\nconst STORY_DIRECTORIES = new Set([\"\u6B63\u6587\", \"\u5927\u7EB2\", \"\u8BBE\u5B9A\", \"\u8FFD\u8E2A\", \"\u5BF9\u6807\", \"\u53C2\u8003\u8D44\u6599\"]);\nconst DRAMA_DIRECTORIES = new Set([\"\u8F93\u5165\", \"\u9879\u76EE\u5F00\u53D1\", \"\u8BBE\u5B9A\u96C6\", \"\u5267\u96C6\", \"\u4EA4\u4ED8\", \"\u521B\u4F5C\u8005\u51B3\u7B56\", \"\u5BA1\u67E5\"]);\nconst GAME_DIRECTORY = \"game-adaptations\";\nconst VIDEO_DIRECTORY = \"video-recaps\";\nconst EDITABLE_EXTENSION = /\\.(?:md|txt|json|jsonl|html|css|[cm]?js|tsx?|jsx)$/iu;\nconst MUTATING_CALLS = new Set([\"write\", \"edit\", \"str_replace_editor\", \"bash\", \"run_code\", \"oh_story_role\"]);\n\n/** Read the latest running Assistant step, including tool-only steps hidden from the Chat list. */\nexport function streamingAssistant(timeline: ConversationTimelineSnapshot): PartialAssistant | null {\n for (const turnNumber of timeline.turnOrder.toReversed()) {\n const turn = timeline.turns.get(turnNumber);\n if (turn === undefined) continue;\n for (const step of turn.steps.toReversed()) {\n const assistant: AssistantChatData | undefined = step.data.get(\"assistant-step\");\n if (assistant?.status === \"running\") return assistant;\n }\n }\n return null;\n}\n\nfunction decodeEscape(character: string): string | undefined {\n switch (character) {\n case \"\\\"\": return \"\\\"\";\n case \"\\\\\": return \"\\\\\";\n case \"/\": return \"/\";\n case \"b\": return \"\\b\";\n case \"f\": return \"\\f\";\n case \"n\": return \"\\n\";\n case \"r\": return \"\\r\";\n case \"t\": return \"\\t\";\n default: return undefined;\n }\n}\n\n/** Read a JSON string even while the model is still streaming its closing quote. */\nexport function jsonStringPrefix(raw: string, key: string): JsonStringPrefix | undefined {\n const match = new RegExp(`\"${key.replace(/[.*+?^${}()|[\\]\\\\]/gu, \"\\\\$&\")}\"\\\\s*:\\\\s*\"`, \"u\").exec(raw);\n if (match === null) return undefined;\n let value = \"\";\n for (let index = match.index + match[0].length; index < raw.length; index += 1) {\n const character = raw[index] ?? \"\";\n if (character === \"\\\"\") return { value, complete: true };\n if (character !== \"\\\\\") { value += character; continue; }\n const escape = raw[index + 1];\n if (escape === undefined) return { value, complete: false };\n if (escape === \"u\") {\n const hex = raw.slice(index + 2, index + 6);\n if (!/^[\\da-f]{4}$/iu.test(hex)) return { value, complete: false };\n value += String.fromCharCode(Number.parseInt(hex, 16));\n index += 5;\n continue;\n }\n const decoded = decodeEscape(escape);\n if (decoded === undefined) return { value, complete: false };\n value += decoded;\n index += 1;\n }\n return { value, complete: false };\n}\n\nfunction completedString(raw: string, key: string): string | undefined {\n const value = jsonStringPrefix(raw, key);\n return value?.complete === true ? value.value : undefined;\n}\n\nfunction parsedArgs(raw: string): Record<string, unknown> | undefined {\n try {\n const value = JSON.parse(raw) as unknown;\n return typeof value === \"object\" && value !== null && !Array.isArray(value) ? value as Record<string, unknown> : undefined;\n } catch { return undefined; }\n}\n\nfunction mutationFromArgs(name: string, callId: string, argsRaw: string, stage: FileMutationActivity[\"stage\"], argumentsComplete?: boolean): FileMutationActivity | undefined {\n const complete = parsedArgs(argsRaw);\n if (name === \"write\") {\n return {\n callId, name, argsRaw, stage,\n path: jsonStringPrefix(argsRaw, \"file_path\")?.value,\n operation: \"replace-file\",\n oldText: undefined,\n newText: jsonStringPrefix(argsRaw, \"content\")?.value,\n replaceAll: false\n };\n }\n if (name === \"edit\") {\n return {\n callId, name, argsRaw, stage,\n path: jsonStringPrefix(argsRaw, \"file_path\")?.value,\n operation: \"replace-text\",\n oldText: completedString(argsRaw, \"old_string\"),\n newText: jsonStringPrefix(argsRaw, \"new_string\")?.value,\n replaceAll: complete?.replace_all === true\n };\n }\n if (name !== \"str_replace_editor\") return undefined;\n const command = completedString(argsRaw, \"command\");\n if (command === \"view\") return undefined;\n const path = jsonStringPrefix(argsRaw, \"path\")?.value;\n if (command === \"create\") {\n return {\n callId, name, argsRaw, stage, path,\n operation: \"replace-file\",\n oldText: undefined,\n newText: jsonStringPrefix(argsRaw, \"file_text\")?.value,\n replaceAll: false\n };\n }\n if (command === \"str_replace\") {\n return {\n callId, name, argsRaw, stage, path,\n operation: \"replace-text\",\n oldText: completedString(argsRaw, \"old_str\"),\n newText: jsonStringPrefix(argsRaw, \"new_str\")?.value ?? ((argumentsComplete ?? complete !== undefined) ? \"\" : undefined),\n replaceAll: complete?.replace_all === true\n };\n }\n if (command === \"insert\") {\n return {\n callId, name, argsRaw, stage, path,\n operation: \"insert-text\",\n oldText: undefined,\n newText: jsonStringPrefix(argsRaw, \"new_str\")?.value,\n replaceAll: false\n };\n }\n return { callId, name, argsRaw, stage, path, operation: undefined, oldText: undefined, newText: undefined, replaceAll: false };\n}\n\nfunction visitRunning(blocks: readonly ToolCallBlock[], visit: (call: RunningToolCall) => void): void {\n for (const block of blocks) {\n if (!(\"kind\" in block)) visit(block);\n visitRunning(block.subCalls, visit);\n }\n}\n\n/** A call a finished Assistant step issued that DSH has not settled yet. */\nexport interface UndispatchedCall {\n readonly callId: string;\n readonly name: string;\n readonly argsRaw: string;\n}\n\n/**\n * Calls of the open Turn whose Assistant step has finished streaming but that have no result yet.\n * DSH 0.1.7 hides such a call's tool row until its durable `tool/call` event \u2014 through pre-execute\n * hooks and any approval \u2014 so it is in neither `partial` nor the running calls, and a call it does\n * list on rc.2 stays `preparing` without arguments. The step's own tool-call block still holds them.\n */\nexport function undispatchedCalls(chat: ChatSnapshot): UndispatchedCall[] {\n const turnNumber = chat.timeline.turnOrder.at(-1);\n const turn = turnNumber === undefined ? undefined : chat.timeline.turns.get(turnNumber);\n // Only a closed Turn is finished: a Turn whose start fell outside the loaded history window\n // reports `unknown` while it still runs. Callers pass the result only while the Session runs.\n if (turn === undefined || turn.status === \"closed\") return [];\n const calls: UndispatchedCall[] = [];\n for (const step of turn.steps) {\n const assistant: AssistantChatData | undefined = step.data.get(\"assistant-step\");\n if (assistant?.status !== \"settled\") continue;\n for (const block of assistant.blocks) {\n if (block.kind === \"tool-call\") calls.push({ callId: block.callId, name: block.name, argsRaw: block.argsRaw });\n }\n }\n if (calls.length === 0) return calls;\n const settled = new Set<string>();\n for (const node of chat.legacy.nodes as readonly unknown[]) {\n const value = node as { readonly kind?: unknown; readonly callId?: unknown };\n if (value.kind === \"tool-result\" && typeof value.callId === \"string\") settled.add(value.callId);\n }\n return calls.filter((call) => !settled.has(call.callId));\n}\n\nexport function sameUndispatchedCalls(left: readonly UndispatchedCall[], right: readonly UndispatchedCall[]): boolean {\n return left.length === right.length && left.every((call, index) => (\n call.callId === right[index]?.callId && call.argsRaw === right[index].argsRaw\n ));\n}\n\n/** Return every active file mutation in official DSH dispatch order, including nested Code Mode calls. */\nexport function fileMutations(\n runningCalls: readonly RunningToolCall[],\n partial: PartialAssistant | null = null,\n undispatched: readonly UndispatchedCall[] = []\n): FileMutationActivity[] {\n const values: FileMutationActivity[] = [];\n visitRunning(runningCalls, (call) => {\n if (call.phase === \"start\") {\n const mutation = mutationFromArgs(call.name, call.callId, call.argsRaw, \"running\");\n if (mutation !== undefined) values.push(mutation);\n return;\n }\n // Alpha publishes lazy arguments while preparing; rc.2 still relies on the\n // Assistant block below. Read on every projection, since args grows in place.\n if (call.args === undefined || ![\"write\", \"edit\", \"str_replace_editor\"].includes(call.name)) return;\n const fields: Record<string, unknown> = {};\n for (const key of [\"file_path\", \"path\", \"content\", \"file_text\", \"new_string\", \"new_str\", \"old_string\", \"old_str\", \"command\", \"insert_line\", \"replace_all\"]) {\n if ([\"old_string\", \"old_str\", \"command\"].includes(key) && !call.args.complete(key)) continue;\n const value = call.args.text(key) ?? call.args.value(key);\n if (value !== undefined) fields[key] = value;\n }\n if (Object.keys(fields).length === 0) return;\n const mutation = mutationFromArgs(call.name, call.callId, JSON.stringify(fields), \"streaming\", call.args.closed());\n if (mutation !== undefined) values.push(mutation);\n });\n for (const call of undispatched) {\n if (values.some((candidate) => candidate.callId === call.callId)) continue;\n const mutation = mutationFromArgs(call.name, call.callId, call.argsRaw, \"running\");\n if (mutation !== undefined) values.push(mutation);\n }\n for (const block of partial?.blocks ?? []) {\n if (block.kind !== \"tool-call\") continue;\n const value = mutationFromArgs(block.name, block.callId, block.argsRaw, \"streaming\");\n if (value !== undefined && !values.some((candidate) => candidate.callId === value.callId)) values.push(value);\n }\n return values;\n}\n\n/** Running calls whose settlement may have changed creative files. */\nexport function mutatingCallIds(runningCalls: readonly RunningToolCall[]): ReadonlySet<string> {\n const ids = new Set<string>();\n visitRunning(runningCalls, (call) => { if (MUTATING_CALLS.has(call.name)) ids.add(call.callId); });\n return ids;\n}\n\nfunction settledMutationSignals(block: ToolCallBlock): string[] {\n const nested = block.subCalls.flatMap(settledMutationSignals);\n if (!(\"kind\" in block) || block.isError) return nested;\n if (block.call === null) return nested;\n const mutation = mutationFromArgs(block.call.name, block.callId, block.call.argsRaw, \"running\");\n return mutation?.path === undefined ? nested : [`${block.callId}\\0${mutation.path}`, ...nested];\n}\n\nfunction latestSettledWrite(chat: ChatSnapshot): { readonly signal: string; readonly turn: number | undefined } | undefined {\n for (const key of chat.order.toReversed()) {\n const node = chat.nodes.get(key);\n if (node?.kind !== \"tool-call\") continue;\n const root = (node.data as { readonly root?: ToolCallBlock }).root;\n const signal = root === undefined ? undefined : settledMutationSignals(root).at(-1);\n if (signal === undefined) continue;\n const location = node.location;\n return { signal, turn: location.kind === \"turn\" || location.kind === \"step\" ? location.turn.turn : undefined };\n }\n return undefined;\n}\n\n/** Latest durable successful mutation, used when a fast call skips the live render window. */\nexport function latestSettledMutation(chat: ChatSnapshot): string | undefined {\n return latestSettledWrite(chat)?.signal;\n}\n\n/** The Turn that produced {@link latestSettledMutation}, when the Chat still locates it. */\nexport function latestSettledMutationTurn(chat: ChatSnapshot): number | undefined {\n return latestSettledWrite(chat)?.turn;\n}\n\n/** The last Turn while it is open. A reloaded Session shows history Turns as closed. */\nexport function openTurn(chat: ChatSnapshot): number | undefined {\n const turnNumber = chat.timeline.turnOrder.at(-1);\n if (turnNumber === undefined) return undefined;\n return chat.timeline.turns.get(turnNumber)?.status === \"open\" ? turnNumber : undefined;\n}\n\n/** Convert a DSH tool path to the creative-relative path accepted by the narrow route. */\nexport function creativeRelativePath(path: string | undefined, cwd: string | undefined): string | undefined {\n if (path === undefined || path === \"\") return undefined;\n const normalized = path.replaceAll(\"\\\\\", \"/\");\n const root = cwd?.replaceAll(\"\\\\\", \"/\").replace(/\\/$/u, \"\");\n const insideRoot = root !== undefined && normalized.startsWith(`${root}/`);\n if ((normalized.startsWith(\"/\") || /^[a-z]:\\//iu.test(normalized) || normalized.startsWith(\"file:\")) && !insideRoot) return undefined;\n const relative = insideRoot ? normalized.slice(root.length + 1) : normalized.replace(/^\\.\\//u, \"\");\n const [directory] = relative.split(\"/\", 1);\n const creative = directory !== undefined && (STORY_DIRECTORIES.has(directory) || DRAMA_DIRECTORIES.has(directory) || directory === GAME_DIRECTORY || directory === VIDEO_DIRECTORY);\n if ((!creative && relative !== \"short-drama.json\") || !EDITABLE_EXTENSION.test(relative)) return undefined;\n if (relative.split(\"/\").some((part) => part === \"..\" || part === \".\" || part === \"\")) return undefined;\n return relative;\n}\n\nexport function workbenchModeForPath(path: string | undefined): WorkbenchMode | undefined {\n if (path === \"short-drama.json\") return \"drama\";\n const directory = path?.split(\"/\", 1)[0];\n if (directory !== undefined && STORY_DIRECTORIES.has(directory)) return \"story\";\n if (directory !== undefined && DRAMA_DIRECTORIES.has(directory)) return \"drama\";\n if (directory === GAME_DIRECTORY) return \"game\";\n if (directory === VIDEO_DIRECTORY) return \"video\";\n return undefined;\n}\n\n/** Choose the first useful document when a creative workbench opens. */\nexport function preferredWorkbenchFile(\n files: readonly WorkspaceFilePath[],\n mode: WorkbenchMode\n): string | undefined {\n const matching = files.filter((file) => workbenchModeForPath(file.path) === mode);\n const preferences = mode === \"story\"\n ? [/^\u6B63\u6587\\/.*\\.md$/u, /^\u5927\u7EB2\\/.*\\.md$/u, /\\.md$/u]\n : mode === \"drama\" ? [\n /^\u5267\u96C6\\/EP0*1\\/\u5267\u672C\\.md$/u,\n /^\u5267\u96C6\\/.*\\/\u5267\u672C\\.md$/u,\n /^\u5267\u96C6\\/EP0*1\\/screenplay\\.md$/iu,\n /^\u5267\u96C6\\/.*\\/screenplay\\.md$/iu,\n /^\u9879\u76EE\u5F00\u53D1\\/creative-brief\\.md$/u,\n /^\u8F93\u5165\\/.*\\.md$/u,\n /\\.md$/u,\n /^short-drama\\.json$/u\n ] : mode === \"game\" ? [\n /^game-adaptations\\/[^/]+\\/PRODUCT_BRIEF\\.md$/u,\n /^game-adaptations\\/[^/]+\\/design\\/GAME_DESIGN\\.md$/u,\n /^game-adaptations\\/[^/]+\\/qa\\/verification\\.json$/u,\n /^game-adaptations\\/[^/]+\\/build\\/app\\/index\\.html$/u,\n /\\.md$/u\n ] : [\n /^video-recaps\\/[^/]+\\/work\\/recap_story_plan\\.json$/u,\n /^video-recaps\\/[^/]+\\/work\\/narration\\.json$/u,\n /^video-recaps\\/[^/]+\\/work\\/assembly_manifest\\.json$/u\n ];\n for (const pattern of preferences) {\n const match = matching.find((file) => pattern.test(file.path));\n if (match !== undefined) return match.path;\n }\n return matching[0]?.path;\n}\n\n/** Project one streamed mutation over its immediate predecessor. */\nexport function previewMutation(activity: FileMutationActivity, base: string): string | undefined {\n if (activity.operation === \"replace-file\") return activity.newText;\n if (activity.operation === \"replace-text\") {\n if (activity.oldText === undefined || activity.newText === undefined || activity.oldText === \"\") return undefined;\n if (activity.replaceAll) return base.includes(activity.oldText) ? base.split(activity.oldText).join(activity.newText) : undefined;\n const at = base.indexOf(activity.oldText);\n return at < 0 ? undefined : `${base.slice(0, at)}${activity.newText}${base.slice(at + activity.oldText.length)}`;\n }\n if (activity.operation === \"insert-text\") {\n if (activity.newText === undefined) return undefined;\n const rawLine = /\"insert_line\"\\s*:\\s*(\\d+)/u.exec(activity.argsRaw)?.[1];\n if (rawLine === undefined) return undefined;\n const line = Number.parseInt(rawLine, 10);\n const parts = base.split(\"\\n\");\n const at = Math.max(0, Math.min(parts.length, line));\n parts.splice(at, 0, activity.newText);\n return parts.join(\"\\n\");\n }\n return undefined;\n}\n", "export interface FileTreeInput {\n readonly path: string;\n readonly bytes: number;\n}\n\nexport interface FileTreeFile {\n readonly kind: \"file\";\n readonly name: string;\n readonly path: string;\n readonly bytes: number;\n}\n\nexport interface FileTreeDirectory {\n readonly kind: \"directory\";\n readonly name: string;\n readonly path: string;\n readonly fileCount: number;\n readonly children: readonly FileTreeNode[];\n}\n\nexport type FileTreeNode = FileTreeFile | FileTreeDirectory;\n\ninterface MutableDirectory {\n readonly name: string;\n readonly path: string;\n readonly directories: Map<string, MutableDirectory>;\n readonly files: FileTreeFile[];\n}\n\nfunction directory(name: string, path: string): MutableDirectory {\n return { name, path, directories: new Map(), files: [] };\n}\n\nfunction compareNames(left: { readonly name: string }, right: { readonly name: string }): number {\n return left.name.localeCompare(right.name, \"zh-Hans-CN\", { numeric: true });\n}\n\nfunction freezeDirectory(value: MutableDirectory): FileTreeDirectory {\n const directories = [...value.directories.values()].map(freezeDirectory).sort(compareNames);\n const files = [...value.files].sort(compareNames);\n return {\n kind: \"directory\",\n name: value.name,\n path: value.path,\n fileCount: files.length + directories.reduce((sum, child) => sum + child.fileCount, 0),\n children: [...directories, ...files]\n };\n}\n\nexport function buildFileTree(files: readonly FileTreeInput[], group: string): readonly FileTreeNode[] {\n const root = directory(group, group);\n for (const file of files) {\n const relative = file.path.startsWith(`${group}/`) ? file.path.slice(group.length + 1) : file.path;\n const segments = relative.split(\"/\").filter((segment) => segment !== \"\");\n const name = segments.pop();\n if (name === undefined) continue;\n let parent = root;\n for (const segment of segments) {\n const path = `${parent.path}/${segment}`;\n const child = parent.directories.get(segment) ?? directory(segment, path);\n parent.directories.set(segment, child);\n parent = child;\n }\n parent.files.push({ kind: \"file\", name, path: file.path, bytes: file.bytes });\n }\n return freezeDirectory(root).children;\n}\n", "const TITLE_KEYS = [\n \"display_name\", \"title\", \"name\", \"shot_id\", \"scene_id\", \"episode_id\", \"character_id\",\n \"location_id\", \"view_id\", \"prop_id\", \"state_id\", \"decision_id\", \"occurrence_id\", \"record_id\", \"id\"\n] as const;\n\nexport interface JsonlRecord {\n readonly line: number;\n readonly raw: string;\n readonly value?: unknown;\n readonly title: string;\n readonly type?: string;\n readonly status?: string;\n readonly error?: string;\n}\n\nfunction objectRecord(value: unknown): Record<string, unknown> | undefined {\n return typeof value === \"object\" && value !== null && !Array.isArray(value) ? value as Record<string, unknown> : undefined;\n}\n\nfunction stringField(record: Record<string, unknown>, keys: readonly string[]): string | undefined {\n for (const key of keys) {\n const value = record[key];\n if (typeof value === \"string\" && value.trim() !== \"\") return value;\n }\n return undefined;\n}\n\nfunction metadata(value: unknown, line: number): Pick<JsonlRecord, \"title\" | \"type\" | \"status\"> {\n const record = objectRecord(value);\n if (record === undefined) return { title: typeof value === \"string\" ? value : JSON.stringify(value) ?? `\u7B2C ${String(line)} \u884C` };\n const type = stringField(record, [\"record_type\", \"type\", \"kind\"]);\n const acceptance = objectRecord(record.creator_acceptance);\n const status = stringField(record, [\"status\"]) ?? (acceptance === undefined ? undefined : stringField(acceptance, [\"status\"]));\n return {\n title: stringField(record, TITLE_KEYS) ?? `\u8BB0\u5F55 ${String(line)}`,\n ...(type === undefined ? {} : { type }),\n ...(status === undefined ? {} : { status })\n };\n}\n\nexport function parseJsonl(content: string): JsonlRecord[] {\n const records: JsonlRecord[] = [];\n const lines = content.replaceAll(\"\\r\\n\", \"\\n\").split(\"\\n\");\n for (const [index, raw] of lines.entries()) {\n if (raw.trim() === \"\") continue;\n try {\n const value = JSON.parse(raw) as unknown;\n records.push({ line: index + 1, raw, value, ...metadata(value, index + 1) });\n } catch (error) {\n records.push({\n line: index + 1,\n raw,\n title: `\u7B2C ${String(index + 1)} \u884C\u683C\u5F0F\u9519\u8BEF`,\n error: error instanceof Error ? error.message : String(error)\n });\n }\n }\n return records;\n}\n\nconst PREVIEW_LIMIT = 200;\n\nexport function JsonlPreview({ content, label }: { readonly content: string; readonly label: string }) {\n const records = parseJsonl(content);\n if (records.length === 0) return <div className=\"oh-story-markdown-empty\">\u8FD9\u4E2A JSONL \u6587\u4EF6\u8FD8\u662F\u7A7A\u7684\u3002</div>;\n const valid = records.filter((record) => record.error === undefined).length;\n const errors = records.length - valid;\n const visible = records.slice(0, PREVIEW_LIMIT);\n return <section className=\"oh-story-jsonl\" aria-label={`${label} \u7ED3\u6784\u5316\u9884\u89C8`}>\n <header className=\"oh-story-jsonl-summary\">\n <strong>{errors === 0 ? `${String(valid)} \u6761\u8BB0\u5F55` : `${String(valid)} \u6761\u6709\u6548\u8BB0\u5F55`}</strong>\n {errors > 0 && <span>{String(errors)} \u6761\u683C\u5F0F\u9519\u8BEF</span>}\n {records.length > PREVIEW_LIMIT && <span>\u4EC5\u663E\u793A\u524D {String(PREVIEW_LIMIT)} \u6761</span>}\n </header>\n <div className=\"oh-story-jsonl-records\">\n {visible.map((record) => record.error === undefined\n ? <details key={record.line} open={records.length <= 2}>\n <summary>\n <span>\u7B2C {String(record.line)} \u884C</span>\n <strong>{record.title}</strong>\n {record.type !== undefined && <code>{record.type}</code>}\n {record.status !== undefined && <em>{record.status}</em>}\n </summary>\n <pre><code>{JSON.stringify(record.value, null, 2)}</code></pre>\n </details>\n : <div className=\"oh-story-jsonl-error\" key={record.line} role=\"alert\">\n <strong>{record.title}</strong>\n <span>{record.error}</span>\n <pre>{record.raw}</pre>\n </div>)}\n </div>\n </section>;\n}\n", "import type { ReactNode } from \"react\";\n\nconst INLINE = /(`[^`\\n]+`|\\*\\*[^*\\n]+\\*\\*|~~[^~\\n]+~~|\\[[^\\]\\n]+\\]\\(https?:\\/\\/[^)\\s]+\\)|\\*[^*\\n]+\\*)/gu;\n\nfunction inline(source: string, key: string): ReactNode[] {\n const nodes: ReactNode[] = [];\n let cursor = 0;\n for (const match of source.matchAll(INLINE)) {\n const token = match[0];\n const index = match.index;\n if (index > cursor) nodes.push(source.slice(cursor, index));\n if (token.startsWith(\"`\")) nodes.push(<code key={`${key}-${String(index)}`}>{token.slice(1, -1)}</code>);\n else if (token.startsWith(\"**\")) nodes.push(<strong key={`${key}-${String(index)}`}>{token.slice(2, -2)}</strong>);\n else if (token.startsWith(\"~~\")) nodes.push(<del key={`${key}-${String(index)}`}>{token.slice(2, -2)}</del>);\n else if (token.startsWith(\"*\")) nodes.push(<em key={`${key}-${String(index)}`}>{token.slice(1, -1)}</em>);\n else {\n const link = /^\\[([^\\]]+)\\]\\((https?:\\/\\/[^)\\s]+)\\)$/u.exec(token);\n nodes.push(link === null ? token : <a key={`${key}-${String(index)}`} href={link[2]} target=\"_blank\" rel=\"noreferrer\">{link[1]}</a>);\n }\n cursor = index + token.length;\n }\n if (cursor < source.length) nodes.push(source.slice(cursor));\n return nodes;\n}\n\ntype Alignment = \"left\" | \"center\" | \"right\" | undefined;\ninterface ListItem { readonly text: string; readonly checked?: boolean }\n\nexport type MarkdownBlock =\n | { readonly kind: \"code\"; readonly lines: readonly string[]; readonly language?: string }\n | { readonly kind: \"heading\"; readonly text: string; readonly level: number }\n | { readonly kind: \"quote\"; readonly lines: readonly string[] }\n | { readonly kind: \"ul\" | \"ol\"; readonly items: readonly ListItem[]; readonly start?: number }\n | { readonly kind: \"table\"; readonly headers: readonly string[]; readonly rows: readonly (readonly string[])[]; readonly alignments: readonly Alignment[] }\n | { readonly kind: \"rule\" }\n | { readonly kind: \"paragraph\"; readonly lines: readonly string[] };\n\nfunction splitTableRow(line: string): string[] {\n let source = line.trim();\n if (source.startsWith(\"|\")) source = source.slice(1);\n if (source.endsWith(\"|\")) source = source.slice(0, -1);\n const cells: string[] = [];\n let cell = \"\";\n for (let index = 0; index < source.length; index += 1) {\n const character = source[index] ?? \"\";\n if (character === \"\\\\\" && source[index + 1] === \"|\") {\n cell += \"|\";\n index += 1;\n } else if (character === \"|\") {\n cells.push(cell.trim());\n cell = \"\";\n } else cell += character;\n }\n cells.push(cell.trim());\n return cells;\n}\n\nfunction tableAlignments(line: string): Alignment[] | undefined {\n const cells = splitTableRow(line);\n if (cells.length === 0 || !cells.every((cell) => /^:?-{3,}:?$/u.test(cell))) return undefined;\n return cells.map((cell) => {\n if (cell.startsWith(\":\") && cell.endsWith(\":\")) return \"center\";\n if (cell.endsWith(\":\")) return \"right\";\n if (cell.startsWith(\":\")) return \"left\";\n return undefined;\n });\n}\n\nfunction beginsBlock(lines: readonly string[], index: number): boolean {\n const line = lines[index] ?? \"\";\n return /^(`{3,}|~{3,})\\s*[\\w-]*\\s*$/u.test(line)\n || /^#{1,6}\\s+/u.test(line)\n || /^(?:-{3,}|\\*{3,}|_{3,})\\s*$/u.test(line)\n || /^>\\s?/u.test(line)\n || /^[-*+]\\s+/u.test(line)\n || /^\\d+[.)]\\s+/u.test(line)\n || (line.includes(\"|\") && tableAlignments(lines[index + 1] ?? \"\") !== undefined);\n}\n\nexport function parseMarkdownBlocks(markdown: string): MarkdownBlock[] {\n const lines = markdown.replaceAll(\"\\r\\n\", \"\\n\").split(\"\\n\");\n const result: MarkdownBlock[] = [];\n for (let index = 0; index < lines.length;) {\n const line = lines[index] ?? \"\";\n if (line.trim() === \"\") { index += 1; continue; }\n\n const fence = /^(`{3,}|~{3,})\\s*([\\w-]*)\\s*$/u.exec(line);\n if (fence !== null) {\n const marker = fence[1] ?? \"```\";\n const markerCharacter = marker[0] ?? \"`\";\n const closing = new RegExp(`^${markerCharacter}{${String(marker.length)},}\\\\s*$`, \"u\");\n const code: string[] = [];\n index += 1;\n while (index < lines.length && !closing.test(lines[index] ?? \"\")) { code.push(lines[index] ?? \"\"); index += 1; }\n if (index < lines.length) index += 1;\n result.push({ kind: \"code\", lines: code, ...(fence[2] === undefined || fence[2] === \"\" ? {} : { language: fence[2] }) });\n continue;\n }\n\n const heading = /^(#{1,6})\\s+(.+)$/u.exec(line);\n if (heading !== null) {\n result.push({ kind: \"heading\", text: heading[2] ?? \"\", level: heading[1]?.length ?? 1 });\n index += 1;\n continue;\n }\n if (/^(?:-{3,}|\\*{3,}|_{3,})\\s*$/u.test(line)) { result.push({ kind: \"rule\" }); index += 1; continue; }\n\n const alignments = line.includes(\"|\") ? tableAlignments(lines[index + 1] ?? \"\") : undefined;\n if (alignments !== undefined) {\n const headers = splitTableRow(line);\n const rows: string[][] = [];\n index += 2;\n while (index < lines.length && (lines[index] ?? \"\").includes(\"|\") && (lines[index] ?? \"\").trim() !== \"\") {\n rows.push(splitTableRow(lines[index] ?? \"\"));\n index += 1;\n }\n result.push({ kind: \"table\", headers, rows, alignments });\n continue;\n }\n\n if (/^>\\s?/u.test(line)) {\n const quote: string[] = [];\n while (index < lines.length && /^>\\s?/u.test(lines[index] ?? \"\")) {\n quote.push((lines[index] ?? \"\").replace(/^>\\s?/u, \"\"));\n index += 1;\n }\n result.push({ kind: \"quote\", lines: quote });\n continue;\n }\n\n const unordered = /^[-*+]\\s+(.+)$/u.exec(line);\n const ordered = /^(\\d+)[.)]\\s+(.+)$/u.exec(line);\n if (unordered !== null || ordered !== null) {\n const kind = unordered !== null ? \"ul\" : \"ol\";\n const items: ListItem[] = [];\n const pattern = kind === \"ul\" ? /^[-*+]\\s+(.+)$/u : /^\\d+[.)]\\s+(.+)$/u;\n const start = ordered === null ? undefined : Number(ordered[1]);\n while (index < lines.length) {\n const item = pattern.exec(lines[index] ?? \"\");\n if (item === null) break;\n const source = item[1] ?? \"\";\n const task = /^\\[([ xX])\\]\\s+(.+)$/u.exec(source);\n items.push(task === null ? { text: source } : { text: task[2] ?? \"\", checked: task[1]?.toLocaleLowerCase() === \"x\" });\n index += 1;\n }\n result.push({ kind, items, ...(start === undefined ? {} : { start }) });\n continue;\n }\n\n const paragraph: string[] = [line];\n index += 1;\n while (index < lines.length) {\n const next = lines[index] ?? \"\";\n if (next.trim() === \"\" || beginsBlock(lines, index)) break;\n paragraph.push(next);\n index += 1;\n }\n result.push({ kind: \"paragraph\", lines: paragraph });\n }\n return result;\n}\n\nfunction Heading({ block, blockKey }: { readonly block: Extract<MarkdownBlock, { readonly kind: \"heading\" }>; readonly blockKey: string }) {\n const children = inline(block.text, blockKey);\n switch (block.level) {\n case 1: return <h1>{children}</h1>;\n case 2: return <h2>{children}</h2>;\n case 3: return <h3>{children}</h3>;\n case 4: return <h4>{children}</h4>;\n case 5: return <h5>{children}</h5>;\n default: return <h6>{children}</h6>;\n }\n}\n\nexport function MarkdownPreview({ content, label }: { readonly content: string; readonly label: string }) {\n const parsed = parseMarkdownBlocks(content);\n if (parsed.length === 0) return <div className=\"oh-story-markdown-empty\">\u8FD9\u4E2A Markdown \u6587\u4EF6\u8FD8\u662F\u7A7A\u7684\u3002</div>;\n return <article className=\"oh-story-markdown\" aria-label={`${label} \u6E32\u67D3\u9884\u89C8`}>\n {parsed.map((block, index) => {\n const key = `block-${String(index)}`;\n if (block.kind === \"code\") return <pre key={key}><code data-language={block.language}>{block.lines.join(\"\\n\")}</code></pre>;\n if (block.kind === \"rule\") return <hr key={key} />;\n if (block.kind === \"quote\") return <blockquote key={key}>{block.lines.map((line, lineIndex) => <p key={`${key}-${String(lineIndex)}`}>{inline(line, `${key}-${String(lineIndex)}`)}</p>)}</blockquote>;\n if (block.kind === \"ul\" || block.kind === \"ol\") {\n const items = block.items.map((item, itemIndex) => <li key={`${key}-${String(itemIndex)}`} className={item.checked === undefined ? undefined : \"oh-story-task-item\"}>\n {item.checked === undefined ? null : <input type=\"checkbox\" checked={item.checked} readOnly disabled aria-label={item.checked ? \"\u5DF2\u5B8C\u6210\" : \"\u672A\u5B8C\u6210\"} />}\n {inline(item.text, `${key}-${String(itemIndex)}`)}\n </li>);\n return block.kind === \"ul\" ? <ul key={key}>{items}</ul> : <ol key={key} start={block.start}>{items}</ol>;\n }\n if (block.kind === \"table\") return <div className=\"oh-story-markdown-table\" key={key}>\n <table>\n <thead><tr>{block.headers.map((cell, cellIndex) => <th key={`${key}-h-${String(cellIndex)}`} style={{ textAlign: block.alignments[cellIndex] }}>{inline(cell, `${key}-h-${String(cellIndex)}`)}</th>)}</tr></thead>\n <tbody>{block.rows.map((row, rowIndex) => <tr key={`${key}-r-${String(rowIndex)}`}>{block.headers.map((_, cellIndex) => <td key={`${key}-r-${String(rowIndex)}-${String(cellIndex)}`} style={{ textAlign: block.alignments[cellIndex] }}>{inline(row[cellIndex] ?? \"\", `${key}-r-${String(rowIndex)}-${String(cellIndex)}`)}</td>)}</tr>)}</tbody>\n </table>\n </div>;\n if (block.kind === \"heading\") return <Heading key={key} block={block} blockKey={key} />;\n if (block.kind === \"paragraph\") return <p key={key}>{block.lines.map((line, lineIndex) => <span key={`${key}-${String(lineIndex)}`}>{lineIndex === 0 ? null : <br />}{inline(line, `${key}-${String(lineIndex)}`)}</span>)}</p>;\n return null;\n })}\n </article>;\n}\n", "export type DramaProductionSection = \"shots\" | \"assets\" | \"tasks\" | \"sequence\" | \"canvas\";\n\nexport type DramaAssetKind = \"character\" | \"scene\" | \"prop\" | \"state\" | \"unknown\";\nexport const PRODUCTION_PROTOCOL_VERSION = \"short-drama/v1\";\n\nexport interface DramaProductionDiagnostic {\n readonly severity: \"error\" | \"warning\";\n readonly code: string;\n readonly path: string;\n readonly offset: number;\n readonly line: number;\n readonly targetId?: string | undefined;\n readonly message: string;\n}\n\nexport interface DramaDocumentTarget {\n readonly path: string;\n readonly offset: number;\n readonly id: string;\n}\n\nexport interface DramaShot {\n readonly id: string;\n readonly title: string;\n readonly path: string;\n readonly offset: number;\n readonly source?: string | undefined;\n /** Screenplay scene IDs named by \u6765\u6E90, in document order; empty when the field names none. */\n readonly sceneIds: readonly string[];\n readonly durationSeconds?: number | undefined;\n readonly purpose?: string | undefined;\n readonly shotSpec?: string | undefined;\n readonly start?: string | undefined;\n readonly end?: string | undefined;\n readonly references: readonly string[];\n readonly keyframePrompt?: string | undefined;\n readonly motion?: DramaMotionPrompt | undefined;\n}\n\nexport interface DramaAsset {\n readonly id: string;\n readonly title: string;\n readonly kind: DramaAssetKind;\n readonly path: string;\n readonly offset: number;\n readonly purpose?: string | undefined;\n readonly reference?: string | undefined;\n readonly prompt?: string | undefined;\n readonly description?: string | undefined;\n}\n\nexport interface DramaMotionPrompt {\n readonly id: string;\n readonly title: string;\n readonly path: string;\n readonly offset: number;\n readonly shotId?: string | undefined;\n readonly durationSeconds?: number | undefined;\n readonly startFrame?: string | undefined;\n readonly end?: string | undefined;\n readonly prompt?: string | undefined;\n}\n\nexport interface DramaVisualAsset {\n readonly id: string;\n readonly title: string;\n readonly kind: DramaAssetKind;\n readonly path: string;\n readonly offset: number;\n readonly description: string;\n readonly stableId: boolean;\n readonly declaredId?: string | undefined;\n}\n\nexport interface DramaEpisodeProduction {\n readonly protocolVersion: typeof PRODUCTION_PROTOCOL_VERSION;\n readonly episodeDirectory: string;\n readonly shots: readonly DramaShot[];\n readonly assets: readonly DramaAsset[];\n readonly visualAssets: readonly DramaVisualAsset[];\n readonly motions: readonly DramaMotionPrompt[];\n readonly targets: ReadonlyMap<string, DramaDocumentTarget>;\n readonly documentPaths: readonly string[];\n readonly diagnostics: readonly DramaProductionDiagnostic[];\n}\n\ninterface MarkdownSection {\n readonly heading: string;\n readonly body: string;\n readonly offset: number;\n}\n\nconst CREATOR_DOCUMENT_NAMES = new Set([\"\u5267\u672C.md\", \"\u89C6\u89C9\u8BBE\u5B9A.md\", \"\u5206\u955C.md\", \"\u56FE\u7247\u63D0\u793A\u8BCD.md\", \"\u89C6\u9891\u63D0\u793A\u8BCD.md\"]);\n\nexport function episodeDirectoryForPath(path: string | undefined): string | undefined {\n if (path === undefined) return undefined;\n const match = /^(\u5267\u96C6\\/[^/]+)\\/[^/]+$/u.exec(path);\n return match?.[1];\n}\n\nexport function isCreatorDocumentPath(path: string): boolean {\n const directory = episodeDirectoryForPath(path);\n const name = path.split(\"/\").at(-1);\n return directory !== undefined && name !== undefined && CREATOR_DOCUMENT_NAMES.has(name);\n}\n\nexport function creatorDocumentPaths(files: readonly { readonly path: string }[], episodeDirectory: string): string[] {\n return files\n .map((file) => file.path)\n .filter((path) => path.startsWith(`${episodeDirectory}/`) && CREATOR_DOCUMENT_NAMES.has(path.slice(episodeDirectory.length + 1)))\n .sort((left, right) => creatorDocumentOrder(left) - creatorDocumentOrder(right) || left.localeCompare(right, \"zh-Hans-CN\"));\n}\n\nexport function parseEpisodeProduction(documents: Readonly<Record<string, string>>, episodeDirectory: string): DramaEpisodeProduction {\n const storyboardPath = `${episodeDirectory}/\u5206\u955C.md`;\n const imagePromptPath = `${episodeDirectory}/\u56FE\u7247\u63D0\u793A\u8BCD.md`;\n const videoPromptPath = `${episodeDirectory}/\u89C6\u9891\u63D0\u793A\u8BCD.md`;\n const visualPath = `${episodeDirectory}/\u89C6\u89C9\u8BBE\u5B9A.md`;\n const shots = parseStoryboard(storyboardPath, documents[storyboardPath] ?? \"\");\n const assets = parseImagePrompts(imagePromptPath, documents[imagePromptPath] ?? \"\");\n const motions = parseVideoPrompts(videoPromptPath, documents[videoPromptPath] ?? \"\");\n const visualAssets = parseVisualAssets(visualPath, documents[visualPath] ?? \"\");\n const motionByShot = new Map(motions.flatMap((motion) => motion.shotId === undefined ? [] : [[motion.shotId, motion] as const]));\n const linkedShots = shots.map((shot) => ({ ...shot, motion: motionByShot.get(shot.id) }));\n const targets = new Map<string, DramaDocumentTarget>();\n for (const item of [...linkedShots, ...assets, ...motions, ...visualAssets]) {\n targets.set(item.id, { path: item.path, offset: item.offset, id: item.id });\n }\n const screenplayPath = `${episodeDirectory}/\u5267\u672C.md`;\n for (const shot of linkedShots) {\n for (const id of sourceKeys(shot)) {\n const target = sectionTarget(screenplayPath, documents[screenplayPath] ?? \"\", id);\n if (target === undefined) continue;\n targets.set(id, target);\n }\n }\n const diagnostics = validateProductionProtocol({\n documents,\n episodeDirectory,\n shots: linkedShots,\n assets,\n visualAssets,\n motions\n });\n return {\n protocolVersion: PRODUCTION_PROTOCOL_VERSION,\n episodeDirectory,\n shots: linkedShots,\n assets,\n visualAssets,\n motions,\n targets,\n documentPaths: Object.keys(documents).filter((path) => path.startsWith(`${episodeDirectory}/`)),\n diagnostics\n };\n}\n\nexport function parseStoryboard(path: string, content: string): DramaShot[] {\n return levelTwoSections(content).flatMap((section) => {\n const match = /^(SHOT-[A-Z0-9-]+)\\s*(?:[\u00B7\uFF5C|]\\s*)?(.*)$/iu.exec(section.heading.trim());\n if (match === null || match[1] === undefined) return [];\n const fields = bulletFields(section.body);\n const id = match[1].toLocaleUpperCase();\n const source = firstField(fields, \"\u6765\u6E90\", \"\u573A\u6B21\");\n return [{\n id,\n title: match[2]?.trim() || id,\n path,\n offset: section.offset,\n source,\n sceneIds: sourceSceneIds(source),\n durationSeconds: seconds(firstField(fields, \"\u65F6\u957F\")),\n purpose: firstField(fields, \"\u76EE\u7684\", \"\u955C\u5934\u76EE\u7684\"),\n shotSpec: firstField(fields, \"\u666F\u522B/\u673A\u4F4D\", \"\u666F\u522B\", \"\u955C\u5934\u89C4\u683C\"),\n start: firstField(fields, \"\u8D77\u70B9\", \"\u8D77\u59CB\"),\n end: firstField(fields, \"\u7EC8\u70B9\", \"\u7ED3\u675F\"),\n references: splitReferences(firstField(fields, \"\u56FE\u7247\u63D0\u793A\u8BCD\u9879\", \"\u53C2\u8003\", \"\u5173\u8054\u8D44\u4EA7\")),\n keyframePrompt: quoteUnderHeading(section.body, \"\u51BB\u7ED3\u5173\u952E\u5E27\u63D0\u793A\u8BCD\")\n }];\n });\n}\n\nexport function parseImagePrompts(path: string, content: string): DramaAsset[] {\n return levelTwoSections(content).flatMap((section) => {\n const match = /^(IMG-[A-Z0-9-]+)\\s*(?:[\u00B7\uFF5C|]\\s*)?(.*)$/iu.exec(section.heading.trim());\n if (match === null || match[1] === undefined) return [];\n const fields = bulletFields(section.body);\n const id = match[1].toLocaleUpperCase();\n const title = match[2]?.trim() || id;\n return [{\n id,\n title,\n kind: inferAssetKind(`${id} ${title} ${firstField(fields, \"\u7528\u9014\") ?? \"\"}`),\n path,\n offset: section.offset,\n purpose: firstField(fields, \"\u7528\u9014\"),\n reference: firstField(fields, \"\u53C2\u8003\", \"\u53C2\u8003\u7EA6\u675F\"),\n prompt: quoteUnderHeading(section.body, \"\u53EF\u590D\u5236\u63D0\u793A\u8BCD\")\n }];\n });\n}\n\nexport function parseVideoPrompts(path: string, content: string): DramaMotionPrompt[] {\n return levelTwoSections(content).flatMap((section) => {\n const match = /^(MOTION-[A-Z0-9-]+)\\s*(?:[\u00B7\uFF5C|]\\s*)?(.*)$/iu.exec(section.heading.trim());\n if (match === null || match[1] === undefined) return [];\n const fields = bulletFields(section.body);\n const id = match[1].toLocaleUpperCase();\n const shotId = firstField(fields, \"\u5206\u955C\", \"\u955C\u5934\")?.match(/SHOT-[A-Z0-9-]+/iu)?.[0]?.toLocaleUpperCase();\n return [{\n id,\n title: match[2]?.trim() || id,\n path,\n offset: section.offset,\n shotId,\n durationSeconds: seconds(firstField(fields, \"\u65F6\u957F\")),\n startFrame: firstField(fields, \"\u8D77\u59CB\u5E27\", \"\u8D77\u70B9\"),\n end: firstField(fields, \"\u7EC8\u70B9\", \"\u7ED3\u675F\"),\n prompt: quoteUnderHeading(section.body, \"\u53EF\u590D\u5236\u63D0\u793A\u8BCD\")\n }];\n });\n}\n\nexport function parseVisualAssets(path: string, content: string): DramaVisualAsset[] {\n return levelTwoSections(content).flatMap((section) => {\n const match = /^(\u4EBA\u7269|\u89D2\u8272|\u9020\u578B|\u5730\u70B9|\u573A\u666F|\u9053\u5177|\u72B6\u6001)\\s*(?:[\u00B7\uFF5C|:]\\s*)?(.*)$/u.exec(section.heading.trim());\n if (match === null || match[1] === undefined) return [];\n const fields = bulletFields(section.body);\n const title = match[2]?.trim() || section.heading.trim();\n const declaredId = firstField(fields, \"ID\", \"\u8D44\u4EA7 ID\", \"\u8D44\u4EA7ID\")?.trim().toLocaleUpperCase();\n const stableId = declaredId !== undefined && /^VISUAL-[A-Z0-9-]+$/u.test(declaredId);\n const id = stableId ? declaredId : `VISUAL-${slug(`${match[1]}-${title}`)}`;\n return [{ id, title, kind: inferAssetKind(`${match[1]} ${title}`), path, offset: section.offset, description: section.body.trim(), stableId, declaredId }];\n });\n}\n\nfunction validateProductionProtocol(input: {\n readonly documents: Readonly<Record<string, string>>;\n readonly episodeDirectory: string;\n readonly shots: readonly DramaShot[];\n readonly assets: readonly DramaAsset[];\n readonly visualAssets: readonly DramaVisualAsset[];\n readonly motions: readonly DramaMotionPrompt[];\n}): DramaProductionDiagnostic[] {\n const diagnostics: DramaProductionDiagnostic[] = [];\n const add = (value: Omit<DramaProductionDiagnostic, \"line\">): void => {\n diagnostics.push({ ...value, line: lineAt(input.documents[value.path] ?? \"\", value.offset) });\n };\n const all = [...input.shots, ...input.assets, ...input.visualAssets, ...input.motions];\n const byId = new Map<string, typeof all>();\n for (const item of all) byId.set(item.id, [...(byId.get(item.id) ?? []), item]);\n for (const [id, items] of byId) {\n if (items.length < 2) continue;\n for (const item of items) add({ severity: \"error\", code: \"duplicate_id\", path: item.path, offset: item.offset, targetId: id, message: `${id} \u5728\u5F53\u524D\u96C6\u5185\u91CD\u590D\uFF0C\u540E\u51FA\u73B0\u7684\u6761\u76EE\u4F1A\u906E\u853D\u524D\u4E00\u6761\u3002` });\n }\n\n for (const visual of input.visualAssets) {\n if (visual.stableId) continue;\n add(visual.declaredId === undefined\n ? { severity: \"warning\", code: \"generated_visual_id\", path: visual.path, offset: visual.offset, targetId: visual.id, message: `${visual.title} \u7F3A\u5C11\u7A33\u5B9A\u7684 \u201C- ID\uFF1AVISUAL-*\u201D\uFF1B\u4FEE\u6539\u6807\u9898\u4F1A\u6539\u53D8\u753B\u5E03\u8282\u70B9\u8EAB\u4EFD\u3002` }\n : { severity: \"warning\", code: \"invalid_visual_id\", path: visual.path, offset: visual.offset, targetId: visual.id, message: `${visual.title} \u7684 \u201C- ID\uFF1A${visual.declaredId}\u201D \u4E0D\u662F\u53EF\u7528\u5F62\u5F0F\uFF0C\u5DF2\u56DE\u9000\u5230\u6807\u9898\u6D3E\u751F ID\uFF1B\u8BF7\u5199\u6210 VISUAL- \u52A0\u5927\u5199\u5B57\u6BCD\u3001\u6570\u5B57\u6216\u8FDE\u5B57\u7B26\u3002` });\n }\n\n const knownReferences = new Set([...input.assets, ...input.visualAssets, ...input.shots, ...input.motions].map((item) => item.id));\n const screenplayPath = `${input.episodeDirectory}/\u5267\u672C.md`;\n for (const shot of input.shots) {\n for (const reference of shot.references) {\n if (!knownReferences.has(reference)) add({ severity: \"warning\", code: \"unknown_reference\", path: shot.path, offset: shot.offset, targetId: shot.id, message: `${shot.id} \u5F15\u7528\u4E86\u672A\u89E3\u6790\u7684 ${reference}\u3002` });\n }\n for (const id of sourceKeys(shot)) {\n if (sectionTarget(screenplayPath, input.documents[screenplayPath] ?? \"\", id) === undefined) {\n add({ severity: \"warning\", code: \"unknown_source\", path: shot.path, offset: shot.offset, targetId: shot.id, message: `${shot.id} \u7684\u6765\u6E90 ${id} \u5728\u5267\u672C\u4E2D\u4E0D\u5B58\u5728\u3002` });\n }\n }\n }\n\n const shots = new Set(input.shots.map((shot) => shot.id));\n const motionsByShot = new Map<string, DramaMotionPrompt[]>();\n for (const motion of input.motions) {\n if (motion.shotId === undefined) {\n add({ severity: \"warning\", code: \"motion_without_shot\", path: motion.path, offset: motion.offset, targetId: motion.id, message: `${motion.id} \u6CA1\u6709\u53EF\u89E3\u6790\u7684 SHOT-* \u5206\u955C\u5B57\u6BB5\u3002` });\n continue;\n }\n if (!shots.has(motion.shotId)) add({ severity: \"error\", code: \"unknown_motion_shot\", path: motion.path, offset: motion.offset, targetId: motion.id, message: `${motion.id} \u6307\u5411\u4E0D\u5B58\u5728\u7684 ${motion.shotId}\u3002` });\n motionsByShot.set(motion.shotId, [...(motionsByShot.get(motion.shotId) ?? []), motion]);\n }\n for (const [shotId, motions] of motionsByShot) {\n if (motions.length < 2) continue;\n for (const motion of motions) add({ severity: \"error\", code: \"multiple_motions\", path: motion.path, offset: motion.offset, targetId: motion.id, message: `${shotId} \u540C\u65F6\u7ED1\u5B9A\u4E86\u591A\u4E2A MOTION\uFF0C\u753B\u5E03\u53EA\u80FD\u786E\u5B9A\u4E00\u4E2A\u3002` });\n }\n\n const parsedOffsets = new Set([...input.shots, ...input.assets, ...input.motions].map((item) => `${item.path}:${String(item.offset)}`));\n for (const [path, prefix] of [\n [`${input.episodeDirectory}/\u5206\u955C.md`, \"SHOT\"],\n [`${input.episodeDirectory}/\u56FE\u7247\u63D0\u793A\u8BCD.md`, \"IMG\"],\n [`${input.episodeDirectory}/\u89C6\u9891\u63D0\u793A\u8BCD.md`, \"MOTION\"]\n ] as const) {\n for (const section of levelTwoSections(input.documents[path] ?? \"\")) {\n if (section.heading.toLocaleUpperCase().startsWith(prefix) && !parsedOffsets.has(`${path}:${String(section.offset)}`)) {\n add({ severity: \"error\", code: \"malformed_heading\", path, offset: section.offset, message: `\u65E0\u6CD5\u89E3\u6790\u6807\u9898 \u201C${section.heading.trim()}\u201D\uFF0C\u9700\u8981\u7A33\u5B9A\u7684 ${prefix}-* ID\u3002` });\n }\n }\n }\n return diagnostics.sort((left, right) => left.path.localeCompare(right.path, \"zh-Hans-CN\") || left.offset - right.offset || left.code.localeCompare(right.code));\n}\n\nexport function productionCompleteness(shot: DramaShot): {\n readonly keyframe: boolean;\n readonly motion: boolean;\n readonly references: boolean;\n readonly complete: boolean;\n} {\n const keyframe = Boolean(shot.keyframePrompt?.trim());\n const motion = Boolean(shot.motion?.prompt?.trim());\n const references = shot.references.length > 0;\n return { keyframe, motion, references, complete: keyframe && motion };\n}\n\nfunction levelTwoSections(content: string): MarkdownSection[] {\n const matches = [...content.matchAll(/^##\\s+(.+)\\s*$/gmu)];\n return matches.map((match, index) => {\n const start = (match.index ?? 0) + match[0].length;\n const end = matches[index + 1]?.index ?? content.length;\n return { heading: match[1] ?? \"\", body: content.slice(start, end), offset: match.index ?? 0 };\n });\n}\n\nfunction bulletFields(body: string): Map<string, string> {\n const fields = new Map<string, string>();\n for (const match of body.matchAll(/^\\s*[-*]\\s+([^\uFF1A:\\n]+)[\uFF1A:]\\s*(.+?)\\s*$/gmu)) {\n const key = match[1]?.trim();\n const value = match[2]?.trim();\n if (key !== undefined && value !== undefined) fields.set(key, value);\n }\n return fields;\n}\n\nfunction firstField(fields: ReadonlyMap<string, string>, ...names: string[]): string | undefined {\n for (const name of names) {\n const value = fields.get(name);\n if (value !== undefined && value !== \"\") return value;\n }\n return undefined;\n}\n\nfunction quoteUnderHeading(body: string, heading: string): string | undefined {\n const escaped = heading.replace(/[.*+?^${}()|[\\]\\\\]/gu, \"\\\\$&\");\n const match = new RegExp(`^###\\\\s+${escaped}\\\\s*$([\\\\s\\\\S]*?)(?=^###\\\\s+|(?![\\\\s\\\\S]))`, \"imu\").exec(body);\n if (match?.[1] === undefined) return undefined;\n const lines = match[1].split(/\\r?\\n/u)\n .filter((line) => /^\\s*>/u.test(line))\n .map((line) => line.replace(/^\\s*>\\s?/u, \"\").trimEnd());\n const value = lines.join(\"\\n\").trim();\n return value === \"\" ? undefined : value;\n}\n\nfunction seconds(value: string | undefined): number | undefined {\n if (value === undefined) return undefined;\n const match = /([0-9]+(?:\\.[0-9]+)?)\\s*(?:s|\u79D2)/iu.exec(value);\n if (match?.[1] === undefined) return undefined;\n const parsed = Number(match[1]);\n return Number.isFinite(parsed) && parsed > 0 ? parsed : undefined;\n}\n\nfunction splitReferences(value: string | undefined): string[] {\n if (value === undefined) return [];\n const ids = value.match(/(?:IMG|SHOT|MOTION)-[A-Z0-9-]+/giu) ?? [];\n return [...new Set(ids.map((id) => id.toLocaleUpperCase()))];\n}\n\nfunction inferAssetKind(value: string): DramaAssetKind {\n if (/(\u4EBA\u7269|\u89D2\u8272|\u9020\u578B|character|portrait|sheet)/iu.test(value)) return \"character\";\n if (/(\u5730\u70B9|\u573A\u666F|\u73AF\u5883|scene|location|corridor|room)/iu.test(value)) return \"scene\";\n if (/(\u9053\u5177|\u7269\u4EF6|prop|object)/iu.test(value)) return \"prop\";\n if (/(\u72B6\u6001|state|look)/iu.test(value)) return \"state\";\n return \"unknown\";\n}\n\nfunction slug(value: string): string {\n return value.trim().toLocaleUpperCase().replace(/[^\\p{Letter}\\p{Number}]+/gu, \"-\").replace(/^-|-$/gu, \"\") || \"ITEM\";\n}\n\nfunction lineAt(content: string, offset: number): number {\n return content.slice(0, Math.max(0, offset)).split(/\\r?\\n/u).length;\n}\n\n// Drama Skills 0.6.5 (#100): \u6765\u6E90 starts with a screenplay scene ID and may\n// continue with a short quote or further IDs joined by \u3001. The ID shape is the\n// one creator_markdown_check.py uses; the checker additionally requires the\n// field to *start* with an ID, which the workbench leaves to it \u2014 here an ID\n// anywhere in the field still navigates.\nexport function sourceSceneIds(source: string | undefined): string[] {\n if (source === undefined) return [];\n return [...new Set([...source.matchAll(/(?:[A-Za-z0-9]+-)+SC[0-9]+/gu)].map((match) => match[0]))];\n}\n\n/** Scene IDs to resolve; a \u6765\u6E90 naming no ID falls back to matching the whole field. */\nfunction sourceKeys(shot: DramaShot): readonly string[] {\n if (shot.sceneIds.length > 0) return shot.sceneIds;\n return shot.source === undefined ? [] : [shot.source];\n}\n\nfunction sectionTarget(path: string, content: string, id: string): DramaDocumentTarget | undefined {\n const offset = content.search(new RegExp(`^##\\\\s+${id.replace(/[.*+?^${}()|[\\]\\\\]/gu, \"\\\\$&\")}(?:\\\\s|$)`, \"imu\"));\n return offset < 0 ? undefined : { path, offset, id };\n}\n\nfunction creatorDocumentOrder(path: string): number {\n const name = path.split(\"/\").at(-1);\n return [\"\u5267\u672C.md\", \"\u89C6\u89C9\u8BBE\u5B9A.md\", \"\u5206\u955C.md\", \"\u56FE\u7247\u63D0\u793A\u8BCD.md\", \"\u89C6\u9891\u63D0\u793A\u8BCD.md\"].indexOf(name ?? \"\");\n}\n", "import { useCallback, useEffect, useMemo, useRef, useState, type KeyboardEvent as ReactKeyboardEvent, type PointerEvent as ReactPointerEvent } from \"react\";\n// Type-only: erased from the browser bundle, but a modality added to the host registry\n// without a label below becomes a type error instead of an unlabelled chip.\nimport type { DramaAdapterModality, DramaAdapterStatus } from \"../drama-adapters.js\";\nimport { productionCompleteness, type DramaDocumentTarget, type DramaEpisodeProduction, type DramaProductionSection } from \"./drama-production.js\";\nimport { endpoint } from \"./workbench-ui.js\";\nimport { nativeBatchPrompt, nativeCompositionPrompt, nativeProductionPrompt } from \"./production-prompts.js\";\nimport { activeProductionJobId, compositionInFlight, createPendingJob, mediaBelongsToEpisode, queuedItemForJob, reconcileProductionJobs, reconcileSequence, referencesForTarget, reorderSequence, sequenceIssues, sequenceSourceEligible, selectedVersionForTarget, type CanvasPoint, type ProductionJob, type ProductionMediaVersion, type ProductionQueueEntry, type ProductionSequenceItem } from \"./production-runtime.js\";\n\ninterface Props {\n readonly sessionId: string;\n readonly production: DramaEpisodeProduction;\n readonly sessionRunning: boolean;\n readonly queue: readonly ProductionQueueEntry[];\n readonly section: DramaProductionSection;\n readonly selectedId: string | undefined;\n readonly jobs: readonly ProductionJob[];\n readonly versions: readonly ProductionMediaVersion[];\n readonly libraryVersions: readonly ProductionMediaVersion[];\n readonly selections: Readonly<Record<string, string>>;\n readonly manualReferences: Readonly<Record<string, readonly string[]>>;\n readonly sequence: readonly ProductionSequenceItem[];\n readonly canvas: Readonly<Record<string, CanvasPoint>>;\n readonly zoom: number;\n readonly onSectionChange: (section: DramaProductionSection) => void;\n readonly onSelect: (id: string | undefined) => void;\n readonly onNavigate: (target: DramaDocumentTarget) => void;\n readonly onJobsChange: (jobs: ProductionJob[]) => void;\n readonly onSelectionsChange: (selections: Record<string, string>) => void;\n readonly onManualReferencesChange: (references: Record<string, string[]>) => void;\n readonly onOpenMedia: (path: string) => void;\n readonly onSequenceChange: (sequence: ProductionSequenceItem[]) => void;\n readonly onCanvasChange: (canvas: Record<string, CanvasPoint>) => void;\n readonly onZoomChange: (zoom: number) => void;\n readonly onDispatchPrompt: (prompt: string) => Promise<void>;\n readonly onCancelTurn: () => Promise<void>;\n readonly onRemoveQueued: (itemId: string) => Promise<void>;\n readonly onRefresh: () => void;\n}\n\nconst SECTION_LABELS: Readonly<Record<DramaProductionSection, string>> = { shots: \"\u955C\u5934\", assets: \"\u7D20\u6750\", tasks: \"\u4EFB\u52A1\", sequence: \"\u6210\u7247\", canvas: \"\u753B\u5E03\" };\nconst SECTION_ORDER = Object.keys(SECTION_LABELS) as DramaProductionSection[];\nconst STATUS_LABELS: Readonly<Record<ProductionJob[\"status\"], string>> = { 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\" };\nconst ASSET_KIND_LABEL = { character: \"\u4EBA\u7269\", scene: \"\u573A\u666F\", prop: \"\u9053\u5177\", state: \"\u72B6\u6001\", unknown: \"\u8BBE\u5B9A\" } as const;\nconst JOB_KIND_LABEL = { image: \"\u56FE\u7247\", video: \"\u89C6\u9891\", composition: \"\u6210\u7247\" } as const;\n/** Where `short-drama-edit` renders the assembled cut, relative to the episode directory. */\nconst ASSEMBLED_CUT_PATH = \"\u5236\u4F5C\u6210\u679C/\u6210\u7247/\u6210\u7247.mp4\";\n\n/** Mirror of the host `/oh-story/drama-preflight` summary: presence only, never values. */\ninterface DramaPreflight {\n readonly python: { readonly ok: boolean; readonly version?: string };\n readonly adapterConfig: { readonly path: string; readonly generated: boolean; readonly ok: boolean };\n readonly adapters: readonly DramaAdapterStatus[];\n}\n\nexport function compositionSources(\n production: DramaEpisodeProduction,\n sequence: readonly ProductionSequenceItem[],\n versions: readonly ProductionMediaVersion[]\n) {\n const versionById = new Map(versions.map((version) => [version.id, version]));\n const shotById = new Map(production.shots.map((shot) => [shot.id, shot]));\n return sequence.flatMap((item) => {\n const version = item.versionId === undefined ? undefined : versionById.get(item.versionId);\n const path = version?.path;\n if (version === undefined || path === undefined) return [];\n const shot = shotById.get(item.shotId);\n const sourceId = version.kind === \"video\"\n ? shot?.motion?.id ?? item.shotId\n : version.targetId.startsWith(\"IMG-\") ? version.targetId : item.shotId;\n return [{ shotId: item.shotId, sourceId, kind: version.kind, path, durationSeconds: shot?.durationSeconds }];\n });\n}\n\nconst MODALITY_LABEL: Readonly<Record<DramaAdapterModality, string>> = { image: \"\u56FE\u7247\", video: \"\u89C6\u9891\", tts: \"\u8BED\u97F3\", music: \"\u97F3\u4E50\" };\n\n/**\n * DeepSeek writes the prompts; the pictures, videos, speech and music come from\n * provider APIs that the produce Skill calls. Nothing in the conversation says so,\n * and the keys live in the host environment, so the \u751F\u4EA7 view states it up front.\n */\nfunction ProductionEnvironment({ sessionId }: { readonly sessionId: string }) {\n const [preflight, setPreflight] = useState<DramaPreflight | \"failed\">();\n const [attempt, setAttempt] = useState(0);\n // The summary is host-wide (the route ignores sessionId); the id only keeps\n // the URL shape shared with every other workbench endpoint.\n useEffect(() => {\n const controller = new AbortController();\n void fetch(endpoint(\"drama-preflight\", sessionId), { signal: controller.signal })\n .then(async (response) => {\n if (!response.ok) throw new Error(`HTTP ${String(response.status)}`);\n const summary = await response.json() as DramaPreflight;\n if (!controller.signal.aborted) setPreflight(summary);\n })\n .catch(() => { if (!controller.signal.aborted) setPreflight(\"failed\"); });\n return () => { controller.abort(); };\n }, [attempt, sessionId]);\n const unconfigured = typeof preflight === \"object\" ? preflight.adapters.filter((adapter) => !adapter.configured) : [];\n return <div className=\"oh-story-production-environment\" role=\"status\" aria-label=\"\u5A92\u4F53\u751F\u6210\u73AF\u5883\">\n <strong>\u751F\u6210\u73AF\u5883</strong>\n {preflight === undefined && <span data-pending>\u68C0\u67E5\u4E2D\u2026</span>}\n {preflight === \"failed\" && <button type=\"button\" onClick={() => { setPreflight(undefined); setAttempt((value) => value + 1); }}>\u73AF\u5883\u68C0\u67E5\u5931\u8D25 \u00B7 \u91CD\u8BD5</button>}\n {typeof preflight === \"object\" && <>\n <span data-ready={preflight.python.ok || undefined}>Python {preflight.python.version ?? \"\u672A\u627E\u5230\"}</span>\n {preflight.adapters.map((adapter) => <span key={adapter.name} data-ready={adapter.configured || undefined} title={adapter.configured ? `${adapter.name} \u5DF2\u914D\u7F6E` : `\u7F3A\u5C11\u73AF\u5883\u53D8\u91CF ${adapter.missing.join(\"\u3001\")}`}>{MODALITY_LABEL[adapter.modality]} {adapter.label}{adapter.configured ? \"\" : ` \u00B7 \u7F3A ${adapter.missing.join(\"\u3001\")}`}</span>)}\n <em>DeepSeek \u53EA\u8D1F\u8D23\u5199\u63D0\u793A\u8BCD\uFF1B\u56FE\u7247\u3001\u89C6\u9891\u3001\u8BED\u97F3\u3001\u97F3\u4E50\u7531\u4E0A\u9762\u7684\u4F9B\u5E94\u5546 API \u751F\u6210\uFF0CKey \u5728\u542F\u52A8 DSH \u524D\u5199\u5165\u5BBF\u4E3B\u673A\u73AF\u5883\u53D8\u91CF\u3002\n {unconfigured.length === preflight.adapters.length && \" \u5F53\u524D\u4E00\u4E2A\u90FD\u6CA1\u914D\u7F6E\uFF0C\u751F\u4EA7\u4EFB\u52A1\u4F1A\u505C\u5728 adapter \u4E4B\u524D\u3002\"}\n {\" \"}Adapter \u914D\u7F6E{preflight.adapterConfig.generated ? \"\u5DF2\u81EA\u52A8\u767B\u8BB0\" : \"\u4F7F\u7528\u81EA\u5B9A\u4E49\u6587\u4EF6\"}{preflight.adapterConfig.ok ? \"\" : \"\uFF08\u5199\u5165\u5931\u8D25\uFF09\"}\uFF1A<code>{preflight.adapterConfig.path}</code>\u3002\u8BE6\u89C1 README\u300C\u5A92\u4F53\u751F\u6210 API\u300D\u3002</em>\n </>}\n </div>;\n}\n\nfunction handleSectionKey(event: ReactKeyboardEvent<HTMLButtonElement>, current: DramaProductionSection, onChange: (section: DramaProductionSection) => void): void {\n const index = SECTION_ORDER.indexOf(current);\n const next = event.key === \"Home\" ? 0\n : event.key === \"End\" ? SECTION_ORDER.length - 1\n : event.key === \"ArrowRight\" ? (index + 1) % SECTION_ORDER.length\n : event.key === \"ArrowLeft\" ? (index - 1 + SECTION_ORDER.length) % SECTION_ORDER.length\n : undefined;\n if (next === undefined) return;\n event.preventDefault();\n onChange(SECTION_ORDER[next]!);\n event.currentTarget.parentElement?.querySelectorAll<HTMLButtonElement>(\"[role='tab']\")[next]?.focus();\n}\n\nexport function DramaProductionView(props: Props) {\n const [notice, setNotice] = useState<string>();\n const protocolErrors = props.production.diagnostics.filter((item) => item.severity === \"error\").length;\n const jobsRef = useRef(props.jobs);\n const commitJobs = useCallback((next: ProductionJob[]) => {\n jobsRef.current = next;\n props.onJobsChange(next);\n }, [props.onJobsChange]);\n useEffect(() => { jobsRef.current = props.jobs; }, [props.jobs]);\n\n useEffect(() => {\n const next = reconcileSequence(props.production.shots.map((shot) => shot.id), props.sequence, props.versions, props.selections, props.production.episodeDirectory);\n if (JSON.stringify(next) !== JSON.stringify(props.sequence)) props.onSequenceChange(next);\n }, [props.production.shots, props.selections, props.sequence, props.versions]);\n\n useEffect(() => {\n const next = reconcileProductionJobs(props.jobs, props.queue, props.sessionRunning, props.versions);\n if (JSON.stringify(next) !== JSON.stringify(props.jobs)) commitJobs(next);\n }, [commitJobs, props.jobs, props.queue, props.sessionRunning, props.versions]);\n\n const dispatchJob = async (job: ProductionJob, references: readonly ProductionMediaVersion[] = []) => {\n commitJobs([...jobsRef.current, { ...job, status: \"awaiting_confirmation\" }]);\n props.onSectionChange(\"tasks\");\n try {\n await props.onDispatchPrompt(nativeProductionPrompt(props.production, job, references));\n setNotice(`${job.targetId} \u6B63\u5728\u51C6\u5907\u5B8C\u6574\u9884\u68C0\uFF1B\u8BF7\u5728 Chat \u67E5\u770B\u5E76\u660E\u786E\u786E\u8BA4\u540E\u518D\u751F\u4EA7\u3002`);\n } catch (error) {\n commitJobs(jobsRef.current.map((item) => item.id === job.id ? { ...item, status: \"failed\", error: error instanceof Error ? error.message : String(error) } : item));\n }\n };\n\n const createJob = async (targetId: string, kind: \"image\" | \"video\", prompt: string) => {\n if (prompt.trim() === \"\") { setNotice(`${targetId} \u6CA1\u6709\u53EF\u6295\u4EA7\u63D0\u793A\u8BCD\u3002`); return; }\n const job = createPendingJob({ id: crypto.randomUUID(), targetId, kind, prompt });\n await dispatchJob(job, kind === \"video\" ? referencesForTarget(targetId, props.production, props.versions, props.selections, props.libraryVersions, props.manualReferences) : []);\n };\n\n const createBatch = async (kind: \"image\" | \"video\") => {\n const candidates = props.production.shots.flatMap((shot) => { const prompt = kind === \"image\" ? shot.keyframePrompt : shot.motion?.prompt; return prompt === undefined ? [] : [{ id: shot.id, prompt }]; });\n if (candidates.length === 0) { setNotice(kind === \"image\" ? \"\u6CA1\u6709\u53EF\u6295\u4EA7\u7684\u5173\u952E\u5E27\u63D0\u793A\u8BCD\u3002\" : \"\u6CA1\u6709\u53EF\u6295\u4EA7\u7684\u89C6\u9891\u63D0\u793A\u8BCD\u3002\"); return; }\n const job = createPendingJob({ id: crypto.randomUUID(), targetId: kind === \"image\" ? \"BATCH-KEYFRAMES\" : \"BATCH-VIDEOS\", kind, prompt: candidates.map((item) => `${item.id}\\n${item.prompt}`).join(\"\\n\\n\"), expectedOutputs: candidates.length });\n commitJobs([...jobsRef.current, { ...job, status: \"awaiting_confirmation\" }]); props.onSectionChange(\"tasks\");\n try { await props.onDispatchPrompt(nativeBatchPrompt(props.production, job, candidates)); setNotice(`${String(candidates.length)} \u4E2A\u955C\u5934\u6B63\u5728\u51C6\u5907\u540C\u4E00\u6279\u6B21\u9884\u68C0\uFF1B\u8BF7\u5728 Chat \u6838\u5BF9\u540E\u660E\u786E\u786E\u8BA4\u3002`); }\n catch (error) { commitJobs(jobsRef.current.map((item) => item.id === job.id ? { ...item, status: \"failed\", error: error instanceof Error ? error.message : String(error) } : item)); }\n };\n\n const dispatchComposition = async (job: ProductionJob) => {\n const ordered = compositionSources(props.production, props.sequence, props.versions);\n commitJobs([...jobsRef.current, job]); props.onSectionChange(\"tasks\");\n try { await props.onDispatchPrompt(nativeCompositionPrompt(props.production, job, ordered)); setNotice(\"\u6210\u7247\u4EFB\u52A1\u5DF2\u8FDB\u5165 DSH \u539F\u751F\u961F\u5217\uFF1B\u6587\u4EF6\u3001FFmpeg \u548C\u5199\u5165\u7EE7\u7EED\u53D7 DSH \u6743\u9650\u4E0E\u5BA1\u6279\u63A7\u5236\u3002\"); }\n catch (error) { commitJobs(jobsRef.current.map((item) => item.id === job.id ? { ...item, status: \"failed\", error: error instanceof Error ? error.message : String(error) } : item)); }\n };\n\n const cancelJob = async (job: ProductionJob) => {\n try { await props.onCancelTurn(); commitJobs(jobsRef.current.map((item) => item.id === job.id ? { ...item, status: \"canceled\", progress: 0 } : item)); setNotice(\"\u5DF2\u8BF7\u6C42\u505C\u6B62\u5F53\u524D DSH Turn\uFF1BDSH Queue \u4E2D\u7684\u5176\u4ED6\u4EFB\u52A1\u4F1A\u4FDD\u7559\u3002\"); }\n catch (error) { setNotice(error instanceof Error ? error.message : String(error)); }\n };\n const removeQueuedJob = async (job: ProductionJob, itemId: string) => {\n try { await props.onRemoveQueued(itemId); commitJobs(jobsRef.current.map((item) => item.id === job.id ? { ...item, status: \"canceled\", progress: 0 } : item)); setNotice(`${job.targetId} \u5DF2\u4ECE DSH Queue \u79FB\u9664\u3002`); }\n catch (error) { setNotice(error instanceof Error ? error.message : String(error)); }\n };\n const composeSequence = () => {\n const issues = sequenceIssues(props.sequence, props.versions, props.production.episodeDirectory);\n if (issues.length > 0) { setNotice(issues[0]); return; }\n // short-drama-edit renders to this fixed path, so the job correlates on the deliverable\n // rather than on a job id in the filename, and ignores a cut that was already there.\n const outputPath = `${props.production.episodeDirectory}/${ASSEMBLED_CUT_PATH}`;\n void dispatchComposition(createPendingJob({\n id: crypto.randomUUID(),\n targetId: props.production.episodeDirectory,\n kind: \"composition\",\n prompt: \"\u6309\u6210\u7247\u987A\u5E8F\u5408\u6210\",\n outputPath,\n supersededOutputIds: props.libraryVersions.flatMap((version) => version.path === outputPath ? [version.id] : [])\n }));\n };\n\n return <div className=\"oh-story-production\">\n <div className=\"oh-story-production-bar\"><div className=\"oh-story-production-tabs\" role=\"tablist\" aria-label=\"\u77ED\u5267\u751F\u4EA7\u89C6\u56FE\">{SECTION_ORDER.map((item) => <button type=\"button\" role=\"tab\" tabIndex={props.section === item ? 0 : -1} aria-selected={props.section === item} key={item} onKeyDown={(event) => { handleSectionKey(event, item, props.onSectionChange); }} onClick={() => { props.onSectionChange(item); }}>{SECTION_LABELS[item]}</button>)}</div><div className=\"oh-story-production-meta\"><span className=\"oh-story-production-summary\">{props.production.shots.length} \u955C \u00B7 {props.production.assets.length + props.production.visualAssets.length} \u7D20\u6750 \u00B7 {props.jobs.filter((job) => job.status === \"awaiting_confirmation\" || job.status === \"running\" || job.status === \"pending\").length} \u4EFB\u52A1</span><button type=\"button\" onClick={props.onRefresh}>\u5237\u65B0</button></div></div>\n <ProductionEnvironment sessionId={props.sessionId} />\n {notice !== undefined && <div className=\"oh-story-production-notice\" role=\"status\"><span>{notice}</span><button type=\"button\" aria-label=\"\u5173\u95ED\u63D0\u793A\" onClick={() => { setNotice(undefined); }}>\u00D7</button></div>}\n {props.production.diagnostics.length > 0 && <details className=\"oh-story-production-diagnostics\"><summary>{protocolErrors > 0 ? `${String(protocolErrors)} \u4E2A\u534F\u8BAE\u9519\u8BEF` : `${String(props.production.diagnostics.length)} \u4E2A\u683C\u5F0F\u63D0\u9192`}</summary><ul>{props.production.diagnostics.slice(0, 8).map((item) => <li data-severity={item.severity} key={`${item.path}:${String(item.offset)}:${item.code}`}><button type=\"button\" onClick={() => { props.onNavigate({ path: item.path, offset: item.offset, id: item.targetId ?? item.code }); }}>{item.path.split(\"/\").at(-1)}:{item.line}</button><span>{item.message}</span></li>)}</ul>{props.production.diagnostics.length > 8 && <p>\u53E6\u6709 {props.production.diagnostics.length - 8} \u9879\uFF0C\u8BF7\u6309\u6587\u6863\u4F4D\u7F6E\u4FEE\u590D\u3002</p>}</details>}\n {props.section === \"shots\" && <ShotBoard {...props} onCreateJob={createJob} onBatch={createBatch} />}\n {props.section === \"assets\" && <AssetBoard {...props} onCreateJob={createJob} />}\n {props.section === \"tasks\" && <TaskBoard jobs={props.jobs} queue={props.queue} sessionRunning={props.sessionRunning} onCancel={cancelJob} onRemoveQueued={removeQueuedJob} />}\n {props.section === \"sequence\" && <SequenceBoard {...props} episodeDirectory={props.production.episodeDirectory} onCompose={composeSequence} />}\n {props.section === \"canvas\" && <ProductionCanvas {...props} />}\n </div>;\n}\n\nfunction ShotBoard(props: Props & { readonly onCreateJob: (targetId: string, kind: \"image\" | \"video\", prompt: string) => Promise<void>; readonly onBatch: (kind: \"image\" | \"video\") => Promise<void> }) {\n const selectedRef = useScrollIntoView(props.selectedId);\n if (props.production.shots.length === 0) return <section className=\"oh-story-shot-board\"><MissingDocument document={`${props.production.episodeDirectory}/\u5206\u955C.md`} documentPaths={props.production.documentPaths} what=\"\u955C\u5934\" skill=\"/short-drama-storyboard\" onNavigate={props.onNavigate} /></section>;\n return <section className=\"oh-story-shot-board\"><div className=\"oh-story-production-actions\"><button type=\"button\" onClick={() => { void props.onBatch(\"image\"); }}>\u51C6\u5907\u6279\u91CF\u5173\u952E\u5E27</button><button type=\"button\" onClick={() => { void props.onBatch(\"video\"); }}>\u51C6\u5907\u6279\u91CF\u89C6\u9891</button></div><div className=\"oh-story-shot-grid\">{props.production.shots.map((shot) => {\n const completeness = productionCompleteness(shot); const versions = props.versions.filter((version) => version.targetId === shot.id); const selected = selectedVersionForTarget(shot.id, props.versions, props.selections, \"image\") ?? selectedVersionForTarget(shot.id, props.versions, props.selections, \"video\");\n return <article className=\"oh-story-shot-card\" role=\"button\" tabIndex={0} aria-pressed={props.selectedId === shot.id} aria-label={`\u9009\u4E2D\u955C\u5934 ${shot.id} ${shot.title}`} ref={props.selectedId === shot.id ? selectedRef : undefined} data-selected={props.selectedId === shot.id || undefined} key={shot.id} onKeyDown={(event) => { if (event.key === \"Enter\" || event.key === \" \") { event.preventDefault(); props.onSelect(shot.id); } }} onClick={() => { props.onSelect(shot.id); }}>\n {selected === undefined ? <div className=\"oh-story-shot-placeholder\"><strong>{shot.id.split(\"-\").at(-1)}</strong><span>\u7B49\u5F85\u5173\u952E\u5E27\u6210\u679C</span></div> : <MediaPreview version={selected} />}<header><button type=\"button\" onClick={(event) => { event.stopPropagation(); props.onNavigate({ path: shot.path, offset: shot.offset, id: shot.id }); }}>{shot.id}</button><span>{shot.durationSeconds === undefined ? \"\u2014\" : `${String(shot.durationSeconds)}s`}</span></header><h3>{shot.title}</h3>{shot.shotSpec !== undefined && <p>{shot.shotSpec}</p>}<dl><dt>\u8D77</dt><dd>{shot.start ?? \"\u672A\u586B\u5199\"}</dd><dt>\u7EC8</dt><dd>{shot.end ?? \"\u672A\u586B\u5199\"}</dd></dl>\n <div className=\"oh-story-shot-status\"><ReadinessBadge label=\"\u5173\u952E\u5E27\" ready={completeness.keyframe} /><ReadinessBadge label=\"\u8FD0\u52A8\" ready={completeness.motion} /><ReadinessBadge label=\"\u53C2\u8003\" ready={completeness.references} /><span>{versions.length} \u7248\u672C</span></div><div className=\"oh-story-reference-links\">{shot.sceneIds.length > 0 ? shot.sceneIds.map((sceneId) => <ReferenceButton key={sceneId} id={sceneId} production={props.production} onNavigate={props.onNavigate} />) : shot.source !== undefined && <ReferenceButton id={shot.source} production={props.production} onNavigate={props.onNavigate} />}{shot.references.map((id) => <ReferenceButton id={id} production={props.production} onNavigate={props.onNavigate} key={id} />)}</div>\n <div className=\"oh-story-card-actions\">{shot.keyframePrompt !== undefined && <button type=\"button\" onClick={(event) => { event.stopPropagation(); void props.onCreateJob(shot.id, \"image\", shot.keyframePrompt ?? \"\"); }}>\u51C6\u5907\u5173\u952E\u5E27</button>}{shot.motion?.prompt !== undefined && <button type=\"button\" onClick={(event) => { event.stopPropagation(); void props.onCreateJob(shot.id, \"video\", shot.motion?.prompt ?? \"\"); }}>\u51C6\u5907\u89C6\u9891</button>}</div>{versions.length > 1 && <VersionStrip targetId={shot.id} versions={versions} selections={props.selections} onSelectionsChange={props.onSelectionsChange} />}\n </article>;\n })}</div></section>;\n}\n\nfunction AssetBoard(props: Props & { readonly onCreateJob: (targetId: string, kind: \"image\" | \"video\", prompt: string) => Promise<void> }) {\n const [query, setQuery] = useState(\"\");\n const [kind, setKind] = useState<\"all\" | \"image\" | \"video\">(\"all\");\n const assets = [...props.production.assets, ...props.production.visualAssets.filter((visual) => !props.production.assets.some((asset) => asset.title === visual.title))];\n const needle = query.trim().toLocaleLowerCase();\n const library = props.libraryVersions.filter((version) => (kind === \"all\" || version.kind === kind) && (needle === \"\" || `${version.targetId} ${version.path ?? \"\"}`.toLocaleLowerCase().includes(needle)));\n const selectedRef = useScrollIntoView(props.selectedId);\n const referenceTarget = props.selectedId?.startsWith(\"SHOT-\") === true ? props.selectedId : undefined;\n const toggleReference = (versionId: string) => {\n if (referenceTarget === undefined) return;\n const current = props.manualReferences[referenceTarget] ?? [];\n const next = current.includes(versionId) ? current.filter((id) => id !== versionId) : [...current, versionId];\n const mutable = Object.fromEntries(Object.entries(props.manualReferences).map(([target, ids]) => [target, [...ids]]));\n props.onManualReferencesChange({ ...mutable, [referenceTarget]: next });\n };\n if (assets.length === 0 && props.libraryVersions.length === 0) return <section className=\"oh-story-assets\"><MissingDocument document={`${props.production.episodeDirectory}/\u56FE\u7247\u63D0\u793A\u8BCD.md`} documentPaths={props.production.documentPaths} what=\"\u7D20\u6750\" skill=\"/short-drama-image-prompts\" onNavigate={props.onNavigate} /></section>;\n return <section className=\"oh-story-assets\"><div className=\"oh-story-asset-grid\">{assets.map((asset) => { const prompt = \"prompt\" in asset ? asset.prompt : asset.description; const versions = props.versions.filter((version) => version.targetId === asset.id); const selected = selectedVersionForTarget(asset.id, props.versions, props.selections, \"image\"); return <article className=\"oh-story-asset-card\" ref={props.selectedId === asset.id ? selectedRef : undefined} data-selected={props.selectedId === asset.id || undefined} key={asset.id}>{selected === undefined ? <div className=\"oh-story-asset-placeholder\">{asset.kind === \"character\" ? \"\u4EBA\" : asset.kind === \"scene\" ? \"\u666F\" : asset.kind === \"prop\" ? \"\u7269\" : \"\u8BBE\"}</div> : <MediaPreview version={selected} />}<div><small>{ASSET_KIND_LABEL[asset.kind]}</small><h3>{asset.title}</h3><button type=\"button\" onClick={() => { props.onNavigate({ path: asset.path, offset: asset.offset, id: asset.id }); }}>{asset.id}</button></div>{prompt !== undefined && <p className=\"oh-story-asset-description\">{prompt}</p>}<div className=\"oh-story-card-actions\">{prompt !== undefined && <button type=\"button\" onClick={() => { void props.onCreateJob(asset.id, \"image\", prompt); }}>\u51C6\u5907\u7D20\u6750</button>}</div>{versions.length > 0 && <VersionStrip targetId={asset.id} versions={versions} selections={props.selections} onSelectionsChange={props.onSelectionsChange} />}</article>; })}</div><div className=\"oh-story-media-library\"><header><div><strong>\u9879\u76EE\u5A92\u4F53\u5E93</strong><span>{library.length}/{props.libraryVersions.length} \u9879 \u00B7 \u53EF\u8DE8\u96C6\u590D\u7528</span></div><div><input aria-label=\"\u641C\u7D22\u9879\u76EE\u5A92\u4F53\" value={query} placeholder=\"\u641C\u7D22 ID \u6216\u8DEF\u5F84\" onChange={(event) => { setQuery(event.target.value); }} /><select aria-label=\"\u7B5B\u9009\u5A92\u4F53\u7C7B\u578B\" value={kind} onChange={(event) => { setKind(event.target.value as typeof kind); }}><option value=\"all\">\u5168\u90E8</option><option value=\"image\">\u56FE\u7247</option><option value=\"video\">\u89C6\u9891</option></select></div></header><p className=\"oh-story-projection-note\">{referenceTarget === undefined ? \"\u5148\u5728\u955C\u5934\u9875\u9009\u4E2D\u4E00\u4E2A\u955C\u5934\uFF0C\u518D\u56DE\u5230\u8FD9\u91CC\u628A\u5DF2\u6709\u56FE\u7247\u8BBE\u4E3A\u8BE5\u955C\u5934\u7684\u8865\u5145\u53C2\u8003\u3002\" : `\u53EF\u628A\u4E0B\u9762\u7684\u56FE\u7247\u8BBE\u4E3A ${referenceTarget} \u7684\u8865\u5145\u53C2\u8003\u3002`}\u8865\u5145\u53C2\u8003\u53EA\u63D0\u793A Agent \u6838\u5BF9\uFF1B\u5199\u8FDB\u6765\u6E90\u6761\u76EE\u7684\u300C\u8F93\u5165\u53C2\u8003\u56FE\u300D\u540E\u624D\u4F1A\u9001\u8FDB\u751F\u4EA7\u3002</p><div className=\"oh-story-media-library-grid\">{library.map((version) => { const selected = referenceTarget !== undefined && (props.manualReferences[referenceTarget] ?? []).includes(version.id); return <article key={version.id}><MediaPreview version={version} /><strong>{version.targetId}</strong><span title={version.path}>{version.path}</span><footer>{version.path !== undefined && <button type=\"button\" onClick={() => { props.onOpenMedia(version.path!); }}>\u6253\u5F00\u6587\u4EF6</button>}{referenceTarget !== undefined && version.kind === \"image\" && <button type=\"button\" aria-pressed={selected} aria-label={`${selected ? \"\u53D6\u6D88\" : \"\u8BBE\u4E3A\"} ${referenceTarget} \u53C2\u8003 ${version.targetId}`} title=\"\u63D0\u793A Agent \u6838\u5BF9\uFF1B\u5199\u8FDB\u300C\u8F93\u5165\u53C2\u8003\u56FE\u300D\u540E\u624D\u4F1A\u9001\u8FDB\u751F\u4EA7\" onClick={() => { toggleReference(version.id); }}>{selected ? \"\u5DF2\u8BBE\u8865\u5145\u53C2\u8003\" : \"\u8BBE\u4E3A\u8865\u5145\u53C2\u8003\"}</button>}</footer></article>; })}</div></div></section>;\n}\n\nfunction TaskBoard({ jobs, queue, sessionRunning, onCancel, onRemoveQueued }: {\n readonly jobs: readonly ProductionJob[];\n readonly queue: readonly ProductionQueueEntry[];\n readonly sessionRunning: boolean;\n readonly onCancel: (job: ProductionJob) => Promise<void>;\n readonly onRemoveQueued: (job: ProductionJob, itemId: string) => Promise<void>;\n}) {\n const activeJobId = activeProductionJobId(jobs, queue, sessionRunning);\n return <section className=\"oh-story-task-board\">\n <div className=\"oh-story-projection-note\">\u56FE\u7247\u3001\u89C6\u9891\u3001\u8BED\u97F3\u3001\u97F3\u4E50\u90FD\u5148\u9884\u68C0\u3001\u540E\u786E\u8BA4\u3002\u8FD9\u91CC\u8DDF\u8E2A\u56FE\u7247\u3001\u89C6\u9891\u4E0E\u6210\u7247\u4EFB\u52A1\uFF1B\u8BED\u97F3\u548C\u97F3\u4E50\u5728 Chat \u91CC\u5B8C\u6210\uFF0C\u7ED3\u679C\u76F4\u63A5\u843D\u5728\u5236\u4F5C\u6210\u679C\u76EE\u5F55\u3002\u4F9B\u5E94\u5546\u89C1\u4E0A\u65B9\u300C\u751F\u6210\u73AF\u5883\u300D\uFF0C\u5B9E\u9645\u8D26\u53F7\u3001\u6A21\u578B\u4E0E\u53EF\u7528\u6027\u7531\u5F53\u524D DSH \u8FD0\u884C\u73AF\u5883\u51B3\u5B9A\u3002</div>\n {jobs.length === 0 ? <div className=\"oh-story-production-empty\">\u8FD8\u6CA1\u6709\u751F\u4EA7\u4EFB\u52A1\u3002\u53EF\u4ECE\u955C\u5934\u6216\u7D20\u6750\u9875\u63D0\u4EA4\u5355\u4E2A\u6216\u6279\u91CF\u4EFB\u52A1\u3002</div> : [...jobs].reverse().map((job) => {\n const queued = queuedItemForJob(job.id, queue);\n const displayStatus = queued === undefined ? STATUS_LABELS[job.status] : \"DSH Queue\";\n return <article key={job.id} data-job-id={job.id} data-status={job.status}><header><strong title={job.targetId}>{job.targetId}</strong><span>{JOB_KIND_LABEL[job.kind]}</span><span>{displayStatus}</span></header><div className=\"oh-story-task-progress\"><i style={{ width: `${String(job.progress)}%` }} /></div><details><summary>\u67E5\u770B\u6295\u4EA7\u63D0\u793A\u8BCD</summary><p>{job.prompt}</p></details>{job.expectedOutputs > 1 && <small>{job.completedOutputs}/{job.expectedOutputs} \u9879\u6210\u679C</small>}{job.error !== undefined && <div className=\"oh-story-error\">{job.error}</div>}{job.output !== undefined && <MediaPreview version={job.output} />}<footer>{queued !== undefined && (job.status === \"awaiting_confirmation\" || job.status === \"pending\" || job.status === \"running\") && <button type=\"button\" onClick={() => { void onRemoveQueued(job, queued.id); }}>\u4ECE DSH Queue \u79FB\u9664</button>}{activeJobId === job.id && <button type=\"button\" onClick={() => { void onCancel(job); }}>\u505C\u6B62\u5F53\u524D DSH Turn</button>}</footer></article>;\n })}\n </section>;\n}\n\nexport function SequenceBoard(props: Pick<Props, \"jobs\" | \"sequence\" | \"versions\" | \"onSequenceChange\"> & { readonly episodeDirectory?: string; readonly onCompose: () => void }) {\n const composing = compositionInFlight(props.jobs);\n const scopedVersions = props.versions.filter((version) => props.episodeDirectory === undefined || mediaBelongsToEpisode(version.path, props.episodeDirectory));\n const issues = sequenceIssues(props.sequence, scopedVersions, props.episodeDirectory); const versionById = new Map(scopedVersions.map((version) => [version.id, version])); const move = (index: number, delta: number) => { const source = props.sequence[index]; const target = props.sequence[index + delta]; if (source !== undefined && target !== undefined) props.onSequenceChange(reorderSequence(props.sequence, index, index + delta)); };\n const chooseSource = (shotId: string, sourceVersionId: string) => {\n props.onSequenceChange(props.sequence.map((item) => item.shotId !== shotId\n ? item\n : sourceVersionId === \"\" ? { shotId: item.shotId, versionId: item.versionId } : { ...item, sourceVersionId, versionId: sourceVersionId }));\n };\n return <section className=\"oh-story-sequence\"><div className=\"oh-story-sequence-summary\"><strong>{props.sequence.length} \u4E2A\u955C\u5934</strong><span>{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`}</span><button type=\"button\" disabled={composing || issues.length > 0 || props.sequence.length < 2} onClick={props.onCompose}>\u5408\u6210\u6210\u7247</button></div>{issues.length > 0 && <ul className=\"oh-story-sequence-issues\">{issues.slice(0, 3).map((issue) => <li key={issue}>{issue}</li>)}{issues.length > 3 && <li>\u53E6\u6709 {issues.length - 3} \u4E2A\u963B\u585E\u9879\uFF0C\u8BF7\u5728\u4E0B\u65B9\u955C\u5934\u884C\u8865\u9F50\u7D20\u6750\u3002</li>}</ul>}<ol>{props.sequence.map((item, index) => { const version = item.versionId === undefined ? undefined : versionById.get(item.versionId); const choices = scopedVersions.filter((candidate) => candidate.path !== undefined && sequenceSourceEligible(item.shotId, candidate)); const explicitMissing = item.sourceVersionId !== undefined && !choices.some((choice) => choice.id === item.sourceVersionId); return <li key={item.shotId}><span>{String(index + 1).padStart(2, \"0\")}</span>{version === undefined ? <div className=\"oh-story-sequence-missing\">\u7F3A\u5C11\u7D20\u6750</div> : <MediaPreview version={version} interactive={false} />}<strong>{item.shotId}</strong><div><select aria-label={`\u9009\u62E9 ${item.shotId} \u6210\u7247\u7D20\u6750`} value={item.sourceVersionId ?? \"\"} onChange={(event) => { chooseSource(item.shotId, event.target.value); }}><option value=\"\">\u81EA\u52A8\uFF08\u89C6\u9891\u4F18\u5148\uFF09</option>{explicitMissing && <option value={item.sourceVersionId} disabled>\u5DF2\u9009\u7D20\u6750\u4E0D\u53EF\u7528</option>}{choices.map((choice) => <option value={choice.id} key={choice.id}>{choice.targetId} \u00B7 {choice.kind === \"video\" ? \"\u89C6\u9891\" : \"\u9759\u5E27\"} \u00B7 {choice.path?.split(\"/\").at(-1)}</option>)}</select><button type=\"button\" aria-label={`\u4E0A\u79FB ${item.shotId}`} disabled={index === 0} onClick={() => { move(index, -1); }}>\u2191</button><button type=\"button\" aria-label={`\u4E0B\u79FB ${item.shotId}`} disabled={index === props.sequence.length - 1} onClick={() => { move(index, 1); }}>\u2193</button></div></li>; })}</ol></section>;\n}\n\nfunction ProductionCanvas(props: Props) {\n const nodes = useMemo(() => { const sourceAssets = [...props.production.assets, ...props.production.visualAssets]; const assets = sourceAssets.map((asset, index) => ({ id: asset.id, label: asset.title, type: \"asset\", initial: { x: 80, y: 80 + index * 150 } })); const shots = props.production.shots.map((shot, index) => ({ id: shot.id, label: shot.title, type: \"shot\", initial: { x: 640, y: 80 + index * 180 } })); return [...assets, ...shots]; }, [props.production.assets, props.production.shots, props.production.visualAssets]);\n const positions = Object.fromEntries(nodes.map((node) => [node.id, props.canvas[node.id] ?? node.initial]));\n const startDrag = (event: ReactPointerEvent<HTMLElement>, id: string) => { event.currentTarget.setPointerCapture(event.pointerId); const origin = positions[id] ?? { x: 0, y: 0 }; const start = { x: event.clientX, y: event.clientY }; const move = (moveEvent: PointerEvent) => { props.onCanvasChange({ ...props.canvas, [id]: { x: origin.x + (moveEvent.clientX - start.x) / props.zoom, y: origin.y + (moveEvent.clientY - start.y) / props.zoom } }); }; const end = () => { globalThis.removeEventListener(\"pointermove\", move); globalThis.removeEventListener(\"pointerup\", end); }; globalThis.addEventListener(\"pointermove\", move); globalThis.addEventListener(\"pointerup\", end); };\n const moveNode = (id: string, x: number, y: number) => { const origin = positions[id] ?? { x: 0, y: 0 }; props.onCanvasChange({ ...props.canvas, [id]: { x: origin.x + x, y: origin.y + y } }); };\n const connections = props.production.shots.flatMap((shot) => shot.references.map((reference) => [reference, shot.id] as const));\n if (nodes.length === 0) return <section className=\"oh-story-canvas-shell\" aria-label=\"\u77ED\u5267\u7D20\u6750\u4E0E\u955C\u5934\u5173\u7CFB\u753B\u5E03\"><MissingDocument document={`${props.production.episodeDirectory}/\u5206\u955C.md`} documentPaths={props.production.documentPaths} what=\"\u5173\u7CFB\" skill=\"/short-drama-storyboard\" onNavigate={props.onNavigate} /></section>;\n return <section className=\"oh-story-canvas-shell\" aria-label=\"\u77ED\u5267\u7D20\u6750\u4E0E\u955C\u5934\u5173\u7CFB\u753B\u5E03\"><div className=\"oh-story-projection-note\">\u6587\u6863\u5173\u7CFB \u00B7 \u5E03\u5C40\u4EC5\u4FDD\u5B58\u5728\u5F53\u524D DSH Session</div><div className=\"oh-story-canvas-controls\"><button type=\"button\" aria-label=\"\u7F29\u5C0F\u753B\u5E03\" onClick={() => { props.onZoomChange(Math.max(.5, props.zoom - .1)); }}>\u2212</button><span>{Math.round(props.zoom * 100)}%</span><button type=\"button\" aria-label=\"\u653E\u5927\u753B\u5E03\" onClick={() => { props.onZoomChange(Math.min(1.8, props.zoom + .1)); }}>\uFF0B</button><button type=\"button\" onClick={() => { props.onCanvasChange({}); props.onZoomChange(.65); }}>\u590D\u4F4D</button></div><div className=\"oh-story-canvas-viewport\"><div className=\"oh-story-canvas\" style={{ transform: `scale(${String(props.zoom)})` }}><svg aria-hidden=\"true\">{connections.map(([from, to]) => { const a = positions[from]; const b = positions[to]; if (a === undefined || b === undefined) return null; return <path key={`${from}:${to}`} data-active={to === props.selectedId || undefined} d={`M ${String(a.x + 180)} ${String(a.y + 50)} C ${String(a.x + 360)} ${String(a.y + 50)}, ${String(b.x - 180)} ${String(b.y + 50)}, ${String(b.x)} ${String(b.y + 50)}`} />; })}</svg>{nodes.map((node) => <article key={node.id} tabIndex={0} aria-label={`${node.type === \"asset\" ? \"\u7D20\u6750\" : \"\u955C\u5934\"} ${node.label}`} data-node-type={node.type} data-selected={node.id === props.selectedId || undefined} style={{ left: positions[node.id]?.x, top: positions[node.id]?.y }} onKeyDown={(event) => { const step = event.shiftKey ? 40 : 10; const delta: readonly [number, number] | undefined = event.key === \"ArrowLeft\" ? [-step, 0] : event.key === \"ArrowRight\" ? [step, 0] : event.key === \"ArrowUp\" ? [0, -step] : event.key === \"ArrowDown\" ? [0, step] : undefined; if (delta !== undefined) { event.preventDefault(); moveNode(node.id, delta[0], delta[1]); } }} onPointerDown={(event) => { startDrag(event, node.id); }} onDoubleClick={() => { const target = props.production.targets.get(node.id); if (target !== undefined) props.onNavigate(target); }}><small>{node.type === \"asset\" ? \"\u7D20\u6750\" : \"\u955C\u5934\"}</small><strong>{node.label}</strong><span>{node.id}</span></article>)}</div></div></section>;\n}\n\n/** Scroll the card an Agent focus_target selected into view; without it the tab switches but the card stays off-screen. */\nfunction useScrollIntoView(selectedId: string | undefined) {\n const ref = useRef<HTMLElement | null>(null);\n useEffect(() => { ref.current?.scrollIntoView({ block: \"nearest\" }); }, [selectedId]);\n return ref;\n}\n\nfunction ReadinessBadge({ label, ready }: { readonly label: string; readonly ready: boolean }) {\n return <span data-ready={ready} aria-label={`${label}${ready ? \"\u5DF2\u5907\" : \"\u5F85\u8865\"}`}><i aria-hidden=\"true\">{ready ? \"\u2713\" : \"\u2014\"}</i>{label}</span>;\n}\n\nfunction MissingDocument({ document, documentPaths, what, skill, onNavigate }: {\n readonly document: string;\n readonly documentPaths: readonly string[];\n readonly what: string;\n readonly skill: string;\n readonly onNavigate: (target: DramaDocumentTarget) => void;\n}) {\n const present = documentPaths.includes(document);\n return <div className=\"oh-story-production-empty\">\n <strong>\u8FD8\u6CA1\u6709\u53EF\u6295\u5F71\u7684{what}\u3002</strong>\n <p>{present\n ? `${document} \u5DF2\u5B58\u5728\uFF0C\u4F46\u6CA1\u6709\u89E3\u6790\u51FA\u6761\u76EE\u3002\u8BF7\u68C0\u67E5\u4E8C\u7EA7\u6807\u9898\u662F\u5426\u4E3A\u7A33\u5B9A\u7684 ID \u5F62\u5F0F\u3002`\n : `\u672C\u96C6\u8FD8\u6CA1\u6709 ${document}\u3002\u5728\u53F3\u4FA7 Chat \u7528 ${skill} \u5199\u597D\u8FD9\u4EFD\u6587\u6863\u540E\uFF0C\u8FD9\u91CC\u4F1A\u81EA\u52A8\u51FA\u73B0\u3002`}</p>\n {present && <button type=\"button\" onClick={() => { onNavigate({ path: document, offset: 0, id: document }); }}>\u6253\u5F00 {document.split(\"/\").at(-1)}</button>}\n </div>;\n}\n\nfunction ReferenceButton({ id, production, onNavigate }: { readonly id: string; readonly production: DramaEpisodeProduction; readonly onNavigate: (target: DramaDocumentTarget) => void }) { const target = production.targets.get(id); return <button type=\"button\" disabled={target === undefined} onClick={(event) => { event.stopPropagation(); if (target !== undefined) onNavigate(target); }}>{id}</button>; }\nfunction MediaPreview({ version, interactive = true }: { readonly version: ProductionMediaVersion; readonly interactive?: boolean }) { return version.kind === \"image\" ? <img className=\"oh-story-media-preview\" src={version.url} alt={version.targetId} loading=\"lazy\" /> : <video className=\"oh-story-media-preview\" src={version.url} controls={interactive} muted={!interactive} preload=\"metadata\" />; }\nfunction VersionStrip({ targetId, versions, selections, onSelectionsChange }: { readonly targetId: string; readonly versions: readonly ProductionMediaVersion[]; readonly selections: Readonly<Record<string, string>>; readonly onSelectionsChange: (value: Record<string, string>) => void }) { const selected = selectedVersionForTarget(targetId, versions, selections)?.id; return <div className=\"oh-story-version-strip\" aria-label={`${targetId} \u6210\u679C\u7248\u672C`}>{versions.map((version, index) => <button type=\"button\" aria-pressed={version.id === selected} aria-label={`\u9009\u62E9 ${targetId} \u7248\u672C ${String(index + 1)}`} data-selected={version.id === selected || undefined} key={version.id} onClick={(event) => { event.stopPropagation(); onSelectionsChange({ ...selections, [targetId]: version.id }); }}><MediaPreview version={version} interactive={false} /><span>V{String(index + 1)}</span></button>)}</div>; }\n", "import type { KeyboardEvent as ReactKeyboardEvent } from \"react\";\n\n/** Roving-focus keyboard contract shared by every workbench tablist. */\nexport function handleTabKey<T extends string>(\n event: ReactKeyboardEvent<HTMLButtonElement>,\n values: readonly T[],\n current: T,\n select: (value: T) => void\n): void {\n let index: number | undefined;\n if (event.key === \"Home\") index = 0;\n else if (event.key === \"End\") index = values.length - 1;\n else if (event.key === \"ArrowRight\") index = (values.indexOf(current) + 1) % values.length;\n else if (event.key === \"ArrowLeft\") index = (values.indexOf(current) - 1 + values.length) % values.length;\n if (index === undefined) return;\n event.preventDefault();\n const value = values[index];\n if (value === undefined) return;\n select(value);\n event.currentTarget.parentElement?.querySelectorAll<HTMLButtonElement>(\"[role='tab']\")[index]?.focus();\n}\n\nexport function endpoint(path: string, sessionId: string, file?: string): string {\n const url = new URL(`/oh-story/${path}`, globalThis.location.origin);\n url.searchParams.set(\"sessionId\", sessionId);\n if (file !== undefined) url.searchParams.set(\"path\", file);\n return url.toString();\n}\n", "import type { DramaEpisodeProduction } from \"./drama-production.js\";\nimport type { ProductionJob, ProductionMediaVersion } from \"./production-runtime.js\";\n\nconst authorityBoundary = \"\u53EA\u4F7F\u7528\u5F53\u524D DSH Preset \u53EF\u89C1\u7684\u5DE5\u5177\uFF1B\u6240\u6709\u6587\u4EF6\u3001\u7F51\u7EDC\u3001\u751F\u6210\u548C\u547D\u4EE4\u64CD\u4F5C\u7EE7\u7EED\u9075\u5B88 DSH \u6743\u9650\u4E0E\u5BA1\u6279\u3002\";\n\n/**\n * The listed references are what the workbench can see, not what the job sends: upstream\n * `prepare` requires `reference_bindings` to equal the source entry's own declaration slot for\n * slot, and a frame's role comes from the \u7528\u9014 that entry's \u8F93\u5165\u53C2\u8003\u56FE records (\u5206\u955C.md for SHOT-*,\n * \u89C6\u9891\u63D0\u793A\u8BCD.md for MOTION-*), never from this list. How a \u7ED3\u675F\u5E27 travels depends on the dialect:\n * frame positions keep it in last_frame, but MiniMax H3 cannot mix frame and reference inputs, so a\n * mixed group goes out whole as full-reference reference_image (upstream minimax-h3.md, and\n * target-model-profile.md \u53C2\u8003\u6761\u4EF6\u65B9\u5F0F).\n */\nconst referenceRules = \"\u53C2\u8003\u8F93\u5165\u4EE5\u6765\u6E90\u6761\u76EE\u81EA\u5DF1\u7684\u58F0\u660E\u4E3A\u51C6\uFF08IMG-* \u7684\u300C\u53C2\u8003\u300D\uFF0CSHOT-*\uFF0FMOTION-* \u7684\u300C\u8F93\u5165\u53C2\u8003\u56FE\u300D\uFF0C\u4EE5\u53CA MOTION-* \u72EC\u7ACB\u7684\u300C\u53C2\u8003\u97F3\u9891\u300D\uFF09\uFF1Areference_bindings \u5FC5\u987B\u4E0E\u8BE5\u6761\u76EE\u9010\u69FD\u4E00\u81F4\uFF0C\u5DE5\u4F5C\u53F0\u5217\u51FA\u7684\u8865\u5145\u53C2\u8003\u53EA\u4F5C\u6838\u5BF9\uFF0C\u6761\u76EE\u91CC\u6CA1\u6709\u58F0\u660E\u7684\u4E0D\u8981\u76F4\u63A5\u52A0\u8FDB job\uFF0C\u786E\u9700\u4F7F\u7528\u65F6\u5148\u8BF7\u62E5\u6709\u8BE5\u6761\u76EE\u7684\u9636\u6BB5\u4FEE\u8BA2\u6587\u6863\u3002\u8D77\u59CB\u5E27\u4E0E\u7ED3\u675F\u5E27\u7684\u89D2\u8272\u53EA\u53D6\u81EA\u6765\u6E90\u6761\u76EE\u81EA\u5DF1\u300C\u8F93\u5165\u53C2\u8003\u56FE\u300D\u5404\u69FD\u4F4D\u8BB0\u5F55\u7684\u7528\u9014\uFF08\u8D77\u59CB\u5E27\uFF0F\u7ED3\u675F\u5E27\uFF09\uFF1ASHOT-* \u770B\u300A\u5206\u955C.md\u300B\uFF0CMOTION-* \u770B\u300A\u89C6\u9891\u63D0\u793A\u8BCD.md\u300B\uFF1B\u518D\u7531\u76EE\u6807\u6A21\u578B\u65B9\u8A00\u7FFB\u6210 adapter \u7684 role\uFF0C\u4E0D\u6309\u6587\u4EF6\u540D\u6216\u5DE5\u4F5C\u53F0\u6E05\u5355\u63A8\u65AD\u3002\u76EE\u6807\u65B9\u8A00\u7528 first_frame\uFF0Flast_frame \u4F4D\u7F6E\u627F\u63A5\u8FD9\u7EC4\u8F93\u5165\u65F6\uFF0C\u7ED3\u675F\u5E27\u53EA\u8FDB last_frame\uFF0C\u7EDD\u4E0D\u964D\u7EA7\u6210\u666E\u901A\u53C2\u8003\u56FE\uFF1B\u65B9\u8A00\u8981\u6C42\u6574\u7EC4\u8D70\u591A\u69FD\u53C2\u8003\u65F6\uFF08\u5982 MiniMax H3 \u7684 full-reference\uFF1A\u9996\u5C3E\u5E27\u8F93\u5165\u4E0E\u53C2\u8003\u8F93\u5165\u4E92\u65A5\uFF0C\u8D77\u59CB\u5E27\u3001\u7ED3\u675F\u5E27\u90FD\u968F\u6574\u7EC4\u4EE5 reference_image \u9001\u5165\uFF09\uFF0C\u6309\u65B9\u8A00\u7FFB\u8BD1\uFF0C\u5E76\u5728\u9884\u89C8\u91CC\u5199\u660E\u7ED3\u675F\u5E27\u5C06\u4F5C\u4E3A\u53C2\u8003\u56FE\u9001\u5165\uFF0C\u6216\u5148\u8BF7\u5206\u955C owner \u53D6\u820D\u3002MOTION-* \u7684\u300C\u53C2\u8003\u97F3\u9891\u300D\u4E0D\u6DF7\u5165\u300C\u8F93\u5165\u53C2\u8003\u56FE\u300D\uFF1A\u5B83\u6392\u5728\u56FE\u7247 binding \u4E4B\u540E\uFF0Crole \u56FA\u5B9A\u4E3A reference_audio\uFF0Ccharacter \u9010\u5B57\u7167\u6284\u8BE5\u884C\u300C\u89D2\u8272\u300D\uFF0C\u97F3\u9891\u987A\u5E8F\u4ECD\u72EC\u7ACB\u4ECE 1 \u7F16\u53F7\uFF1Badapter profile \u672A\u663E\u5F0F\u58F0\u660E\u652F\u6301 reference_audio \u65F6\u5FC5\u987B\u5728\u63D0\u4EA4\u524D\u5931\u8D25\uFF0C\u4E0D\u80FD\u9759\u9ED8\u4E22\u5F03\u6216\u628A\u97F3\u9891\u5F53\u56FE\u7247\u3002\";\n/** Upstream's SHOT-* selector extracts only the start frame, so the note belongs to image jobs alone. */\nconst shotStartFrameNote = \"\u5206\u955C.md \u7684 SHOT-* \u53EA\u4EA7\u51FA\u8D77\u59CB\u5E27\uFF1B\u8981\u4EA7\u51FA\u7ED3\u675F\u5E27\uFF0C\u5148\u7531\u56FE\u7247\u63D0\u793A\u8BCD\u9636\u6BB5\u5EFA\u7ACB\u72EC\u7ACB\u7684 IMG-* \u6761\u76EE\u518D\u6295\u4EA7\u3002\";\n\nfunction referenceParagraph(kind: ProductionJob[\"kind\"]): string {\n return kind === \"image\" ? `${referenceRules}${shotStartFrameNote}` : referenceRules;\n}\n\nexport function nativeProductionPrompt(\n production: DramaEpisodeProduction,\n job: ProductionJob,\n references: readonly ProductionMediaVersion[]\n): string {\n const referenceText = references.length === 0\n ? \"\u65E0\"\n : references.map((item) => `${item.targetId}: ${item.path ?? item.url}`).join(\"\\n\");\n return `/short-drama-produce\n\n\u53EA\u51C6\u5907\u5F53\u524D\u5355\u9879\u751F\u4EA7\u4EFB\u52A1\uFF0C\u4E0D\u8FD0\u884C Provider\u3002\n- \u4EFB\u52A1 ID\uFF1A${job.id}\n- \u4EFB\u52A1\u7C7B\u578B\uFF1A${job.kind === \"image\" ? \"\u56FE\u7247/\u5173\u952E\u5E27\" : \"\u955C\u5934\u89C6\u9891\"}\n- \u5EFA\u8BAE adapter \u5951\u7EA6\uFF1A${job.kind === \"image\" ? \"gpt-image-2\" : \"seedance\"}\uFF08\u5B9E\u9645\u914D\u7F6E\u4E0E\u6A21\u578B\u4EE5\u5F53\u524D DSH \u8FD0\u884C\u73AF\u5883\u4E3A\u51C6\uFF09\n- \u6295\u4EA7\u5BF9\u8C61\uFF1A${job.targetId}\n- \u521B\u4F5C\u6587\u6863\u76EE\u5F55\uFF1A${production.episodeDirectory}\n- \u5DE5\u4F5C\u53F0\u5217\u51FA\u7684\u8865\u5145\u53C2\u8003\uFF08\u4E0D\u662F\u751F\u4EA7\u8F93\u5165\u5FEB\u7167\uFF09\uFF1A\n${referenceText}\n- \u8F93\u51FA\u76EE\u5F55\uFF1A${production.episodeDirectory}/\u5236\u4F5C\u6210\u679C/${job.targetId}\n- \u8F93\u51FA\u6587\u4EF6\u540D\u5FC5\u987B\u540C\u65F6\u5305\u542B\u6295\u4EA7\u5BF9\u8C61 ID \u4E0E\u4EFB\u52A1 ID ${job.id}\uFF0C\u4EE5\u4FBF DSH \u5DE5\u4F5C\u53F0\u5173\u8054\u7248\u672C\u3002\n\n\u5F85\u9884\u68C0\u63D0\u793A\u8BCD\uFF1A\n${job.prompt}\n\n${referenceParagraph(job.kind)}\n\n\u6309 short-drama-produce \u7684\u786C\u95F8\u95E8\u5EFA\u7ACB\u4E34\u65F6 job \u5E76\u6267\u884C prepare\uFF0C\u5728 Chat \u4E2D\u5B8C\u6574\u5C55\u793A adapter\u3001\u6A21\u578B/profile\u3001\u6570\u91CF\u3001\u53C2\u6570\u3001references\u3001outputs \u4E0E overwrite\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\u4EFB\u52A1 ID\uFF0C\u5E76\u8FD0\u884C Provider\u3002${authorityBoundary}`;\n}\n\nexport function nativeBatchPrompt(\n production: DramaEpisodeProduction,\n job: ProductionJob,\n candidates: readonly { readonly id: string; readonly prompt: string }[]\n): string {\n return `/short-drama-produce\n\n\u53EA\u51C6\u5907\u5F53\u524D\u6279\u91CF\u751F\u4EA7\u4EFB\u52A1\uFF0C\u4E0D\u8FD0\u884C Provider\u3002\n- \u6279\u6B21\u4EFB\u52A1 ID\uFF1A${job.id}\n- \u4EFB\u52A1\u7C7B\u578B\uFF1A${job.kind === \"image\" ? \"\u6279\u91CF\u5173\u952E\u5E27\" : \"\u6279\u91CF\u955C\u5934\u89C6\u9891\"}\n- \u5EFA\u8BAE adapter \u5951\u7EA6\uFF1A${job.kind === \"image\" ? \"gpt-image-2\" : \"seedance\"}\uFF08\u5B9E\u9645\u914D\u7F6E\u4E0E\u6A21\u578B\u4EE5\u5F53\u524D DSH \u8FD0\u884C\u73AF\u5883\u4E3A\u51C6\uFF09\n- \u521B\u4F5C\u6587\u6863\u76EE\u5F55\uFF1A${production.episodeDirectory}\n- \u8F93\u51FA\u6839\u76EE\u5F55\uFF1A${production.episodeDirectory}/\u5236\u4F5C\u6210\u679C\n- \u6BCF\u4E2A\u8F93\u51FA\u6587\u4EF6\u540D\u5FC5\u987B\u5305\u542B\u5BF9\u5E94\u955C\u5934 ID \u4E0E\u6279\u6B21\u4EFB\u52A1 ID ${job.id}\u3002\n\n${candidates.map((item) => `## ${item.id}\\n${item.prompt}`).join(\"\\n\\n\")}\n\n${referenceParagraph(job.kind)}\n\n\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}`;\n}\n\n/**\n * Upstream's edit stage owns only the \u526A\u8F91\u5355 CUT items, the delivery spec, and what it writes under\n * \u5236\u4F5C\u6210\u679C/\u6210\u7247/ (short-drama-edit stage-contract.md). Normalised clips therefore go to \u6210\u7247/\u89C4\u683C\u7EDF\u4E00/,\n * which mediaTargetFromPath keeps out of the shot versions, and carry no job id that could correlate\n * them with a production job. An external mix ends with the loudnorm pass render itself runs\n * (edit_tool.py `_loudnorm_filter`, then AAC 192k at 48 kHz).\n */\nexport function nativeCompositionPrompt(\n production: DramaEpisodeProduction,\n job: ProductionJob,\n orderedSources: readonly {\n readonly shotId: string;\n readonly sourceId: string;\n readonly kind: ProductionMediaVersion[\"kind\"];\n readonly path: string;\n readonly durationSeconds?: number | undefined;\n }[]\n): string {\n return `/short-drama-edit\n\n\u6267\u884C\u521B\u4F5C\u8005\u5DF2\u660E\u786E\u786E\u8BA4\u7684\u6210\u7247\u88C5\u914D\u4EFB\u52A1\u3002\n- \u4EFB\u52A1 ID\uFF1A${job.id}\n- \u5267\u96C6\uFF1A${production.episodeDirectory}\n- \u521B\u4F5C\u8005\u5728\u6210\u7247\u89C6\u56FE\u6392\u5B9A\u7684\u955C\u5E8F\u4E0E\u5B9E\u9645\u6765\u6E90\uFF08\u81EA\u52A8\u6A21\u5F0F\u5DF2\u6309\u89C6\u9891\u4F18\u5148\u89E3\u6790\uFF1B\u663E\u5F0F\u9009\u6E90\u4F18\u5148\u4E8E\u81EA\u52A8\u7ED3\u679C\uFF09\uFF0C\u4E0D\u5F97\u81EA\u884C\u6362\u5E8F\u6216\u66FF\u6362\uFF1A\n${orderedSources.map((source, index) => `${String(index + 1)}. ${source.shotId} \u2192 ${source.sourceId} \u00B7 ${source.kind === \"video\" ? \"\u89C6\u9891\" : \"\u9759\u5E27\"} \u00B7 ${source.path}${source.kind === \"image\" ? ` \u00B7 \u5206\u955C\u65F6\u957F ${source.durationSeconds === undefined ? \"\u672A\u586B\u5199\" : `${String(source.durationSeconds)} \u79D2`}` : \"\"}`).join(\"\\n\")}\n- \u526A\u8F91\u5355\uFF1A${production.episodeDirectory}/\u526A\u8F91\u5355.md\n- \u8F93\u51FA\uFF1A${production.episodeDirectory}/\u5236\u4F5C\u6210\u679C/\u6210\u7247/\n\n\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\u4E0A\u9762\u6807\u4E3A\u89C6\u9891\u7684\u6765\u6E90\u4F7F\u7528\u5BF9\u5E94 MOTION-*\uFF0C\u6807\u4E3A\u9759\u5E27\u7684\u6765\u6E90\u9010\u5B57\u4F7F\u7528\u7ED9\u51FA\u7684 SHOT-* \u6216 IMG-*\uFF1B\u9759\u5E27\u4EE5\u5217\u51FA\u7684\u5206\u955C\u65F6\u957F\u4E3A\u8D77\u70B9\uFF0C\u4F46\u82E5\u5DF2\u6709\u914D\u97F3\uFF0C\u987B\u5148\u91CF\u51FA\u771F\u5B9E\u6709\u58F0\u533A\u95F4\u5E76\u636E\u6B64\u6392\u65F6\u957F\uFF0C\u4E0D\u80FD\u622A\u65AD\u53F0\u8BCD\u3002\u526A\u8F91\u5355\u8BB0\u5F55\u7D20\u6750\u53D6\u820D\u3001\u5165\u51FA\u70B9\u3001\u540E\u671F\u5904\u7406\u4E0E\u4EA4\u4ED8\u89C4\u683C\uFF0C\u4E0D\u6539\u5199\u5267\u672C\u3001\u5206\u955C\u6216\u89C6\u9891\u63D0\u793A\u8BCD\u7684\u8BED\u4E49\uFF1B\u4E0D\u8981\u9000\u56DE\u53BB\u751F\u6210\u65B0\u7D20\u6750\u3002\n\n\u6309\u5F53\u524D\u5236\u4F5C\u5F62\u6001\u4E3A\u6BCF\u4E00\u955C\u4EA4\u4EE3\u4E0B\u843D\uFF1A\u89C6\u9891\u6BB5\u6765\u6E90\u5199 MOTION-*\uFF1B\u9759\u5E27\u6BB5\u6765\u6E90\u5199\u5206\u955C\u91CC\u7684 SHOT-* \u6216\u56FE\u7247\u63D0\u793A\u8BCD\u91CC\u7684 IMG-*\uFF0C\u4E0D\u5F97\u56E0\u4E3A\u7701\u94B1\u3001\u5931\u8D25\u6216\u6392\u961F\u81EA\u884C\u628A\u89C6\u9891\u6539\u6210\u9759\u5E27\u3002\u5B58\u5728 SHOT-* \u9759\u5E27\u65F6\uFF0C\u5206\u955C\u91CC\u7684\u6BCF\u955C\u5FC5\u987B\u5165\u7247\u6216\u5217\u5165\u300C\u672A\u91C7\u7528\u955C\u5934\u300D\uFF1B\u5B58\u5728\u89C6\u9891\u6BB5\u65F6\uFF0C\u89C6\u9891\u63D0\u793A\u8BCD\u91CC\u7684\u6BCF\u4E2A MOTION-* \u4E5F\u5FC5\u987B\u5165\u7247\u6216\u8BF4\u660E\u672A\u91C7\u7528\u3002\u89C6\u9891\u4E0E\u9759\u5E27\u6DF7\u526A\u65F6\uFF0C\u540C\u4E00\u955C\u7528\u4E86 SHOT-* \u53EF\u540C\u65F6\u8986\u76D6\u5BF9\u5E94 MOTION-*\uFF0C\u7528\u4E86 MOTION-* \u53EF\u540C\u65F6\u8986\u76D6\u5BF9\u5E94 SHOT-*\u3002\u672A\u91C7\u7528\u9879\u5199\u8FDB\u526A\u8F91\u5355\u5F00\u5934\uFF08\u4EA4\u4ED8\u89C4\u683C\u6240\u5728\u5904\u3001\u7B2C\u4E00\u4E2A\u300C## CUT-\u300D\u4E4B\u524D\uFF09\u7684\u4E00\u884C\uFF1A\u300C- \u672A\u91C7\u7528\u955C\u5934\uFF1AMOTION-\u2026\uFF08\u7406\u7531\uFF1A\u6587\u4EF6\u7F3A\u5931\u2014\u2014\u2026\uFF09\uFF1BSHOT-\u2026\uFF08\u7406\u7531\uFF1A\u8D28\u91CF\u4E0D\u53EF\u7528\u2014\u2014\u2026\uFF09\u300D\u3002\u591A\u9879\u7528\u5168\u89D2\u300C\uFF1B\u300D\u8FDE\u63A5\uFF0C\u7406\u7531\u4E0D\u80FD\u4E3A\u7A7A\u3001\u81EA\u8EAB\u4E0D\u542B\u300C\uFF1B\u300D\uFF0C\u5E76\u5199\u660E\u5C5E\u4E8E\u6587\u4EF6\u7F3A\u5931\u3001\u8D28\u91CF\u4E0D\u53EF\u7528\u8FD8\u662F\u53D9\u4E8B\u53D6\u820D\uFF1B\u6F0F\u6389\u4EFB\u4F55\u4E00\u4E2A\uFF0Ccheck \u90FD\u4F1A\u963B\u65AD\u3002\n\n\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\u89C6\u9891 CUT \u7684\u7D20\u6750\u5FC5\u987B\u540C\u5BBD\u3001\u540C\u9AD8\u3001\u540C\u5E27\u7387\uFF1Arender \u4E0D\u66FF\u89C6\u9891\u7F29\u653E\u6216\u6539\u5E27\u7387\uFF1B\u9759\u5E27\u5219\u6309\u4EA4\u4ED8\u89C4\u683C\u7B49\u6BD4\u94FA\u6EE1\u3001\u5C45\u4E2D\u88C1\u5207\u5E76\u6309\u8FD0\u955C\u51FA\u753B\uFF0C\u56E0\u6B64\u53EA\u8981\u6709\u9759\u5E27\u5C31\u5FC5\u987B\u586B\u5199\u300C\u753B\u5E45\u4E0E\u5E27\u7387\u300D\u3002\u89C6\u9891\u88AB check \u62A5\u51FA\u753B\u5E45\u6216\u5E27\u7387\u4E0D\u4E00\u81F4\u65F6\uFF0C\u5728\u5F53\u524D DSH \u6267\u884C\u73AF\u5883\u91CC\u7ECF\u5BA1\u6279\u7528 ffmpeg \u6309\u4EA4\u4ED8\u89C4\u683C\u7EDF\u4E00\u3001\u4FDD\u7559\u6784\u56FE\uFF0C\u65B0\u6587\u4EF6\u5199\u5230 ${production.episodeDirectory}/\u5236\u4F5C\u6210\u679C/\u6210\u7247/\u89C4\u683C\u7EDF\u4E00/\u2014\u2014\u8FD9\u662F\u526A\u8F91\u9636\u6BB5\u81EA\u5DF1\u7684\u4E2D\u95F4\u6587\u4EF6\uFF0C\u4E0D\u653E\u5728\u751F\u4EA7\u9636\u6BB5\u7684\u539F\u7D20\u6750\u65C1\u8FB9\u3001\u4E0D\u8986\u76D6\u5DF2\u751F\u4EA7\u7684\u7D20\u6750\uFF0C\u6587\u4EF6\u540D\u4E5F\u4E0D\u6CBF\u7528\u539F\u6587\u4EF6\u91CC\u7684\u4EFB\u52A1 ID\uFF08\u53EF\u76F4\u63A5\u7528 MOTION ID\uFF09\uFF1B\u5728\u8BE5 CUT \u4E0B\u8BB0\u5F55\u88C1\u5207\u6216\u7559\u8FB9\uFF08\u4E0D\u8981\u5199\u8FDB\u300C\u753B\u9762\u300D\u884C\uFF0C\u5B83\u53EA\u8BA4\u4EAE\u5EA6\u3001\u9971\u548C\u3001\u8272\u6E29\u6216\u300C\u65E0\u300D\u300C\u4E0D\u6821\u300D\uFF09\uFF0C\u628A\u300C\u6765\u6E90\u300D\u6539\u6307\u65B0\u6587\u4EF6\uFF0C\u5165\u51FA\u70B9\u968F\u8F6C\u6362\u53D8\u5316\u65F6\u540C\u6B65\u4FEE\u6539\uFF0C\u518D\u91CD\u8DD1 check\u3002\u9759\u5E27\u6765\u6E90\u5165\u70B9\u5199 0.00\u3001\u51FA\u70B9\u7B49\u4E8E\u65F6\u957F\u4E14\u81F3\u5C11 0.50 \u79D2\uFF1B\u9700\u8981\u8FD0\u52A8\u65F6\u53EA\u7528\u526A\u8F91\u5355\u652F\u6301\u7684\u56FA\u5B9A\u3001\u63A8\u8FD1\u3001\u62C9\u8FDC\u6216\u5E73\u79FB\u5199\u6CD5\u3002\n\n\u9ED8\u8BA4\u7684\u786C\u5B57\u5E55\u8DEF\u7EBF\u9700\u8981\u5E26 libass \u7684 ffmpeg\uFF0C\u7F3A libass \u65F6\u5982\u5B9E\u62A5\u51FA\uFF0C\u4E0D\u8981\u6084\u6084\u53BB\u6389\u5B57\u5E55\u3002Remotion \u5728\u9879\u76EE\u5916\u7684 ~/.cache/short-drama-edit/remotion \u91CC\u88C5 Node \u4F9D\u8D56\u3001\u9010\u5E27\u8FC7\u65E0\u5934\u6D4F\u89C8\u5668\uFF1A\u53EF\u9009\u7684 Remotion \u5B57\u5E55\u8DEF\u7EBF\u8981\u5B83\uFF0C\u526A\u8F91\u5355\u91CC\u53EA\u8981\u6709\u300C\u753B\u9762\u6587\u5B57\u300D\u884C\u4E5F\u5FC5\u987B\u8981\u5B83\uFF1B\u53EA\u6709\u521B\u4F5C\u8005\u660E\u786E\u540C\u610F\u8FD9\u6B21\u5B89\u88C5\uFF08\u5728\u8BE5\u76EE\u5F55 npm install\uFF0C0.8 \u4E4B\u524D\u88C5\u8FC7\u7684\u8981\u91CD\u88C5\u4E00\u6B21\uFF09\u65F6\u624D\u8D70\uFF0C\u672A\u540C\u610F\u5C31\u4E0D\u5199\u300C\u753B\u9762\u6587\u5B57\u300D\u884C\uFF0C\u5E76\u544A\u8BC9\u521B\u4F5C\u8005\u753B\u9762\u91CC\u7559\u7ED9\u9762\u677F\u7684\u7A7A\u767D\u4F1A\u4FDD\u6301\u7A7A\u767D\u3002\u526A\u8F91\u5355\u7684\u300C\u58F0\u97F3\u300D\u884C\u53EA\u662F\u8BB0\u5F55\uFF0Crender \u4E0D\u6267\u884C\u5B83\uFF1Arender \u5207\u6BB5\u3001\u9759\u5E27\u51FA\u753B\u4E0E\u8FD0\u955C\u3001\u540C\u573A\u666F\u81EA\u52A8\u63A5\u955C\uFF08CUT \u5199\u4E86\u300C\u753B\u9762\u300D\u6821\u6B63\u5C31\u66FF\u4EE3\u5B83\uFF0C\u300C\u753B\u9762\uFF1A\u4E0D\u6821\u300D\u8DF3\u8FC7\u5B83\uFF0C\u4EA4\u4ED8\u89C4\u683C\u5199\u300C\u63A5\u955C\u5339\u914D\uFF1A\u65E0\u300D\u6574\u96C6\u5173\u95ED\uFF09\u3001\u786C\u62FC\u63A5\u3001\u6DF7\u5165\u300C\u97F3\u6548\u300D\u300C\u914D\u97F3\u300D\u300C\u73AF\u5883\u58F0\u300D\u884C\u3001\u70E7\u5B57\u5E55\u4E0E\u753B\u9762\u6587\u5B57\u3001\u53EF\u9009\u9897\u7C92\u3001\u7EDF\u4E00\u54CD\u5EA6\u3002\u914D\u97F3\u53EF\u7528\u8D1F\u8D77\u70B9\u505A J-cut\uFF0C\u4E5F\u53EF\u8DE8\u5207\u70B9\u505A L-cut\uFF1B\u5B57\u5E55\u540C\u6837\u53EF\u8DE8\u5207\u70B9\uFF0C\u6309\u6574\u6761\u7247\u6838\u5BF9\u4E0D\u91CD\u53E0\u4E14\u4E0D\u8D8A\u8FC7\u7ED3\u5C3E\u3002\u300C\u97F3\u6548\u300D\u300C\u914D\u97F3\u300D\u300C\u73AF\u5883\u58F0\u300D\u4E4B\u5916\u7684\u6DF7\u97F3\u3001\u4EA4\u53C9\u6DE1\u5165\u3001\u914D\u4E50\u3001\u8F6C\u573A\u6216\u683C\u5F0F\u8F6C\u6362\u90FD\u662F\u53E6\u4E00\u6B65\u7ECF\u5BA1\u6279\u7684\u5916\u90E8 ffmpeg \u5904\u7406\uFF0C\u5148\u5199\u5230\u4E34\u65F6\u6587\u4EF6\uFF1B\u8FD9\u4E00\u6B65\u6700\u540E\u8981\u50CF render \u4E00\u6837\u6309\u526A\u8F91\u5355\u7684\u300C\u4EA4\u4ED8\u54CD\u5EA6\u300D\u5BF9\u6574\u7247\u505A\u4E24\u904D loudnorm\uFF08I=\u4EA4\u4ED8\u54CD\u5EA6\u3001TP=-1.5\u3001LRA=11\uFF0C\u7B2C\u4E8C\u904D\u4EE3\u5165\u7B2C\u4E00\u904D\u7684\u5B9E\u6D4B\u503C\u5E76\u7528 linear=true\uFF09\uFF0C\u97F3\u9891\u7F16\u7801\u4E3A AAC 192k\u300148 kHz\uFF0C\u7136\u540E\u624D\u66FF\u6362 ${production.episodeDirectory}/\u5236\u4F5C\u6210\u679C/\u6210\u7247/\u6210\u7247.mp4\uFF0C\u5E76\u628A\u547D\u4EE4\u8BB0\u8FDB\u526A\u8F91\u5355\uFF1B\u91CD\u65B0 render \u4F1A\u8986\u76D6\u6210\u7247\uFF0C\u8FD9\u4E9B\u6B65\u9AA4\u8981\u91CD\u505A\u3002\u6700\u540E\u5BF9\u4EA4\u4ED8\u7684\u8FD9\u4EFD\u6210\u7247.mp4 \u8FD0\u884C edit_tool.py verify \u5E76\u62A5\u544A\u5B9E\u6D4B\u6570\u5B57\uFF0C\u300C\u672A\u6D4B\u300D\u9879\u7167\u5B9E\u5199\u672A\u6D4B\u3002\n\nffmpeg \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`;\n}\n", "export type ProductionJobKind = \"image\" | \"video\" | \"composition\";\nexport type ProductionJobStatus = \"awaiting_confirmation\" | \"pending\" | \"running\" | \"dispatched_unknown\" | \"succeeded\" | \"failed\" | \"canceled\";\n\nexport interface ProductionMediaVersion {\n readonly id: string;\n readonly targetId: string;\n readonly kind: \"image\" | \"video\";\n readonly url: string;\n /** Workspace-relative path when the result is owned by the DSH FileSystem. */\n readonly path?: string | undefined;\n}\n\nexport interface ProductionJob {\n readonly id: string;\n readonly targetId: string;\n readonly kind: ProductionJobKind;\n readonly status: ProductionJobStatus;\n readonly progress: number;\n readonly prompt: string;\n readonly error?: string | undefined;\n readonly output?: ProductionMediaVersion | undefined;\n readonly expectedOutputs: number;\n readonly completedOutputs: number;\n /**\n * Deliverable whose name the job cannot influence. Drama Skills 0.7 renders the\n * assembled cut to a fixed path, so it carries no job id to correlate on.\n */\n readonly outputPath?: string | undefined;\n /** Versions already at `outputPath` when the job was dispatched, so an earlier cut never completes it. */\n readonly supersededOutputIds?: readonly string[] | undefined;\n}\n\nexport interface ProductionSequenceItem {\n readonly shotId: string;\n /** Creator-chosen source for this cut; absent keeps automatic video-first resolution. */\n readonly sourceVersionId?: string | undefined;\n /** Resolved source used for preview and composition; recomputed as media changes. */\n readonly versionId?: string | undefined;\n}\n\nexport interface CanvasPoint {\n readonly x: number;\n readonly y: number;\n}\n\nexport interface ProductionQueueEntry {\n readonly id: string;\n readonly preview: string;\n}\n\nfunction record(value: unknown): Record<string, unknown> | undefined {\n return typeof value === \"object\" && value !== null && !Array.isArray(value) ? value as Record<string, unknown> : undefined;\n}\n\n/**\n * DSH Queue rows from the host `inbox` projection's `next-turn` list. DSH 0.1.7 removed\n * `SessionSnapshot.queue`; reading it threw and blanked the whole workbench (#50). The\n * projection is wire JSON and absent without agent-loop, so every row is checked rather than\n * trusted. Like DSH's own QueueDock, a row whose prompt RPC already has a transcript echo is\n * a turn being claimed, not a queued one. The preview is the row's full text: the job-id label\n * is matched against it, and the old 200-character preview could cut that label off.\n */\nexport function productionQueueFromInbox(rows: unknown, claimedRequestIds: ReadonlySet<string> = new Set()): ProductionQueueEntry[] {\n if (!Array.isArray(rows)) return [];\n return rows.flatMap((row) => {\n const item = record(row);\n if (item === undefined || typeof item.id !== \"string\" || !Array.isArray(item.content)) return [];\n const source = record(item.source);\n if (source?.kind === \"user\" && typeof source.rpcId === \"string\" && claimedRequestIds.has(source.rpcId)) return [];\n const preview = item.content.flatMap((block) => {\n const value = record(block);\n return value?.type === \"text\" && typeof value.text === \"string\" ? [value.text] : [];\n }).join(\" \");\n return [{ id: item.id, preview }];\n });\n}\n\nexport function createPendingJob(input: {\n readonly id: string;\n readonly targetId: string;\n readonly kind: ProductionJobKind;\n readonly prompt: string;\n readonly expectedOutputs?: number | undefined;\n readonly outputPath?: string | undefined;\n readonly supersededOutputIds?: readonly string[] | undefined;\n}): ProductionJob {\n return {\n id: input.id,\n targetId: input.targetId,\n kind: input.kind,\n status: \"pending\",\n progress: 0,\n prompt: input.prompt,\n expectedOutputs: Math.max(1, Math.floor(input.expectedOutputs ?? 1)),\n completedOutputs: 0,\n outputPath: input.outputPath,\n supersededOutputIds: input.supersededOutputIds\n };\n}\n\nexport function selectedVersionForTarget(\n targetId: string,\n versions: readonly ProductionMediaVersion[],\n selections: Readonly<Record<string, string>>,\n kind?: ProductionMediaVersion[\"kind\"]\n): ProductionMediaVersion | undefined {\n const candidates = versions.filter((version) => version.targetId === targetId && (kind === undefined || version.kind === kind));\n return candidates.find((version) => version.id === selections[targetId]) ?? candidates.at(-1);\n}\n\n/**\n * Upstream's edit stage owns what it writes under \u5236\u4F5C\u6210\u679C/\u6210\u7247/ \u2014 the cut, its segments, and clips\n * normalised into \u6210\u7247/\u89C4\u683C\u7EDF\u4E00/ \u2014 so none of it is a new version of a shot or asset, even when a\n * filename carries that shot's or MOTION's ID.\n */\nconst EDIT_OUTPUT_DIRECTORY = /(?:^|\\/)\u5236\u4F5C\u6210\u679C\\/\u6210\u7247\\//u;\n\nexport function mediaTargetFromPath(path: string, knownTargets: readonly string[]): string | undefined {\n if (EDIT_OUTPUT_DIRECTORY.test(path)) return undefined;\n const upper = path.toLocaleUpperCase();\n const segments = upper.split(\"/\");\n const filename = segments.at(-1) ?? \"\";\n return [...knownTargets].sort((left, right) => right.length - left.length).find((target) => {\n const canonical = target.toLocaleUpperCase();\n return segments.includes(canonical)\n || filename === canonical\n || filename.startsWith(`${canonical}.`)\n || filename.startsWith(`${canonical}-`);\n });\n}\n\nexport function mediaVersionMatchesJob(version: ProductionMediaVersion, jobId: string): boolean {\n if (version.path === undefined || jobId.trim() === \"\") return false;\n const escaped = jobId.replace(/[.*+?^${}()|[\\]\\\\]/gu, \"\\\\$&\");\n const basename = version.path.split(\"/\").at(-1) ?? \"\";\n return new RegExp(`(?:^|[-_.])${escaped}(?:[-_.]|$)`, \"u\").test(basename);\n}\n\nexport function outputsForJob(job: ProductionJob, versions: readonly ProductionMediaVersion[]): ProductionMediaVersion[] {\n if (job.outputPath === undefined) return versions.filter((version) => mediaVersionMatchesJob(version, job.id));\n const superseded = new Set(job.supersededOutputIds ?? []);\n return versions.filter((version) => version.path === job.outputPath && !superseded.has(version.id));\n}\n\n/**\n * True while a composition the creator already dispatched has not settled. Every composition\n * for an episode renders to the same upstream path, so a second one dispatched now would be\n * completed by the first one's cut \u2014 and, once marked succeeded, could no longer be removed\n * from the DSH Queue.\n */\nexport function compositionInFlight(jobs: readonly ProductionJob[]): boolean {\n return jobs.some((job) => job.kind === \"composition\"\n && (job.status === \"awaiting_confirmation\" || job.status === \"pending\" || job.status === \"running\"));\n}\n\n/**\n * A composition whose Turn ended without a cut stays dispatched_unknown so a late cut can still\n * complete it, and compositionInFlight lets the creator compose again. Both render to the same\n * upstream path, so once a new composition is dispatched its cut would complete the old job too.\n * Fail the old one instead, keeping the check findings its error already reports.\n */\nexport function settleSupersededCompositions(jobs: readonly ProductionJob[], next: ProductionJob): ProductionJob[] {\n if (next.kind !== \"composition\") return [...jobs];\n return jobs.map((job) => (\n job.id !== next.id\n && job.kind === \"composition\"\n && job.status === \"dispatched_unknown\"\n && (job.targetId === next.targetId || (job.outputPath !== undefined && job.outputPath === next.outputPath))\n ? { ...job, status: \"failed\" }\n : job\n ));\n}\n\nexport function referencesForTarget(\n targetId: string,\n production: { readonly shots: readonly { readonly id: string; readonly references: readonly string[] }[] },\n versions: readonly ProductionMediaVersion[],\n selections: Readonly<Record<string, string>>,\n libraryVersions: readonly ProductionMediaVersion[] = versions,\n manualReferences: Readonly<Record<string, readonly string[]>> = {}\n): ProductionMediaVersion[] {\n const shot = production.shots.find((item) => item.id === targetId);\n if (shot === undefined) return [];\n const declared = shot.references.flatMap((id) => {\n const version = selectedVersionForTarget(id, versions, selections, \"image\");\n return version === undefined ? [] : [version];\n });\n const manual = (manualReferences[targetId] ?? []).flatMap((id) => {\n const version = libraryVersions.find((item) => item.id === id && item.kind === \"image\");\n return version === undefined ? [] : [version];\n });\n return [...new Map([...declared, ...manual].map((version) => [version.id, version])).values()];\n}\n\nexport function mediaBelongsToEpisode(path: string | undefined, episodeDirectory: string): boolean {\n if (path === undefined) return true;\n if (path.startsWith(`${episodeDirectory}/`)) return true;\n const episodeName = episodeDirectory.split(\"/\").at(-1);\n return episodeName !== undefined && path.startsWith(`\u4EA4\u4ED8/${episodeName}/`);\n}\n\nexport function sequenceSourceEligible(shotId: string, version: ProductionMediaVersion): boolean {\n return version.kind === \"video\"\n ? version.targetId === shotId\n : version.targetId === shotId || version.targetId.startsWith(\"IMG-\");\n}\n\nexport function queuedItemForJob(jobId: string, queue: readonly ProductionQueueEntry[]): ProductionQueueEntry | undefined {\n if (jobId.trim() === \"\") return undefined;\n const escaped = jobId.replace(/[.*+?^${}()|[\\]\\\\]/gu, \"\\\\$&\");\n // The prompts label the id as \u300C\u4EFB\u52A1 ID\uFF1A<id>\u300D / \u300C\u6279\u6B21\u4EFB\u52A1 ID\uFF1A<id>\u300D. Anchor on that label so an\n // id merely quoted inside another job's output paths cannot mark this job as queued.\n const labelled = new RegExp(`\u4EFB\u52A1\\\\s*ID\\\\s*[\uFF1A:]\\\\s*${escaped}(?:[\\\\s.,;\u3001\u3002]|$)`, \"u\");\n return queue.find((item) => labelled.test(item.preview));\n}\n\nexport function activeProductionJobId(\n jobs: readonly ProductionJob[],\n queue: readonly ProductionQueueEntry[],\n sessionRunning: boolean\n): string | undefined {\n if (!sessionRunning) return undefined;\n return [...jobs].reverse().find((job) => (\n (job.status === \"awaiting_confirmation\" || job.status === \"pending\" || job.status === \"running\")\n && queuedItemForJob(job.id, queue) === undefined\n ))?.id;\n}\n\n/** Reconcile the lightweight Session projection against DSH Queue/Turn state and real workspace outputs. */\nexport function reconcileProductionJobs(\n jobs: readonly ProductionJob[],\n queue: readonly ProductionQueueEntry[],\n sessionRunning: boolean,\n versions: readonly ProductionMediaVersion[]\n): ProductionJob[] {\n const latestPending = [...jobs].reverse().find((job) => (\n job.status === \"pending\" && queuedItemForJob(job.id, queue) === undefined\n ));\n\n // Retire an unfinished composition only once a newer one actually runs, and before outputs are\n // matched, so the newer cut cannot complete it. A dispatch that fails or is withdrawn from the\n // Queue leaves the older one to be finished in Chat.\n const settleCompositions = (list: readonly ProductionJob[]): ProductionJob[] => list\n .filter((job) => job.kind === \"composition\" && job.status === \"running\")\n .reduce((current, running) => settleSupersededCompositions(current, running), [...list]);\n const reconciled = settleCompositions(jobs).map((job): ProductionJob => {\n const queued = queuedItemForJob(job.id, queue) !== undefined;\n // A terminal job is never revived by a result that arrived later. This matters most for\n // `outputPath`: a shared deliverable name carries no job identity, so without this guard\n // the next cut would complete a job the creator canceled, and bury the error a failed one\n // reported. A job-id correlated failure keeps its old behaviour \u2014 that output really is its own.\n if (job.status === \"canceled\" || job.status === \"succeeded\") return job;\n if (job.status === \"failed\" && job.outputPath !== undefined) return job;\n const outputs = outputsForJob(job, versions);\n\n if (outputs.length >= job.expectedOutputs) {\n return {\n ...job,\n status: \"succeeded\",\n progress: 100,\n completedOutputs: outputs.length,\n output: outputs[0],\n error: undefined\n };\n }\n if (job.status === \"awaiting_confirmation\" && outputs.length === 0) return job;\n if (job.status === \"running\" && queued) return { ...job, status: \"pending\", progress: 0 };\n if (job.status === \"pending\" && sessionRunning && !queued && job === latestPending) {\n return { ...job, status: \"running\", progress: Math.max(10, job.progress), error: undefined };\n }\n if (!sessionRunning && !queued && (job.status === \"running\" || job.status === \"dispatched_unknown\")) {\n return {\n ...job,\n status: \"dispatched_unknown\",\n progress: Math.round(outputs.length / job.expectedOutputs * 100),\n completedOutputs: outputs.length,\n // Assembly is local ffmpeg, so nothing was billed: a missing cut usually means edit_tool\n // check blocked the render, and those findings \u2014 not a billing warning \u2014 are what to show.\n error: outputs.length > 0\n ? `DSH Turn \u5DF2\u7ED3\u675F\uFF0C\u5DF2\u53D1\u73B0 ${String(outputs.length)}/${String(job.expectedOutputs)} \u9879\u6210\u679C\uFF1B\u8BF7\u5237\u65B0\u6838\u5BF9\u5269\u4F59\u8F93\u51FA\u3002`\n : job.kind === \"composition\"\n ? \"\u6210\u7247\u672A\u751F\u6210\uFF1A\u8BF7\u5728 Chat \u67E5\u770B edit_tool check \u7684\u963B\u65AD\u9879\uFF08\u672A\u91C7\u7528\u955C\u5934\u7406\u7531\u3001\u753B\u5E45/\u5E27\u7387\u4E0D\u4E00\u81F4\u7B49\uFF09\uFF0C\u4FEE\u6B63\u540E\u518D\u5408\u6210\u3002\"\n : \"DSH Turn \u5DF2\u7ED3\u675F\uFF0C\u5C1A\u672A\u53D1\u73B0\u5173\u8054\u6210\u679C\u3002\u4EFB\u52A1\u53EF\u80FD\u5DF2\u6D3E\u53D1\uFF0C\u8BF7\u5148\u5237\u65B0\u6210\u679C\uFF0C\u907F\u514D\u91CD\u590D\u8BA1\u8D39\u3002\"\n };\n }\n if (outputs.length > 0) {\n return {\n ...job,\n status: job.status === \"failed\" ? \"failed\" : \"running\",\n progress: Math.max(10, Math.round(outputs.length / job.expectedOutputs * 100)),\n completedOutputs: outputs.length,\n error: job.status === \"failed\" ? job.error : undefined\n };\n }\n return job;\n });\n return settleCompositions(reconciled);\n}\n\nexport function reconcileSequence(\n shotIds: readonly string[],\n current: readonly ProductionSequenceItem[],\n versions: readonly ProductionMediaVersion[],\n selections: Readonly<Record<string, string>>,\n episodeDirectory?: string\n): ProductionSequenceItem[] {\n const scopedVersions = episodeDirectory === undefined\n ? versions\n : versions.filter((version) => mediaBelongsToEpisode(version.path, episodeDirectory));\n const shotSet = new Set(shotIds);\n const preserved = current.filter((item) => shotSet.has(item.shotId));\n const present = new Set(preserved.map((item) => item.shotId));\n const appended: ProductionSequenceItem[] = shotIds.filter((shotId) => !present.has(shotId)).map((shotId) => ({ shotId }));\n return [...preserved, ...appended].map((item) => {\n if (item.sourceVersionId !== undefined) {\n const explicit = scopedVersions.find((version) => version.id === item.sourceVersionId && sequenceSourceEligible(item.shotId, version));\n return { ...item, versionId: explicit?.id };\n }\n // A produced video remains the preferred cut source even when the version strip currently\n // points at its earlier keyframe. Static assembly is the fallback: use an explicitly selected\n // SHOT/IMG image first, otherwise the current shot's accepted keyframe. Never pull an image\n // from another target merely because it happened to arrive last.\n const video = selectedVersionForTarget(item.shotId, scopedVersions, selections, \"video\");\n const selectedImageId = selections[item.shotId];\n const selectedImage = selectedImageId === undefined ? undefined : scopedVersions.find((version) => (\n version.id === selectedImageId\n && version.kind === \"image\"\n && (version.targetId === item.shotId || version.targetId.startsWith(\"IMG-\"))\n ));\n const shotImage = selectedVersionForTarget(item.shotId, scopedVersions, selections, \"image\");\n const preservedImage = scopedVersions.find((version) => (\n version.id === item.versionId && version.kind === \"image\" && version.targetId.startsWith(\"IMG-\")\n ));\n const image = selectedImage ?? shotImage ?? preservedImage;\n return { shotId: item.shotId, versionId: video?.id ?? image?.id };\n });\n}\n\nexport function sequenceIssues(sequence: readonly ProductionSequenceItem[], versions: readonly ProductionMediaVersion[], episodeDirectory?: string): string[] {\n const versionById = new Map(versions\n .filter((version) => episodeDirectory === undefined || mediaBelongsToEpisode(version.path, episodeDirectory))\n .map((version) => [version.id, version]));\n const issues: string[] = [];\n for (const item of sequence) {\n const version = item.versionId === undefined ? undefined : versionById.get(item.versionId);\n if (version === undefined || (version.kind !== \"video\" && version.kind !== \"image\")) {\n issues.push(item.sourceVersionId === undefined\n ? `${item.shotId} \u7F3A\u5C11\u5DF2\u9009\u89C6\u9891\u6216\u5173\u952E\u5E27\u7D20\u6750`\n : `${item.shotId} \u663E\u5F0F\u9009\u62E9\u7684\u6210\u7247\u7D20\u6750\u5DF2\u4E0D\u53EF\u7528`);\n }\n else if (version.path === undefined) issues.push(`${item.shotId} \u7684${version.kind === \"video\" ? \"\u89C6\u9891\" : \"\u5173\u952E\u5E27\"}\u6CA1\u6709\u53EF\u4F9B DSH \u8BFB\u53D6\u7684\u5DE5\u4F5C\u533A\u8DEF\u5F84`);\n }\n return issues;\n}\n\nexport function reorderSequence(sequence: readonly ProductionSequenceItem[], source: number, target: number): ProductionSequenceItem[] {\n if (!Number.isInteger(source) || !Number.isInteger(target)) return [...sequence];\n if (source < 0 || target < 0 || source >= sequence.length || target >= sequence.length || source === target) return [...sequence];\n const next = [...sequence];\n const [item] = next.splice(source, 1);\n if (item !== undefined) next.splice(target, 0, item);\n return next;\n}\n", "export const OH_STORY_PRODUCTION_TOOL_NAME = \"oh_story_production\";\n\nexport const PRODUCTION_INTENT_ACTIONS = [\n \"open_section\",\n \"focus_target\",\n \"set_sequence\",\n \"track_job\"\n] as const;\n\nexport const PRODUCTION_INTENT_SECTIONS = [\"shots\", \"assets\", \"tasks\", \"sequence\", \"canvas\"] as const;\nexport const PRODUCTION_INTENT_JOB_KINDS = [\"image\", \"video\", \"composition\"] as const;\n\nexport type ProductionIntentAction = typeof PRODUCTION_INTENT_ACTIONS[number];\nexport type ProductionIntentSection = typeof PRODUCTION_INTENT_SECTIONS[number];\nexport type ProductionIntentJobKind = typeof PRODUCTION_INTENT_JOB_KINDS[number];\n\nexport interface ProductionIntentArgs {\n readonly action: ProductionIntentAction;\n readonly episode: string;\n readonly section?: ProductionIntentSection | undefined;\n readonly targetId?: string | undefined;\n readonly shotIds?: readonly string[] | undefined;\n readonly jobId?: string | undefined;\n readonly jobKind?: ProductionIntentJobKind | undefined;\n readonly expectedOutputs?: number | undefined;\n readonly prompt?: string | undefined;\n}\n\nfunction requiredText(value: string | undefined, field: string): string {\n const normalized = value?.trim();\n if (!normalized) throw new Error(`oh_story_production ${field} is required for this action.`);\n if (normalized.length > 512) throw new Error(`oh_story_production ${field} is too long.`);\n return normalized;\n}\n\n/** Validate the cross-runtime UI intent without reading or mutating workspace state. */\nexport function validateProductionIntent(args: ProductionIntentArgs): ProductionIntentArgs {\n const episode = args.episode.trim().replaceAll(\"\\\\\", \"/\").replace(/\\/$/u, \"\");\n if (!/^\u5267\u96C6\\/EP\\d{3,}$/u.test(episode)) {\n throw new Error(\"oh_story_production episode must use the creator path form \u5267\u96C6/EP001.\");\n }\n if (args.action === \"open_section\") {\n if (args.section === undefined) throw new Error(\"oh_story_production section is required for open_section.\");\n return { action: args.action, episode, section: args.section };\n }\n if (args.action === \"focus_target\") {\n return { action: args.action, episode, targetId: requiredText(args.targetId, \"targetId\"), section: args.section };\n }\n if (args.action === \"set_sequence\") {\n const shotIds = args.shotIds?.map((value) => value.trim()).filter((value) => value !== \"\") ?? [];\n if (shotIds.length === 0) throw new Error(\"oh_story_production shotIds must contain at least one shot for set_sequence.\");\n if (shotIds.length > 500 || new Set(shotIds).size !== shotIds.length || shotIds.some((value) => !/^SHOT-[A-Z0-9-]+$/u.test(value))) {\n throw new Error(\"oh_story_production shotIds must be unique canonical SHOT-* identifiers.\");\n }\n return { action: args.action, episode, shotIds };\n }\n // Leave expectedOutputs/prompt undefined when the caller omits them: track_job re-registers a job the\n // workbench already created, and defaulting here would silently reset a batch's count to 1.\n const expectedOutputs = args.expectedOutputs;\n if (expectedOutputs !== undefined && (!Number.isInteger(expectedOutputs) || expectedOutputs < 1 || expectedOutputs > 500)) {\n throw new Error(\"oh_story_production expectedOutputs must be an integer between 1 and 500.\");\n }\n if (args.jobKind === undefined) throw new Error(\"oh_story_production jobKind is required for track_job.\");\n const prompt = args.prompt?.trim();\n return {\n action: args.action,\n episode,\n jobId: requiredText(args.jobId, \"jobId\"),\n targetId: requiredText(args.targetId, \"targetId\"),\n jobKind: args.jobKind,\n expectedOutputs,\n prompt: prompt === \"\" ? undefined : prompt\n };\n}\n", "import type { ChatSnapshot } from \"@deepseek-ai/dsh-client-ui-chat/client\";\nimport type { ToolCallBlock } from \"@deepseek-ai/dsh-client-ui-conversation/client\";\nimport {\n OH_STORY_PRODUCTION_TOOL_NAME,\n validateProductionIntent,\n type ProductionIntentArgs\n} from \"../production-intent.js\";\n\nexport interface SettledProductionIntent {\n readonly callId: string;\n readonly intent: ProductionIntentArgs;\n}\n\nfunction parsedIntent(block: ToolCallBlock): SettledProductionIntent | undefined {\n if (!(\"kind\" in block) || block.isError || block.call?.name !== OH_STORY_PRODUCTION_TOOL_NAME) return undefined;\n try {\n const args = JSON.parse(block.call.argsRaw) as ProductionIntentArgs;\n return { callId: block.callId, intent: validateProductionIntent(args) };\n } catch {\n return undefined;\n }\n}\n\nfunction visit(block: ToolCallBlock, output: SettledProductionIntent[]): void {\n const direct = parsedIntent(block);\n if (direct !== undefined) output.push(direct);\n for (const child of block.subCalls) visit(child, output);\n}\n\n/** Replay durable successful Agent UI intents in official DSH Chat order. */\nexport function settledProductionIntents(chat: ChatSnapshot): SettledProductionIntent[] {\n const output: SettledProductionIntent[] = [];\n for (const key of chat.order) {\n const node = chat.nodes.get(key);\n if (node?.kind !== \"tool-call\") continue;\n const root = (node.data as { readonly root?: ToolCallBlock }).root;\n if (root !== undefined) visit(root, output);\n }\n return output;\n}\n", "import { useEffect, useId, useRef, useState } from \"react\";\nimport { workbenchLabel, type WorkbenchMode } from \"./file-activity.js\";\nimport { endpoint, handleTabKey } from \"./workbench-ui.js\";\n\nexport interface VideoPreviewAsset {\n readonly role: \"source\" | \"edited\" | \"final\";\n readonly label: string;\n readonly path: string;\n readonly bytes: number;\n readonly version: string;\n readonly mimeType: string;\n}\n\nexport interface VideoArtifactSummary {\n readonly label: string;\n readonly path: string;\n readonly version: string;\n readonly kind: \"plan\" | \"script\" | \"subtitle\" | \"quality\" | \"manifest\";\n}\n\nexport interface VideoProject {\n readonly id: string;\n readonly root: string;\n readonly title: string;\n readonly state: \"not-started\" | \"working\" | \"waiting\" | \"ready\";\n readonly stage: string;\n readonly stageLabel: string;\n readonly nextArtifact?: string | undefined;\n readonly previews: readonly VideoPreviewAsset[];\n readonly artifacts: readonly VideoArtifactSummary[];\n}\n\ninterface FilePayload { readonly content: string }\ninterface VideoPreflight {\n readonly python: { readonly ok: boolean; readonly version?: string };\n readonly ffmpeg: { readonly ok: boolean; readonly subtitles: boolean };\n readonly ffprobe: { readonly ok: boolean };\n readonly credentials: { readonly mimo: boolean; readonly fish: boolean; readonly indexTts: boolean; readonly ttsProvider: string };\n}\n\nfunction preferredPreview(project: VideoProject): VideoPreviewAsset | undefined {\n return project.previews.find((item) => item.role === \"final\")\n ?? project.previews.find((item) => item.role === \"edited\")\n ?? project.previews.find((item) => item.role === \"source\");\n}\n\nfunction readableBytes(bytes: number): string {\n if (bytes < 1_024 * 1_024) return `${(bytes / 1_024).toFixed(1)} KB`;\n if (bytes < 1_024 * 1_024 * 1_024) return `${(bytes / (1_024 * 1_024)).toFixed(1)} MB`;\n return `${(bytes / (1_024 * 1_024 * 1_024)).toFixed(2)} GB`;\n}\n\nfunction ActionIcon({ name }: { readonly name: \"reload\" | \"fullscreen\" | \"external\" }) {\n const paths = {\n reload: <><path d=\"M20 11a8 8 0 1 0-2.34 5.66\"/><path d=\"M20 4v7h-7\"/></>,\n fullscreen: <><path d=\"M8 3H3v5M16 3h5v5M8 21H3v-5M16 21h5v-5\"/></>,\n external: <><path d=\"M14 3h7v7M21 3l-9 9\"/><path d=\"M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6\"/></>\n };\n return <svg aria-hidden viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.8\" strokeLinecap=\"round\" strokeLinejoin=\"round\">{paths[name]}</svg>;\n}\n\nfunction preferredArtifact(project: VideoProject): VideoArtifactSummary | undefined {\n return project.artifacts.find((item) => item.path.endsWith(\"final_qc.json\"))\n ?? project.artifacts.find((item) => item.path.endsWith(\"assembly_qc.json\"))\n ?? project.artifacts.find((item) => item.kind === \"quality\")\n ?? project.artifacts.at(-1);\n}\n\nfunction artifactKindLabel(kind: VideoArtifactSummary[\"kind\"]): string {\n return { plan: \"\u65B9\u6848\", script: \"\u6587\u7A3F\", subtitle: \"\u5B57\u5E55\", quality: \"\u8D28\u68C0\", manifest: \"\u6E05\u5355\" }[kind];\n}\n\nfunction VideoPreview({ project, sessionId, running }: { readonly project: VideoProject; readonly sessionId: string; readonly running: boolean }) {\n const shellRef = useRef<HTMLDivElement>(null);\n const initial = preferredPreview(project);\n const [role, setRole] = useState<VideoPreviewAsset[\"role\"] | undefined>(initial?.role);\n const selected = project.previews.find((item) => item.role === role) ?? preferredPreview(project);\n const [loaded, setLoaded] = useState(initial);\n const [revision, setRevision] = useState(0);\n const [ready, setReady] = useState(false);\n const [error, setError] = useState(false);\n if (selected === undefined || loaded === undefined) return <div className=\"oh-video-preview-empty\">\n <span aria-hidden>\u25B6</span>\n <strong>\u8FD8\u6CA1\u6709\u53EF\u9884\u89C8\u7684\u89C6\u9891</strong>\n <p>\u628A\u539F\u7247\u5BFC\u5165 <code>video-recaps/&lt;\u9879\u76EE&gt;/sources/</code>\uFF0C\u7136\u540E\u5728\u53F3\u4FA7 Chat \u4F7F\u7528 <code>/video-recap</code>\u3002\u526A\u540E\u7247\u548C\u6700\u7EC8\u6210\u7247\u4F1A\u81EA\u52A8\u51FA\u73B0\u5728\u8FD9\u91CC\u3002</p>\n <div className=\"oh-video-prompt-example\"><span>\u63CF\u8FF0\u793A\u4F8B</span><q>\u628A\u8FD9\u6BB5\u89C6\u9891\u505A\u6210 3 \u5206\u949F\u4E2D\u6587\u89E3\u8BF4\uFF0C\u4FDD\u7559\u5173\u952E\u539F\u58F0\uFF0C\u5B57\u5E55\u70E7\u8FDB\u753B\u9762\u3002</q></div>\n </div>;\n const pending = selected.path !== loaded.path || selected.version !== loaded.version;\n const load = (asset: VideoPreviewAsset): void => {\n setRole(asset.role);\n setLoaded(asset);\n setReady(false);\n setError(false);\n setRevision((value) => value + 1);\n };\n const runtimeState = error ? \"\u89C6\u9891\u8F7D\u5165\u5931\u8D25 \u00B7 \u53EF\u91CD\u65B0\u8F7D\u5165\"\n : running ? \"Agent \u6B63\u5728\u66F4\u65B0\u9879\u76EE \u00B7 \u5F53\u524D\u64AD\u653E\u4FDD\u6301\u4E0D\u53D8\"\n : pending ? \"\u65B0\u7248\u672C\u5DF2\u5C31\u7EEA \u00B7 \u7531\u4F60\u51B3\u5B9A\u4F55\u65F6\u8F7D\u5165\"\n : ready ? `${loaded.label}\u5DF2\u8F7D\u5165 \u00B7 ${readableBytes(loaded.bytes)}` : \"\u6B63\u5728\u8BFB\u53D6\u89C6\u9891\u4FE1\u606F\u2026\";\n const mediaUrl = `${endpoint(\"media\", sessionId, loaded.path)}&version=${encodeURIComponent(loaded.version)}&reload=${String(revision)}`;\n return <div ref={shellRef} className=\"oh-video-preview-shell\" data-state={error ? \"error\" : running ? \"building\" : ready ? \"ready\" : \"loading\"}>\n <div className=\"oh-video-stagebar\">\n <div className=\"oh-video-version-tabs\" role=\"tablist\" aria-label=\"\u9884\u89C8\u7248\u672C\">\n {project.previews.map((asset) => <button\n type=\"button\"\n role=\"tab\"\n key={asset.role}\n aria-selected={asset.role === selected.role}\n tabIndex={asset.role === selected.role ? 0 : -1}\n onKeyDown={(event) => { handleTabKey(event, project.previews.map((item) => item.role), selected.role, (next) => {\n const asset = project.previews.find((item) => item.role === next);\n if (asset !== undefined) load(asset);\n }); }}\n onClick={() => { load(asset); }}\n >{asset.label}</button>)}\n </div>\n <span className=\"oh-video-runtime-state\" role=\"status\" aria-live=\"polite\"><i aria-hidden /><em>{runtimeState}</em></span>\n <div className=\"oh-video-preview-actions\">\n {pending && <button type=\"button\" onClick={() => { load(selected); }}>\u8F7D\u5165\u65B0\u7248\u672C</button>}\n <button type=\"button\" title=\"\u91CD\u65B0\u8F7D\u5165\" aria-label=\"\u91CD\u65B0\u8F7D\u5165\u89C6\u9891\" onClick={() => { load(loaded); }}><ActionIcon name=\"reload\" /></button>\n <button type=\"button\" title=\"\u5168\u5C4F\" aria-label=\"\u5168\u5C4F\u9884\u89C8\" onClick={() => { void shellRef.current?.requestFullscreen(); }}><ActionIcon name=\"fullscreen\" /></button>\n <a href={mediaUrl} target=\"_blank\" rel=\"noreferrer\" title=\"\u5728\u65B0\u7A97\u53E3\u6253\u5F00\" aria-label=\"\u5728\u65B0\u7A97\u53E3\u6253\u5F00\u89C6\u9891\"><ActionIcon name=\"external\" /></a>\n </div>\n </div>\n <div className=\"oh-video-player-stage\">\n <video\n key={`${loaded.path}:${loaded.version}:${String(revision)}`}\n src={mediaUrl}\n controls\n preload=\"metadata\"\n playsInline\n onLoadedMetadata={() => { setReady(true); setError(false); }}\n onError={() => { setError(true); setReady(false); }}\n />\n </div>\n </div>;\n}\n\nfunction VideoArtifacts({ project, sessionId }: { readonly project: VideoProject; readonly sessionId: string }) {\n const [selected, setSelected] = useState(preferredArtifact(project)?.path);\n const [content, setContent] = useState<string>();\n const [error, setError] = useState<string>();\n const [preflight, setPreflight] = useState<VideoPreflight | \"failed\">();\n useEffect(() => { setSelected(preferredArtifact(project)?.path); }, [project.id]);\n useEffect(() => {\n if (selected === undefined) { setContent(undefined); return; }\n const controller = new AbortController();\n setContent(undefined);\n setError(undefined);\n void fetch(endpoint(\"file\", sessionId, selected), { signal: controller.signal })\n .then(async (response) => {\n const payload = await response.json() as FilePayload & { readonly error?: string };\n if (!response.ok) throw new Error(payload.error ?? `HTTP ${String(response.status)}`);\n setContent(payload.content);\n })\n .catch((reason: unknown) => { if (!controller.signal.aborted) setError(reason instanceof Error ? reason.message : String(reason)); });\n return () => { controller.abort(); };\n }, [selected, sessionId]);\n const selectedArtifact = project.artifacts.find((item) => item.path === selected);\n return <div className=\"oh-video-artifacts\">\n <aside aria-label=\"\u89C6\u9891\u9879\u76EE\u4EA7\u7269\">\n <div className=\"oh-video-artifacts-heading\"><strong>\u9879\u76EE\u4EA7\u7269</strong><span>{project.artifacts.length}</span></div>\n <div className=\"oh-video-environment\">\n <strong>\u8FD0\u884C\u73AF\u5883</strong>\n {typeof preflight === \"object\" ? <>\n <span data-ready={preflight.python.ok || undefined}>Python {preflight.python.version ?? \"\u672A\u627E\u5230\"}</span>\n <span data-ready={(preflight.ffmpeg.ok && preflight.ffmpeg.subtitles) || undefined}>ffmpeg {preflight.ffmpeg.subtitles ? \"\u00B7 libass\" : \"\u00B7 \u7F3A\u5B57\u5E55\u6EE4\u955C\"}</span>\n <span data-ready={preflight.ffprobe.ok || undefined}>ffprobe {preflight.ffprobe.ok ? \"\u53EF\u7528\" : \"\u672A\u627E\u5230\"}</span>\n <span data-ready={preflight.credentials.mimo || undefined}>MiMo Key {preflight.credentials.mimo ? \"\u5DF2\u914D\u7F6E\" : \"\u672A\u914D\u7F6E\"}</span>\n {/* auto voices with MiMo when its key is set and falls back to Fish Audio otherwise. */}\n {(preflight.credentials.ttsProvider === \"fish-audio\" || (preflight.credentials.ttsProvider === \"auto\" && !preflight.credentials.mimo))\n && <span data-ready={preflight.credentials.fish || undefined}>Fish Key {preflight.credentials.fish ? \"\u5DF2\u914D\u7F6E\" : \"\u672A\u914D\u7F6E\"}</span>}\n {preflight.credentials.ttsProvider === \"index-tts\"\n && <span data-ready={preflight.credentials.indexTts || undefined}>IndexTTS {preflight.credentials.indexTts ? \"\u5DF2\u914D\u7F6E\" : \"\u7F3A INDEX_TTS_ENDPOINT / INDEX_TTS_VOICE\"}</span>}\n <em>DSH Host \u8FDB\u7A0B\u73AF\u5883\uFF1BAgent \u6267\u884C\u4E16\u754C\u4EE5 <code>video-recap --doctor</code> \u4E3A\u51C6\u3002</em>\n </> : <button type=\"button\" onClick={() => {\n void fetch(endpoint(\"video-preflight\", sessionId)).then(async (response) => {\n if (!response.ok) throw new Error(`HTTP ${String(response.status)}`);\n setPreflight(await response.json() as VideoPreflight);\n }).catch(() => { setPreflight(\"failed\"); });\n }}>{preflight === \"failed\" ? \"\u73AF\u5883\u68C0\u67E5\u5931\u8D25 \u00B7 \u91CD\u8BD5\" : \"\u68C0\u67E5\u73AF\u5883\"}</button>}\n </div>\n <nav>\n {project.artifacts.length === 0 && <p>\u6D41\u6C34\u7EBF\u542F\u52A8\u540E\uFF0C\u5173\u952E\u4EA7\u7269\u4F1A\u51FA\u73B0\u5728\u8FD9\u91CC\u3002</p>}\n {project.artifacts.map((artifact) => <button\n type=\"button\"\n key={artifact.path}\n aria-current={artifact.path === selected ? \"page\" : undefined}\n onClick={() => { setSelected(artifact.path); }}\n ><span>{artifact.label}</span><small>{artifact.path.split(\"/\").at(-1)}</small></button>)}\n </nav>\n </aside>\n <section>\n {selectedArtifact !== undefined && <header className=\"oh-video-artifact-header\">\n <div><strong>{selectedArtifact.label}</strong><span>{selectedArtifact.path.split(\"/\").at(-1)}</span></div>\n <em>{artifactKindLabel(selectedArtifact.kind)}</em>\n </header>}\n <div className=\"oh-video-artifact-content\">{project.artifacts.length === 0 ? <div className=\"oh-video-artifacts-empty\">\u6545\u4E8B\u65B9\u6848\u3001\u89E3\u8BF4\u8BCD\u3001\u5B57\u5E55\u548C\u8D28\u68C0\u62A5\u544A\u4F1A\u6309\u4E0A\u6E38\u6D41\u6C34\u7EBF\u5199\u5165\u8FD9\u91CC\u3002</div>\n : error !== undefined ? <div className=\"oh-story-error\">{error}</div>\n : content === undefined ? <div className=\"oh-video-artifacts-empty\">\u6B63\u5728\u8F7D\u5165\u4EA7\u7269\u2026</div>\n : <pre>{content}</pre>}</div>\n </section>\n </div>;\n}\n\nexport function VideoStudio({\n sessionId,\n projects,\n running,\n projectId,\n tab,\n hidden,\n workbenches,\n paneId,\n labelledBy,\n onProject,\n onTab,\n onWorkbench,\n onCollapse\n}: {\n readonly sessionId: string;\n readonly projects: readonly VideoProject[];\n readonly running: boolean;\n readonly projectId: string | undefined;\n readonly tab: \"preview\" | \"artifacts\";\n readonly hidden: boolean;\n readonly workbenches: readonly WorkbenchMode[];\n readonly paneId: string;\n readonly labelledBy: string;\n readonly onProject: (id: string) => void;\n readonly onTab: (tab: \"preview\" | \"artifacts\") => void;\n readonly onWorkbench: (mode: WorkbenchMode) => void;\n readonly onCollapse: () => void;\n}) {\n const project = projects.find((item) => item.id === projectId) ?? projects[0];\n const tabsId = useId();\n useEffect(() => { if (project !== undefined && project.id !== projectId) onProject(project.id); }, [onProject, project, projectId]);\n const tabs = [\"preview\", \"artifacts\"] as const;\n return <main id={paneId} className=\"oh-video-studio\" role=\"tabpanel\" aria-labelledby={labelledBy} hidden={hidden}>\n <header className=\"oh-video-toolbar\">\n <div className=\"oh-workbench-cluster\">\n <div className=\"oh-video-mode-tabs\" role=\"tablist\" aria-label=\"\u521B\u4F5C\u5DE5\u4F5C\u53F0\">{workbenches.map((mode) => <button\n type=\"button\" role=\"tab\" key={mode} aria-selected={mode === \"video\"} tabIndex={mode === \"video\" ? 0 : -1}\n onKeyDown={(event) => { handleTabKey(event, workbenches, \"video\", onWorkbench); }} onClick={() => { onWorkbench(mode); }}\n >{workbenchLabel(mode)}</button>)}</div>\n <button className=\"oh-workbench-collapse\" type=\"button\" title=\"\u6536\u8D77\u521B\u4F5C\u5DE5\u4F5C\u53F0\" aria-label=\"\u6536\u8D77\u521B\u4F5C\u5DE5\u4F5C\u53F0\" onClick={onCollapse}>\u00D7</button>\n </div>\n <label className=\"oh-video-project\"><span>\u89C6\u9891\u9879\u76EE</span><select aria-label=\"\u89C6\u9891\u9879\u76EE\" value={project?.id ?? \"\"} disabled={project === undefined} onChange={(event) => { onProject(event.target.value); }}>\n {projects.map((item) => <option key={item.id} value={item.id}>{item.title}</option>)}\n </select></label>\n {project !== undefined && <span className=\"oh-video-stage\" data-state={project.state}><i aria-hidden />{project.stageLabel}</span>}\n <div className=\"oh-video-tabs\" role=\"tablist\" aria-label=\"\u89C6\u9891\u5DE5\u4F5C\u53F0\">{tabs.map((item) => <button\n type=\"button\" role=\"tab\" key={item} id={`${tabsId}-${item}-tab`} aria-controls={`${tabsId}-${item}-panel`}\n aria-selected={tab === item} tabIndex={tab === item ? 0 : -1}\n onKeyDown={(event) => { handleTabKey(event, tabs, tab, onTab); }} onClick={() => { onTab(item); }}\n >{item === \"preview\" ? \"\u9884\u89C8\" : \"\u4EA7\u7269\"}</button>)}</div>\n </header>\n {project === undefined ? <div className=\"oh-video-preview-empty\"><span aria-hidden>\u25B6</span><strong>\u8FD8\u6CA1\u6709\u89C6\u9891\u9879\u76EE</strong><p>\u5728\u53F3\u4FA7 Chat \u544A\u8BC9 Agent \u8981\u5904\u7406\u7684\u89C6\u9891\uFF1B\u9879\u76EE\u4F1A\u521B\u5EFA\u5728 <code>video-recaps/&lt;\u9879\u76EE&gt;/</code>\u3002</p></div> : <div className=\"oh-video-panels\">\n <div role=\"tabpanel\" id={`${tabsId}-preview-panel`} aria-labelledby={`${tabsId}-preview-tab`} hidden={tab !== \"preview\"}><VideoPreview key={project.id} project={project} sessionId={sessionId} running={running} /></div>\n <div role=\"tabpanel\" id={`${tabsId}-artifacts-panel`} aria-labelledby={`${tabsId}-artifacts-tab`} hidden={tab !== \"artifacts\"}><VideoArtifacts project={project} sessionId={sessionId} /></div>\n </div>}\n </main>;\n}\n", "/**\n * DSH is a general Harness: one installed plugin must not turn every Session\n * into a writing surface. The workbench claims the conversation layout only for\n * a workspace that actually holds creative work, and the creator can always\n * take the layout back.\n */\n\nexport type WorkbenchPreference = \"open\" | \"closed\";\n\nexport interface WorkbenchWorkspace {\n readonly files: readonly unknown[];\n readonly games: readonly { readonly source: \"workspace\" | \"example\" }[];\n readonly videos: readonly unknown[];\n}\n\nexport interface WorkbenchPreferenceStorage {\n getItem: (key: string) => string | null;\n setItem: (key: string, value: string) => void;\n}\n\n/** The bundled game example ships with the plugin, so it never marks a workspace as creative. */\nexport function hasCreativeProject(workspace: WorkbenchWorkspace | undefined): boolean {\n if (workspace === undefined) return false;\n return workspace.files.length > 0\n || workspace.videos.length > 0\n || workspace.games.some((game) => game.source === \"workspace\");\n}\n\n/** An explicit creator choice always wins over what the workspace happens to contain. */\nexport function resolveWorkbenchOpen(preference: WorkbenchPreference | undefined, creativeProject: boolean): boolean {\n return preference === undefined ? creativeProject : preference === \"open\";\n}\n\nexport function workbenchPreferenceKey(cwd: string): string {\n return `oh-story.workbench.${cwd}`;\n}\n\n/** The DSH Session Store is not persisted, so the choice is kept per workspace instead. */\nexport function readWorkbenchPreference(storage: WorkbenchPreferenceStorage | undefined, cwd: string | undefined): WorkbenchPreference | undefined {\n if (storage === undefined || cwd === undefined) return undefined;\n let value: string | null;\n try { value = storage.getItem(workbenchPreferenceKey(cwd)); }\n catch { return undefined; }\n return value === \"open\" || value === \"closed\" ? value : undefined;\n}\n\nexport function writeWorkbenchPreference(storage: WorkbenchPreferenceStorage | undefined, cwd: string | undefined, preference: WorkbenchPreference): void {\n if (storage === undefined || cwd === undefined) return;\n // Private windows and blocked site data refuse to persist; the Session still keeps the choice.\n try { storage.setItem(workbenchPreferenceKey(cwd), preference); }\n catch { /* the Session Store remains the in-session authority */ }\n}\n\n/** Reading the property itself throws when the browser blocks site data. */\nexport function workbenchPreferenceStorage(): WorkbenchPreferenceStorage | undefined {\n try { return globalThis.localStorage; }\n catch { return undefined; }\n}\n", ".oh-story-bridge-marker { display: none; }\n.oh-story-welcome {\n box-sizing: border-box;\n order: -1;\n flex-shrink: 0;\n width: min(640px, calc(100% - 32px));\n margin: 24px auto;\n padding: 20px 24px;\n border: 1px solid var(--dsw-alias-border-l2);\n border-radius: 12px;\n color: var(--dsw-alias-label-primary);\n background: var(--dsw-alias-bg-base);\n font: 14px/1.7 var(--dsw-font-family);\n overflow-wrap: anywhere;\n}\n.oh-story-welcome h2 { margin: 0 0 8px; font-size: 20px; }\n.oh-story-welcome p { margin: 8px 0 0; }\n.oh-story-welcome ol { margin: 12px 0; padding-left: 24px; }\n.oh-story-split-surface { display: contents; font-family: var(--dsw-font-family); }\n\n/* Collapsed, the plugin owns nothing but this control: DSH renders the\n conversation exactly as it does without the plugin installed. The launcher is\n fixed to the conversation column's own corner, which the bridge publishes,\n because the surrounding shell is not ours to place things in. */\n.oh-story-launcher {\n box-sizing: border-box;\n display: flex;\n position: fixed;\n z-index: 9;\n top: calc(var(--oh-story-seam-top, 0px) + 10px);\n right: calc(var(--oh-story-seam-right, 0px) + 14px);\n min-height: 28px;\n align-items: center;\n gap: 6px;\n border: 1px solid var(--dsw-alias-border-l2);\n border-radius: 999px;\n color: var(--dsw-alias-label-secondary);\n background: var(--dsw-alias-bg-base);\n padding: 3px 11px;\n cursor: pointer;\n font-family: var(--dsw-font-family);\n font-size: 12px;\n line-height: 20px;\n}\n.oh-story-launcher b { font-weight: 500; }\n.oh-story-launcher:hover { color: var(--dsw-alias-label-primary); background: var(--dsw-alias-interactive-bg-hover); }\n.oh-story-launcher:focus-visible { outline: 2px solid var(--dsw-alias-state-business-primary); outline-offset: 2px; }\n\n/* DSH documents every [data-slot] wrapper as a stable addressable styling\n seam. The official Session body and composer stay mounted; this only turns\n their scroll host into a three-column writing surface. */\n[data-conversation-scroll]:has(> [data-slot=\"conversation.session\"] > .oh-story-split-surface[data-open=\"true\"]) {\n --os-border: var(--dsw-alias-border-l2);\n --os-muted: var(--dsw-alias-label-secondary);\n display: grid;\n grid-template-columns: clamp(184px, 16%, 200px) minmax(240px, 1fr) clamp(408px, 40%, 520px);\n grid-template-rows: minmax(0, 1fr);\n min-height: 0;\n overflow-x: hidden;\n overflow-y: auto;\n position: relative;\n scrollbar-gutter: stable;\n scroll-padding-bottom: calc(max(var(--dsh-composer-height, 152px), var(--oh-story-composer-height, 0px)) + 16px);\n}\n\n/* Keep the final Chat flow above the overlapping official Composer. */\n[data-conversation-scroll]:has(> [data-slot=\"conversation.session\"] > .oh-story-split-surface[data-open=\"true\"])\n > [data-slot=\"conversation.session\"] > :not(.oh-story-split-surface) {\n grid-column: 3;\n grid-row: 1;\n min-width: 0;\n min-height: 100%;\n border-left: 1px solid var(--os-border);\n}\n\n/* DSH 0.1.7 nests a data-chat-flow inside every step-process group; only the top-level flow needs room. */\n[data-conversation-scroll]:has(> [data-slot=\"conversation.session\"] > .oh-story-split-surface[data-open=\"true\"])\n [data-chat-flow]:not([data-step-process-content]) {\n padding-bottom: calc(max(var(--dsh-composer-height, 152px), var(--oh-story-composer-height, 0px)) + 16px);\n}\n\n[data-conversation-scroll]:has(> [data-slot=\"conversation.session\"] > .oh-story-split-surface[data-open=\"true\"])\n > [data-composer-seat] {\n grid-column: 3;\n grid-row: 1;\n align-self: start;\n min-width: 0;\n width: 100%;\n position: sticky;\n top: calc(var(--oh-story-scroll-height, 720px) - max(var(--dsh-composer-height, 152px), var(--oh-story-composer-height, 0px)));\n bottom: auto;\n}\n\n/* Game mode keeps the official Conversation on the right but merges the two\n creator columns into one playable Studio. */\n[data-conversation-scroll][data-oh-story-workbench=\"game\"]:has(> [data-slot=\"conversation.session\"] > .oh-story-split-surface[data-open=\"true\"]) {\n --game-stage: #0d100e;\n --game-stage-raised: #161a17;\n --game-accent: var(--dsw-alias-state-business-primary);\n --game-warning: #f4bd55;\n --game-danger: #f06b63;\n grid-template-columns: minmax(0, 1fr) clamp(400px, 34%, 520px);\n overflow: hidden;\n}\n\n[data-conversation-scroll][data-oh-story-workbench=\"game\"]:has(> [data-slot=\"conversation.session\"] > .oh-story-split-surface[data-open=\"true\"])\n > [data-slot=\"conversation.session\"] > :not(.oh-story-split-surface),\n[data-conversation-scroll][data-oh-story-workbench=\"game\"]:has(> [data-slot=\"conversation.session\"] > .oh-story-split-surface[data-open=\"true\"])\n > [data-composer-seat] { grid-column: 2; }\n\n/* DSH 0.1.2 lays two 40px column-resize strips (z-index 8) over the whole\n conversation area. The workbench replaces that column geometry, so the strip\n no longer marks a real column seam here \u2014 it just swallows clicks on the\n right edge of the file tree. The creator panes take the clicks back. */\n.oh-story-tree,\n.oh-story-editor {\n box-sizing: border-box;\n grid-row: 1;\n position: sticky;\n z-index: 9;\n top: 0;\n align-self: start;\n min-width: 0;\n min-height: 0;\n height: 100%;\n color: inherit;\n background: var(--dsw-alias-bg-base);\n}\n\n.oh-game-studio {\n box-sizing: border-box;\n display: flex;\n grid-column: 1;\n grid-row: 1;\n position: sticky;\n z-index: 9;\n top: 0;\n min-width: 0;\n min-height: 0;\n height: 100%;\n align-self: start;\n overflow: hidden;\n flex-direction: column;\n border-right: 1px solid var(--os-border);\n color: var(--dsw-alias-label-primary);\n background: var(--dsw-alias-bg-base);\n}\n.oh-game-studio[hidden] { display: none; }\n\n.oh-game-toolbar {\n box-sizing: border-box;\n display: grid;\n min-height: 56px;\n flex: none;\n grid-template-columns: auto minmax(160px, 1fr) auto;\n align-items: center;\n gap: 9px;\n padding: 8px 12px;\n border-bottom: 1px solid var(--os-border);\n background: var(--dsw-alias-bg-base);\n}\n\n.oh-game-mode-tabs {\n display: flex;\n margin-right: 2px;\n padding-right: 9px;\n border-right: 1px solid var(--os-border);\n}\n.oh-game-mode-tabs button {\n min-width: 42px;\n min-height: 36px;\n border: 0;\n border-radius: 5px;\n color: var(--os-muted);\n background: transparent;\n padding: 4px 7px;\n cursor: pointer;\n white-space: nowrap;\n font: 11px/1 var(--dsw-font-family);\n}\n.oh-game-mode-tabs button:hover { color: var(--dsw-alias-label-primary); }\n.oh-game-mode-tabs button[aria-selected=\"true\"] { color: var(--dsw-alias-label-primary); background: var(--dsw-alias-button-ghost-active-fill); font-weight: 500; }\n\n.oh-game-project { display: flex; min-width: 0; align-items: center; gap: 7px; color: var(--os-muted); font-size: 11px; }\n.oh-game-project > span { flex: none; }\n.oh-game-project select,\n.oh-game-design select {\n min-width: 0;\n border: 1px solid var(--os-border);\n border-radius: 8px;\n color: var(--dsw-alias-label-primary);\n background: var(--dsw-alias-bg-base);\n padding: 6px 28px 6px 9px;\n font: inherit;\n}\n.oh-game-project select { max-width: 360px; min-height: 36px; flex: 1; overflow: hidden; text-overflow: ellipsis; font-weight: 500; }\n.oh-game-design select { min-height: 36px; }\n.oh-game-project select:focus-visible,\n.oh-game-design select:focus-visible,\n.oh-game-mode-tabs button:focus-visible,\n.oh-game-tabs button:focus-visible,\n.oh-game-preview-status button:focus-visible,\n.oh-game-mobile-switcher button:focus-visible { outline: 2px solid var(--dsw-alias-state-business-primary); outline-offset: 1px; }\n\n.oh-game-tabs,\n.oh-game-mobile-switcher {\n display: flex;\n padding: 2px;\n border: 1px solid var(--os-border);\n border-radius: 9px;\n background: var(--dsw-alias-bg-base);\n}\n.oh-game-tabs button,\n.oh-game-mobile-switcher button {\n min-width: 56px;\n min-height: 36px;\n border: 0;\n border-radius: 6px;\n color: var(--os-muted);\n background: transparent;\n cursor: pointer;\n font: 12px/1 var(--dsw-font-family);\n}\n.oh-game-tabs button:hover,\n.oh-game-mobile-switcher button:hover { color: var(--dsw-alias-label-primary); }\n.oh-game-tabs button[aria-selected=\"true\"],\n.oh-game-mobile-switcher button[aria-selected=\"true\"] { color: var(--dsw-alias-label-primary); background: var(--dsw-alias-button-ghost-active-fill); box-shadow: 0 1px 2px rgb(0 0 0 / 7%); font-weight: 600; }\n.oh-game-panels,\n.oh-game-panel {\n display: flex;\n min-width: 0;\n min-height: 0;\n flex: 1;\n overflow: hidden;\n flex-direction: column;\n}\n.oh-game-panel[hidden] { display: none; }\n\n.oh-game-preview-shell {\n display: grid;\n min-width: 0;\n min-height: 0;\n flex: 1;\n grid-template-rows: 40px minmax(0, 1fr);\n position: relative;\n overflow: hidden;\n border-top: 2px solid var(--game-accent);\n background-color: var(--game-stage);\n}\n.oh-game-preview-shell[data-state=\"building\"] { border-top-color: var(--game-warning); animation: oh-game-build-line 1.4s linear infinite; }\n.oh-game-preview-shell[data-state=\"error\"] { border-top-color: var(--game-danger); }\n.oh-game-preview-status {\n display: flex;\n min-width: 0;\n align-items: center;\n justify-content: space-between;\n gap: 12px;\n padding: 0 10px 0 12px;\n color: rgb(244 248 240 / 76%);\n background: var(--game-stage-raised);\n font-size: 11px;\n}\n.oh-game-runtime-state { display: inline-flex; overflow: hidden; min-width: 0; align-items: center; gap: 7px; text-overflow: ellipsis; white-space: nowrap; }\n.oh-game-runtime-state > i { width: 6px; height: 6px; flex: none; border-radius: 50%; background: var(--dsw-alias-state-success-primary, #45b96f); }\n.oh-game-preview-shell[data-state=\"loading\"] .oh-game-runtime-state > i { background: rgb(255 255 255 / 42%); box-shadow: none; }\n.oh-game-preview-shell[data-state=\"building\"] .oh-game-runtime-state > i { background: var(--game-warning); }\n.oh-game-preview-shell[data-state=\"error\"] .oh-game-runtime-state > i { background: var(--game-danger); }\n.oh-game-preview-status > div { display: flex; flex: none; gap: 6px; }\n.oh-game-preview-status button {\n min-height: 36px;\n border: 1px solid rgb(255 255 255 / 14%);\n border-radius: 6px;\n color: rgb(255 255 255 / 84%);\n background: rgb(255 255 255 / 5%);\n padding: 3px 8px;\n cursor: pointer;\n font: inherit;\n}\n.oh-game-preview-status button:hover { background: rgb(255 255 255 / 11%); }\n.oh-game-reload { display: inline-flex; align-items: center; gap: 5px; }\n.oh-game-reload b { font: inherit; font-weight: 500; }\n.oh-game-preview-shell iframe { width: 100%; height: 100%; min-width: 0; min-height: 0; border: 0; background: var(--game-stage); }\n.oh-game-focus-hint {\n position: absolute;\n right: 10px;\n bottom: 10px;\n z-index: 2;\n padding: 4px 8px;\n border: 1px solid rgb(255 255 255 / 12%);\n border-radius: 6px;\n color: rgb(255 255 255 / 62%);\n background: rgb(8 10 9 / 82%);\n pointer-events: none;\n font-size: 10px;\n}\n.oh-game-focus-hint[data-focused] { color: var(--game-accent); }\n\n.oh-game-preview-empty,\n.oh-game-design-empty {\n display: grid;\n max-width: 560px;\n margin: auto;\n padding: 36px;\n place-items: center;\n gap: 8px;\n color: var(--os-muted);\n text-align: center;\n line-height: 1.65;\n}\n.oh-game-preview-empty { width: 100%; max-width: none; min-height: 0; flex: 1; box-sizing: border-box; align-content: center; color: rgb(244 248 240 / 70%); background: var(--game-stage); }\n.oh-game-preview-empty > span { color: var(--game-accent); font-size: 30px; }\n.oh-game-preview-empty strong,\n.oh-game-design-empty strong { color: inherit; font-size: 15px; }\n.oh-game-preview-empty p,\n.oh-game-design-empty p { margin: 0; }\n.oh-game-preview-empty code,\n.oh-game-design-empty code { font: 11px/1.5 ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace; }\n.oh-game-prompt-example { display: grid; max-width: 560px; gap: 4px; margin-top: 8px; padding: 10px 12px; border: 1px solid rgb(255 255 255 / 12%); border-radius: 8px; text-align: left; }\n.oh-game-prompt-example span { color: var(--game-accent); font-size: 10px; font-weight: 600; }\n.oh-game-prompt-example q { color: rgb(244 248 240 / 72%); quotes: none; font-size: 11px; }\n\n.oh-game-design { display: flex; min-height: 0; flex: 1; overflow: hidden; flex-direction: column; }\n.oh-game-design > label { display: flex; min-height: 42px; flex: none; align-items: center; gap: 10px; padding: 0 14px; border-bottom: 1px solid var(--os-border); color: var(--os-muted); font-size: 11px; }\n.oh-game-design select { max-width: min(560px, 75%); }\n.oh-game-source { box-sizing: border-box; min-height: 0; flex: 1; overflow: auto; margin: 0; padding: 18px 22px 48px; color: var(--dsw-alias-label-secondary); background: var(--dsw-alias-markdown-code-block); white-space: pre-wrap; overflow-wrap: anywhere; font: 12px/1.65 ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace; }\n\n.oh-game-mobile-switcher { display: none; }\n\n@keyframes oh-game-build-line { 50% { border-top-color: var(--game-accent); } }\n\n.oh-story-tree {\n grid-column: 1;\n overflow: auto;\n padding: 14px 10px 24px;\n border-right: 1px solid var(--os-border);\n background: var(--dsw-specific-sidebar-fill);\n}\n\n.oh-story-editor {\n display: flex;\n grid-column: 2;\n overflow: hidden;\n flex-direction: column;\n}\n\n.oh-story-brand,\n.oh-story-editor header,\n.oh-story-role summary {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 12px;\n}\n\n.oh-story-brand { min-height: 28px; gap: 8px; padding: 0 5px 8px 7px; font-size: 14px; font-weight: 500; white-space: nowrap; }\n.oh-story-brand-cluster { display: flex; min-width: 0; align-items: center; gap: 6px; }\n.oh-story-brand-cluster strong { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font: inherit; }\n.oh-story-kind { flex: none; padding: 1px 6px; border-radius: 5px; color: var(--dsw-alias-label-secondary); background: var(--dsw-alias-button-ghost-active-fill); font-size: 11px; line-height: 16px; font-weight: 500; }\n\n.oh-story-brand button,\n.oh-story-save,\n.oh-story-role button {\n border: 1px solid var(--dsw-alias-border-l2);\n border-radius: 999px;\n color: var(--dsw-alias-label-secondary);\n background: var(--dsw-alias-bg-base);\n padding: 3px 9px;\n cursor: pointer;\n font: inherit;\n}\n\n.oh-story-brand button { display: grid; width: 28px; height: 28px; place-items: center; border: 0; padding: 0; background: transparent; font-size: 16px; }\n.oh-story-brand button:hover,\n.oh-story-save:hover:not(:disabled),\n.oh-story-role button:hover { color: var(--dsw-alias-label-primary); background: var(--dsw-alias-interactive-bg-hover); }\n.oh-story-brand button:focus-visible,\n.oh-story-save:focus-visible,\n.oh-story-mode-tabs button:focus-visible,\n.oh-story-editor-tabs button:focus-visible,\n.oh-story-tree nav button:focus-visible,\n.oh-story-role button:focus-visible { outline: 2px solid var(--dsw-alias-state-business-primary); outline-offset: -2px; }\n.oh-story-save:disabled { opacity: .48; cursor: default; }\n\n.oh-story-brand-actions { display: flex; flex: none; align-items: center; gap: 2px; }\n\n.oh-workbench-cluster { display: flex; min-width: 0; align-items: center; gap: 6px; }\n.oh-workbench-collapse {\n display: grid;\n width: 28px;\n height: 28px;\n flex: none;\n place-items: center;\n border: 0;\n border-radius: 5px;\n color: var(--os-muted);\n background: transparent;\n padding: 0;\n cursor: pointer;\n font: inherit;\n font-size: 16px;\n}\n.oh-workbench-collapse:hover { color: var(--dsw-alias-label-primary); background: var(--dsw-alias-interactive-bg-hover); }\n.oh-workbench-collapse:focus-visible { outline: 2px solid var(--dsw-alias-state-business-primary); outline-offset: -2px; }\n\n.oh-story-mode-tabs { display: flex; margin: 0 4px 8px; padding: 2px; border: 1px solid var(--os-border); border-radius: 7px; background: var(--dsw-alias-bg-layer-1); }\n\n.oh-story-mode-tabs button,\n.oh-story-editor-tabs button {\n position: relative;\n min-height: 24px;\n flex: 1;\n border: 0;\n color: var(--os-muted);\n background: transparent;\n border-radius: 5px;\n cursor: pointer;\n font: inherit;\n font-size: 11px;\n}\n\n.oh-story-mode-tabs button:hover,\n.oh-story-editor-tabs button:hover { color: var(--dsw-alias-label-primary); }\n.oh-story-mode-tabs button[aria-selected=\"true\"],\n.oh-story-editor-tabs button[aria-selected=\"true\"] { color: var(--dsw-alias-label-primary); background: var(--dsw-alias-bg-base); box-shadow: 0 1px 2px rgb(0 0 0 / 8%); font-weight: 500; }\n\n.oh-story-file-group,\n.oh-story-file-folder { margin: 0; }\n.oh-story-file-group > summary,\n.oh-story-file-folder > summary {\n display: flex;\n align-items: center;\n gap: 5px;\n min-height: 26px;\n padding: 0 7px;\n border-radius: 6px;\n color: var(--os-muted);\n cursor: pointer;\n list-style: none;\n font-size: 11px;\n font-weight: 600;\n}\n.oh-story-file-folder > summary { padding-left: min(calc(7px + var(--oh-story-indent, 0px)), 49px); }\n.oh-story-file-group > summary { margin-top: 3px; }\n.oh-story-file-group > summary::-webkit-details-marker,\n.oh-story-file-folder > summary::-webkit-details-marker { display: none; }\n.oh-story-file-group > summary::before,\n.oh-story-file-folder > summary::before { width: 8px; content: \"\u203A\"; transform: rotate(0); transition: transform .12s ease; }\n.oh-story-file-group[open] > summary::before,\n.oh-story-file-folder[open] > summary::before { transform: rotate(90deg); }\n.oh-story-file-group > summary:hover,\n.oh-story-file-folder > summary:hover { color: var(--dsw-alias-label-primary); background: var(--dsw-alias-interactive-bg-hover); }\n.oh-story-file-group > summary span,\n.oh-story-file-folder > summary span { margin-left: auto; color: var(--dsw-alias-label-secondary); font-weight: 400; }\n\n.oh-story-tree nav button {\n display: block;\n width: 100%;\n overflow: hidden;\n padding: 6px 8px 6px min(calc(14px + var(--oh-story-indent, 0px)), 56px);\n border: 0;\n border-radius: 6px;\n color: inherit;\n background: transparent;\n text-align: left;\n text-overflow: ellipsis;\n white-space: nowrap;\n cursor: pointer;\n font: inherit;\n font-size: 12px;\n}\n.oh-story-tree nav button:hover { background: var(--dsw-alias-interactive-bg-hover); }\n.oh-story-tree nav button[aria-current=\"page\"] { background: var(--dsw-alias-button-ghost-active-fill); color: var(--dsw-alias-label-primary); }\n.oh-story-tree nav button[data-agent-target] { box-shadow: inset 2px 0 var(--dsw-alias-state-business-primary); }\n\n.oh-story-editor > header {\n min-height: 44px;\n flex: none;\n padding: 0 14px;\n border-bottom: 1px solid var(--os-border);\n}\n\n.oh-story-editor-path {\n overflow: hidden;\n min-width: 0;\n flex: 1;\n text-overflow: ellipsis;\n white-space: nowrap;\n font-size: 12px;\n color: var(--os-muted);\n}\n.oh-story-editor-path > span { overflow: hidden; display: block; text-overflow: ellipsis; }\n.oh-story-editor-path > strong { display: none; overflow: hidden; text-overflow: ellipsis; font: inherit; }\n\n.oh-story-editor-actions { display: flex; flex: none; align-items: center; gap: 8px; }\n.oh-story-editor-tabs {\n display: flex;\n padding: 2px;\n border: 1px solid var(--os-border);\n border-radius: 7px;\n background: var(--dsw-alias-bg-layer-1);\n}\n.oh-story-editor-tabs button { min-height: 24px; padding: 0 9px; border-radius: 5px; font-size: 11px; }\n.oh-story-save { min-height: 28px; }\n\n.oh-story-editor textarea {\n box-sizing: border-box;\n width: 100%;\n min-height: 0;\n flex: 1;\n resize: none;\n border: 0;\n outline: 0;\n padding: clamp(20px, 6%, 48px) clamp(22px, 10%, 84px) 48px;\n color: var(--dsw-alias-label-primary);\n background: transparent;\n font: 16px/1.9 ui-serif, \"Songti SC\", \"STSong\", Georgia, serif;\n}\n.oh-story-editor textarea[data-format=\"structured\"] {\n tab-size: 2;\n font: 13px/1.65 ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;\n}\n\n.oh-story-markdown {\n box-sizing: border-box;\n width: 100%;\n min-height: 0;\n flex: 1;\n overflow: auto;\n padding: clamp(24px, 8%, 56px) clamp(24px, 10%, 92px) 64px;\n color: var(--dsw-alias-label-primary);\n font: 16px/1.85 ui-serif, \"Songti SC\", \"STSong\", Georgia, serif;\n overflow-wrap: anywhere;\n}\n.oh-story-markdown > :first-child { margin-top: 0; }\n.oh-story-markdown > :last-child { margin-bottom: 0; }\n.oh-story-markdown h1,\n.oh-story-markdown h2,\n.oh-story-markdown h3,\n.oh-story-markdown h4,\n.oh-story-markdown h5,\n.oh-story-markdown h6 { margin: 1.45em 0 .6em; font-family: var(--dsw-font-family); line-height: 1.35; letter-spacing: -.01em; }\n.oh-story-markdown h1 { font-size: 1.75em; }\n.oh-story-markdown h2 { padding-bottom: .35em; border-bottom: 1px solid var(--os-border); font-size: 1.35em; }\n.oh-story-markdown h3 { font-size: 1.15em; }\n.oh-story-markdown p { margin: .75em 0; }\n.oh-story-markdown ul,\n.oh-story-markdown ol { margin: .75em 0; padding-left: 1.6em; }\n.oh-story-markdown li { margin: .28em 0; }\n.oh-story-markdown .oh-story-task-item { list-style: none; margin-left: -1.35em; }\n.oh-story-task-item input { margin: 0 .55em 0 0; accent-color: var(--dsw-alias-state-business-primary); }\n.oh-story-markdown blockquote { margin: 1em 0; padding: .1em 1em; border-left: 3px solid var(--dsw-alias-state-business-primary); color: var(--dsw-alias-label-secondary); }\n/* DSH gives inline code its own alias; the block fill is a different surface. */\n.oh-story-markdown code { padding: .15em .4em; border-radius: 4px; background: var(--dsw-alias-markdown-inline-code); font: .86em/1.6 ui-monospace, SFMono-Regular, Menlo, monospace; }\n.oh-story-markdown pre { overflow: auto; margin: 1em 0; padding: 14px 16px; border: 1px solid var(--dsw-alias-border-l1); border-radius: 10px; background: var(--dsw-alias-markdown-code-block); }\n.oh-story-markdown pre code { padding: 0; background: transparent; }\n.oh-story-markdown a { color: var(--dsw-alias-state-business-primary); text-decoration-thickness: 1px; text-underline-offset: 3px; }\n.oh-story-markdown del { color: var(--os-muted); }\n.oh-story-markdown-table { overflow-x: auto; margin: 1em 0; border: 1px solid var(--os-border); border-radius: 10px; }\n.oh-story-markdown table { width: 100%; border-collapse: collapse; font-family: ui-sans-serif, system-ui, \"PingFang SC\", sans-serif; font-size: 13px; line-height: 1.55; }\n.oh-story-markdown th,\n.oh-story-markdown td { min-width: 96px; padding: 9px 12px; border-right: 1px solid var(--os-border); border-bottom: 1px solid var(--os-border); vertical-align: top; }\n.oh-story-markdown th:last-child,\n.oh-story-markdown td:last-child { border-right: 0; }\n.oh-story-markdown tbody tr:last-child td { border-bottom: 0; }\n.oh-story-markdown th { background: var(--dsw-alias-bg-layer-1); font-weight: 600; }\n.oh-story-markdown hr { margin: 2em 0; border: 0; border-top: 1px solid var(--os-border); }\n.oh-story-markdown-empty { margin: auto; color: var(--os-muted); font-size: 13px; }\n\n.oh-story-jsonl {\n box-sizing: border-box;\n display: flex;\n width: 100%;\n min-height: 0;\n flex: 1;\n overflow: hidden;\n flex-direction: column;\n color: var(--dsw-alias-label-primary);\n background: var(--dsw-alias-bg-base);\n}\n.oh-story-jsonl-summary { display: flex; min-height: 42px; flex: none; align-items: center; gap: 10px; padding: 0 18px; border-bottom: 1px solid var(--os-border); font-size: 12px; }\n.oh-story-jsonl-summary strong { font-weight: 600; }\n.oh-story-jsonl-summary span { color: var(--os-muted); }\n.oh-story-jsonl-records { overflow: auto; padding: 14px 18px 36px; }\n.oh-story-jsonl details,\n.oh-story-jsonl-error { overflow: hidden; margin-bottom: 10px; border: 1px solid var(--os-border); border-radius: 10px; background: var(--dsw-alias-bg-layer-1); }\n.oh-story-jsonl summary { display: flex; min-height: 42px; align-items: center; gap: 9px; padding: 0 12px; cursor: pointer; list-style: none; font: 12px/1.4 var(--dsw-font-family); }\n.oh-story-jsonl summary::-webkit-details-marker { display: none; }\n.oh-story-jsonl summary::before { content: \"\u203A\"; color: var(--os-muted); font-size: 16px; transition: transform .12s ease; }\n.oh-story-jsonl details[open] summary::before { transform: rotate(90deg); }\n.oh-story-jsonl summary > span { flex: none; color: var(--os-muted); font-variant-numeric: tabular-nums; }\n.oh-story-jsonl summary > strong { overflow: hidden; min-width: 80px; flex: 1; text-overflow: ellipsis; white-space: nowrap; font-weight: 600; }\n.oh-story-jsonl summary > code,\n.oh-story-jsonl summary > em { flex: none; padding: 2px 6px; border-radius: 5px; background: var(--dsw-alias-button-ghost-active-fill); color: var(--dsw-alias-label-secondary); font: 11px/1.35 ui-monospace, SFMono-Regular, Menlo, monospace; font-style: normal; }\n.oh-story-jsonl pre { overflow: auto; max-height: 520px; margin: 0; padding: 14px 16px; border-top: 1px solid var(--os-border); background: var(--dsw-alias-markdown-code-block); color: var(--dsw-alias-label-secondary); white-space: pre-wrap; overflow-wrap: anywhere; font: 12px/1.6 ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace; }\n.oh-story-jsonl-error { display: grid; gap: 5px; padding: 12px; border-color: var(--dsw-alias-state-error-primary); font-size: 12px; }\n.oh-story-jsonl-error > strong { color: var(--dsw-alias-state-error-primary); }\n.oh-story-jsonl-error > span { color: var(--os-muted); }\n.oh-story-jsonl-error pre { margin: 3px -12px -12px; }\n\n.oh-story-stream,\n.oh-story-conflict,\n.oh-story-warning {\n flex: none;\n padding: 7px 12px;\n border-bottom: 1px solid var(--os-border);\n font-size: 11px;\n line-height: 1.4;\n}\n\n.oh-story-stream { color: var(--dsw-alias-state-business-primary); background: var(--dsw-alias-button-ghost-active-fill); }\n.oh-story-stream[data-stage=\"streaming\"] { animation: oh-story-pulse 1.2s ease-in-out infinite alternate; }\n.oh-story-conflict { color: var(--dsw-alias-state-warn-label); background: var(--dsw-specific-tip); }\n.oh-story-conflict > div { display: flex; gap: 6px; margin-top: 6px; }\n.oh-story-conflict button,\n.oh-story-empty button {\n border: 1px solid var(--os-border);\n border-radius: 6px;\n color: inherit;\n background: var(--dsw-alias-bg-base);\n padding: 3px 8px;\n cursor: pointer;\n font: inherit;\n}\n.oh-story-warning { color: var(--dsw-alias-state-warn-label); background: var(--dsw-specific-tip); }\n\n@keyframes oh-story-pulse { to { opacity: .62; } }\n@media (prefers-reduced-motion: reduce) { .oh-story-stream[data-stage=\"streaming\"] { animation: none; } }\n\n.oh-story-empty { margin: auto; max-width: 480px; padding: 30px; color: var(--os-muted); line-height: 1.7; text-align: center; }\n.oh-story-error { margin: 8px; padding: 8px 10px; border-radius: 8px; color: var(--dsw-alias-state-error-primary); background: var(--dsw-specific-tip); font-size: 12px; }\n\n.oh-story-role { display: flex; flex-direction: column; margin: 0; overflow: hidden; }\n.oh-story-role summary { min-height: 24px; padding: 0; cursor: pointer; list-style: none; font-size: 14px; line-height: 24px; }\n.oh-story-role summary::-webkit-details-marker { display: none; }\n.oh-story-role summary span { color: var(--dsw-alias-state-business-primary); }\n.oh-story-role summary strong { margin-right: auto; color: var(--dsw-alias-label-secondary); font-weight: 500; }\n.oh-story-role summary em { color: var(--dsw-alias-label-caption); font-style: normal; font-size: 12px; }\n.oh-story-role[data-state=\"error\"] summary em { color: var(--dsw-alias-state-error-primary); }\n.oh-story-role pre { max-height: 260px; overflow: auto; margin: 4px 0 4px 4px; padding: 12px 16px; border: 1px solid var(--dsw-alias-border-l1); border-radius: 12px; color: var(--dsw-alias-label-secondary); background: var(--dsw-alias-markdown-code-block); white-space: pre-wrap; font: var(--dsw-font-markdown-code-block-small); }\n.oh-story-role > button { align-self: flex-start; margin: 4px 0 2px 4px; font-size: 11px; }\n\n/* Short-drama production views are projections of the creator Markdown and\n DSH Session state. They intentionally use only DSH semantic tokens. */\n.oh-story-production { min-height: 0; flex: 1; overflow: auto; background: var(--dsw-alias-bg-base); font: 12px/1.5 var(--dsw-font-family); }\n.oh-story-production button,\n.oh-story-production select { border: 1px solid var(--os-border); border-radius: 6px; color: inherit; background: var(--dsw-alias-bg-base); padding: 4px 8px; cursor: pointer; font: inherit; }\n.oh-story-production button:hover:not(:disabled) { background: var(--dsw-alias-interactive-bg-hover); }\n.oh-story-production button:disabled { opacity: .45; cursor: default; }\n.oh-story-production button:focus-visible,\n.oh-story-canvas article:focus-visible { outline: 2px solid var(--dsw-alias-state-business-primary); outline-offset: 2px; }\n.oh-story-production-bar,\n.oh-story-production-notice,\n.oh-story-production-actions,\n.oh-story-sequence-summary { display: flex; align-items: center; gap: 8px; }\n.oh-story-production-bar { position: sticky; z-index: 5; top: 0; justify-content: space-between; min-height: 44px; box-sizing: border-box; padding: 6px 12px; border-bottom: 1px solid var(--os-border); background: color-mix(in srgb, var(--dsw-alias-bg-base) 94%, transparent); backdrop-filter: blur(12px); }\n.oh-story-production-tabs { display: flex; align-self: stretch; gap: 16px; }\n.oh-story-production-tabs button { position: relative; border: 0; border-radius: 0; padding: 0; background: transparent; color: var(--os-muted); }\n.oh-story-production-tabs button[aria-selected=\"true\"] { color: var(--dsw-alias-label-primary); }\n.oh-story-production-tabs button[aria-selected=\"true\"]::after { position: absolute; right: 0; bottom: -6px; left: 0; height: 2px; border-radius: 2px; background: var(--dsw-alias-state-business-primary); content: \"\"; }\n.oh-story-production-meta { display: flex; align-items: center; gap: 8px; }\n.oh-story-production-meta > button { padding-block: 2px; color: var(--os-muted); }\n.oh-story-production-summary { color: var(--os-muted); white-space: nowrap; }\n.oh-story-production-notice { justify-content: space-between; margin: 8px 12px 0; padding: 7px 9px; border: 1px solid var(--os-border); border-radius: 7px; color: var(--dsw-alias-label-secondary); background: var(--dsw-alias-bg-layer-1); }\n.oh-story-production-notice button { border: 0; background: transparent; }\n.oh-story-production-environment { display: flex; min-width: 0; flex-wrap: wrap; align-items: center; gap: 5px 10px; margin: 8px 12px 0; padding: 7px 9px; border: 1px solid var(--os-border); border-radius: 7px; color: var(--os-muted); background: var(--dsw-alias-bg-layer-1); font-size: 10px; }\n/* Environment names such as MINIMAX_VIDEO_RESOLUTIONS and the temp-dir path are longer than the 500 px editor column; let them break rather than widen the view. */\n.oh-story-production-environment > * { min-width: 0; max-width: 100%; overflow-wrap: anywhere; }\n.oh-story-production-environment strong { color: var(--dsw-alias-label-secondary); font-size: 11px; }\n.oh-story-production-environment span::before { content: \"\u25CF\"; margin-right: 4px; color: var(--video-danger, #d9534f); }\n.oh-story-production-environment span[data-ready]::before { color: var(--dsw-alias-state-success-primary, #45b96f); }\n.oh-story-production-environment span[data-pending]::before { color: var(--os-muted); }\n.oh-story-production-environment em { flex-basis: 100%; font-style: normal; line-height: 1.5; }\n.oh-story-production-environment code { font-size: 10px; overflow-wrap: anywhere; }\n.oh-story-production-environment button { min-height: 24px; border: 1px solid var(--os-border); border-radius: 6px; padding: 0 8px; color: inherit; background: var(--dsw-alias-bg-base); cursor: pointer; font: inherit; }\n.oh-story-production-diagnostics { margin: 8px 12px 0; padding: 7px 9px; border: 1px solid var(--dsw-alias-state-warn-label); border-radius: 7px; background: var(--dsw-specific-tip); }\n.oh-story-production-diagnostics summary { color: var(--dsw-alias-state-warn-label); cursor: pointer; }\n.oh-story-production-diagnostics ul { display: grid; gap: 4px; margin: 8px 0 0; padding: 0; list-style: none; }\n.oh-story-production-diagnostics li { display: grid; grid-template-columns: auto minmax(0, 1fr); align-items: start; gap: 6px; color: var(--dsw-alias-label-secondary); }\n.oh-story-production-diagnostics li[data-severity=\"error\"] { color: var(--dsw-alias-state-error-primary); }\n.oh-story-production-diagnostics li button { border: 0; padding: 0; color: inherit; background: transparent; text-align: left; }\n.oh-story-production-diagnostics p { margin: 6px 0 0; color: var(--os-muted); }\n.oh-story-production-actions { justify-content: flex-end; margin-bottom: 12px; }\n.oh-story-production-actions button:last-child,\n.oh-story-sequence-summary button { color: var(--dsw-alias-state-business-primary); border-color: var(--dsw-alias-state-business-primary); }\n.oh-story-shot-board { padding: 16px 12px; }\n.oh-story-shot-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); align-items: start; gap: 12px; }\n.oh-story-shot-card,\n.oh-story-asset-card,\n.oh-story-task-board > article { min-width: 0; overflow: hidden; border: 1px solid var(--os-border); border-radius: 10px; background: var(--dsw-alias-bg-layer-1); }\n.oh-story-shot-card { padding: 10px; cursor: default; transition: border-color .15s ease, background-color .15s ease; }\n.oh-story-shot-card:hover { border-color: var(--dsw-alias-border-l2); }\n.oh-story-shot-card { cursor: pointer; }\n.oh-story-shot-card:focus-visible,\n.oh-story-asset-card:focus-visible { outline: 2px solid var(--dsw-alias-state-business-primary); outline-offset: 2px; }\n.oh-story-shot-card[data-selected],\n.oh-story-asset-card[data-selected] { border-color: var(--dsw-alias-state-business-primary); background: color-mix(in srgb, var(--dsw-alias-state-business-primary) 4%, var(--dsw-alias-bg-layer-1)); }\n.oh-story-shot-card > header,\n.oh-story-task-board article > header { display: flex; min-height: 0; align-items: center; gap: 8px; padding: 0; border: 0; }\n.oh-story-shot-card > header > button { overflow: hidden; min-width: 0; flex: 1; border: 0; padding: 0; color: var(--dsw-alias-state-business-primary); background: transparent; text-align: left; text-overflow: ellipsis; white-space: nowrap; }\n.oh-story-shot-card > header > span { color: var(--os-muted); font-variant-numeric: tabular-nums; }\n.oh-story-shot-card h3,\n.oh-story-asset-card h3 { margin: 7px 0 4px; font-size: 13px; font-weight: 600; }\n.oh-story-shot-card > p,\n.oh-story-asset-card > p,\n.oh-story-task-board article > p { margin: 5px 0; color: var(--os-muted); }\n.oh-story-shot-placeholder { display: grid; height: 132px; place-content: center; gap: 3px; margin-bottom: 8px; border-radius: 7px; color: var(--os-muted); background: var(--dsw-alias-button-ghost-active-fill); text-align: center; }\n.oh-story-shot-placeholder strong { color: var(--dsw-alias-label-secondary); font-size: 22px; font-variant-numeric: tabular-nums; }\n.oh-story-shot-card dl { display: grid; grid-template-columns: 20px minmax(0, 1fr); margin: 7px 0; }\n.oh-story-shot-card dt { color: var(--dsw-alias-state-business-primary); }\n.oh-story-shot-card dd { min-width: 0; margin: 0; overflow-wrap: anywhere; }\n.oh-story-shot-status,\n.oh-story-reference-links,\n.oh-story-card-actions { display: flex; flex-wrap: wrap; gap: 5px; margin-top: 7px; }\n.oh-story-shot-status span { padding: 1px 5px; border-radius: 5px; color: var(--os-muted); background: var(--dsw-alias-button-ghost-active-fill); }\n.oh-story-shot-status span[data-ready=\"true\"] { color: var(--dsw-alias-state-business-primary); }\n.oh-story-shot-status span > i { margin-right: 3px; font-style: normal; }\n.oh-story-reference-links button { max-width: 100%; overflow: hidden; padding: 1px 5px; border: 0; color: var(--dsw-alias-state-business-primary); background: transparent; text-overflow: ellipsis; }\n.oh-story-card-actions { padding-top: 8px; border-top: 1px solid var(--os-border); }\n.oh-story-card-actions button { flex: 1; padding-block: 4px; }\n.oh-story-card-actions button:last-child { color: var(--dsw-alias-state-business-primary); border-color: color-mix(in srgb, var(--dsw-alias-state-business-primary) 45%, var(--os-border)); }\n.oh-story-media-preview { display: block; width: 100%; height: 168px; border-radius: 7px; background: var(--dsw-alias-bg-base); object-fit: contain; }\n.oh-story-media-document { display: grid; min-height: 0; flex: 1; overflow: auto; place-items: center; padding: 24px; }\n.oh-story-media-document img,\n.oh-story-media-document video { display: block; max-width: 100%; max-height: 100%; object-fit: contain; }\n.oh-story-media-document audio { width: min(520px, 100%); }\n.oh-story-version-strip { display: flex; gap: 5px; overflow-x: auto; margin-top: 8px; padding-top: 8px; border-top: 1px solid var(--os-border); }\n.oh-story-version-strip > button { position: relative; width: 64px; min-width: 64px; padding: 2px; }\n.oh-story-version-strip > button[data-selected] { border-color: var(--dsw-alias-state-business-primary); }\n.oh-story-version-strip .oh-story-media-preview { height: 72px; }\n.oh-story-version-strip span { position: absolute; right: 3px; bottom: 3px; padding: 0 3px; border-radius: 3px; background: var(--dsw-alias-bg-base); font-size: 10px; }\n.oh-story-asset-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: 12px; padding: 16px 12px; }\n.oh-story-asset-card { padding: 10px; }\n.oh-story-asset-card > div:nth-child(2) > button { overflow: hidden; max-width: 100%; border: 0; padding: 0; color: var(--dsw-alias-state-business-primary); background: transparent; text-overflow: ellipsis; }\n.oh-story-asset-card small { color: var(--os-muted); text-transform: uppercase; }\n.oh-story-asset-placeholder { display: grid; height: 112px; place-items: center; border-radius: 7px; color: var(--os-muted); background: var(--dsw-alias-button-ghost-active-fill); font-size: 28px; }\n.oh-story-asset-description { display: -webkit-box; overflow: hidden; -webkit-box-orient: vertical; -webkit-line-clamp: 5; line-clamp: 5; }\n.oh-story-media-library { margin: 0 12px 14px; padding-top: 12px; border-top: 1px solid var(--os-border); }\n.oh-story-media-library > header { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-bottom: 10px; }\n.oh-story-media-library > header > div { display: flex; align-items: center; gap: 7px; }\n.oh-story-media-library > header span { color: var(--os-muted); }\n.oh-story-media-library input { width: 180px; box-sizing: border-box; border: 1px solid var(--os-border); border-radius: 6px; padding: 5px 8px; color: inherit; background: var(--dsw-alias-bg-base); font: inherit; }\n.oh-story-media-library > .oh-story-projection-note { margin-bottom: 10px; }\n.oh-story-media-library-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(160px, 1fr)); gap: 8px; }\n.oh-story-media-library-grid > article { display: flex; min-width: 0; flex-direction: column; gap: 5px; padding: 7px; border: 1px solid var(--os-border); border-radius: 8px; background: var(--dsw-alias-bg-layer-1); }\n.oh-story-media-library-grid .oh-story-media-preview { height: 116px; }\n.oh-story-media-library-grid > article > span { overflow: hidden; color: var(--os-muted); font-size: 10px; text-overflow: ellipsis; white-space: nowrap; }\n.oh-story-media-library-grid footer { display: flex; gap: 4px; margin-top: auto; }\n.oh-story-media-library-grid footer button { min-width: 0; flex: 1; padding-inline: 4px; }\n.oh-story-media-library-grid footer button[aria-pressed=\"true\"] { color: var(--dsw-alias-state-business-primary); border-color: var(--dsw-alias-state-business-primary); }\n.oh-story-task-board { display: grid; gap: 10px; padding: 12px; }\n.oh-story-task-board > article { padding: 11px; }\n.oh-story-task-board > article[data-status=\"dispatched_unknown\"] { border-color: var(--dsw-alias-state-warn-label); }\n.oh-story-task-board > article[data-status=\"dispatched_unknown\"] .oh-story-error { color: var(--dsw-alias-state-warn-label); background: var(--dsw-specific-tip); }\n.oh-story-task-board article > header strong { min-width: 0; flex: 1; overflow: hidden; text-overflow: ellipsis; }\n.oh-story-task-board article > header span { padding: 1px 5px; border-radius: 5px; color: var(--os-muted); background: var(--dsw-alias-button-ghost-active-fill); }\n.oh-story-task-progress { height: 3px; overflow: hidden; margin-top: 8px; border-radius: 3px; background: var(--os-border); }\n.oh-story-task-progress i { display: block; height: 100%; background: var(--dsw-alias-state-business-primary); transition: width .2s ease; }\n.oh-story-task-board details { margin-top: 8px; color: var(--os-muted); }\n.oh-story-task-board details summary { cursor: pointer; }\n.oh-story-task-board details p { max-height: 120px; overflow: auto; margin: 6px 0; padding: 8px; border-radius: 6px; background: var(--dsw-alias-bg-base); white-space: pre-wrap; }\n.oh-story-task-board footer { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: 5px; margin-top: 8px; }\n.oh-story-projection-note { padding: 7px 10px; border: 1px solid var(--os-border); border-radius: 7px; color: var(--os-muted); background: var(--dsw-alias-bg-layer-1); }\n.oh-story-task-board > .oh-story-projection-note { margin-bottom: 0; }\n.oh-story-production-empty { padding: 48px 20px; color: var(--os-muted); text-align: center; }\n.oh-story-production-empty strong { display: block; margin-bottom: 6px; color: var(--dsw-alias-text-1); font-size: 13px; }\n.oh-story-production-empty p { margin: 0 auto; max-width: 44em; line-height: 1.6; }\n.oh-story-production-empty button { margin-top: 12px; }\n.oh-story-sequence { padding: 12px; }\n.oh-story-sequence-summary { justify-content: space-between; margin-bottom: 10px; }\n.oh-story-sequence-summary span { margin-left: auto; color: var(--os-muted); }\n.oh-story-sequence-issues { margin: 0 0 10px; padding: 8px 8px 8px 28px; border-radius: 7px; color: var(--dsw-alias-state-warn-label); background: var(--dsw-specific-tip); }\n.oh-story-sequence-issues li + li { margin-top: 2px; }\n.oh-story-sequence ol { display: grid; gap: 6px; margin: 0; padding: 0; list-style: none; }\n.oh-story-sequence > ol > li { display: grid; min-height: 70px; grid-template-columns: 28px 96px minmax(0, 1fr) auto; align-items: center; gap: 8px; padding: 7px; border: 1px solid var(--os-border); border-radius: 8px; background: var(--dsw-alias-bg-layer-1); }\n.oh-story-sequence > ol > li > span { color: var(--os-muted); font-variant-numeric: tabular-nums; }\n.oh-story-sequence > ol > li .oh-story-media-preview,\n.oh-story-sequence-missing { width: 96px; height: 54px; }\n.oh-story-sequence-missing { display: grid; place-items: center; border-radius: 5px; color: var(--os-muted); background: var(--dsw-alias-button-ghost-active-fill); }\n.oh-story-sequence > ol > li > strong { overflow: hidden; text-overflow: ellipsis; }\n.oh-story-sequence > ol > li > div:last-child { display: grid; width: clamp(160px, 25vw, 260px); min-width: 0; grid-template-columns: minmax(0, 1fr) auto auto; gap: 3px; }\n.oh-story-sequence > ol > li select { width: 100%; min-width: 0; }\n.oh-story-canvas-shell { position: relative; display: flex; height: max(580px, calc(100% - 84px)); min-height: 580px; flex-direction: column; overflow: hidden; }\n.oh-story-canvas-shell > .oh-story-projection-note { z-index: 3; flex: none; margin: 8px 168px 8px 8px; }\n.oh-story-canvas-controls { position: absolute; z-index: 4; top: 8px; right: 8px; display: flex; align-items: center; gap: 3px; padding: 3px; border: 1px solid var(--os-border); border-radius: 8px; background: var(--dsw-alias-bg-base); }\n.oh-story-canvas-controls span { min-width: 44px; color: var(--os-muted); text-align: center; }\n.oh-story-canvas-viewport { width: 100%; min-height: 0; flex: 1; overflow: auto; background-color: var(--dsw-alias-bg-base); background-image: radial-gradient(var(--os-border) 1px, transparent 1px); background-size: 20px 20px; }\n.oh-story-canvas { position: relative; width: 1800px; height: 1800px; transform-origin: 0 0; }\n.oh-story-canvas svg { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; pointer-events: none; }\n.oh-story-canvas path { fill: none; opacity: .35; stroke: var(--dsw-alias-border-l2); stroke-width: 1.5; }\n.oh-story-canvas path[data-active] { opacity: .8; stroke: var(--dsw-alias-state-business-primary); }\n.oh-story-canvas article { position: absolute; display: flex; width: 180px; min-height: 76px; box-sizing: border-box; flex-direction: column; gap: 4px; padding: 10px; border: 1px solid var(--os-border); border-radius: 8px; background: var(--dsw-alias-bg-layer-1); box-shadow: 0 4px 14px rgb(0 0 0 / 8%); cursor: grab; user-select: none; touch-action: none; }\n.oh-story-canvas article:active { cursor: grabbing; }\n.oh-story-canvas article[data-node-type=\"shot\"] { border-color: var(--dsw-alias-state-business-primary); }\n.oh-story-canvas article[data-selected] { box-shadow: 0 0 0 2px color-mix(in srgb, var(--dsw-alias-state-business-primary) 28%, transparent), 0 4px 14px rgb(0 0 0 / 8%); }\n.oh-story-canvas article small { color: var(--os-muted); text-transform: uppercase; }\n.oh-story-canvas article strong,\n.oh-story-canvas article span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\n.oh-story-canvas article span { color: var(--os-muted); font-size: 10px; }\n\n[data-conversation-scroll][data-oh-story-layout=\"medium\"]:has(> [data-slot=\"conversation.session\"] > .oh-story-split-surface[data-open=\"true\"]) {\n grid-template-columns: clamp(104px, 18%, 184px) minmax(200px, 1fr) clamp(300px, 45%, 408px);\n}\n\n[data-conversation-scroll][data-oh-story-layout=\"compact\"]:has(> [data-slot=\"conversation.session\"] > .oh-story-split-surface[data-open=\"true\"]) {\n grid-template-columns: clamp(80px, 16%, 104px) minmax(0, 1fr) clamp(228px, 48%, 300px);\n}\n\n[data-oh-story-layout=\"medium\"] .oh-story-file-folder > summary { padding-left: min(calc(7px + var(--oh-story-indent, 0px)), 35px); }\n[data-oh-story-layout=\"medium\"] .oh-story-tree nav button { padding-left: min(calc(14px + var(--oh-story-indent, 0px)), 42px); }\n[data-oh-story-layout=\"medium\"] .oh-story-editor textarea { padding-right: 28px; padding-left: 28px; }\n\n[data-oh-story-layout=\"compact\"] .oh-story-tree { padding-inline: 4px; }\n[data-oh-story-layout=\"compact\"] .oh-story-brand { gap: 4px; padding-inline: 2px; font-size: 11px; }\n[data-oh-story-layout=\"compact\"] .oh-story-brand-cluster { gap: 4px; }\n[data-oh-story-layout=\"compact\"] .oh-story-brand-cluster strong > span { display: none; }\n[data-oh-story-layout=\"compact\"] .oh-story-kind { padding-inline: 4px; font-size: 11px; }\n[data-oh-story-layout=\"compact\"] .oh-story-brand button { width: 24px; height: 24px; }\n[data-oh-story-layout=\"compact\"] .oh-story-mode-tabs { margin-inline: 0; }\n[data-oh-story-layout=\"compact\"] .oh-story-mode-tabs button { padding-inline: 3px; font-size: 11px; }\n[data-oh-story-layout=\"compact\"] .oh-story-file-folder > summary { padding-left: min(calc(5px + var(--oh-story-indent, 0px)), 19px); }\n[data-oh-story-layout=\"compact\"] .oh-story-tree nav button { padding-right: 4px; padding-left: min(calc(7px + var(--oh-story-indent, 0px)), 21px); }\n[data-oh-story-layout=\"compact\"] .oh-story-editor > header {\n display: grid;\n min-height: 68px;\n grid-template-columns: minmax(0, 1fr);\n grid-template-rows: 24px 36px;\n align-content: center;\n gap: 0;\n padding: 4px 3px;\n}\n[data-oh-story-layout=\"compact\"] .oh-story-editor-path > span { display: none; }\n[data-oh-story-layout=\"compact\"] .oh-story-editor-path > strong { display: block; font-size: 11px; line-height: 24px; }\n[data-oh-story-layout=\"compact\"] .oh-story-editor-actions { width: 100%; min-width: 0; justify-content: flex-end; gap: 4px; }\n[data-oh-story-layout=\"compact\"] .oh-story-editor-tabs { min-width: 0; flex: 1; }\n[data-oh-story-layout=\"compact\"] .oh-story-editor-tabs button { min-width: 0; padding-inline: 2px; white-space: nowrap; }\n[data-oh-story-layout=\"compact\"] .oh-story-save { flex: none; padding-inline: 4px; white-space: nowrap; font-size: 11px; }\n[data-oh-story-layout=\"compact\"] .oh-story-editor textarea { padding: 16px 12px 40px; }\n[data-oh-story-layout=\"compact\"] .oh-story-markdown { padding: 18px 12px 48px; }\n[data-oh-story-layout=\"compact\"] .oh-story-jsonl-summary { padding-inline: 10px; }\n[data-oh-story-layout=\"compact\"] .oh-story-jsonl-records { padding: 8px 7px 28px; }\n[data-oh-story-layout=\"compact\"] .oh-story-jsonl summary { gap: 6px; padding-inline: 7px; }\n[data-oh-story-layout=\"compact\"] .oh-story-jsonl summary > span { display: none; }\n[data-oh-story-layout=\"compact\"] .oh-story-jsonl summary > strong { min-width: 32px; }\n[data-oh-story-layout=\"compact\"] .oh-story-jsonl summary > code,\n[data-oh-story-layout=\"compact\"] .oh-story-jsonl summary > em { display: none; }\n\n[data-conversation-scroll][data-oh-story-workbench=\"game\"][data-oh-story-layout=\"medium\"]:has(> [data-slot=\"conversation.session\"] > .oh-story-split-surface[data-open=\"true\"]) {\n grid-template-columns: minmax(0, 1fr) clamp(360px, 42%, 440px);\n}\n[data-oh-story-workbench=\"game\"][data-oh-story-layout=\"medium\"] .oh-game-toolbar { grid-template-columns: auto minmax(140px, 1fr) auto; }\n\n[data-conversation-scroll][data-oh-story-workbench=\"game\"][data-oh-story-layout=\"compact\"]:has(> [data-slot=\"conversation.session\"] > .oh-story-split-surface[data-open=\"true\"]) {\n display: grid;\n grid-template-columns: minmax(0, 1fr);\n overflow: hidden;\n}\n[data-conversation-scroll][data-oh-story-workbench=\"game\"][data-oh-story-layout=\"compact\"]\n > [data-slot=\"conversation.session\"] > :not(.oh-story-split-surface),\n[data-conversation-scroll][data-oh-story-workbench=\"game\"][data-oh-story-layout=\"compact\"]\n > [data-composer-seat],\n[data-conversation-scroll][data-oh-story-workbench=\"game\"][data-oh-story-layout=\"compact\"] .oh-game-studio {\n grid-column: 1;\n}\n[data-conversation-scroll][data-oh-story-workbench=\"game\"][data-oh-story-layout=\"compact\"][data-oh-studio-pane=\"studio\"]\n > [data-slot=\"conversation.session\"] > :not(.oh-story-split-surface),\n[data-conversation-scroll][data-oh-story-workbench=\"game\"][data-oh-story-layout=\"compact\"][data-oh-studio-pane=\"studio\"]\n > [data-composer-seat],\n[data-conversation-scroll][data-oh-story-workbench=\"game\"][data-oh-story-layout=\"compact\"][data-oh-studio-pane=\"chat\"] .oh-game-studio { display: none; }\n[data-conversation-scroll][data-oh-story-workbench=\"game\"][data-oh-story-layout=\"compact\"] .oh-game-mobile-switcher {\n display: flex;\n position: absolute;\n top: 8px;\n right: 8px;\n z-index: 20;\n border-color: var(--dsw-alias-border-l1);\n box-shadow: 0 4px 14px rgb(0 0 0 / 12%);\n}\n[data-conversation-scroll][data-oh-story-workbench=\"game\"][data-oh-story-layout=\"compact\"] .oh-game-mobile-switcher button { min-width: 52px; min-height: 32px; }\n[data-conversation-scroll][data-oh-story-workbench=\"game\"][data-oh-story-layout=\"compact\"] .oh-game-toolbar {\n min-height: 101px;\n grid-template-columns: auto minmax(0, 1fr) 112px;\n grid-template-rows: 44px 44px;\n align-content: center;\n gap: 5px;\n padding: 4px 8px;\n}\n[data-conversation-scroll][data-oh-story-workbench=\"game\"][data-oh-story-layout=\"compact\"] .oh-game-toolbar > .oh-workbench-cluster { grid-column: 1; grid-row: 1; width: fit-content; }\n[data-conversation-scroll][data-oh-story-workbench=\"game\"][data-oh-story-layout=\"compact\"] .oh-game-project > span { display: none; }\n[data-conversation-scroll][data-oh-story-workbench=\"game\"][data-oh-story-layout=\"compact\"] .oh-game-project { grid-column: 1 / -1; grid-row: 2; }\n[data-conversation-scroll][data-oh-story-workbench=\"game\"][data-oh-story-layout=\"compact\"] .oh-game-project select { max-width: none; width: 100%; min-height: 44px; }\n[data-conversation-scroll][data-oh-story-workbench=\"game\"][data-oh-story-layout=\"compact\"] .oh-game-tabs { grid-column: 2; grid-row: 1; width: fit-content; justify-self: end; }\n[data-conversation-scroll][data-oh-story-workbench=\"game\"][data-oh-story-layout=\"compact\"] .oh-game-mode-tabs button,\n[data-conversation-scroll][data-oh-story-workbench=\"game\"][data-oh-story-layout=\"compact\"] .oh-game-tabs button,\n[data-conversation-scroll][data-oh-story-workbench=\"game\"][data-oh-story-layout=\"compact\"] .oh-game-mobile-switcher button { min-height: 44px; }\n[data-conversation-scroll][data-oh-story-workbench=\"game\"][data-oh-story-layout=\"compact\"] .oh-game-preview-shell { grid-template-rows: 46px minmax(0, 1fr); }\n[data-conversation-scroll][data-oh-story-workbench=\"game\"][data-oh-story-layout=\"compact\"] .oh-game-preview-status button { min-height: 36px; }\n[data-conversation-scroll][data-oh-story-workbench=\"game\"][data-oh-story-layout=\"compact\"] .oh-game-reload b { display: none; }\n[data-conversation-scroll][data-oh-story-workbench=\"game\"][data-oh-story-layout=\"compact\"] .oh-game-preview-status { padding-left: 8px; }\n[data-conversation-scroll][data-oh-story-workbench=\"game\"][data-oh-story-layout=\"compact\"] .oh-game-preview-status > span { max-width: 40%; }\n.oh-game-runtime-state > em { display: block; overflow: hidden; min-width: 0; font-style: normal; text-overflow: ellipsis; white-space: nowrap; }\n\n/* DSH may keep its navigation drawer open at a 500 px browser viewport,\n leaving the conversation center close to 212 px wide. The Studio publishes\n its measured width because a container style query cannot style the\n container itself. Row one stays clear for the \u5236\u4F5C / \u5BF9\u8BDD switch. */\n[data-conversation-scroll][data-oh-story-workbench=\"game\"][data-oh-story-layout=\"compact\"] .oh-game-studio[data-oh-game-narrow] .oh-game-toolbar {\n min-height: 193px;\n grid-template-columns: minmax(0, 1fr);\n grid-template-rows: repeat(4, 44px);\n align-content: center;\n padding: 4px 8px;\n}\n[data-conversation-scroll][data-oh-story-workbench=\"game\"][data-oh-story-layout=\"compact\"] .oh-game-studio[data-oh-game-narrow] .oh-game-toolbar > .oh-workbench-cluster {\n grid-column: 1;\n grid-row: 2;\n justify-self: start;\n}\n[data-conversation-scroll][data-oh-story-workbench=\"game\"][data-oh-story-layout=\"compact\"] .oh-game-studio[data-oh-game-narrow] .oh-game-tabs {\n grid-column: 1;\n grid-row: 3;\n justify-self: start;\n}\n[data-conversation-scroll][data-oh-story-workbench=\"game\"][data-oh-story-layout=\"compact\"] .oh-game-studio[data-oh-game-narrow] .oh-game-project {\n grid-column: 1;\n grid-row: 4;\n}\n[data-conversation-scroll][data-oh-story-workbench=\"game\"][data-oh-story-layout=\"compact\"] .oh-game-studio[data-oh-game-narrow] .oh-game-project select {\n width: 100%;\n max-width: none;\n min-height: 44px;\n}\n[data-conversation-scroll][data-oh-story-workbench=\"game\"][data-oh-story-layout=\"compact\"] .oh-game-studio[data-oh-game-narrow] .oh-game-preview-status {\n gap: 4px;\n padding-right: 6px;\n padding-left: 6px;\n}\n[data-conversation-scroll][data-oh-story-workbench=\"game\"][data-oh-story-layout=\"compact\"] .oh-game-studio[data-oh-game-narrow] .oh-game-preview-status > span { max-width: 36%; }\n\n@media (prefers-reduced-motion: reduce) {\n .oh-game-preview-shell[data-state=\"building\"] { animation: none; }\n}\n\n@media (prefers-contrast: more) {\n .oh-game-preview-status button,\n .oh-game-tabs,\n .oh-game-mode-tabs,\n .oh-game-mobile-switcher { border-width: 2px; }\n}\n[data-oh-story-layout=\"compact\"] .oh-story-production-summary { display: none; }\n[data-oh-story-layout=\"compact\"] .oh-story-production-bar { flex-wrap: wrap; padding-inline: 4px; }\n[data-oh-story-layout=\"compact\"] .oh-story-production-tabs { width: 100%; gap: 0; }\n[data-oh-story-layout=\"compact\"] .oh-story-production-tabs button { min-width: 0; flex: 1; padding-inline: 0; font-size: 11px; }\n[data-oh-story-layout=\"compact\"] .oh-story-production-meta { width: 100%; justify-content: flex-end; }\n[data-oh-story-layout=\"compact\"] .oh-story-shot-grid,\n[data-oh-story-layout=\"compact\"] .oh-story-asset-grid { grid-template-columns: minmax(0, 1fr); }\n[data-oh-story-layout=\"compact\"] .oh-story-media-library > header { align-items: stretch; flex-direction: column; }\n[data-oh-story-layout=\"compact\"] .oh-story-media-library > header > div:last-child { display: grid; grid-template-columns: minmax(0, 1fr) auto; }\n[data-oh-story-layout=\"compact\"] .oh-story-media-library input { width: 100%; }\n[data-oh-story-layout=\"compact\"] .oh-story-sequence { padding-inline: 6px; }\n[data-oh-story-layout=\"compact\"] .oh-story-sequence-summary { flex-wrap: wrap; }\n[data-oh-story-layout=\"compact\"] .oh-story-sequence-summary span { display: none; }\n[data-oh-story-layout=\"compact\"] .oh-story-sequence > ol > li { grid-template-columns: 24px 64px minmax(0, 1fr); gap: 5px; }\n[data-oh-story-layout=\"compact\"] .oh-story-sequence > ol > li .oh-story-media-preview,\n[data-oh-story-layout=\"compact\"] .oh-story-sequence-missing { width: 64px; height: 40px; }\n[data-oh-story-layout=\"compact\"] .oh-story-sequence > ol > li > div:last-child { grid-column: 1 / -1; width: auto; }\n[data-oh-story-layout=\"compact\"] .oh-story-sequence > ol > li select { grid-column: 1 / -1; }\n[data-oh-story-layout=\"compact\"] .oh-story-sequence > ol > li button:first-of-type { grid-column: 2; }\n[data-oh-story-layout=\"compact\"] .oh-story-canvas-shell > .oh-story-projection-note { overflow: hidden; max-height: 48px; margin: 8px; }\n[data-oh-story-layout=\"compact\"] .oh-story-canvas-controls { position: static; flex: none; align-self: flex-end; margin: 0 8px 8px; }\n\n/* Video mode intentionally stays a preview surface: one player, a read-only artifact view,\n and the official DSH Conversation. It shares no nonlinear-editor or timeline runtime. */\n[data-conversation-scroll][data-oh-story-workbench=\"video\"]:has(> [data-slot=\"conversation.session\"] > .oh-story-split-surface[data-open=\"true\"]) {\n --video-stage: #0b0d10;\n --video-stage-raised: #15181d;\n --video-accent: var(--dsw-alias-state-business-primary);\n --video-warning: #f4bd55;\n --video-danger: #f06b63;\n grid-template-columns: minmax(0, 1fr) clamp(400px, 34%, 520px);\n overflow: hidden;\n}\n[data-conversation-scroll][data-oh-story-workbench=\"video\"]:has(> [data-slot=\"conversation.session\"] > .oh-story-split-surface[data-open=\"true\"])\n > [data-slot=\"conversation.session\"] > :not(.oh-story-split-surface),\n[data-conversation-scroll][data-oh-story-workbench=\"video\"]:has(> [data-slot=\"conversation.session\"] > .oh-story-split-surface[data-open=\"true\"])\n > [data-composer-seat] { grid-column: 2; }\n\n.oh-video-studio {\n box-sizing: border-box;\n display: flex;\n grid-column: 1;\n grid-row: 1;\n position: sticky;\n top: 0;\n min-width: 0;\n min-height: 0;\n height: 100%;\n align-self: start;\n overflow: hidden;\n flex-direction: column;\n border-right: 1px solid var(--os-border);\n color: var(--dsw-alias-label-primary);\n background: var(--dsw-alias-bg-base);\n}\n.oh-video-studio[hidden] { display: none; }\n.oh-video-toolbar {\n box-sizing: border-box;\n display: grid;\n min-height: 100px;\n flex: none;\n grid-template-columns: minmax(0, 1fr) auto;\n grid-template-rows: 40px 40px;\n align-items: center;\n gap: 4px 12px;\n padding: 8px 12px 9px;\n border-bottom: 1px solid var(--os-border);\n background: var(--dsw-alias-bg-base);\n}\n.oh-video-mode-tabs { display: flex; width: fit-content; grid-column: 1; grid-row: 1; padding: 2px; border: 1px solid var(--os-border); border-radius: 9px; background: var(--dsw-alias-bg-layer-1); }\n.oh-video-mode-tabs button,\n.oh-video-tabs button,\n.oh-video-version-tabs button {\n min-height: 36px;\n border: 0;\n border-radius: 6px;\n padding: 4px 8px;\n color: var(--os-muted);\n background: transparent;\n cursor: pointer;\n white-space: nowrap;\n font: 12px/1 var(--dsw-font-family);\n}\n.oh-video-mode-tabs button { min-width: 48px; }\n.oh-video-mode-tabs button:hover,\n.oh-video-tabs button:hover,\n.oh-video-version-tabs button:hover { color: var(--dsw-alias-label-primary); }\n.oh-video-mode-tabs button[aria-selected=\"true\"],\n.oh-video-tabs button[aria-selected=\"true\"],\n.oh-video-version-tabs button[aria-selected=\"true\"] { color: var(--dsw-alias-label-primary); background: var(--dsw-alias-bg-base); box-shadow: 0 1px 2px rgb(0 0 0 / 9%); font-weight: 600; }\n.oh-video-project { display: flex; min-width: 0; grid-column: 1; grid-row: 2; align-items: center; gap: 9px; color: var(--os-muted); font-size: 11px; }\n.oh-video-project > span { flex: none; }\n.oh-video-project select {\n width: min(100%, 440px);\n min-width: 0;\n min-height: 36px;\n border: 1px solid var(--os-border);\n border-radius: 8px;\n padding: 6px 28px 6px 9px;\n color: var(--dsw-alias-label-primary);\n background: var(--dsw-alias-bg-base);\n overflow: hidden;\n text-overflow: ellipsis;\n font: inherit;\n font-weight: 500;\n}\n.oh-video-stage { display: inline-flex; grid-column: 2; grid-row: 2; align-items: center; gap: 7px; border: 1px solid var(--os-border); border-radius: 999px; padding: 5px 9px; color: var(--os-muted); background: var(--dsw-alias-bg-layer-1); white-space: nowrap; font-size: 11px; }\n.oh-video-stage > i { width: 7px; height: 7px; border-radius: 50%; background: var(--video-warning); }\n.oh-video-stage[data-state=\"ready\"] > i { background: var(--dsw-alias-state-success-primary, #45b96f); }\n.oh-video-stage[data-state=\"not-started\"] > i { background: var(--os-muted); }\n.oh-video-tabs,\n.oh-video-version-tabs { display: flex; padding: 2px; border: 1px solid var(--os-border); border-radius: 9px; }\n.oh-video-tabs { grid-column: 2; grid-row: 1; }\n.oh-video-tabs button { min-width: 56px; }\n.oh-video-panels,\n.oh-video-panels > [role=\"tabpanel\"] { display: flex; min-width: 0; min-height: 0; flex: 1; overflow: hidden; flex-direction: column; }\n.oh-video-panels > [hidden] { display: none; }\n\n.oh-video-preview-shell { display: grid; min-width: 0; min-height: 0; flex: 1; grid-template-rows: 48px minmax(0, 1fr); overflow: hidden; border-top: 2px solid var(--video-accent); background: var(--video-stage); }\n.oh-video-preview-shell[data-state=\"building\"] { border-top-color: var(--video-warning); }\n.oh-video-preview-shell[data-state=\"error\"] { border-top-color: var(--video-danger); }\n.oh-video-stagebar { display: grid; min-width: 0; grid-template-columns: auto minmax(80px, 1fr) auto; align-items: center; gap: 10px; padding: 0 10px; color: rgb(244 248 255 / 74%); background: var(--video-stage-raised); font-size: 11px; }\n.oh-video-version-tabs { border-color: rgb(255 255 255 / 13%); }\n.oh-video-version-tabs button[aria-selected=\"true\"] { color: #fff; background: rgb(255 255 255 / 12%); }\n.oh-video-runtime-state { display: flex; min-width: 0; align-items: center; justify-content: center; gap: 7px; overflow: hidden; }\n.oh-video-runtime-state > i { width: 6px; height: 6px; flex: none; border-radius: 50%; background: var(--dsw-alias-state-success-primary, #45b96f); }\n.oh-video-preview-shell[data-state=\"building\"] .oh-video-runtime-state > i { background: var(--video-warning); }\n.oh-video-preview-shell[data-state=\"error\"] .oh-video-runtime-state > i { background: var(--video-danger); }\n.oh-video-runtime-state > em { overflow: hidden; font-style: normal; text-overflow: ellipsis; white-space: nowrap; }\n.oh-video-preview-actions { display: flex; gap: 5px; }\n.oh-video-preview-actions button,\n.oh-video-preview-actions a { display: grid; min-width: 34px; min-height: 34px; box-sizing: border-box; place-items: center; border: 1px solid rgb(255 255 255 / 14%); border-radius: 6px; padding: 3px 8px; color: rgb(255 255 255 / 84%); background: rgb(255 255 255 / 5%); cursor: pointer; text-decoration: none; font: inherit; }\n.oh-video-preview-actions svg { width: 16px; height: 16px; }\n.oh-video-preview-actions button:hover,\n.oh-video-preview-actions a:hover { background: rgb(255 255 255 / 11%); }\n.oh-video-player-stage { display: grid; min-width: 0; min-height: 0; place-items: center; overflow: hidden; padding: 14px; background: radial-gradient(circle at 50% 40%, #1b2027, var(--video-stage) 62%); }\n.oh-video-player-stage video { display: block; width: min(100%, 1200px); height: auto; max-width: 100%; max-height: 100%; border-radius: 4px; object-fit: contain; background: #000; box-shadow: 0 16px 50px rgb(0 0 0 / 32%); }\n.oh-video-preview-shell:fullscreen { width: 100vw; height: 100vh; }\n\n.oh-video-preview-empty,\n.oh-video-artifacts-empty { display: grid; max-width: 620px; margin: auto; place-items: center; gap: 9px; padding: 36px; color: var(--os-muted); text-align: center; line-height: 1.65; }\n.oh-video-preview-empty { width: 100%; max-width: none; min-height: 0; box-sizing: border-box; flex: 1; align-content: center; color: rgb(244 248 255 / 70%); background: var(--video-stage); }\n.oh-video-preview-empty > span { color: var(--video-accent); font-size: 32px; }\n.oh-video-preview-empty strong { color: rgb(255 255 255 / 92%); }\n.oh-video-preview-empty p { max-width: 560px; margin: 0; }\n.oh-video-preview-empty code { color: rgb(255 255 255 / 88%); }\n.oh-video-prompt-example { max-width: 560px; margin-top: 10px; padding: 12px 14px; border: 1px solid rgb(255 255 255 / 11%); border-radius: 9px; background: rgb(255 255 255 / 4%); text-align: left; }\n.oh-video-prompt-example span { display: block; margin-bottom: 4px; color: var(--video-accent); font-size: 10px; font-weight: 600; }\n.oh-video-prompt-example q { quotes: none; }\n\n.oh-video-artifacts { display: grid; min-width: 0; min-height: 0; flex: 1; grid-template-columns: minmax(150px, 220px) minmax(0, 1fr); overflow: hidden; }\n.oh-video-artifacts > aside { display: flex; min-height: 0; flex-direction: column; overflow: hidden; padding: 8px; border-right: 1px solid var(--os-border); background: var(--dsw-alias-bg-layer-1); }\n.oh-video-artifacts-heading { display: flex; min-height: 30px; flex: none; align-items: center; justify-content: space-between; padding: 0 7px; }\n.oh-video-artifacts-heading strong { font-size: 11px; }\n.oh-video-artifacts-heading span { min-width: 20px; border-radius: 999px; padding: 1px 5px; color: var(--os-muted); background: var(--dsw-alias-button-ghost-active-fill); text-align: center; font-size: 10px; }\n.oh-video-artifacts > aside nav { min-height: 0; flex: 1; overflow: auto; }\n.oh-video-artifacts > aside nav button { display: flex; width: 100%; min-width: 0; position: relative; flex-direction: column; align-items: flex-start; gap: 3px; border: 0; border-radius: 7px; padding: 9px; color: inherit; background: transparent; cursor: pointer; text-align: left; }\n.oh-video-artifacts > aside nav button:hover,\n.oh-video-artifacts > aside nav button[aria-current=\"page\"] { background: var(--dsw-alias-button-ghost-active-fill); }\n.oh-video-artifacts > aside nav button[aria-current=\"page\"]::before { content: \"\"; width: 2px; position: absolute; inset-block: 8px; left: 2px; border-radius: 2px; background: var(--video-accent); }\n.oh-video-artifacts > aside nav small { width: 100%; overflow: hidden; color: var(--os-muted); text-overflow: ellipsis; white-space: nowrap; }\n.oh-video-artifacts > aside nav > p { margin: 10px 4px; color: var(--os-muted); font-size: 11px; line-height: 1.5; }\n.oh-video-environment { display: grid; gap: 5px; margin-bottom: 8px; padding: 8px; border: 1px solid var(--os-border); border-radius: 8px; background: var(--dsw-alias-bg-layer-1); }\n.oh-video-environment strong { font-size: 11px; }\n.oh-video-environment span { color: var(--os-muted); font-size: 10px; }\n.oh-video-environment em { color: var(--os-muted); font-size: 10px; font-style: normal; line-height: 1.5; }\n.oh-video-environment code { font-size: 10px; }\n.oh-video-environment span::before { content: \"\u25CF\"; margin-right: 5px; color: var(--video-danger); }\n.oh-video-environment span[data-ready]::before { color: var(--dsw-alias-state-success-primary, #45b96f); }\n.oh-video-environment button { min-height: 30px; border: 1px solid var(--os-border); border-radius: 6px; color: inherit; background: var(--dsw-alias-bg-base); cursor: pointer; font: inherit; }\n.oh-video-artifacts > section { display: flex; min-width: 0; min-height: 0; overflow: hidden; flex-direction: column; }\n.oh-video-artifact-header { display: flex; min-height: 54px; box-sizing: border-box; flex: none; align-items: center; justify-content: space-between; gap: 12px; padding: 8px 16px; border-bottom: 1px solid var(--os-border); }\n.oh-video-artifact-header > div { display: flex; min-width: 0; flex-direction: column; gap: 3px; }\n.oh-video-artifact-header strong { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 12px; }\n.oh-video-artifact-header span { overflow: hidden; color: var(--os-muted); text-overflow: ellipsis; white-space: nowrap; font-size: 10px; }\n.oh-video-artifact-header em { flex: none; border: 1px solid var(--os-border); border-radius: 999px; padding: 3px 7px; color: var(--os-muted); background: var(--dsw-alias-bg-layer-1); font-size: 10px; font-style: normal; }\n.oh-video-artifact-content { min-width: 0; min-height: 0; flex: 1; overflow: auto; }\n.oh-video-artifact-content pre { min-width: 0; min-height: 100%; box-sizing: border-box; margin: 0; padding: 20px; color: inherit; background: var(--dsw-alias-bg-base); white-space: pre-wrap; overflow-wrap: anywhere; font: 12px/1.65 var(--dsw-font-family-mono, ui-monospace, monospace); }\n\n[data-conversation-scroll][data-oh-story-workbench=\"video\"][data-oh-story-layout=\"medium\"]:has(> [data-slot=\"conversation.session\"] > .oh-story-split-surface[data-open=\"true\"]) { grid-template-columns: minmax(0, 1fr) clamp(360px, 42%, 440px); }\n[data-oh-story-workbench=\"video\"][data-oh-story-layout=\"medium\"] .oh-video-project select { width: 100%; }\n\n[data-conversation-scroll][data-oh-story-workbench=\"video\"][data-oh-story-layout=\"compact\"]:has(> [data-slot=\"conversation.session\"] > .oh-story-split-surface[data-open=\"true\"]) { display: grid; grid-template-columns: minmax(0, 1fr); overflow: hidden; }\n[data-conversation-scroll][data-oh-story-workbench=\"video\"][data-oh-story-layout=\"compact\"]\n > [data-slot=\"conversation.session\"] > :not(.oh-story-split-surface),\n[data-conversation-scroll][data-oh-story-workbench=\"video\"][data-oh-story-layout=\"compact\"]\n > [data-composer-seat],\n[data-conversation-scroll][data-oh-story-workbench=\"video\"][data-oh-story-layout=\"compact\"] .oh-video-studio { grid-column: 1; }\n[data-conversation-scroll][data-oh-story-workbench=\"video\"][data-oh-story-layout=\"compact\"][data-oh-studio-pane=\"studio\"]\n > [data-slot=\"conversation.session\"] > :not(.oh-story-split-surface),\n[data-conversation-scroll][data-oh-story-workbench=\"video\"][data-oh-story-layout=\"compact\"][data-oh-studio-pane=\"studio\"]\n > [data-composer-seat],\n[data-conversation-scroll][data-oh-story-workbench=\"video\"][data-oh-story-layout=\"compact\"][data-oh-studio-pane=\"chat\"] .oh-video-studio { display: none; }\n[data-conversation-scroll][data-oh-story-workbench=\"video\"][data-oh-story-layout=\"compact\"] .oh-game-mobile-switcher { display: flex; position: absolute; top: 8px; right: 8px; z-index: 20; border-color: var(--dsw-alias-border-l1); box-shadow: 0 4px 14px rgb(0 0 0 / 12%); }\n[data-conversation-scroll][data-oh-story-workbench=\"video\"][data-oh-story-layout=\"compact\"] .oh-video-toolbar { min-height: 142px; grid-template-columns: minmax(0, 1fr) auto; grid-template-rows: 44px 44px 38px; align-content: center; gap: 2px 6px; padding: 4px 8px; }\n[data-conversation-scroll][data-oh-story-workbench=\"video\"][data-oh-story-layout=\"compact\"] .oh-video-toolbar > .oh-workbench-cluster { grid-column: 1 / -1; grid-row: 1; width: fit-content; }\n[data-conversation-scroll][data-oh-story-workbench=\"video\"][data-oh-story-layout=\"compact\"] .oh-video-tabs { grid-column: 2; grid-row: 2; justify-self: end; }\n[data-conversation-scroll][data-oh-story-workbench=\"video\"][data-oh-story-layout=\"compact\"] .oh-video-project { grid-column: 1; grid-row: 2; }\n[data-conversation-scroll][data-oh-story-workbench=\"video\"][data-oh-story-layout=\"compact\"] .oh-video-project > span { display: none; }\n[data-conversation-scroll][data-oh-story-workbench=\"video\"][data-oh-story-layout=\"compact\"] .oh-video-stage { grid-column: 1 / -1; grid-row: 3; justify-self: start; }\n[data-conversation-scroll][data-oh-story-workbench=\"video\"][data-oh-story-layout=\"compact\"] .oh-video-stagebar { grid-template-columns: minmax(0, 1fr) auto; grid-template-rows: 42px 38px; gap: 2px 6px; padding: 3px 7px; }\n[data-conversation-scroll][data-oh-story-workbench=\"video\"][data-oh-story-layout=\"compact\"] .oh-video-preview-shell { grid-template-rows: 86px minmax(0, 1fr); }\n[data-conversation-scroll][data-oh-story-workbench=\"video\"][data-oh-story-layout=\"compact\"] .oh-video-version-tabs { grid-column: 1; grid-row: 1; }\n[data-conversation-scroll][data-oh-story-workbench=\"video\"][data-oh-story-layout=\"compact\"] .oh-video-runtime-state { grid-column: 1; grid-row: 2; justify-content: flex-start; }\n[data-conversation-scroll][data-oh-story-workbench=\"video\"][data-oh-story-layout=\"compact\"] .oh-video-preview-actions { grid-column: 2; grid-row: 1 / 3; }\n[data-conversation-scroll][data-oh-story-workbench=\"video\"][data-oh-story-layout=\"compact\"] .oh-video-preview-actions button:first-child { max-width: 70px; }\n[data-conversation-scroll][data-oh-story-workbench=\"video\"][data-oh-story-layout=\"compact\"] .oh-video-artifacts { grid-template-columns: minmax(105px, 35%) minmax(0, 1fr); }\n"],
5
+ "mappings": "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AA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA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",
6
+ "names": ["import_react", "name", "visit", "mutation", "directory", "name", "record", "import_jsx_runtime", "directory", "name", "import_jsx_runtime", "import_react", "import_jsx_runtime", "name", "asset", "import_jsx_runtime", "activity", "name", "directory", "open"]
7
7
  }