@oh-story/dsh 0.1.16 → 0.1.18

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 (271) hide show
  1. package/README.md +13 -13
  2. package/lib/client.js +173 -111
  3. package/lib/client.js.map +3 -3
  4. package/lib/drama/package.json +4 -0
  5. package/lib/index.js +58 -28
  6. package/lib/index.js.map +2 -2
  7. package/lib/novel-to-game/README.md +3 -3
  8. package/lib/novel-to-game/README_ZH.md +4 -4
  9. package/lib/novel-to-game/VERSION +1 -1
  10. package/lib/novel-to-game/manifest.json +25 -20
  11. package/lib/novel-to-game/package.json +4 -0
  12. package/lib/novel-to-game/skills/game-art-direction/references/art-direction-method.md +4 -0
  13. package/lib/novel-to-game/skills/game-build/SKILL.md +7 -1
  14. package/lib/novel-to-game/skills/game-build/references/baked-sprite-workflow.md +19 -0
  15. package/lib/novel-to-game/skills/game-concept/references/concept-method.md +4 -1
  16. package/lib/novel-to-game/skills/novel-to-game/SKILL.md +6 -3
  17. package/lib/novel-to-game/skills/novel-to-game/references/intake-method.md +1 -0
  18. package/lib/novel-to-game/skills/novel-to-game/references/pipeline-contract.md +13 -2
  19. package/lib/oh-story/manifest.json +417 -592
  20. package/lib/oh-story/package.json +4 -0
  21. package/lib/oh-story/roles/chapter-extractor.md +4 -3
  22. package/lib/oh-story/roles/character-designer.md +20 -85
  23. package/lib/oh-story/roles/consistency-checker.md +5 -5
  24. package/lib/oh-story/roles/narrative-writer.md +9 -9
  25. package/lib/oh-story/roles/story-architect.md +19 -26
  26. package/lib/oh-story/roles/story-explorer.md +4 -5
  27. package/lib/oh-story/roles/story-researcher.md +6 -7
  28. package/lib/oh-story/skills/browser-cdp/SKILL.md +26 -15
  29. package/lib/oh-story/skills/story/SKILL.md +94 -54
  30. package/lib/oh-story/skills/story/VERSION +1 -1
  31. package/lib/oh-story/skills/story-cover/SKILL.md +41 -220
  32. package/lib/oh-story/skills/story-cover/references/api-fallback.md +128 -0
  33. package/lib/oh-story/skills/story-cover/references/cover-styles.md +61 -95
  34. package/lib/oh-story/skills/story-deslop/SKILL.md +32 -27
  35. package/lib/oh-story/skills/story-deslop/references/agent-calls.md +4 -4
  36. package/lib/oh-story/skills/story-deslop/references/banned-words.md +7 -9
  37. package/lib/oh-story/skills/story-deslop/references/deslop-gates.md +12 -12
  38. package/lib/oh-story/skills/story-deslop/references/expression.md +10 -3
  39. package/lib/oh-story/skills/story-deslop/references/story-logic.md +1 -1
  40. package/lib/oh-story/skills/story-deslop/references/style-resolution.md +1 -1
  41. package/lib/oh-story/skills/story-import/SKILL.md +12 -11
  42. package/lib/oh-story/skills/story-import/references/benchmark-sync.md +50 -0
  43. package/lib/oh-story/skills/story-import/references/character-state-reverse.md +3 -4
  44. package/lib/oh-story/skills/story-import/references/deep-analysis.md +2 -3
  45. package/lib/oh-story/skills/story-import/references/import-report.md +5 -4
  46. package/lib/oh-story/skills/story-import/references/import-special-cases.md +6 -16
  47. package/lib/oh-story/skills/story-import/references/import-tracking.md +2 -2
  48. package/lib/oh-story/skills/story-import/references/length-routing.md +1 -43
  49. package/lib/oh-story/skills/story-import/references/outline-reverse-rules.md +8 -8
  50. package/lib/oh-story/skills/story-import/references/outline-reverse.md +2 -2
  51. package/lib/oh-story/skills/story-import/references/structure-mapping-long.md +113 -125
  52. package/lib/oh-story/skills/story-import/references/structure-mapping-short.md +77 -88
  53. package/lib/oh-story/skills/story-import/scripts/build_outline_brief.py +36 -59
  54. package/lib/oh-story/skills/story-import/scripts/check-outline-contract.js +5 -1
  55. package/lib/oh-story/skills/story-import/scripts/outline_view.py +286 -0
  56. package/lib/oh-story/skills/story-long-analyze/SKILL.md +38 -75
  57. package/lib/oh-story/skills/story-long-analyze/references/author-facing.md +21 -23
  58. package/lib/oh-story/skills/story-long-analyze/references/final-checks.md +8 -17
  59. package/lib/oh-story/skills/story-long-analyze/references/inspiration-library.md +18 -5
  60. package/lib/oh-story/skills/story-long-analyze/references/pipeline-ops.md +8 -14
  61. package/lib/oh-story/skills/story-long-analyze/references/stage1-golden-chapters.md +26 -27
  62. package/lib/oh-story/skills/story-long-analyze/references/stage2-extraction.md +74 -162
  63. package/lib/oh-story/skills/story-long-analyze/references/stage3-plot-rhythm.md +124 -309
  64. package/lib/oh-story/skills/story-long-analyze/references/stage4-characters-settings.md +49 -166
  65. package/lib/oh-story/skills/story-long-analyze/references/stage5-report.md +12 -15
  66. package/lib/oh-story/skills/story-long-analyze/references/style-profile-generator.md +110 -34
  67. package/lib/oh-story/skills/story-long-analyze/references/synthesis-inputs.md +12 -2
  68. package/lib/oh-story/skills/story-long-analyze/scripts/inspect_existing_assets.py +3 -1
  69. package/lib/oh-story/skills/story-long-analyze/scripts/manage_analysis_run.py +5 -1
  70. package/lib/oh-story/skills/story-long-scan/SKILL.md +49 -72
  71. package/lib/oh-story/skills/story-long-scan/references/genre-trends.md +47 -167
  72. package/lib/oh-story/skills/story-long-scan/references/platform-ciweimao.md +23 -8
  73. package/lib/oh-story/skills/story-long-scan/references/platform-fanqie.md +24 -22
  74. package/lib/oh-story/skills/story-long-scan/references/platform-jjwxc.md +25 -13
  75. package/lib/oh-story/skills/story-long-scan/references/platform-qidian.md +41 -27
  76. package/lib/oh-story/skills/story-long-scan/references/platform-qimao.md +24 -16
  77. package/lib/oh-story/skills/story-long-scan/references/topic-decision.md +31 -33
  78. package/lib/oh-story/skills/story-long-write/SKILL.md +5 -5
  79. package/lib/oh-story/skills/story-long-write/references/agent-calls.md +1 -1
  80. package/lib/oh-story/skills/story-long-write/references/artifact-protocols.md +51 -24
  81. package/lib/oh-story/skills/story-long-write/references/banned-words.md +7 -9
  82. package/lib/oh-story/skills/story-long-write/references/benchmark-recall.md +3 -3
  83. package/lib/oh-story/skills/story-long-write/references/character-basics.md +57 -95
  84. package/lib/oh-story/skills/story-long-write/references/character-relations.md +119 -269
  85. package/lib/oh-story/skills/story-long-write/references/cross-book-recall.md +2 -2
  86. package/lib/oh-story/skills/story-long-write/references/dialogue-mastery.md +8 -8
  87. package/lib/oh-story/skills/story-long-write/references/emotion-on-page.md +7 -7
  88. package/lib/oh-story/skills/story-long-write/references/emotional-arc-design.md +38 -298
  89. package/lib/oh-story/skills/story-long-write/references/emotional-methods.md +12 -53
  90. package/lib/oh-story/skills/story-long-write/references/female-audience-writing.md +39 -85
  91. package/lib/oh-story/skills/story-long-write/references/genre-readers.md +97 -163
  92. package/lib/oh-story/skills/story-long-write/references/long-chapter-hooks.md +39 -119
  93. package/lib/oh-story/skills/story-long-write/references/long-chapter-quality.md +39 -91
  94. package/lib/oh-story/skills/story-long-write/references/long-genre-catalog.md +81 -310
  95. package/lib/oh-story/skills/story-long-write/references/long-genre-mechanics.md +115 -326
  96. package/lib/oh-story/skills/story-long-write/references/long-reversal.md +1 -1
  97. package/lib/oh-story/skills/story-long-write/references/long-suspense.md +8 -8
  98. package/lib/oh-story/skills/story-long-write/references/opening-design.md +38 -334
  99. package/lib/oh-story/skills/story-long-write/references/outline-methods.md +128 -281
  100. package/lib/oh-story/skills/story-long-write/references/plot-core-methods.md +58 -499
  101. package/lib/oh-story/skills/story-long-write/references/project-files.md +10 -14
  102. package/lib/oh-story/skills/story-long-write/references/reference-index.md +29 -82
  103. package/lib/oh-story/skills/story-long-write/references/revision-diagnosis.md +31 -0
  104. package/lib/oh-story/skills/story-long-write/references/stop-and-fix.md +2 -2
  105. package/lib/oh-story/skills/story-long-write/references/style-combat-face.md +12 -19
  106. package/lib/oh-story/skills/story-long-write/references/style-genre-modules.md +3 -171
  107. package/lib/oh-story/skills/story-long-write/references/style-resolution.md +1 -1
  108. package/lib/oh-story/skills/story-long-write/references/workflow-chapter.md +8 -6
  109. package/lib/oh-story/skills/story-long-write/references/workflow-daily.md +2 -2
  110. package/lib/oh-story/skills/story-long-write/references/workflow-outline.md +47 -47
  111. package/lib/oh-story/skills/story-long-write/references/workflow-revision.md +7 -7
  112. package/lib/oh-story/skills/story-long-write/references/workflow-setup.md +4 -9
  113. package/lib/oh-story/skills/story-long-write/references/workflow-volume.md +72 -98
  114. package/lib/oh-story/skills/story-long-write/references/writing-craft.md +59 -115
  115. package/lib/oh-story/skills/story-long-write/scripts/build_architect_brief.py +38 -18
  116. package/lib/oh-story/skills/story-long-write/scripts/build_writer_prompt.py +23 -11
  117. package/lib/oh-story/skills/story-long-write/scripts/check-outline-contract.js +5 -1
  118. package/lib/oh-story/skills/story-long-write/scripts/outline_view.py +1 -1
  119. package/lib/oh-story/skills/story-review/SKILL.md +26 -24
  120. package/lib/oh-story/skills/story-review/references/agent-prompts.md +13 -9
  121. package/lib/oh-story/skills/story-review/references/banned-words.md +7 -9
  122. package/lib/oh-story/skills/story-review/references/expression.md +10 -3
  123. package/lib/oh-story/skills/story-review/references/quality-rubric.md +7 -7
  124. package/lib/oh-story/skills/story-review/references/review-tracking.md +2 -1
  125. package/lib/oh-story/skills/story-review/references/rubrics/fanqie.md +8 -9
  126. package/lib/oh-story/skills/story-review/references/rubrics/qidian.md +9 -11
  127. package/lib/oh-story/skills/story-review/references/rubrics/zhihu.md +9 -8
  128. package/lib/oh-story/skills/story-review/references/solo.md +6 -5
  129. package/lib/oh-story/skills/story-review/references/story-logic.md +1 -1
  130. package/lib/oh-story/skills/story-review/references/style-resolution.md +1 -1
  131. package/lib/oh-story/skills/story-setup/SKILL.md +24 -31
  132. package/lib/oh-story/skills/story-setup/references/agent-references/agent-reference-profiles.md +12 -13
  133. package/lib/oh-story/skills/story-setup/references/agent-references/banned-words.md +7 -9
  134. package/lib/oh-story/skills/story-setup/references/agent-references/benchmark-style-load.md +1 -1
  135. package/lib/oh-story/skills/story-setup/references/agent-references/character-basics.md +57 -95
  136. package/lib/oh-story/skills/story-setup/references/agent-references/character-relations.md +119 -269
  137. package/lib/oh-story/skills/story-setup/references/agent-references/deslop-gates.md +12 -12
  138. package/lib/oh-story/skills/story-setup/references/agent-references/dialogue-mastery.md +8 -8
  139. package/lib/oh-story/skills/story-setup/references/agent-references/emotion-on-page.md +7 -7
  140. package/lib/oh-story/skills/story-setup/references/agent-references/emotional-arc-design.md +38 -298
  141. package/lib/oh-story/skills/story-setup/references/agent-references/expression.md +10 -3
  142. package/lib/oh-story/skills/story-setup/references/agent-references/female-audience-writing.md +141 -0
  143. package/lib/oh-story/skills/story-setup/references/agent-references/genre-readers.md +96 -161
  144. package/lib/oh-story/skills/story-setup/references/agent-references/long-chapter-hooks.md +39 -119
  145. package/lib/oh-story/skills/story-setup/references/agent-references/long-emotional-methods.md +13 -54
  146. package/lib/oh-story/skills/story-setup/references/agent-references/long-genre-catalog.md +81 -310
  147. package/lib/oh-story/skills/story-setup/references/agent-references/long-genre-mechanics.md +115 -326
  148. package/lib/oh-story/skills/story-setup/references/agent-references/long-reversal.md +1 -1
  149. package/lib/oh-story/skills/story-setup/references/agent-references/long-suspense.md +8 -8
  150. package/lib/oh-story/skills/story-setup/references/agent-references/opening-design.md +38 -334
  151. package/lib/oh-story/skills/story-setup/references/agent-references/outline-methods.md +128 -281
  152. package/lib/oh-story/skills/story-setup/references/agent-references/plot-core-methods.md +58 -499
  153. package/lib/oh-story/skills/story-setup/references/agent-references/short-chapter-hooks.md +63 -171
  154. package/lib/oh-story/skills/story-setup/references/agent-references/short-emotional-methods.md +11 -63
  155. package/lib/oh-story/skills/story-setup/references/agent-references/short-genre-formulas.md +40 -50
  156. package/lib/oh-story/skills/story-setup/references/agent-references/short-reversal.md +14 -39
  157. package/lib/oh-story/skills/story-setup/references/agent-references/story-logic.md +1 -1
  158. package/lib/oh-story/skills/story-setup/references/agent-references/style-combat-face.md +12 -19
  159. package/lib/oh-story/skills/story-setup/references/agent-references/style-genre-modules.md +3 -171
  160. package/lib/oh-story/skills/story-setup/references/agent-references/style-resolution.md +1 -1
  161. package/lib/oh-story/skills/story-setup/references/agent-references/writing-craft.md +59 -115
  162. package/lib/oh-story/skills/story-short-analyze/SKILL.md +41 -90
  163. package/lib/oh-story/skills/story-short-analyze/references/analysis-characters.md +66 -0
  164. package/lib/oh-story/skills/story-short-analyze/references/analysis-short-genres.md +21 -20
  165. package/lib/oh-story/skills/story-short-analyze/references/analysis-short-hooks.md +4 -3
  166. package/lib/oh-story/skills/story-short-analyze/references/analysis-short-mechanics.md +4 -4
  167. package/lib/oh-story/skills/story-short-analyze/references/analysis-short-suspense.md +5 -5
  168. package/lib/oh-story/skills/story-short-analyze/references/analysis-submission.md +52 -0
  169. package/lib/oh-story/skills/story-short-analyze/references/optional-modules.md +23 -73
  170. package/lib/oh-story/skills/story-short-analyze/references/output-contract.md +25 -26
  171. package/lib/oh-story/skills/story-short-analyze/references/quality-checklist.md +20 -38
  172. package/lib/oh-story/skills/story-short-analyze/references/source-story-quality.md +9 -158
  173. package/lib/oh-story/skills/story-short-analyze/references/stage2-3-structure-emotion.md +39 -26
  174. package/lib/oh-story/skills/story-short-analyze/references/stage4-6-reversal-summary.md +42 -71
  175. package/lib/oh-story/skills/story-short-scan/SKILL.md +52 -62
  176. package/lib/oh-story/skills/story-short-scan/references/manual-rank-input.md +16 -12
  177. package/lib/oh-story/skills/story-short-scan/references/platform-dianzhong.md +10 -4
  178. package/lib/oh-story/skills/story-short-scan/references/platform-heiyan.md +15 -6
  179. package/lib/oh-story/skills/story-short-scan/references/real-market-data.md +34 -72
  180. package/lib/oh-story/skills/story-short-scan/references/topic-match.md +33 -13
  181. package/lib/oh-story/skills/story-short-write/SKILL.md +5 -5
  182. package/lib/oh-story/skills/story-short-write/references/agent-calls.md +3 -3
  183. package/lib/oh-story/skills/story-short-write/references/banned-words.md +7 -9
  184. package/lib/oh-story/skills/story-short-write/references/benchmark-recall.md +17 -22
  185. package/lib/oh-story/skills/story-short-write/references/cross-book-recall.md +22 -37
  186. package/lib/oh-story/skills/story-short-write/references/deslop-gates.md +12 -12
  187. package/lib/oh-story/skills/story-short-write/references/dialogue-mastery.md +8 -8
  188. package/lib/oh-story/skills/story-short-write/references/emotional-methods.md +11 -63
  189. package/lib/oh-story/skills/story-short-write/references/expression.md +10 -3
  190. package/lib/oh-story/skills/story-short-write/references/genre-styles//344/270/226/346/203/205/346/211/223/350/204/270.md +3 -3
  191. package/lib/oh-story/skills/story-short-write/references/genre-styles//345/217/214/347/224/267/344/270/273.md +6 -6
  192. package/lib/oh-story/skills/story-short-write/references/genre-styles//345/244/215/344/273/207/346/211/223/350/204/270.md +8 -8
  193. package/lib/oh-story/skills/story-short-write/references/genre-styles//345/256/205/346/226/227/345/256/253/346/226/227.md +4 -4
  194. package/lib/oh-story/skills/story-short-write/references/genre-styles//346/200/273/350/243/201/350/261/252/351/227/250.md +9 -9
  195. package/lib/oh-story/skills/story-short-write/references/genre-styles//346/202/254/347/226/221.md +10 -10
  196. package/lib/oh-story/skills/story-short-write/references/genre-styles//346/260/221/344/277/227/346/200/252/350/260/210.md +7 -7
  197. package/lib/oh-story/skills/story-short-write/references/genre-styles//346/262/231/351/233/225/350/204/221/346/264/236.md +6 -6
  198. package/lib/oh-story/skills/story-short-write/references/genre-styles//347/224/234/345/256/240.md +6 -6
  199. package/lib/oh-story/skills/story-short-write/references/genre-styles//350/277/275/345/246/273/347/201/253/350/221/254/345/234/272.md +12 -12
  200. package/lib/oh-story/skills/story-short-write/references/genre-writing-formulas.md +40 -50
  201. package/lib/oh-story/skills/story-short-write/references/hooks-chapter.md +63 -171
  202. package/lib/oh-story/skills/story-short-write/references/reference-index.md +13 -14
  203. package/lib/oh-story/skills/story-short-write/references/short-craft.md +10 -29
  204. package/lib/oh-story/skills/story-short-write/references/short-deslop.md +2 -2
  205. package/lib/oh-story/skills/story-short-write/references/short-format.md +12 -32
  206. package/lib/oh-story/skills/story-short-write/references/short-reversal.md +14 -39
  207. package/lib/oh-story/skills/story-short-write/references/story-logic.md +1 -1
  208. package/lib/oh-story/skills/story-short-write/references/style-resolution.md +1 -1
  209. package/lib/oh-story/skills/story-short-write/references/submission-craft.md +29 -19
  210. package/lib/oh-story/skills/story-short-write/references/villain-and-reveal.md +14 -19
  211. package/lib/oh-story/skills/story-short-write/references/workflow-design.md +67 -26
  212. package/lib/oh-story/skills/story-short-write/references/workflow-draft.md +10 -11
  213. package/lib/oh-story/skills/story-short-write/references/workflow-revision.md +50 -69
  214. package/lib/oh-story/skills/story-short-write/scripts/check-phase2-contract.js +21 -16
  215. package/lib/types/client/file-activity.d.ts +10 -0
  216. package/lib/types/client/file-activity.d.ts.map +1 -1
  217. package/lib/types/client/game-preview-state.d.ts +34 -0
  218. package/lib/types/client/game-preview-state.d.ts.map +1 -0
  219. package/lib/types/client/index.d.ts.map +1 -1
  220. package/lib/types/client/video-studio.d.ts +24 -0
  221. package/lib/types/client/video-studio.d.ts.map +1 -1
  222. package/lib/types/host-python.d.ts +10 -3
  223. package/lib/types/host-python.d.ts.map +1 -1
  224. package/lib/types/native-hooks.d.ts.map +1 -1
  225. package/lib/types/skill-provider.d.ts.map +1 -1
  226. package/lib/types/workspace-route.d.ts +6 -0
  227. package/lib/types/workspace-route.d.ts.map +1 -1
  228. package/lib/video-recap/package.json +4 -0
  229. package/package.json +23 -23
  230. package/lib/oh-story/skills/story-import/references/format-and-structure.md +0 -168
  231. package/lib/oh-story/skills/story-import/references/state-tracking.md +0 -45
  232. package/lib/oh-story/skills/story-import/references/tracking-transaction.md +0 -146
  233. package/lib/oh-story/skills/story-long-analyze/references/deconstruction-notes.md +0 -270
  234. package/lib/oh-story/skills/story-long-analyze/references/semantic-acceptance-fixtures.md +0 -84
  235. package/lib/oh-story/skills/story-long-analyze/references/style-profile-protocol.md +0 -133
  236. package/lib/oh-story/skills/story-long-scan/references/publishing-guide.md +0 -101
  237. package/lib/oh-story/skills/story-long-scan/references/reader-profiling.md +0 -92
  238. package/lib/oh-story/skills/story-long-write/references/character-design-methods.md +0 -428
  239. package/lib/oh-story/skills/story-long-write/references/commercial-core-methods.md +0 -503
  240. package/lib/oh-story/skills/story-long-write/references/deslop-gates.md +0 -34
  241. package/lib/oh-story/skills/story-long-write/references/expression.md +0 -76
  242. package/lib/oh-story/skills/story-long-write/references/narrative-focus.md +0 -63
  243. package/lib/oh-story/skills/story-long-write/references/outline-conflict.md +0 -457
  244. package/lib/oh-story/skills/story-long-write/references/outline-rhythm.md +0 -389
  245. package/lib/oh-story/skills/story-long-write/references/outline-structure-theory.md +0 -272
  246. package/lib/oh-story/skills/story-long-write/references/plot-emotion-system.md +0 -354
  247. package/lib/oh-story/skills/story-long-write/references/plot-frameworks.md +0 -710
  248. package/lib/oh-story/skills/story-long-write/references/plot-special-topics.md +0 -624
  249. package/lib/oh-story/skills/story-long-write/references/story-logic.md +0 -65
  250. package/lib/oh-story/skills/story-long-write/references/style-craft.md +0 -306
  251. package/lib/oh-story/skills/story-review/references/character-relations.md +0 -433
  252. package/lib/oh-story/skills/story-review/references/dialogue-mastery.md +0 -285
  253. package/lib/oh-story/skills/story-review/references/plot-core-methods.md +0 -522
  254. package/lib/oh-story/skills/story-review/references/review-quality.md +0 -243
  255. package/lib/oh-story/skills/story-setup/references/agent-references/character-design-methods.md +0 -428
  256. package/lib/oh-story/skills/story-setup/references/agent-references/outline-conflict.md +0 -457
  257. package/lib/oh-story/skills/story-setup/references/agent-references/outline-rhythm.md +0 -389
  258. package/lib/oh-story/skills/story-setup/references/agent-references/short-paragraph-hooks.md +0 -145
  259. package/lib/oh-story/skills/story-short-analyze/references/analysis-character-basics.md +0 -433
  260. package/lib/oh-story/skills/story-short-analyze/references/analysis-character-design.md +0 -426
  261. package/lib/oh-story/skills/story-short-analyze/references/analysis-character-relations.md +0 -384
  262. package/lib/oh-story/skills/story-short-analyze/references/analysis-paragraph-hooks.md +0 -144
  263. package/lib/oh-story/skills/story-short-analyze/references/analysis-reader-profile.md +0 -238
  264. package/lib/oh-story/skills/story-short-analyze/references/analysis-writing-techniques.md +0 -464
  265. package/lib/oh-story/skills/story-short-analyze/references/deconstruction-examples.md +0 -79
  266. package/lib/oh-story/skills/story-short-analyze/references/real-market-data.md +0 -89
  267. package/lib/oh-story/skills/story-short-analyze/references/zhihu-style.md +0 -54
  268. package/lib/oh-story/skills/story-short-write/references/hooks-paragraph.md +0 -145
  269. package/lib/oh-story/skills/story-short-write/references/output-contract.md +0 -116
  270. package/lib/oh-story/skills/story-short-write/references/short-prose-quality.md +0 -207
  271. package/lib/oh-story/skills/story-short-write/references/writing-workflow.md +0 -50
package/lib/client.js CHANGED
@@ -36,7 +36,7 @@ var WORKBENCH_LABELS = {
36
36
  function workbenchLabel(mode) {
37
37
  return WORKBENCH_LABELS[mode];
38
38
  }
39
- var STORY_DIRECTORIES = /* @__PURE__ */ new Set(["\u6B63\u6587", "\u5927\u7EB2", "\u8BBE\u5B9A", "\u8FFD\u8E2A", "\u5BF9\u6807", "\u53C2\u8003\u8D44\u6599"]), DRAMA_DIRECTORIES = /* @__PURE__ */ new Set(["\u8F93\u5165", "\u9879\u76EE\u5F00\u53D1", "\u8BBE\u5B9A\u96C6", "\u5267\u96C6", "\u4EA4\u4ED8", "\u521B\u4F5C\u8005\u51B3\u7B56", "\u5BA1\u67E5"]), GAME_DIRECTORY = "game-adaptations", VIDEO_DIRECTORY = "video-recaps", EDITABLE_EXTENSION = /\.(?:md|txt|json|jsonl|html|css|[cm]?js|tsx?|jsx)$/iu, MUTATING_CALLS = /* @__PURE__ */ new Set(["write", "edit", "str_replace_editor", "bash", "run_code", "oh_story_role"]);
39
+ var STORY_DIRECTORIES = /* @__PURE__ */ new Set(["\u6B63\u6587", "\u5927\u7EB2", "\u8BBE\u5B9A", "\u8FFD\u8E2A", "\u5BF9\u6807", "\u53C2\u8003\u8D44\u6599"]), DRAMA_DIRECTORIES = /* @__PURE__ */ new Set(["\u8F93\u5165", "\u9879\u76EE\u5F00\u53D1", "\u8BBE\u5B9A\u96C6", "\u5267\u96C6", "\u4EA4\u4ED8", "\u521B\u4F5C\u8005\u51B3\u7B56", "\u5BA1\u67E5"]), SHORT_STORY_FILES = /* @__PURE__ */ new Set(["\u6B63\u6587.md", "\u8BBE\u5B9A.md", "\u5C0F\u8282\u5927\u7EB2.md"]), GAME_DIRECTORY = "game-adaptations", VIDEO_DIRECTORY = "video-recaps", EDITABLE_EXTENSION = /\.(?:md|txt|json|jsonl|html|css|[cm]?js|tsx?|jsx)$/iu, MUTATING_CALLS = /* @__PURE__ */ new Set(["write", "edit", "str_replace_editor", "bash", "run_code", "oh_story_role"]);
40
40
  function streamingAssistant(timeline) {
41
41
  for (let turnNumber of timeline.turnOrder.toReversed()) {
42
42
  let turn = timeline.turns.get(turnNumber);
@@ -264,19 +264,24 @@ function creativeRelativePath(path, cwd) {
264
264
  let normalized = path.replaceAll("\\", "/"), root = cwd?.replaceAll("\\", "/").replace(/\/$/u, ""), insideRoot = root !== void 0 && normalized.startsWith(`${root}/`);
265
265
  if ((normalized.startsWith("/") || /^[a-z]:\//iu.test(normalized) || normalized.startsWith("file:")) && !insideRoot) return;
266
266
  let relative = insideRoot ? normalized.slice(root.length + 1) : normalized.replace(/^\.\//u, ""), [directory2] = relative.split("/", 1);
267
- if (!(!(directory2 !== void 0 && (STORY_DIRECTORIES.has(directory2) || DRAMA_DIRECTORIES.has(directory2) || directory2 === GAME_DIRECTORY || directory2 === VIDEO_DIRECTORY)) && relative !== "short-drama.json" || !EDITABLE_EXTENSION.test(relative)) && !relative.split("/").some((part) => part === ".." || part === "." || part === ""))
267
+ if (!(!(directory2 !== void 0 && (STORY_DIRECTORIES.has(directory2) || DRAMA_DIRECTORIES.has(directory2) || directory2 === GAME_DIRECTORY || directory2 === VIDEO_DIRECTORY)) && relative !== "short-drama.json" && !SHORT_STORY_FILES.has(relative) || !EDITABLE_EXTENSION.test(relative)) && !relative.split("/").some((part) => part === ".." || part === "." || part === ""))
268
268
  return relative;
269
269
  }
270
270
  function workbenchModeForPath(path) {
271
271
  if (path === "short-drama.json") return "drama";
272
+ if (path !== void 0 && SHORT_STORY_FILES.has(path)) return "story";
272
273
  let directory2 = path?.split("/", 1)[0];
273
274
  if (directory2 !== void 0 && STORY_DIRECTORIES.has(directory2)) return "story";
274
275
  if (directory2 !== void 0 && DRAMA_DIRECTORIES.has(directory2)) return "drama";
275
276
  if (directory2 === GAME_DIRECTORY) return "game";
276
277
  if (directory2 === VIDEO_DIRECTORY) return "video";
277
278
  }
279
+ function initialWorkbenchMode(current, files, games, videos) {
280
+ let hasWork = (mode) => mode === "game" ? games.some((game) => game.source === "workspace") : mode === "video" ? videos.length > 0 : files.some((file) => workbenchModeForPath(file.path) === mode);
281
+ return hasWork(current) ? current : ["story", "drama", "game", "video"].find(hasWork) ?? current;
282
+ }
278
283
  function preferredWorkbenchFile(files, mode) {
279
- let matching = files.filter((file) => workbenchModeForPath(file.path) === mode), preferences = mode === "story" ? [/^正文\/.*\.md$/u, /^大纲\/.*\.md$/u, /\.md$/u] : mode === "drama" ? [
284
+ let matching = files.filter((file) => workbenchModeForPath(file.path) === mode), preferences = mode === "story" ? [/^正文\/.*\.md$/u, /^正文\.md$/u, /^小节大纲\.md$/u, /^大纲\/.*\.md$/u, /\.md$/u] : mode === "drama" ? [
280
285
  /^剧集\/EP0*1\/剧本\.md$/u,
281
286
  /^剧集\/.*\/剧本\.md$/u,
282
287
  /^剧集\/EP0*1\/screenplay\.md$/iu,
@@ -1307,7 +1312,7 @@ function ProductionStatus({ sessionId, diagnostics, onNavigate }) {
1307
1312
  }, children: [
1308
1313
  /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("i", { "aria-hidden": "true" }),
1309
1314
  "\u751F\u6210\u73AF\u5883",
1310
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("em", { children: typeof preflight != "object" ? "\u68C0\u67E5\u4E2D\u2026" : preflight.python.ok ? `${String(configured)}/${String(total)} \u4F9B\u5E94\u5546\u5DF2\u914D\u7F6E` : "\u9700\u8981 Python 3.10+" }),
1315
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("em", { children: typeof preflight != "object" ? "\u68C0\u67E5\u4E2D\u2026" : preflight.python.ok ? `${String(configured)}/${String(total)} \u4F9B\u5E94\u5546\u5DF2\u914D\u7F6E` : `\u9700\u8981 Python ${preflight.python.minimum}+` }),
1311
1316
  /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("b", { "aria-hidden": "true" })
1312
1317
  ] }),
1313
1318
  diagnostics.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("button", { type: "button", className: "oh-story-status-pill", "data-tone": protocolErrors > 0 ? "error" : "warning", "aria-expanded": open === "diagnostics", "aria-controls": "oh-story-production-diagnostics", onClick: () => {
@@ -1324,7 +1329,7 @@ function ProductionStatus({ sessionId, diagnostics, onNavigate }) {
1324
1329
  /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("i", { "aria-hidden": "true" }),
1325
1330
  /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { children: "\u8FD0\u884C" }),
1326
1331
  /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("strong", { children: "Python" }),
1327
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("small", { children: preflight.python.ok ? preflight.python.version : `${preflight.python.version ?? "\u672A\u627E\u5230"} \xB7 Skill \u811A\u672C\u9700\u8981 3.10+` })
1332
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("small", { children: preflight.python.ok ? preflight.python.version : `${preflight.python.version ?? "\u672A\u627E\u5230"} \xB7 \u77ED\u5267\u811A\u672C\u9700\u8981 ${preflight.python.minimum}+` })
1328
1333
  ] }),
1329
1334
  preflight.adapters.map((adapter) => /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("li", { "data-ready": adapter.configured || void 0, children: [
1330
1335
  /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("i", { "aria-hidden": "true" }),
@@ -1953,8 +1958,63 @@ function VideoPreview({ project, sessionId, running }) {
1953
1958
  ) })
1954
1959
  ] });
1955
1960
  }
1961
+ function VideoEnvironmentReport({ preflight }) {
1962
+ let fish = preflight.credentials.ttsProvider === "fish-audio" || preflight.credentials.ttsProvider === "auto" && !preflight.credentials.mimo;
1963
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
1964
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("span", { "data-ready": preflight.python.ok || void 0, children: [
1965
+ "Python ",
1966
+ preflight.python.version ?? "\u672A\u627E\u5230",
1967
+ preflight.python.ok ? "" : ` \xB7 \u9700\u8981 ${preflight.python.minimum}+`
1968
+ ] }),
1969
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("span", { "data-ready": preflight.ffmpeg.ok && preflight.ffmpeg.subtitles || void 0, children: [
1970
+ "ffmpeg ",
1971
+ preflight.ffmpeg.ok ? preflight.ffmpeg.subtitles ? "\xB7 libass" : "\xB7 \u7F3A\u5B57\u5E55\u6EE4\u955C" : "\u672A\u627E\u5230"
1972
+ ] }),
1973
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("span", { "data-ready": preflight.ffprobe.ok || void 0, children: [
1974
+ "ffprobe ",
1975
+ preflight.ffprobe.ok ? "\u53EF\u7528" : "\u672A\u627E\u5230"
1976
+ ] }),
1977
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("span", { "data-ready": preflight.credentials.mimo || void 0, children: [
1978
+ "MiMo Key ",
1979
+ preflight.credentials.mimo ? "\u5DF2\u914D\u7F6E" : "\u672A\u914D\u7F6E"
1980
+ ] }),
1981
+ fish && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("span", { "data-ready": preflight.credentials.fish || void 0, children: [
1982
+ "Fish Key ",
1983
+ preflight.credentials.fish ? "\u5DF2\u914D\u7F6E" : "\u672A\u914D\u7F6E"
1984
+ ] }),
1985
+ preflight.credentials.ttsProvider === "index-tts" && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("span", { "data-ready": preflight.credentials.indexTts || void 0, children: [
1986
+ "IndexTTS ",
1987
+ preflight.credentials.indexTts ? "\u5DF2\u914D\u7F6E" : "\u7F3A INDEX_TTS_ENDPOINT / INDEX_TTS_VOICE"
1988
+ ] }),
1989
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("em", { children: [
1990
+ "Key \u4E0E PATH \u5728\u542F\u52A8 DSH \u7684\u7EC8\u7AEF\u91CC\u8BBE\u7F6E\uFF0C\u91CD\u542F DSH \u540E\u751F\u6548\u3002\u8FD9\u91CC\u68C0\u67E5 DSH Host \u8FDB\u7A0B\uFF1BAgent \u6267\u884C\u4E16\u754C\u4EE5 ",
1991
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("code", { children: "video-recap --doctor" }),
1992
+ " \u4E3A\u51C6\u3002"
1993
+ ] })
1994
+ ] });
1995
+ }
1996
+ function VideoEnvironment({ sessionId }) {
1997
+ let [preflight, setPreflight] = (0, import_react3.useState)(), [attempt, setAttempt] = (0, import_react3.useState)(0);
1998
+ return (0, import_react3.useEffect)(() => {
1999
+ let controller = new AbortController();
2000
+ return fetch(endpoint("video-preflight", sessionId), { signal: controller.signal }).then(async (response) => {
2001
+ if (!response.ok) throw new Error(`HTTP ${String(response.status)}`);
2002
+ let summary = await response.json();
2003
+ controller.signal.aborted || setPreflight(summary);
2004
+ }).catch(() => {
2005
+ controller.signal.aborted || setPreflight("failed");
2006
+ }), () => {
2007
+ controller.abort();
2008
+ };
2009
+ }, [attempt, sessionId]), /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "oh-video-environment", role: "group", "aria-label": "\u89C6\u9891\u8FD0\u884C\u73AF\u5883", children: [
2010
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("strong", { children: "\u8FD0\u884C\u73AF\u5883" }),
2011
+ typeof preflight == "object" ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(VideoEnvironmentReport, { preflight }) : preflight === "failed" ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { type: "button", onClick: () => {
2012
+ setPreflight(void 0), setAttempt((value) => value + 1);
2013
+ }, children: "\u73AF\u5883\u68C0\u67E5\u5931\u8D25 \xB7 \u91CD\u8BD5" }) : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("em", { children: "\u6B63\u5728\u68C0\u67E5 Python\u3001ffmpeg \u4E0E MiMo Key\u2026" })
2014
+ ] });
2015
+ }
1956
2016
  function VideoArtifacts({ project, sessionId }) {
1957
- let [selected, setSelected] = (0, import_react3.useState)(preferredArtifact(project)?.path), [content, setContent] = (0, import_react3.useState)(), [error, setError] = (0, import_react3.useState)(), [preflight, setPreflight] = (0, import_react3.useState)();
2017
+ let [selected, setSelected] = (0, import_react3.useState)(preferredArtifact(project)?.path), [content, setContent] = (0, import_react3.useState)(), [error, setError] = (0, import_react3.useState)();
1958
2018
  (0, import_react3.useEffect)(() => {
1959
2019
  setSelected(preferredArtifact(project)?.path);
1960
2020
  }, [project.id]), (0, import_react3.useEffect)(() => {
@@ -1980,47 +2040,7 @@ function VideoArtifacts({ project, sessionId }) {
1980
2040
  /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("strong", { children: "\u9879\u76EE\u4EA7\u7269" }),
1981
2041
  /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { children: project.artifacts.length })
1982
2042
  ] }),
1983
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "oh-video-environment", children: [
1984
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("strong", { children: "\u8FD0\u884C\u73AF\u5883" }),
1985
- typeof preflight == "object" ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
1986
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("span", { "data-ready": preflight.python.ok || void 0, children: [
1987
- "Python ",
1988
- preflight.python.version ?? "\u672A\u627E\u5230"
1989
- ] }),
1990
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("span", { "data-ready": preflight.ffmpeg.ok && preflight.ffmpeg.subtitles || void 0, children: [
1991
- "ffmpeg ",
1992
- preflight.ffmpeg.subtitles ? "\xB7 libass" : "\xB7 \u7F3A\u5B57\u5E55\u6EE4\u955C"
1993
- ] }),
1994
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("span", { "data-ready": preflight.ffprobe.ok || void 0, children: [
1995
- "ffprobe ",
1996
- preflight.ffprobe.ok ? "\u53EF\u7528" : "\u672A\u627E\u5230"
1997
- ] }),
1998
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("span", { "data-ready": preflight.credentials.mimo || void 0, children: [
1999
- "MiMo Key ",
2000
- preflight.credentials.mimo ? "\u5DF2\u914D\u7F6E" : "\u672A\u914D\u7F6E"
2001
- ] }),
2002
- (preflight.credentials.ttsProvider === "fish-audio" || preflight.credentials.ttsProvider === "auto" && !preflight.credentials.mimo) && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("span", { "data-ready": preflight.credentials.fish || void 0, children: [
2003
- "Fish Key ",
2004
- preflight.credentials.fish ? "\u5DF2\u914D\u7F6E" : "\u672A\u914D\u7F6E"
2005
- ] }),
2006
- preflight.credentials.ttsProvider === "index-tts" && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("span", { "data-ready": preflight.credentials.indexTts || void 0, children: [
2007
- "IndexTTS ",
2008
- preflight.credentials.indexTts ? "\u5DF2\u914D\u7F6E" : "\u7F3A INDEX_TTS_ENDPOINT / INDEX_TTS_VOICE"
2009
- ] }),
2010
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("em", { children: [
2011
- "DSH Host \u8FDB\u7A0B\u73AF\u5883\uFF1BAgent \u6267\u884C\u4E16\u754C\u4EE5 ",
2012
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("code", { children: "video-recap --doctor" }),
2013
- " \u4E3A\u51C6\u3002"
2014
- ] })
2015
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { type: "button", onClick: () => {
2016
- fetch(endpoint("video-preflight", sessionId)).then(async (response) => {
2017
- if (!response.ok) throw new Error(`HTTP ${String(response.status)}`);
2018
- setPreflight(await response.json());
2019
- }).catch(() => {
2020
- setPreflight("failed");
2021
- });
2022
- }, children: preflight === "failed" ? "\u73AF\u5883\u68C0\u67E5\u5931\u8D25 \xB7 \u91CD\u8BD5" : "\u68C0\u67E5\u73AF\u5883" })
2023
- ] }),
2043
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(VideoEnvironment, { sessionId }),
2024
2044
  /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("nav", { children: [
2025
2045
  project.artifacts.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { children: "\u6D41\u6C34\u7EBF\u542F\u52A8\u540E\uFF0C\u5173\u952E\u4EA7\u7269\u4F1A\u51FA\u73B0\u5728\u8FD9\u91CC\u3002" }),
2026
2046
  project.artifacts.map((artifact) => /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
@@ -2130,8 +2150,9 @@ function VideoStudio({
2130
2150
  /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("p", { children: [
2131
2151
  "\u5728\u53F3\u4FA7 Chat \u544A\u8BC9 Agent \u8981\u5904\u7406\u7684\u89C6\u9891\uFF1B\u9879\u76EE\u4F1A\u521B\u5EFA\u5728 ",
2132
2152
  /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("code", { children: "video-recaps/<\u9879\u76EE>/" }),
2133
- "\u3002"
2134
- ] })
2153
+ "\u3002\u5F00\u59CB\u524D\u5148\u770B\u4E0B\u9762\u7684\u8FD0\u884C\u73AF\u5883\uFF1A\u7F3A\u9879\u65F6\u6D41\u6C34\u7EBF\u4F1A\u5728\u5904\u7406\u524D\u505C\u4E0B\u3002"
2154
+ ] }),
2155
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(VideoEnvironment, { sessionId })
2135
2156
  ] }) : /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "oh-video-panels", children: [
2136
2157
  /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { role: "tabpanel", id: `${tabsId}-preview-panel`, "aria-labelledby": `${tabsId}-preview-tab`, hidden: tab !== "preview", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(VideoPreview, { project, sessionId, running }, project.id) }),
2137
2158
  /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { role: "tabpanel", id: `${tabsId}-artifacts-panel`, "aria-labelledby": `${tabsId}-artifacts-tab`, hidden: tab !== "artifacts", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(VideoArtifacts, { project, sessionId }) })
@@ -2174,6 +2195,18 @@ function workbenchPreferenceStorage() {
2174
2195
  }
2175
2196
  }
2176
2197
 
2198
+ // src/client/game-preview-state.ts
2199
+ function gamePreviewStatus(state) {
2200
+ let failed = state.frameError || state.probe === "failed";
2201
+ return state.building ? { tone: "building", label: "Agent \u6B63\u5728\u66F4\u65B0\u6E38\u620F\u6587\u4EF6 \xB7 \u5F53\u524D\u9884\u89C8\u4FDD\u6301\u4E0D\u53D8" } : state.pending ? { tone: state.frameLoaded && !failed ? "ready" : "loading", label: "\u65B0\u7248\u672C\u5DF2\u5C31\u7EEA \xB7 \u7531\u4F60\u51B3\u5B9A\u4F55\u65F6\u8F7D\u5165" } : failed ? { tone: "error", label: "\u9884\u89C8\u8F7D\u5165\u5931\u8D25 \xB7 \u53EF\u91CD\u65B0\u8F7D\u5165" } : state.frameLoaded ? { tone: "ready", label: state.isolated ? "\u9884\u89C8\u5DF2\u8F7D\u5165" : "\u9884\u89C8\u5DF2\u8F7D\u5165 \xB7 \u5F53\u524D\u90E8\u7F72\u65E0\u6CD5\u9694\u79BB\u6765\u6E90\uFF0C\u5B58\u6863\u529F\u80FD\u4E0D\u53EF\u7528" } : { tone: "loading", label: "\u6B63\u5728\u8F7D\u5165\u9884\u89C8\u2026" };
2202
+ }
2203
+ function previewUrls(path, version, revision, origin) {
2204
+ let url = new URL(path, origin);
2205
+ url.searchParams.set("build", version), url.searchParams.set("reload", String(revision));
2206
+ let probeHref = url.toString();
2207
+ return url.hostname === "127.0.0.1" ? url.hostname = "localhost" : url.hostname === "localhost" && (url.hostname = "127.0.0.1"), { href: url.toString(), probeHref, isolated: url.origin !== new URL(origin).origin };
2208
+ }
2209
+
2177
2210
  // inline-css:/home/runner/work/oh-story-dsh/oh-story-dsh/packages/dsh-plugin/src/client/plugin.css
2178
2211
  var plugin_default = `.oh-story-bridge-marker { display: none; }
2179
2212
  .oh-story-welcome {
@@ -2193,6 +2226,10 @@ var plugin_default = `.oh-story-bridge-marker { display: none; }
2193
2226
  .oh-story-welcome h2 { margin: 0 0 8px; font-size: 20px; }
2194
2227
  .oh-story-welcome p { margin: 8px 0 0; }
2195
2228
  .oh-story-welcome ol { margin: 12px 0; padding-left: 24px; }
2229
+ .oh-story-welcome-example { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 12px; padding-top: 12px; border-top: 1px solid var(--dsw-alias-border-l2); }
2230
+ .oh-story-welcome-example button { min-height: 32px; border: 1px solid var(--dsw-alias-border-l2); border-radius: 8px; padding: 4px 12px; color: inherit; background: var(--dsw-alias-bg-layer-1); cursor: pointer; font: inherit; font-weight: 600; }
2231
+ .oh-story-welcome-example button:hover { background: var(--dsw-alias-button-ghost-active-fill); }
2232
+ .oh-story-welcome-example span { color: var(--dsw-alias-label-secondary); font-size: 12px; }
2196
2233
  .oh-story-split-surface { display: contents; font-family: var(--dsw-font-family); }
2197
2234
 
2198
2235
  /* Collapsed, the plugin owns nothing but this control: DSH renders the
@@ -2457,20 +2494,9 @@ var plugin_default = `.oh-story-bridge-marker { display: none; }
2457
2494
  .oh-game-reload { display: inline-flex; align-items: center; gap: 5px; }
2458
2495
  .oh-game-reload b { font: inherit; font-weight: 500; }
2459
2496
  .oh-game-preview-shell iframe { width: 100%; height: 100%; min-width: 0; min-height: 0; border: 0; background: var(--game-stage); }
2460
- .oh-game-focus-hint {
2461
- position: absolute;
2462
- right: 10px;
2463
- bottom: 10px;
2464
- z-index: 2;
2465
- padding: 4px 8px;
2466
- border: 1px solid rgb(255 255 255 / 12%);
2467
- border-radius: 6px;
2468
- color: rgb(255 255 255 / 62%);
2469
- background: rgb(8 10 9 / 82%);
2470
- pointer-events: none;
2471
- font-size: 10px;
2472
- }
2497
+ .oh-game-focus-hint { flex: none; margin-left: auto; color: rgb(255 255 255 / 52%); font-size: 10px; white-space: nowrap; }
2473
2498
  .oh-game-focus-hint[data-focused] { color: var(--game-accent); }
2499
+ .oh-game-studio[data-oh-game-narrow] .oh-game-focus-hint { display: none; }
2474
2500
 
2475
2501
  .oh-game-preview-empty,
2476
2502
  .oh-game-design-empty {
@@ -3153,7 +3179,8 @@ var plugin_default = `.oh-story-bridge-marker { display: none; }
3153
3179
  [data-conversation-scroll][data-oh-story-workbench="game"][data-oh-story-layout="compact"] .oh-game-preview-status button { min-height: 36px; }
3154
3180
  [data-conversation-scroll][data-oh-story-workbench="game"][data-oh-story-layout="compact"] .oh-game-reload b { display: none; }
3155
3181
  [data-conversation-scroll][data-oh-story-workbench="game"][data-oh-story-layout="compact"] .oh-game-preview-status { padding-left: 8px; }
3156
- [data-conversation-scroll][data-oh-story-workbench="game"][data-oh-story-layout="compact"] .oh-game-preview-status > span { max-width: 40%; }
3182
+ [data-conversation-scroll][data-oh-story-workbench="game"][data-oh-story-layout="compact"] .oh-game-preview-status > .oh-game-runtime-state { max-width: 40%; }
3183
+ [data-conversation-scroll][data-oh-story-workbench="game"][data-oh-story-layout="compact"] .oh-game-focus-hint { display: none; }
3157
3184
  .oh-game-runtime-state > em { display: block; overflow: hidden; min-width: 0; font-style: normal; text-overflow: ellipsis; white-space: nowrap; }
3158
3185
 
3159
3186
  /* DSH may keep its navigation drawer open at a 500 px browser viewport,
@@ -3191,7 +3218,7 @@ var plugin_default = `.oh-story-bridge-marker { display: none; }
3191
3218
  padding-right: 6px;
3192
3219
  padding-left: 6px;
3193
3220
  }
3194
- [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%; }
3221
+ [data-conversation-scroll][data-oh-story-workbench="game"][data-oh-story-layout="compact"] .oh-game-studio[data-oh-game-narrow] .oh-game-preview-status > .oh-game-runtime-state { max-width: 36%; }
3195
3222
 
3196
3223
  @media (prefers-reduced-motion: reduce) {
3197
3224
  .oh-game-preview-shell[data-state="building"] { animation: none; }
@@ -3359,6 +3386,10 @@ var plugin_default = `.oh-story-bridge-marker { display: none; }
3359
3386
  .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; }
3360
3387
  .oh-video-prompt-example span { display: block; margin-bottom: 4px; color: var(--video-accent); font-size: 10px; font-weight: 600; }
3361
3388
  .oh-video-prompt-example q { quotes: none; }
3389
+ .oh-video-preview-empty .oh-video-environment { width: min(100%, 420px); box-sizing: border-box; margin: 10px 0 0; border-color: rgb(255 255 255 / 11%); background: rgb(255 255 255 / 4%); text-align: left; }
3390
+ .oh-video-preview-empty .oh-video-environment strong { color: rgb(255 255 255 / 92%); }
3391
+ .oh-video-preview-empty .oh-video-environment span,
3392
+ .oh-video-preview-empty .oh-video-environment em { color: rgb(244 248 255 / 70%); font-size: 11px; }
3362
3393
 
3363
3394
  .oh-video-artifacts { display: grid; min-width: 0; min-height: 0; flex: 1; grid-template-columns: minmax(150px, 220px) minmax(0, 1fr); overflow: hidden; }
3364
3395
  .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); }
@@ -3532,13 +3563,13 @@ var WorkspaceRequestError = class extends Error {
3532
3563
  }
3533
3564
  status;
3534
3565
  }, GROUP_ORDER = {
3535
- story: ["\u6B63\u6587", "\u5927\u7EB2", "\u8BBE\u5B9A", "\u8FFD\u8E2A", "\u5BF9\u6807", "\u53C2\u8003\u8D44\u6599"],
3566
+ story: ["\u77ED\u7BC7", "\u6B63\u6587", "\u5927\u7EB2", "\u8BBE\u5B9A", "\u8FFD\u8E2A", "\u5BF9\u6807", "\u53C2\u8003\u8D44\u6599"],
3536
3567
  drama: ["\u9879\u76EE", "\u8F93\u5165", "\u9879\u76EE\u5F00\u53D1", "\u8BBE\u5B9A\u96C6", "\u5267\u96C6", "\u5BA1\u67E5", "\u521B\u4F5C\u8005\u51B3\u7B56", "\u4EA4\u4ED8"],
3537
3568
  game: ["game-adaptations"],
3538
3569
  video: ["video-recaps"]
3539
3570
  }, WORKBENCH_MODES = ["story", "drama", "game", "video"], EDITOR_MODES = ["preview", "source", "production"];
3540
3571
  function groupForPath(path) {
3541
- return path === "short-drama.json" ? "\u9879\u76EE" : path.split("/", 1)[0] ?? "\u5176\u4ED6";
3572
+ return path === "short-drama.json" ? "\u9879\u76EE" : SHORT_STORY_FILES.has(path) ? "\u77ED\u7BC7" : path.split("/", 1)[0] ?? "\u5176\u4ED6";
3542
3573
  }
3543
3574
  async function json(response) {
3544
3575
  let value = await response.json();
@@ -3595,44 +3626,53 @@ function FileTreeNodes({
3595
3626
  ] }, node.path);
3596
3627
  }) });
3597
3628
  }
3598
- function useWorkspace(sessionId) {
3599
- let [version, setVersion] = (0, import_react4.useState)(0), [workspace, setWorkspace] = (0, import_react4.useState)(), [error, setError] = (0, import_react4.useState)(), [loading, setLoading] = (0, import_react4.useState)(!0), reload = (0, import_react4.useCallback)(() => {
3629
+ var LIVE_WORKSPACE_REFRESH_MS = 4e3;
3630
+ function useWorkspace(sessionId, live) {
3631
+ let [version, setVersion] = (0, import_react4.useState)(0), [workspace, setWorkspace] = (0, import_react4.useState)(), [error, setError] = (0, import_react4.useState)(), [loading, setLoading] = (0, import_react4.useState)(!0), listed = (0, import_react4.useRef)(void 0), inFlight = (0, import_react4.useRef)(void 0), reload = (0, import_react4.useCallback)(() => {
3600
3632
  setLoading(!0), setVersion((value) => value + 1);
3601
3633
  }, []);
3602
3634
  return (0, import_react4.useEffect)(() => {
3603
3635
  let controller = new AbortController();
3604
- return setError(void 0), fetch(endpoint("workspace", sessionId), { signal: controller.signal }).then((response) => json(response)).then(setWorkspace).catch((reason) => {
3636
+ return inFlight.current = controller, fetch(endpoint("workspace", sessionId), { signal: controller.signal }).then((response) => json(response)).then((payload) => {
3637
+ setError(void 0);
3638
+ let text = JSON.stringify(payload);
3639
+ text !== listed.current && (listed.current = text, setWorkspace(payload));
3640
+ }).catch((reason) => {
3605
3641
  controller.signal.aborted || setError(reason instanceof Error ? reason.message : String(reason));
3606
3642
  }).finally(() => {
3607
- controller.signal.aborted || setLoading(!1);
3643
+ inFlight.current === controller && (inFlight.current = void 0), controller.signal.aborted || setLoading(!1);
3608
3644
  }), () => {
3609
3645
  controller.abort();
3610
3646
  };
3611
- }, [sessionId, version]), { workspace, error, loading, reload };
3612
- }
3613
- function isolatedPreviewUrl(path, version, revision) {
3614
- let url = new URL(path, globalThis.location.origin);
3615
- return url.hostname === "127.0.0.1" ? url.hostname = "localhost" : url.hostname === "localhost" && (url.hostname = "127.0.0.1"), url.searchParams.set("build", version), url.searchParams.set("reload", String(revision)), { href: url.toString(), isolated: url.origin !== globalThis.location.origin };
3647
+ }, [sessionId, version]), (0, import_react4.useEffect)(() => {
3648
+ if (!live) return;
3649
+ let timer = globalThis.setInterval(() => {
3650
+ inFlight.current !== void 0 || globalThis.document.visibilityState === "hidden" || setVersion((value) => value + 1);
3651
+ }, LIVE_WORKSPACE_REFRESH_MS);
3652
+ return () => {
3653
+ globalThis.clearInterval(timer);
3654
+ };
3655
+ }, [live]), { workspace, error, loading, reload };
3616
3656
  }
3617
- function PreviewProbe({ href, onFailed }) {
3618
- let failedRef = (0, import_react4.useRef)(onFailed);
3657
+ function PreviewProbe({ href, onResult }) {
3658
+ let resultRef = (0, import_react4.useRef)(onResult);
3619
3659
  return (0, import_react4.useEffect)(() => {
3620
- failedRef.current = onFailed;
3621
- }, [onFailed]), (0, import_react4.useEffect)(() => {
3660
+ resultRef.current = onResult;
3661
+ }, [onResult]), (0, import_react4.useEffect)(() => {
3622
3662
  let controller = new AbortController();
3623
3663
  return fetch(href, { signal: controller.signal }).then((response) => {
3624
3664
  if (controller.signal.aborted) return;
3625
3665
  let type = response.headers.get("content-type") ?? "";
3626
- (!response.ok || !type.includes("text/html")) && failedRef.current();
3666
+ resultRef.current(href, response.ok && type.includes("text/html") ? "ok" : "failed");
3627
3667
  }).catch(() => {
3628
- controller.signal.aborted || failedRef.current();
3668
+ controller.signal.aborted || resultRef.current(href, "failed");
3629
3669
  }), () => {
3630
3670
  controller.abort();
3631
3671
  };
3632
3672
  }, [href]), null;
3633
3673
  }
3634
3674
  function GamePreview({ project, building }) {
3635
- let shellRef = (0, import_react4.useRef)(null), fullscreenButtonRef = (0, import_react4.useRef)(null), restoreFullscreenFocus = (0, import_react4.useRef)(!1), [focused, setFocused] = (0, import_react4.useState)(!1), [loaded, setLoaded] = (0, import_react4.useState)(!1), [loadError, setLoadError] = (0, import_react4.useState)(!1), [revision, setRevision] = (0, import_react4.useState)(0), [loadedVersion, setLoadedVersion] = (0, import_react4.useState)(project.previewVersion);
3675
+ let shellRef = (0, import_react4.useRef)(null), fullscreenButtonRef = (0, import_react4.useRef)(null), restoreFullscreenFocus = (0, import_react4.useRef)(!1), [focused, setFocused] = (0, import_react4.useState)(!1), [loaded, setLoaded] = (0, import_react4.useState)(!1), [loadError, setLoadError] = (0, import_react4.useState)(!1), [probe, setProbe] = (0, import_react4.useState)(), [revision, setRevision] = (0, import_react4.useState)(0), [loadedVersion, setLoadedVersion] = (0, import_react4.useState)(project.previewVersion);
3636
3676
  if ((0, import_react4.useEffect)(() => {
3637
3677
  let document = shellRef.current?.ownerDocument;
3638
3678
  if (document === void 0) return;
@@ -3657,33 +3697,42 @@ function GamePreview({ project, building }) {
3657
3697
  /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("q", { children: "\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" })
3658
3698
  ] })
3659
3699
  ] });
3660
- let preview = isolatedPreviewUrl(project.previewUrl, loadedVersion, revision), pending = project.previewVersion !== loadedVersion, reload = () => {
3700
+ let preview = previewUrls(project.previewUrl, loadedVersion, revision, globalThis.location.origin), pending = project.previewVersion !== loadedVersion, reload = () => {
3661
3701
  setLoaded(!1), setLoadError(!1), setLoadedVersion(project.previewVersion), setRevision((value) => value + 1);
3662
3702
  }, refresh = () => {
3663
3703
  setLoaded(!1), setLoadError(!1), setRevision((value) => value + 1);
3664
- }, runtimeState = loadError ? "\u9884\u89C8\u8F7D\u5165\u5931\u8D25 \xB7 \u53EF\u91CD\u65B0\u8F7D\u5165" : building ? "Agent \u6B63\u5728\u66F4\u65B0\u6E38\u620F\u6587\u4EF6 \xB7 \u5F53\u524D\u9884\u89C8\u4FDD\u6301\u4E0D\u53D8" : pending ? "\u65B0\u7248\u672C\u5DF2\u5C31\u7EEA \xB7 \u7531\u4F60\u51B3\u5B9A\u4F55\u65F6\u8F7D\u5165" : loaded ? preview.isolated ? "\u9884\u89C8\u5DF2\u8F7D\u5165" : "\u9884\u89C8\u5DF2\u8F7D\u5165 \xB7 \u5F53\u524D\u90E8\u7F72\u65E0\u6CD5\u9694\u79BB\u6765\u6E90\uFF0C\u5B58\u6863\u529F\u80FD\u4E0D\u53EF\u7528" : "\u6B63\u5728\u8F7D\u5165\u9884\u89C8\u2026";
3665
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { ref: shellRef, className: "oh-game-preview-shell", "data-state": loadError ? "error" : building ? "building" : loaded ? "ready" : "loading", children: [
3704
+ }, status = gamePreviewStatus({
3705
+ frameLoaded: loaded,
3706
+ frameError: loadError,
3707
+ // A result for an earlier URL describes a build the frame no longer shows.
3708
+ probe: probe?.href === preview.probeHref ? probe.result : "pending",
3709
+ building,
3710
+ pending,
3711
+ isolated: preview.isolated
3712
+ }), runtimeState = status.label, fullscreen = () => {
3713
+ let shell = shellRef.current;
3714
+ shell !== null && (restoreFullscreenFocus.current = !0, shell.requestFullscreen().catch(() => {
3715
+ restoreFullscreenFocus.current = !1;
3716
+ }));
3717
+ };
3718
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { ref: shellRef, className: "oh-game-preview-shell", "data-state": status.tone, children: [
3666
3719
  /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "oh-game-preview-status", children: [
3667
3720
  /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: "oh-game-runtime-state", role: "status", "aria-live": "polite", title: runtimeState, children: [
3668
3721
  /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("i", { "aria-hidden": !0 }),
3669
3722
  /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("em", { children: runtimeState })
3670
3723
  ] }),
3724
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "oh-game-focus-hint", "data-focused": focused || void 0, children: focused ? "\u6E38\u620F\u6B63\u5728\u63A5\u6536\u952E\u9F20\u8F93\u5165" : "\u70B9\u51FB\u753B\u9762\u8FDB\u5165\u8BD5\u73A9" }),
3671
3725
  /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { children: [
3672
3726
  pending && !building && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", onClick: reload, children: "\u8F7D\u5165\u65B0\u7248\u672C" }),
3673
3727
  /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("button", { className: "oh-game-reload", type: "button", onClick: refresh, "aria-label": "\u91CD\u65B0\u8F7D\u5165\u6E38\u620F", children: [
3674
3728
  /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { "aria-hidden": !0, children: "\u21BB" }),
3675
3729
  /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("b", { children: "\u5237\u65B0" })
3676
3730
  ] }),
3677
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { ref: fullscreenButtonRef, type: "button", onClick: () => {
3678
- let shell = shellRef.current;
3679
- shell !== null && (restoreFullscreenFocus.current = !0, shell.requestFullscreen().catch(() => {
3680
- restoreFullscreenFocus.current = !1;
3681
- }));
3682
- }, children: "\u5168\u5C4F\u8BD5\u73A9" })
3731
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { ref: fullscreenButtonRef, type: "button", onClick: fullscreen, children: "\u5168\u5C4F\u8BD5\u73A9" })
3683
3732
  ] })
3684
3733
  ] }),
3685
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(PreviewProbe, { href: preview.href, onFailed: () => {
3686
- setLoaded(!1), setLoadError(!0);
3734
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(PreviewProbe, { href: preview.probeHref, onResult: (href, result) => {
3735
+ setProbe({ href, result });
3687
3736
  } }),
3688
3737
  /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
3689
3738
  "iframe",
@@ -3695,7 +3744,7 @@ function GamePreview({ project, building }) {
3695
3744
  allowFullScreen: !0,
3696
3745
  referrerPolicy: "no-referrer",
3697
3746
  onLoad: () => {
3698
- setLoadError(!1), setLoaded(!0);
3747
+ setLoaded(!0);
3699
3748
  },
3700
3749
  onError: () => {
3701
3750
  setLoaded(!1), setLoadError(!0);
@@ -3708,8 +3757,7 @@ function GamePreview({ project, building }) {
3708
3757
  }
3709
3758
  },
3710
3759
  `${project.id}:${loadedVersion}:${String(revision)}`
3711
- ),
3712
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "oh-game-focus-hint", "data-focused": focused || void 0, children: focused ? "\u6E38\u620F\u6B63\u5728\u63A5\u6536\u952E\u9F20\u8F93\u5165" : "\u70B9\u51FB\u753B\u9762\u8FDB\u5165\u8BD5\u73A9" })
3760
+ )
3713
3761
  ] });
3714
3762
  }
3715
3763
  function GameDesign({
@@ -3873,8 +3921,12 @@ function CreativeWorkbench({
3873
3921
  let path = creativeRelativePath(activity2.path, workspace?.cwd);
3874
3922
  return path === void 0 ? [] : [{ activity: activity2, path }];
3875
3923
  }), [activities, workspace?.cwd]), primaryActivity = normalizedActivities.at(-1), activityPaths = (0, import_react4.useMemo)(() => new Set(normalizedActivities.map((value) => value.path)), [normalizedActivities]), settledPath = settledMutation === void 0 ? void 0 : creativeRelativePath(settledMutation.slice(settledMutation.indexOf("\0") + 1), workspace?.cwd), activity = primaryActivity?.activity, activityPath = primaryActivity?.path, workbench = useStore((memory) => memory.workbench), setWorkbench = actions.setWorkbench, gameTab = useStore((memory) => memory.gameTab), setGameTab = actions.setGameTab, gameProjectId = useStore((memory) => memory.gameProjectId), setGameProjectId = actions.setGameProjectId, gamePane = useStore((memory) => memory.gamePane), setGamePane = actions.setGamePane, videoTab = useStore((memory) => memory.videoTab), setVideoTab = actions.setVideoTab, videoProjectId = useStore((memory) => memory.videoProjectId), setVideoProjectId = actions.setVideoProjectId, videoPane = useStore((memory) => memory.videoPane), setVideoPane = actions.setVideoPane, selected = useStore((memory) => memory.selected), setSelected = actions.setSelected, buffers = useStore((memory) => memory.buffers), setBuffers = actions.setBuffers, buffersRef = (0, import_react4.useRef)({}), expanded = useStore((memory) => memory.expanded), setExpanded = actions.setExpanded, productionSection = useStore((memory) => memory.productionSection), setProductionSection = actions.setProductionSection, productionSelectedIds = useStore((memory) => memory.productionSelectedIds), productionJobsByEpisode = useStore((memory) => memory.productionJobs), productionSelectionsByEpisode = useStore((memory) => memory.productionSelections), productionReferencesByEpisode = useStore((memory) => memory.productionReferences), productionSequenceByEpisode = useStore((memory) => memory.productionSequence), productionCanvasByEpisode = useStore((memory) => memory.productionCanvas), productionViewportByEpisode = useStore((memory) => memory.productionViewport), productionIntentCalls = useStore((memory) => memory.productionIntentCalls), surfaceRef = (0, import_react4.useRef)(null), setWorkbenchPreference = actions.setWorkbenchPreference, applyWorkbenchPreference = (0, import_react4.useCallback)((preference) => {
3876
- setWorkbenchPreference(preference), writeWorkbenchPreference(workbenchPreferenceStorage(), workspace?.cwd, preference);
3877
- }, [setWorkbenchPreference, workspace?.cwd]), compactTabsId = (0, import_react4.useId)(), compactStudioId = `${compactTabsId}-studio-panel`, compactVideoStudioId = `${compactTabsId}-video-studio-panel`, compactChatId = `${compactTabsId}-chat-panel`, navRef = (0, import_react4.useRef)(null), activityBases = (0, import_react4.useRef)(/* @__PURE__ */ new Map()), previousSignals = (0, import_react4.useRef)(/* @__PURE__ */ new Set()), consumedSettledMutation = useStore((memory) => memory.settledMutation), liveTurns = (0, import_react4.useRef)(/* @__PURE__ */ new Set());
3924
+ setWorkbenchPreference(preference);
3925
+ let storage = workbenchPreferenceStorage();
3926
+ (creativeProject || readWorkbenchPreference(storage, workspace?.cwd) !== void 0) && writeWorkbenchPreference(storage, workspace?.cwd, preference);
3927
+ }, [creativeProject, setWorkbenchPreference, workspace?.cwd]), exampleGameId = workspace?.games.find((game) => game.source === "example")?.id, playExample = exampleGameId === void 0 ? void 0 : () => {
3928
+ setGameProjectId(exampleGameId), setGameTab("preview"), setWorkbench("game"), applyWorkbenchPreference("open");
3929
+ }, compactTabsId = (0, import_react4.useId)(), compactStudioId = `${compactTabsId}-studio-panel`, compactVideoStudioId = `${compactTabsId}-video-studio-panel`, compactChatId = `${compactTabsId}-chat-panel`, navRef = (0, import_react4.useRef)(null), activityBases = (0, import_react4.useRef)(/* @__PURE__ */ new Map()), previousSignals = (0, import_react4.useRef)(/* @__PURE__ */ new Set()), consumedSettledMutation = useStore((memory) => memory.settledMutation), liveTurns = (0, import_react4.useRef)(/* @__PURE__ */ new Set());
3878
3930
  liveTurn !== void 0 && liveTurns.current.add(liveTurn);
3879
3931
  let saveLocks = (0, import_react4.useRef)(/* @__PURE__ */ new Set()), buffer = selected === void 0 ? void 0 : buffers[selected], selectedFile = workspace?.files.find((file) => file.path === selected), selectedMedia = selectedFile?.kind === "media", dirty = buffer?.source === "human" && buffer.content !== buffer.saved, saving = buffer?.saving === !0, fileError = buffer?.error, conflict = buffer?.conflict, selectedLower = selected?.toLocaleLowerCase(), markdown = selectedLower?.endsWith(".md") === !0, jsonl = selectedLower?.endsWith(".jsonl") === !0, structured = jsonl || selectedLower?.endsWith(".json") === !0, previewable = markdown || jsonl, episodeDirectory = episodeDirectoryForPath(selected), productionAvailable = selected !== void 0 && isCreatorDocumentPath(selected) && episodeDirectory !== void 0, editorModes = productionAvailable ? EDITOR_MODES : EDITOR_MODES.filter((mode) => mode !== "production"), episodeDocumentPaths = (0, import_react4.useMemo)(
3880
3932
  () => episodeDirectory === void 0 ? [] : creatorDocumentPaths(workspace?.files.filter((file) => file.kind === "text") ?? [], episodeDirectory),
@@ -3926,7 +3978,14 @@ function CreativeWorkbench({
3926
3978
  episodeDirectory !== void 0 && actions.setProductionCanvas((current) => ({ ...current, [episodeDirectory]: canvas }));
3927
3979
  }, [actions, episodeDirectory]), setProductionViewport = (0, import_react4.useCallback)((viewport) => {
3928
3980
  episodeDirectory !== void 0 && actions.setProductionViewport((current) => ({ ...current, [episodeDirectory]: viewport }));
3929
- }, [actions, episodeDirectory]), editorMode = useStore((memory) => memory.editorMode), setEditorMode = actions.setEditorMode, modeSelection = (0, import_react4.useRef)(selected), textareaRef = (0, import_react4.useRef)(null), editorPositions = (0, import_react4.useRef)(/* @__PURE__ */ new Map()), editorReady = buffer !== void 0 && buffer.missing !== !0, workspaceKind = workbench === "game" || workbench === "video" ? void 0 : workbench, gameBuilding = normalizedActivities.some(({ path }) => path.startsWith("game-adaptations/")), videoBuilding = normalizedActivities.some(({ path }) => path.startsWith("video-recaps/"));
3981
+ }, [actions, episodeDirectory]), editorMode = useStore((memory) => memory.editorMode), setEditorMode = actions.setEditorMode, modeSelection = (0, import_react4.useRef)(selected), textareaRef = (0, import_react4.useRef)(null), editorPositions = (0, import_react4.useRef)(/* @__PURE__ */ new Map()), editorReady = buffer !== void 0 && buffer.missing !== !0, workspaceKind = workbench === "game" || workbench === "video" ? void 0 : workbench, initialWorkbenchFor = (0, import_react4.useRef)(void 0);
3982
+ (0, import_react4.useEffect)(() => {
3983
+ if (workspace === void 0 || initialWorkbenchFor.current === workspace.cwd) return;
3984
+ initialWorkbenchFor.current = workspace.cwd;
3985
+ let next = initialWorkbenchMode(workbench, workspace.files, workspace.games, workspace.videos);
3986
+ next !== workbench && setWorkbench(next);
3987
+ }, [setWorkbench, workbench, workspace]);
3988
+ let gameBuilding = normalizedActivities.some(({ path }) => path.startsWith("game-adaptations/")), videoBuilding = normalizedActivities.some(({ path }) => path.startsWith("video-recaps/"));
3930
3989
  (0, import_react4.useEffect)(() => {
3931
3990
  buffersRef.current = buffers;
3932
3991
  }, [buffers]);
@@ -4571,7 +4630,7 @@ function CreativeWorkbench({
4571
4630
  )
4572
4631
  ] })
4573
4632
  ] })
4574
- ] }) : !creativeProject && error === void 0 ? welcome ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(WelcomeGuide, {}) : null : /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { ref: surfaceRef, className: "oh-story-split-surface", "data-open": "false", children: [
4633
+ ] }) : !creativeProject && error === void 0 ? welcome ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(WelcomeGuide, { onPlayExample: playExample }) : null : /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { ref: surfaceRef, className: "oh-story-split-surface", "data-open": "false", children: [
4575
4634
  /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("style", { children: plugin_default }),
4576
4635
  /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("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: () => {
4577
4636
  applyWorkbenchPreference("open");
@@ -4603,7 +4662,7 @@ function SessionWorkbenchBridge({ sessionId, useSession, useSessions, useProject
4603
4662
  let marker = (0, import_react4.useRef)(null), [target, setTarget] = (0, import_react4.useState)(), runningCalls = useChat((snapshot) => snapshot.legacy.runningCalls), partial = useChat((snapshot) => streamingAssistant(snapshot.timeline)), undispatched = useChat((snapshot) => undispatchedCalls(snapshot), sameUndispatchedCalls), settledMutation = useChat((snapshot) => latestSettledMutation(snapshot)), settledMutationTurn = useChat((snapshot) => latestSettledMutationTurn(snapshot)), liveTurn = useChat((snapshot) => openTurn(snapshot)), workbench = useStore((memory) => memory.workbench), gamePane = useStore((memory) => memory.gamePane), videoPane = useStore((memory) => memory.videoPane), sessionRunning = useSession((snapshot) => snapshot.running), inboxRows = useProjection("inbox", (inbox) => inbox?.["next-turn"]), pendingSubmissions = useSession((snapshot) => snapshot.pendingSubmissions), productionQueue = (0, import_react4.useMemo)(() => productionQueueFromInbox(
4604
4663
  inboxRows,
4605
4664
  new Set(pendingSubmissions.filter((item) => item.placement === "transcript").map((item) => item.requestId))
4606
- ), [inboxRows, pendingSubmissions]), chat = useChat((snapshot) => snapshot), productionIntents = (0, import_react4.useMemo)(() => settledProductionIntents(chat), [chat]), { workspace, error, loading: workspaceLoading, reload } = useWorkspace(sessionId), chosenPreference = useStore((memory) => memory.workbenchPreference), creativeProject = hasCreativeProject(workspace), welcome = useSessions((state) => state.byId[sessionId]?.blank === !0) && workspace !== void 0 && !workspaceLoading && !creativeProject, storedPreference = (0, import_react4.useMemo)(
4665
+ ), [inboxRows, pendingSubmissions]), chat = useChat((snapshot) => snapshot), productionIntents = (0, import_react4.useMemo)(() => settledProductionIntents(chat), [chat]), { workspace, error, loading: workspaceLoading, reload } = useWorkspace(sessionId, sessionRunning), chosenPreference = useStore((memory) => memory.workbenchPreference), creativeProject = hasCreativeProject(workspace), welcome = useSessions((state) => state.byId[sessionId]?.blank === !0) && workspace !== void 0 && !workspaceLoading && !creativeProject, storedPreference = (0, import_react4.useMemo)(
4607
4666
  () => readWorkbenchPreference(workbenchPreferenceStorage(), workspace?.cwd),
4608
4667
  [workspace?.cwd]
4609
4668
  ), open = resolveWorkbenchOpen(chosenPreference ?? storedPreference, creativeProject);
@@ -4701,26 +4760,29 @@ function SessionWorkbenchBridge({ sessionId, useSession, useSessions, useProject
4701
4760
  ), target)
4702
4761
  ] });
4703
4762
  }
4704
- function WelcomeGuide() {
4763
+ function WelcomeGuide({ onPlayExample }) {
4705
4764
  return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("section", { className: "oh-story-welcome", "aria-label": "Oh Story \u4F7F\u7528\u5F15\u5BFC", children: [
4706
4765
  /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("style", { children: plugin_default }),
4707
4766
  /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("h2", { children: "Oh Story \u5DF2\u52A0\u8F7D" }),
4708
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { children: "\u4F5C\u54C1\u76EE\u5F55\u4E2D\u6709\u521B\u4F5C\u6587\u4EF6\u65F6\uFF0C\u5C0F\u8BF4\u3001\u77ED\u5267\u3001\u6E38\u620F\u3001\u89C6\u9891\u5DE5\u4F5C\u53F0\u4F1A\u81EA\u52A8\u663E\u793A\u3002" }),
4709
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("ol", { children: [
4710
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("li", { children: "\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" }),
4711
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("li", { children: "\u5728\u4E0B\u65B9\u300C\u9009\u62E9\u5DE5\u4F5C\u533A / Choose workspace\u300D\u4E2D\u9009\u4E2D\u8BE5\u76EE\u5F55\uFF0C\u6216\u6253\u5F00\u5DF2\u6709\u4F1A\u8BDD\u3002" }),
4712
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("li", { children: "\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" })
4713
- ] }),
4714
4767
  /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("p", { children: [
4715
- "\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 ",
4768
+ "\u76F4\u63A5\u5728\u4E0B\u65B9\u8F93\u5165\u6846\u8BF4\u4F60\u60F3\u5199\u4EC0\u4E48\uFF0C\u6BD4\u5982\u300C\u5199\u4E00\u7BC7 8000 \u5B57\u7684\u91CD\u751F\u590D\u4EC7\u77ED\u7BC7\u300D\uFF0C\u6216\u8F93\u5165 ",
4716
4769
  /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("code", { children: "/story" }),
4717
4770
  "\u3001",
4718
4771
  /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("code", { children: "/short-drama" }),
4719
4772
  "\u3001",
4720
4773
  /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("code", { children: "/novel-to-game quick" }),
4721
- " \u6216 ",
4774
+ "\u3001",
4722
4775
  /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("code", { children: "/video-recap" }),
4723
- "\u3002"
4776
+ "\u3002\u5199\u51FA\u7B2C\u4E00\u4E2A\u521B\u4F5C\u6587\u4EF6\u540E\uFF0C\u5C0F\u8BF4\u3001\u77ED\u5267\u3001\u6E38\u620F\u3001\u89C6\u9891\u5DE5\u4F5C\u53F0\u4F1A\u81EA\u52A8\u51FA\u73B0\u3002"
4777
+ ] }),
4778
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("ol", { children: [
4779
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("li", { children: "\u4E0D\u9009\u6587\u4EF6\u5939\u4E5F\u80FD\u5F00\u59CB\uFF1A\u4F5C\u54C1\u4F1A\u5199\u8FDB DSH \u81EA\u52A8\u5EFA\u7ACB\u7684\u300C\u9ED8\u8BA4\u5DE5\u4F5C\u533A / Default workspace\u300D\u3002" }),
4780
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("li", { children: "\u60F3\u653E\u8FDB\u81EA\u5DF1\u7684\u4F5C\u54C1\u6587\u4EF6\u5939\uFF1A\u70B9\u51FB\u5DE6\u4FA7\u300C\u5DE5\u4F5C\u533A / Workspaces\u300D\u65C1\u7684\u300C\u6DFB\u52A0\u5DE5\u4F5C\u533A / Add workspace\u300D\uFF0C\u5728\u7CFB\u7EDF\u5F39\u51FA\u7684\u6587\u4EF6\u5939\u7A97\u53E3\u91CC\u9009\u62E9\uFF0C\u518D\u5728\u4E0B\u65B9\u300C\u9009\u62E9\u5DE5\u4F5C\u533A / Choose workspace\u300D\u4E2D\u9009\u4E2D\u5B83\u3002" }),
4781
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("li", { children: "\u8F93\u5165\u6846\u53F3\u4E0B\u89D2\u663E\u793A\u6A21\u578B\u540D\u5C31\u8BF4\u660E\u5DF2\u914D\u7F6E\u597D\uFF1B\u6CA1\u6709\u6A21\u578B\u65F6\uFF0C\u5728\u300C\u8BBE\u7F6E \u2192 \u6A21\u578B\u300D\u586B\u5165 API Key\u3002\u53EA\u67E5\u770B\u5DF2\u6709\u4F5C\u54C1\u65E0\u9700 API Key\u3002" })
4782
+ ] }),
4783
+ onPlayExample !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "oh-story-welcome-example", children: [
4784
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", onClick: onPlayExample, children: "\u5148\u73A9\u5185\u7F6E\u793A\u4F8B\u300A\u91D1\u74F6\u6885 \xB7 \u98CE\u6708\u603B\u8D26\u300B" }),
4785
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { children: "\u968F\u63D2\u4EF6\u9644\u5E26\u7684\u5B8C\u6574 ADV \u6E38\u620F\uFF0C\u4E0D\u7528 API Key\u3002\u5185\u5BB9 18+\uFF0C\u8FDB\u5165\u524D\u4F1A\u786E\u8BA4\u5E74\u9F84\u3002" })
4724
4786
  ] })
4725
4787
  ] });
4726
4788
  }