@oh-story/dsh 0.1.9 → 0.1.11

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 (529) hide show
  1. package/README.md +14 -14
  2. package/lib/client.js +209 -73
  3. package/lib/client.js.map +3 -3
  4. package/lib/drama/manifest.json +248 -168
  5. package/lib/drama/skills/short-drama/SKILL.md +16 -4
  6. package/lib/drama/skills/short-drama/assets/project-template/short-drama.json +3 -0
  7. package/lib/drama/skills/short-drama/references/creator-documents.md +3 -0
  8. package/lib/drama/skills/short-drama/references/knowhow-index.md +15 -0
  9. package/lib/drama/skills/short-drama/scripts/creator_markdown_check.py +14 -0
  10. package/lib/drama/skills/short-drama/scripts/project_tool.py +131 -0
  11. package/lib/drama/skills/short-drama-assets/SKILL.md +2 -1
  12. package/lib/drama/skills/short-drama-assets/references/asset-review-checklist.md +2 -0
  13. package/lib/drama/skills/short-drama-assets/references/character-and-look.md +10 -0
  14. package/lib/drama/skills/short-drama-assets/references/continuity-lock.md +6 -9
  15. package/lib/drama/skills/short-drama-assets/references/era-anchors.md +37 -0
  16. package/lib/drama/skills/short-drama-assets/references/stage-contract.md +2 -0
  17. package/lib/drama/skills/short-drama-assets/references/voice-direction.md +28 -0
  18. package/lib/drama/skills/short-drama-develop/SKILL.md +10 -4
  19. package/lib/drama/skills/short-drama-develop/assets/adaptation-map.example.jsonl +1 -1
  20. package/lib/drama/skills/short-drama-develop/assets/creative-brief.md +8 -0
  21. package/lib/drama/skills/short-drama-develop/references/adaptation-craft.md +80 -13
  22. package/lib/drama/skills/short-drama-develop/references/episode-design.md +95 -12
  23. package/lib/drama/skills/short-drama-develop/references/genre-and-hook-playbook.md +9 -5
  24. package/lib/drama/skills/short-drama-develop/references/genre-cards//345/244/215/344/273/207/346/211/223/350/204/270.md +1 -1
  25. package/lib/drama/skills/short-drama-develop/references/genre-cards//347/263/273/347/273/237/346/265/201.md +51 -0
  26. package/lib/drama/skills/short-drama-develop/references/genre-cards//351/200/206/350/242/255.md +51 -0
  27. package/lib/drama/skills/short-drama-develop/references/genre-cards//351/207/215/347/224/237/347/251/277/350/266/212.md +51 -0
  28. package/lib/drama/skills/short-drama-develop/references/genre-cards.md +10 -7
  29. package/lib/drama/skills/short-drama-develop/references/premise-devices.md +15 -9
  30. package/lib/drama/skills/short-drama-develop/references/serial-character-and-memory.md +3 -2
  31. package/lib/drama/skills/short-drama-develop/references/stage-contract.md +14 -7
  32. package/lib/drama/skills/short-drama-develop/references/story-craft.md +7 -3
  33. package/lib/drama/skills/short-drama-edit/SKILL.md +65 -44
  34. package/lib/drama/skills/short-drama-edit/assets/remotion/README.md +49 -13
  35. package/lib/drama/skills/short-drama-edit/assets/remotion/package.json +4 -2
  36. package/lib/drama/skills/short-drama-edit/assets/remotion/src/Overlay.tsx +31 -0
  37. package/lib/drama/skills/short-drama-edit/assets/remotion/src/Root.tsx +5 -5
  38. package/lib/drama/skills/short-drama-edit/assets/remotion/src/Subtitles.tsx +68 -69
  39. package/lib/drama/skills/short-drama-edit/assets/remotion/src/font.ts +39 -29
  40. package/lib/drama/skills/short-drama-edit/assets/remotion/src/rules.mjs +188 -0
  41. package/lib/drama/skills/short-drama-edit/assets/remotion/src/schema.ts +26 -13
  42. package/lib/drama/skills/short-drama-edit/assets/remotion/src/screen/Card.tsx +72 -0
  43. package/lib/drama/skills/short-drama-edit/assets/remotion/src/screen/CornerChip.tsx +39 -0
  44. package/lib/drama/skills/short-drama-edit/assets/remotion/src/screen/ScreenText.tsx +36 -0
  45. package/lib/drama/skills/short-drama-edit/assets/remotion/src/screen/SystemPanel.tsx +44 -0
  46. package/lib/drama/skills/short-drama-edit/assets/remotion/src/screen/TaskPanel.tsx +100 -0
  47. package/lib/drama/skills/short-drama-edit/assets/remotion/src/screen/chrome.tsx +197 -0
  48. package/lib/drama/skills/short-drama-edit/assets/remotion/src/screen/tokens.ts +62 -0
  49. package/lib/drama/skills/short-drama-edit/assets/remotion/tsconfig.json +1 -0
  50. package/lib/drama/skills/short-drama-edit/assets//345/211/252/350/276/221/345/215/225.md +6 -4
  51. package/lib/drama/skills/short-drama-edit/references/cut-craft.md +26 -67
  52. package/lib/drama/skills/short-drama-edit/references/delivery-verify.md +31 -56
  53. package/lib/drama/skills/short-drama-edit/references/generated-footage.md +42 -78
  54. package/lib/drama/skills/short-drama-edit/references/sound-and-subtitles.md +44 -92
  55. package/lib/drama/skills/short-drama-edit/references/stage-contract.md +14 -16
  56. package/lib/drama/skills/short-drama-edit/scripts/edit_tool.py +1272 -125
  57. package/lib/drama/skills/short-drama-edit/scripts/selftest.py +113 -9
  58. package/lib/drama/skills/short-drama-image-prompts/SKILL.md +2 -0
  59. package/lib/drama/skills/short-drama-image-prompts/references/common-recipe.md +11 -0
  60. package/lib/drama/skills/short-drama-novel-analyze/SKILL.md +3 -3
  61. package/lib/drama/skills/short-drama-novel-analyze/assets/episode-candidate.example.jsonl +2 -2
  62. package/lib/drama/skills/short-drama-novel-analyze/references/adaptation-triage.md +8 -4
  63. package/lib/drama/skills/short-drama-novel-analyze/references/adaptation-value.md +10 -3
  64. package/lib/drama/skills/short-drama-novel-analyze/references/aggregation-and-entities.md +25 -1
  65. package/lib/drama/skills/short-drama-novel-analyze/references/stage-contract.md +1 -0
  66. package/lib/drama/skills/short-drama-produce/SKILL.md +5 -1
  67. package/lib/drama/skills/short-drama-produce/references/adapter-contract.md +14 -20
  68. package/lib/drama/skills/short-drama-produce/references/providers/minimax-h3-video.md +8 -26
  69. package/lib/drama/skills/short-drama-produce/references/providers/minimax-speech.md +41 -0
  70. package/lib/drama/skills/short-drama-produce/scripts/provider_adapters.py +142 -1
  71. package/lib/drama/skills/short-drama-review/SKILL.md +4 -5
  72. package/lib/drama/skills/short-drama-review/references/production-quality-gates.md +6 -19
  73. package/lib/drama/skills/short-drama-review/references/review-method.md +6 -1
  74. package/lib/drama/skills/short-drama-review/references/rubric-assets-prompts.md +11 -0
  75. package/lib/drama/skills/short-drama-review/references/rubric-story-script.md +77 -3
  76. package/lib/drama/skills/short-drama-review/references/rubric-visual-motion.md +24 -35
  77. package/lib/drama/skills/short-drama-review/references/stage-contract.md +3 -0
  78. package/lib/drama/skills/short-drama-storyboard/SKILL.md +23 -11
  79. package/lib/drama/skills/short-drama-storyboard/references/blocking-playbooks.md +1 -1
  80. package/lib/drama/skills/short-drama-storyboard/references/lighting-craft.md +39 -0
  81. package/lib/drama/skills/short-drama-storyboard/references/production-shot-grammar.md +2 -2
  82. package/lib/drama/skills/short-drama-storyboard/references/shot-craft.md +139 -34
  83. package/lib/drama/skills/short-drama-storyboard/references/stage-contract.md +5 -3
  84. package/lib/drama/skills/short-drama-video-prompts/SKILL.md +15 -12
  85. package/lib/drama/skills/short-drama-video-prompts/references/camera-audio-continuity.md +29 -0
  86. package/lib/drama/skills/short-drama-video-prompts/references/delivery-profile.md +4 -5
  87. package/lib/drama/skills/short-drama-video-prompts/references/generability.md +4 -2
  88. package/lib/drama/skills/short-drama-video-prompts/references/minimax-h3.md +52 -39
  89. package/lib/drama/skills/short-drama-video-prompts/references/motion-recipe.md +24 -21
  90. package/lib/drama/skills/short-drama-video-prompts/references/performance-action-timing.md +9 -23
  91. package/lib/drama/skills/short-drama-video-prompts/references/production-prompt-grammar.md +14 -26
  92. package/lib/drama/skills/short-drama-video-prompts/references/review-and-fixtures.md +1 -1
  93. package/lib/drama/skills/short-drama-video-prompts/references/seedance-2.0.md +2 -3
  94. package/lib/drama/skills/short-drama-video-prompts/references/seedance-2.5.md +34 -9
  95. package/lib/drama/skills/short-drama-video-prompts/references/stage-contract.md +3 -2
  96. package/lib/drama/skills/short-drama-video-prompts/references/target-model-profile.md +8 -1
  97. package/lib/drama/skills/short-drama-video-prompts/references/wan-3.0.md +103 -0
  98. package/lib/drama/skills/short-drama-video-prompts/scripts/motion_timing_check.py +8 -7
  99. package/lib/drama/skills/short-drama-write/SKILL.md +10 -7
  100. package/lib/drama/skills/short-drama-write/references/dialogue-craft.md +1 -1
  101. package/lib/drama/skills/short-drama-write/references/script-craft.md +56 -3
  102. package/lib/drama/skills/short-drama-write/references/stage-contract.md +4 -0
  103. package/lib/drama/skills/short-drama-write/scripts/duration_estimate.py +48 -2
  104. package/lib/index.js +346 -98
  105. package/lib/index.js.map +4 -4
  106. package/lib/novel-to-game/README.md +299 -59
  107. package/lib/novel-to-game/README_ZH.md +299 -56
  108. package/lib/novel-to-game/VERSION +1 -1
  109. package/lib/novel-to-game/examples/jin-ping-mei/build/BUILD_BRIEF.md +3 -1
  110. package/lib/novel-to-game/examples/jin-ping-mei/build/app/RUN.md +11 -3
  111. package/lib/novel-to-game/examples/jin-ping-mei/build/app/css/new-guofeng.css +397 -8
  112. package/lib/novel-to-game/examples/jin-ping-mei/build/app/css/style.css +0 -31
  113. package/lib/novel-to-game/examples/jin-ping-mei/build/app/js/data.js +71 -73
  114. package/lib/novel-to-game/examples/jin-ping-mei/build/app/js/engine.js +78 -89
  115. package/lib/novel-to-game/examples/jin-ping-mei/build/app/js/main.js +37 -14
  116. package/lib/novel-to-game/examples/jin-ping-mei/build/app/js/text.js +5 -5
  117. package/lib/novel-to-game/examples/jin-ping-mei/build/app/package.json +2 -1
  118. package/lib/novel-to-game/examples/jin-ping-mei/qa/README.md +11 -16
  119. package/lib/novel-to-game/examples/jin-ping-mei/qa/verification.json +11 -11
  120. package/lib/novel-to-game/examples/jin-ping-mei/qa/verify_playable_model.mjs +23 -0
  121. package/lib/novel-to-game/manifest.json +77 -87
  122. package/lib/novel-to-game/skills/game-art-direction/SKILL.md +7 -12
  123. package/lib/novel-to-game/skills/game-art-direction/references/art-direction-method.md +27 -106
  124. package/lib/novel-to-game/skills/game-build/SKILL.md +13 -14
  125. package/lib/novel-to-game/skills/game-build/references/blender-asset-workflow.md +24 -0
  126. package/lib/novel-to-game/skills/game-build/references/build-brief-contract.md +45 -82
  127. package/lib/novel-to-game/skills/game-build/references/generative-media-pipeline.md +14 -45
  128. package/lib/novel-to-game/skills/game-build/references/playable-model-contract.md +30 -65
  129. package/lib/novel-to-game/skills/game-build/references/tts-production-contract.md +13 -27
  130. package/lib/novel-to-game/skills/game-concept/SKILL.md +13 -15
  131. package/lib/novel-to-game/skills/game-concept/references/concept-method.md +28 -75
  132. package/lib/novel-to-game/skills/game-qa/SKILL.md +6 -7
  133. package/lib/novel-to-game/skills/game-qa/references/test-design-method.md +9 -5
  134. package/lib/novel-to-game/skills/game-world-design/SKILL.md +12 -16
  135. package/lib/novel-to-game/skills/game-world-design/references/narrative-design-method.md +23 -72
  136. package/lib/novel-to-game/skills/game-world-design/references/numeric-design-method.md +14 -48
  137. package/lib/novel-to-game/skills/game-world-design/references/world-design-method.md +36 -103
  138. package/lib/novel-to-game/skills/novel-game-analyze/SKILL.md +4 -10
  139. package/lib/novel-to-game/skills/novel-game-analyze/references/gameability-protocol.md +4 -4
  140. package/lib/novel-to-game/skills/novel-to-game/SKILL.md +9 -21
  141. package/lib/novel-to-game/skills/novel-to-game/references/intake-method.md +5 -4
  142. package/lib/novel-to-game/skills/novel-to-game/references/pipeline-contract.md +5 -8
  143. package/lib/oh-story/manifest.json +607 -327
  144. package/lib/oh-story/roles/chapter-extractor.md +177 -237
  145. package/lib/oh-story/roles/character-designer.md +1 -2
  146. package/lib/oh-story/roles/consistency-checker.md +15 -13
  147. package/lib/oh-story/roles/narrative-writer.md +36 -38
  148. package/lib/oh-story/roles/story-architect.md +9 -61
  149. package/lib/oh-story/roles/story-explorer.md +20 -125
  150. package/lib/oh-story/roles/story-researcher.md +0 -1
  151. package/lib/oh-story/skills/story/SKILL.md +15 -9
  152. package/lib/oh-story/skills/story/VERSION +1 -1
  153. package/lib/oh-story/skills/story/references/author-memory-maintenance.md +75 -0
  154. package/lib/oh-story/skills/story/references/author-memory.md +46 -94
  155. package/lib/oh-story/skills/story/scripts/author_memory_commit.py +934 -170
  156. package/lib/oh-story/skills/story-cover/SKILL.md +10 -1
  157. package/lib/oh-story/skills/story-deslop/SKILL.md +59 -73
  158. package/lib/oh-story/skills/story-deslop/references/agent-calls.md +5 -0
  159. package/lib/oh-story/skills/story-deslop/references/anti-ai-writing.md +12 -11
  160. package/lib/oh-story/skills/story-deslop/references/author-memory-maintenance.md +75 -0
  161. package/lib/oh-story/skills/story-deslop/references/author-memory.md +46 -94
  162. package/lib/oh-story/skills/story-deslop/references/banned-words.md +2 -2
  163. package/lib/oh-story/skills/story-deslop/references/deslop-gates.md +22 -5
  164. package/lib/oh-story/skills/story-deslop/references/style-resolution.md +4 -4
  165. package/lib/oh-story/skills/story-deslop/scripts/author_memory_commit.py +934 -170
  166. package/lib/oh-story/skills/story-deslop/scripts/check-ai-patterns.js +155 -8
  167. package/lib/oh-story/skills/story-import/SKILL.md +64 -584
  168. package/lib/oh-story/skills/story-import/references/character-state-reverse.md +1 -1
  169. package/lib/oh-story/skills/story-import/references/deep-analysis.md +47 -0
  170. package/lib/oh-story/skills/story-import/references/format-and-structure.md +1 -1
  171. package/lib/oh-story/skills/story-import/references/import-report.md +64 -0
  172. package/lib/oh-story/skills/story-import/references/import-special-cases.md +34 -0
  173. package/lib/oh-story/skills/story-import/references/import-tracking.md +95 -0
  174. package/lib/oh-story/skills/story-import/references/length-routing.md +1 -1
  175. package/lib/oh-story/skills/story-import/references/outline-reverse-rules.md +79 -0
  176. package/lib/oh-story/skills/story-import/references/outline-reverse.md +24 -0
  177. package/lib/oh-story/skills/story-import/references/state-tracking.md +4 -69
  178. package/lib/oh-story/skills/story-import/references/structure-mapping-long.md +98 -92
  179. package/lib/oh-story/skills/story-import/references/structure-mapping-short.md +24 -12
  180. package/lib/oh-story/skills/story-import/references/tracking-initialization.md +1 -1
  181. package/lib/oh-story/skills/story-import/references/tracking-transaction.md +15 -11
  182. package/lib/oh-story/skills/story-import/scripts/build_outline_brief.py +332 -0
  183. package/lib/oh-story/skills/story-import/scripts/check-outline-contract.js +132 -27
  184. package/lib/oh-story/skills/story-import/scripts/tracking_commit.py +478 -15
  185. package/lib/oh-story/skills/story-import/scripts/wordcount_core.py +182 -23
  186. package/lib/oh-story/skills/story-long-analyze/SKILL.md +81 -270
  187. package/lib/oh-story/skills/story-long-analyze/references/author-facing.md +252 -0
  188. package/lib/oh-story/skills/story-long-analyze/references/deconstruction-notes.md +3 -3
  189. package/lib/oh-story/skills/story-long-analyze/references/final-checks.md +19 -0
  190. package/lib/oh-story/skills/story-long-analyze/references/index-rebuild.md +11 -0
  191. package/lib/oh-story/skills/story-long-analyze/references/inspiration-library.md +105 -0
  192. package/lib/oh-story/skills/story-long-analyze/references/pipeline-ops.md +138 -64
  193. package/lib/oh-story/skills/story-long-analyze/references/semantic-acceptance-fixtures.md +84 -0
  194. package/lib/oh-story/skills/story-long-analyze/references/stage1-golden-chapters.md +128 -0
  195. package/lib/oh-story/skills/story-long-analyze/references/stage2-extraction.md +229 -0
  196. package/lib/oh-story/skills/story-long-analyze/references/stage3-plot-rhythm.md +480 -0
  197. package/lib/oh-story/skills/story-long-analyze/references/stage4-characters-settings.md +195 -0
  198. package/lib/oh-story/skills/story-long-analyze/references/stage5-report.md +33 -0
  199. package/lib/oh-story/skills/story-long-analyze/references/style-profile-generator.md +55 -128
  200. package/lib/oh-story/skills/story-long-analyze/references/style-profile-protocol.md +6 -6
  201. package/lib/oh-story/skills/story-long-analyze/references/synthesis-inputs.md +39 -0
  202. package/lib/oh-story/skills/story-long-analyze/scripts/build_chapter_index.py +466 -0
  203. package/lib/oh-story/skills/story-long-analyze/scripts/inspect_existing_assets.py +702 -0
  204. package/lib/oh-story/skills/story-long-analyze/scripts/inspiration_index.py +864 -0
  205. package/lib/oh-story/skills/story-long-analyze/scripts/manage_analysis_run.py +1145 -0
  206. package/lib/oh-story/skills/story-long-analyze/scripts/render_relation_chart.py +425 -0
  207. package/lib/oh-story/skills/story-long-scan/SKILL.md +45 -194
  208. package/lib/oh-story/skills/story-long-scan/references/platform-ciweimao.md +19 -0
  209. package/lib/oh-story/skills/story-long-scan/references/platform-fanqie.md +45 -0
  210. package/lib/oh-story/skills/story-long-scan/references/platform-jjwxc.md +28 -0
  211. package/lib/oh-story/skills/story-long-scan/references/platform-qidian.md +35 -0
  212. package/lib/oh-story/skills/story-long-scan/references/platform-qimao.md +27 -0
  213. package/lib/oh-story/skills/story-long-scan/references/topic-decision.md +6 -2
  214. package/lib/oh-story/skills/story-long-write/SKILL.md +49 -81
  215. package/lib/oh-story/skills/story-long-write/references/agent-calls.md +47 -0
  216. package/lib/oh-story/skills/story-long-write/references/anti-ai-writing.md +12 -11
  217. package/lib/oh-story/skills/story-long-write/references/artifact-protocols.md +24 -202
  218. package/lib/oh-story/skills/story-long-write/references/author-memory-maintenance.md +75 -0
  219. package/lib/oh-story/skills/story-long-write/references/author-memory.md +46 -94
  220. package/lib/oh-story/skills/story-long-write/references/banned-words.md +2 -2
  221. package/lib/oh-story/skills/story-long-write/references/benchmark-recall.md +7 -11
  222. package/lib/oh-story/skills/story-long-write/references/character-relations.md +49 -1
  223. package/lib/oh-story/skills/story-long-write/references/cross-book-recall.md +26 -0
  224. package/lib/oh-story/skills/story-long-write/references/deslop-gates.md +171 -0
  225. package/lib/oh-story/skills/story-long-write/references/dialogue-mastery.md +4 -0
  226. package/lib/oh-story/skills/story-long-write/references/emotion-on-page.md +116 -0
  227. package/lib/oh-story/skills/story-long-write/references/emotional-arc-design.md +1 -114
  228. package/lib/oh-story/skills/story-long-write/references/emotional-methods.md +2 -2
  229. package/lib/oh-story/skills/story-long-write/references/genre-prose-cards.md +1 -1
  230. package/lib/oh-story/skills/story-long-write/references/long-chapter-quality.md +7 -15
  231. package/lib/oh-story/skills/story-long-write/references/long-format.md +0 -8
  232. package/lib/oh-story/skills/story-long-write/references/long-genre-catalog.md +1 -1
  233. package/lib/oh-story/skills/story-long-write/references/long-genre-mechanics.md +3 -3
  234. package/lib/oh-story/skills/story-long-write/references/opening-design.md +2 -2
  235. package/lib/oh-story/skills/story-long-write/references/outline-conflict.md +4 -4
  236. package/lib/oh-story/skills/story-long-write/references/outline-methods.md +7 -7
  237. package/lib/oh-story/skills/story-long-write/references/outline-rhythm.md +3 -3
  238. package/lib/oh-story/skills/story-long-write/references/outline-structure-theory.md +14 -69
  239. package/lib/oh-story/skills/story-long-write/references/plot-frameworks.md +1 -1
  240. package/lib/oh-story/skills/story-long-write/references/plot-special-topics.md +2 -2
  241. package/lib/oh-story/skills/story-long-write/references/project-files.md +19 -13
  242. package/lib/oh-story/skills/story-long-write/references/reader-contract-and-progression.md +13 -5
  243. package/lib/oh-story/skills/story-long-write/references/reference-index.md +5 -6
  244. package/lib/oh-story/skills/story-long-write/references/stop-and-fix.md +9 -0
  245. package/lib/oh-story/skills/story-long-write/references/style-combat-face.md +1 -58
  246. package/lib/oh-story/skills/story-long-write/references/style-genre-modules.md +1 -1
  247. package/lib/oh-story/skills/story-long-write/references/style-resolution.md +4 -4
  248. package/lib/oh-story/skills/story-long-write/references/tracking-initialization.md +1 -1
  249. package/lib/oh-story/skills/story-long-write/references/tracking-transaction.md +15 -11
  250. package/lib/oh-story/skills/story-long-write/references/workflow-chapter.md +81 -121
  251. package/lib/oh-story/skills/story-long-write/references/workflow-daily.md +41 -139
  252. package/lib/oh-story/skills/story-long-write/references/workflow-outline.md +157 -0
  253. package/lib/oh-story/skills/story-long-write/references/workflow-revision.md +57 -67
  254. package/lib/oh-story/skills/story-long-write/references/workflow-setup.md +112 -253
  255. package/lib/oh-story/skills/story-long-write/references/workflow-volume.md +142 -0
  256. package/lib/oh-story/skills/story-long-write/references/writer-prompt-fallback.md +6 -4
  257. package/lib/oh-story/skills/story-long-write/references/writing-craft.md +19 -65
  258. package/lib/oh-story/skills/story-long-write/scripts/author_memory_commit.py +934 -170
  259. package/lib/oh-story/skills/story-long-write/scripts/build_architect_brief.py +260 -0
  260. package/lib/oh-story/skills/story-long-write/scripts/build_writer_prompt.py +226 -25
  261. package/lib/oh-story/skills/story-long-write/scripts/check-ai-patterns.js +155 -8
  262. package/lib/oh-story/skills/story-long-write/scripts/check-outline-contract.js +132 -27
  263. package/lib/oh-story/skills/story-long-write/scripts/check-outline-copy.js +7 -2
  264. package/lib/oh-story/skills/story-long-write/scripts/outline_view.py +7 -4
  265. package/lib/oh-story/skills/story-long-write/scripts/storyctl.py +304 -46
  266. package/lib/oh-story/skills/story-long-write/scripts/tracking_commit.py +478 -15
  267. package/lib/oh-story/skills/story-long-write/scripts/wordcount_core.py +182 -23
  268. package/lib/oh-story/skills/story-review/SKILL.md +31 -302
  269. package/lib/oh-story/skills/story-review/references/agent-prompts.md +184 -0
  270. package/lib/oh-story/skills/story-review/references/anti-ai-writing.md +12 -11
  271. package/lib/oh-story/skills/story-review/references/author-memory-maintenance.md +75 -0
  272. package/lib/oh-story/skills/story-review/references/author-memory.md +46 -94
  273. package/lib/oh-story/skills/story-review/references/banned-words.md +2 -2
  274. package/lib/oh-story/skills/story-review/references/batch-review.md +19 -0
  275. package/lib/oh-story/skills/story-review/references/character-relations.md +49 -1
  276. package/lib/oh-story/skills/story-review/references/dialogue-mastery.md +4 -0
  277. package/lib/oh-story/skills/story-review/references/review-quality.md +6 -11
  278. package/lib/oh-story/skills/story-review/references/review-tracking.md +10 -0
  279. package/lib/oh-story/skills/story-review/references/solo.md +52 -0
  280. package/lib/oh-story/skills/story-review/references/style-resolution.md +4 -4
  281. package/lib/oh-story/skills/story-review/references/tracking-initialization.md +1 -1
  282. package/lib/oh-story/skills/story-review/references/tracking-transaction.md +15 -11
  283. package/lib/oh-story/skills/story-review/scripts/author_memory_commit.py +934 -170
  284. package/lib/oh-story/skills/story-review/scripts/check-ai-patterns.js +155 -8
  285. package/lib/oh-story/skills/story-review/scripts/tracking_commit.py +478 -15
  286. package/lib/oh-story/skills/story-review/scripts/wordcount_core.py +182 -23
  287. package/lib/oh-story/skills/story-setup/SKILL.md +71 -452
  288. package/lib/oh-story/skills/story-setup/references/agent-references/agent-quality.md +4 -4
  289. package/lib/oh-story/skills/story-setup/references/agent-references/anti-ai-writing.md +12 -11
  290. package/lib/oh-story/skills/story-setup/references/agent-references/banned-words.md +2 -2
  291. package/lib/oh-story/skills/story-setup/references/agent-references/benchmark-style-load.md +107 -0
  292. package/lib/oh-story/skills/story-setup/references/agent-references/character-relations.md +49 -1
  293. package/lib/oh-story/skills/story-setup/references/agent-references/deslop-gates.md +22 -5
  294. package/lib/oh-story/skills/story-setup/references/agent-references/dialogue-mastery.md +4 -0
  295. package/lib/oh-story/skills/story-setup/references/agent-references/emotion-on-page.md +116 -0
  296. package/lib/oh-story/skills/story-setup/references/agent-references/emotional-arc-design.md +1 -114
  297. package/lib/oh-story/skills/story-setup/references/agent-references/format-and-structure.md +1 -1
  298. package/lib/oh-story/skills/story-setup/references/agent-references/genre-prose-cards.md +1 -1
  299. package/lib/oh-story/skills/story-setup/references/agent-references/long-emotional-methods.md +2 -2
  300. package/lib/oh-story/skills/story-setup/references/agent-references/long-genre-catalog.md +1 -1
  301. package/lib/oh-story/skills/story-setup/references/agent-references/long-genre-mechanics.md +3 -3
  302. package/lib/oh-story/skills/story-setup/references/agent-references/long-quality.md +7 -5
  303. package/lib/oh-story/skills/story-setup/references/agent-references/opening-design.md +2 -2
  304. package/lib/oh-story/skills/story-setup/references/agent-references/outline-conflict.md +4 -4
  305. package/lib/oh-story/skills/story-setup/references/agent-references/outline-methods.md +7 -7
  306. package/lib/oh-story/skills/story-setup/references/agent-references/outline-rhythm.md +3 -3
  307. package/lib/oh-story/skills/story-setup/references/agent-references/short-emotional-methods.md +1 -1
  308. package/lib/oh-story/skills/story-setup/references/agent-references/short-genre-formulas.md +0 -15
  309. package/lib/oh-story/skills/story-setup/references/agent-references/short-reversal.md +1 -1
  310. package/lib/oh-story/skills/story-setup/references/agent-references/style-combat-face.md +1 -58
  311. package/lib/oh-story/skills/story-setup/references/agent-references/style-genre-modules.md +1 -1
  312. package/lib/oh-story/skills/story-setup/references/agent-references/style-resolution.md +4 -4
  313. package/lib/oh-story/skills/story-setup/references/agent-references/writing-craft.md +19 -65
  314. package/lib/oh-story/skills/story-setup/references/diagnostics.md +4 -4
  315. package/lib/oh-story/skills/story-short-analyze/SKILL.md +56 -110
  316. package/lib/oh-story/skills/story-short-analyze/references/analysis-character-relations.md +1 -1
  317. package/lib/oh-story/skills/story-short-analyze/references/analysis-method.md +42 -0
  318. package/lib/oh-story/skills/story-short-analyze/references/optional-modules.md +97 -0
  319. package/lib/oh-story/skills/story-short-analyze/references/output-contract.md +9 -47
  320. package/lib/oh-story/skills/story-short-analyze/references/quality-checklist.md +80 -0
  321. package/lib/oh-story/skills/story-short-analyze/references/source-story-quality.md +4 -4
  322. package/lib/oh-story/skills/story-short-analyze/references/stage2-3-structure-emotion.md +308 -0
  323. package/lib/oh-story/skills/story-short-analyze/references/stage4-6-reversal-summary.md +611 -0
  324. package/lib/oh-story/skills/story-short-scan/SKILL.md +35 -65
  325. package/lib/oh-story/skills/story-short-scan/references/manual-rank-input.md +36 -0
  326. package/lib/oh-story/skills/story-short-scan/references/platform-dianzhong.md +24 -0
  327. package/lib/oh-story/skills/story-short-scan/references/platform-heiyan.md +21 -0
  328. package/lib/oh-story/skills/story-short-scan/references/topic-match.md +38 -0
  329. package/lib/oh-story/skills/story-short-write/SKILL.md +23 -175
  330. package/lib/oh-story/skills/story-short-write/references/agent-calls.md +13 -0
  331. package/lib/oh-story/skills/story-short-write/references/author-memory-maintenance.md +75 -0
  332. package/lib/oh-story/skills/story-short-write/references/author-memory.md +46 -94
  333. package/lib/oh-story/skills/story-short-write/references/banned-words.md +2 -2
  334. package/lib/oh-story/skills/story-short-write/references/benchmark-recall.md +1 -21
  335. package/lib/oh-story/skills/story-short-write/references/dialogue-mastery.md +4 -0
  336. package/lib/oh-story/skills/story-short-write/references/emotional-methods.md +1 -1
  337. package/lib/oh-story/skills/story-short-write/references/genre-writing-formulas.md +0 -15
  338. package/lib/oh-story/skills/story-short-write/references/output-contract.md +9 -47
  339. package/lib/oh-story/skills/story-short-write/references/reference-index.md +17 -47
  340. package/lib/oh-story/skills/story-short-write/references/scene-craft.md +40 -0
  341. package/lib/oh-story/skills/story-short-write/references/short-craft.md +7 -43
  342. package/lib/oh-story/skills/story-short-write/references/short-format.md +3 -3
  343. package/lib/oh-story/skills/story-short-write/references/short-prose-quality.md +2 -1
  344. package/lib/oh-story/skills/story-short-write/references/short-reversal.md +1 -1
  345. package/lib/oh-story/skills/story-short-write/references/style-resolution.md +4 -4
  346. package/lib/oh-story/skills/story-short-write/references/submission-craft.md +1 -1
  347. package/lib/oh-story/skills/story-short-write/references/villain-and-reveal.md +5 -10
  348. package/lib/oh-story/skills/story-short-write/references/workflow-design.md +21 -13
  349. package/lib/oh-story/skills/story-short-write/references/workflow-draft.md +116 -0
  350. package/lib/oh-story/skills/story-short-write/references/workflow-revision.md +99 -0
  351. package/lib/oh-story/skills/story-short-write/references/writing-workflow.md +7 -119
  352. package/lib/oh-story/skills/story-short-write/scripts/author_memory_commit.py +934 -170
  353. package/lib/oh-story/skills/story-short-write/scripts/check-ai-patterns.js +155 -8
  354. package/lib/oh-story/skills/story-short-write/scripts/check-outline-copy.js +7 -2
  355. package/lib/types/client/drama-production-view.d.ts.map +1 -1
  356. package/lib/types/client/file-activity.d.ts +19 -1
  357. package/lib/types/client/file-activity.d.ts.map +1 -1
  358. package/lib/types/client/index.d.ts.map +1 -1
  359. package/lib/types/client/production-prompts.d.ts +7 -0
  360. package/lib/types/client/production-prompts.d.ts.map +1 -1
  361. package/lib/types/client/production-runtime.d.ts +16 -0
  362. package/lib/types/client/production-runtime.d.ts.map +1 -1
  363. package/lib/types/client/video-studio.d.ts.map +1 -1
  364. package/lib/types/drama-adapters.d.ts +5 -3
  365. package/lib/types/drama-adapters.d.ts.map +1 -1
  366. package/lib/types/native-hooks.d.ts +53 -1
  367. package/lib/types/native-hooks.d.ts.map +1 -1
  368. package/lib/types/role-identity.d.ts +17 -0
  369. package/lib/types/role-identity.d.ts.map +1 -0
  370. package/lib/types/role-tool.d.ts.map +1 -1
  371. package/lib/types/skill-provider.d.ts.map +1 -1
  372. package/lib/types/video-project.d.ts.map +1 -1
  373. package/lib/types/workspace-route.d.ts.map +1 -1
  374. package/lib/video-recap/CHANGELOG.md +60 -1
  375. package/lib/video-recap/README.en.md +348 -137
  376. package/lib/video-recap/README.md +340 -136
  377. package/lib/video-recap/manifest.json +406 -251
  378. package/lib/video-recap/skills/video-assemble/SKILL.md +30 -15
  379. package/lib/video-recap/skills/video-assemble/references/audio-modes.md +63 -0
  380. package/lib/video-recap/skills/video-assemble/references/explicit-audio-mix.md +75 -0
  381. package/lib/video-recap/skills/video-assemble/references/foreground-compose.md +118 -0
  382. package/lib/video-recap/skills/video-assemble/references/narration-adoption.md +103 -0
  383. package/lib/video-recap/skills/video-assemble/references/packaging.md +45 -0
  384. package/lib/video-recap/skills/video-assemble/references/pair-media.md +74 -0
  385. package/lib/video-recap/skills/video-assemble/references/source-score.md +147 -0
  386. package/lib/video-recap/skills/video-assemble/references/subtitle-track.md +202 -0
  387. package/lib/video-recap/skills/video-assemble/scripts/adoption/__init__.py +1 -0
  388. package/lib/video-recap/skills/video-assemble/scripts/adoption/audio_mix_binding.py +279 -0
  389. package/lib/video-recap/skills/video-assemble/scripts/adoption/frozen_audio.py +187 -0
  390. package/lib/video-recap/skills/video-assemble/scripts/adoption/narration_binding.py +323 -0
  391. package/lib/video-recap/skills/video-assemble/scripts/adoption/strict_inputs.py +109 -0
  392. package/lib/video-recap/skills/video-assemble/scripts/adoption/strict_publish.py +130 -0
  393. package/lib/video-recap/skills/video-assemble/scripts/artifacts.py +10 -46
  394. package/lib/video-recap/skills/video-assemble/scripts/assemble.py +378 -119
  395. package/lib/video-recap/skills/video-assemble/scripts/assemble_constants.py +29 -12
  396. package/lib/video-recap/skills/video-assemble/scripts/assembly_contract.py +95 -44
  397. package/lib/video-recap/skills/video-assemble/scripts/assembly_settings.py +75 -32
  398. package/lib/video-recap/skills/video-assemble/scripts/audio_mix.py +11 -11
  399. package/lib/video-recap/skills/video-assemble/scripts/compose_foreground.py +293 -0
  400. package/lib/video-recap/skills/video-assemble/scripts/export_jianying.py +71 -78
  401. package/lib/video-recap/skills/video-assemble/scripts/jianying/__init__.py +1 -0
  402. package/lib/video-recap/skills/video-assemble/scripts/{jianying_builders.py → jianying/builders.py} +39 -67
  403. package/lib/video-recap/skills/video-assemble/scripts/{jianying_model.py → jianying/model.py} +3 -11
  404. package/lib/video-recap/skills/video-assemble/scripts/{jianying_optional.py → jianying/optional.py} +1 -1
  405. package/lib/video-recap/skills/video-assemble/scripts/jianying/schema.py +53 -0
  406. package/lib/video-recap/skills/video-assemble/scripts/{jianying_templates.py → jianying/templates.py} +1 -1
  407. package/lib/video-recap/skills/video-assemble/scripts/{jianying_timeline_contract.py → jianying/timeline_contract.py} +34 -13
  408. package/lib/video-recap/skills/video-assemble/scripts/{jianying_writer.py → jianying/writer.py} +7 -17
  409. package/lib/video-recap/skills/video-assemble/scripts/lib.py +37 -4
  410. package/lib/video-recap/skills/video-assemble/scripts/media.py +12 -21
  411. package/lib/video-recap/skills/video-assemble/scripts/narration_audio.py +64 -34
  412. package/lib/video-recap/skills/video-assemble/scripts/packaging.py +122 -0
  413. package/lib/video-recap/skills/video-assemble/scripts/pair_media.py +216 -0
  414. package/lib/video-recap/skills/video-assemble/scripts/render_preflight.py +1 -3
  415. package/lib/video-recap/skills/video-assemble/scripts/source_score.py +469 -0
  416. package/lib/video-recap/skills/video-assemble/scripts/source_subtitles.py +25 -9
  417. package/lib/video-recap/skills/video-assemble/scripts/subtitles/__init__.py +1 -0
  418. package/lib/video-recap/skills/video-assemble/scripts/{subtitle_core.py → subtitles/core.py} +13 -6
  419. package/lib/video-recap/skills/video-assemble/scripts/{subtitle_render.py → subtitles/render.py} +5 -4
  420. package/lib/video-recap/skills/video-assemble/scripts/subtitles/track.py +324 -0
  421. package/lib/video-recap/skills/video-assemble/scripts/subtitles/track_binding.py +200 -0
  422. package/lib/video-recap/skills/video-assemble/scripts/timeline.py +30 -46
  423. package/lib/video-recap/skills/video-assemble/scripts/timeline_emit.py +91 -7
  424. package/lib/video-recap/skills/video-assemble/scripts/visual_render.py +22 -8
  425. package/lib/video-recap/skills/video-cut/SKILL.md +34 -16
  426. package/lib/video-recap/skills/video-cut/references/shot-review.md +50 -0
  427. package/lib/video-recap/skills/video-cut/scripts/cut.py +2 -28
  428. package/lib/video-recap/skills/video-cut/scripts/cut_cli.py +58 -62
  429. package/lib/video-recap/skills/video-cut/scripts/cut_contract.py +21 -106
  430. package/lib/video-recap/skills/video-cut/scripts/cut_render.py +14 -9
  431. package/lib/video-recap/skills/video-cut/scripts/lib.py +39 -0
  432. package/lib/video-recap/skills/video-cut/scripts/narration_mapping.py +2 -155
  433. package/lib/video-recap/skills/video-cut/scripts/narrative_selection.py +244 -0
  434. package/lib/video-recap/skills/video-cut/scripts/shot_review.py +357 -0
  435. package/lib/video-recap/skills/video-recap/SKILL.md +86 -42
  436. package/lib/video-recap/skills/video-recap/references/audio-routing.md +126 -0
  437. package/lib/video-recap/skills/video-recap/references/config-playbook.md +12 -8
  438. package/lib/video-recap/skills/video-recap/references/data-schema.md +44 -33
  439. package/lib/video-recap/skills/video-recap/references/resource-library.md +151 -0
  440. package/lib/video-recap/skills/video-recap/references/shift-left-qc-schema.md +1 -1
  441. package/lib/video-recap/skills/video-recap/scripts/doctor.py +123 -30
  442. package/lib/video-recap/skills/video-recap/scripts/final_qc.py +22 -75
  443. package/lib/video-recap/skills/video-recap/scripts/lib.py +3 -3
  444. package/lib/video-recap/skills/video-recap/scripts/library.py +509 -0
  445. package/lib/video-recap/skills/video-recap/scripts/materials.py +63 -91
  446. package/lib/video-recap/skills/video-recap/scripts/mimo_qc.py +8 -70
  447. package/lib/video-recap/skills/video-recap/scripts/project_binding.py +286 -0
  448. package/lib/video-recap/skills/video-recap/scripts/qc/__init__.py +1 -0
  449. package/lib/video-recap/skills/video-recap/scripts/{mimo_qc_client.py → qc/mimo_client.py} +1 -1
  450. package/lib/video-recap/skills/video-recap/scripts/{mimo_qc_evidence.py → qc/mimo_evidence.py} +33 -66
  451. package/lib/video-recap/skills/video-recap/scripts/{mimo_qc_observations.py → qc/mimo_observations.py} +3 -11
  452. package/lib/video-recap/skills/video-recap/scripts/{mimo_qc_payload.py → qc/mimo_payload.py} +4 -7
  453. package/lib/video-recap/skills/video-recap/scripts/{mimo_qc_report.py → qc/mimo_report.py} +17 -28
  454. package/lib/video-recap/skills/video-recap/scripts/{mimo_qc_runner.py → qc/mimo_runner.py} +2 -2
  455. package/lib/video-recap/skills/video-recap/scripts/qc_contract.py +0 -19
  456. package/lib/video-recap/skills/video-recap/scripts/recap_cli.py +119 -50
  457. package/lib/video-recap/skills/video-recap/scripts/recap_inspect.py +32 -114
  458. package/lib/video-recap/skills/video-recap/scripts/recap_review.py +9 -23
  459. package/lib/video-recap/skills/video-recap/scripts/recap_runner.py +387 -334
  460. package/lib/video-recap/skills/video-recap/scripts/recap_runtime.py +23 -23
  461. package/lib/video-recap/skills/video-recap/scripts/recap_source.py +278 -0
  462. package/lib/video-recap/skills/video-recap/scripts/recap_stage_qc.py +25 -12
  463. package/lib/video-recap/skills/video-recap/scripts/recap_timeline.py +59 -52
  464. package/lib/video-recap/skills/video-recap/scripts/resource_lock.py +162 -0
  465. package/lib/video-recap/skills/video-script/SKILL.md +16 -13
  466. package/lib/video-recap/skills/video-script/references/creative-editing-playbook.md +9 -5
  467. package/lib/video-recap/skills/video-script/references/promotional-copy.md +68 -0
  468. package/lib/video-recap/skills/video-script/references/research-guide.md +1 -1
  469. package/lib/video-recap/skills/video-script/scripts/evidence_bundle.py +24 -76
  470. package/lib/video-recap/skills/video-script/scripts/lib.py +10 -87
  471. package/lib/video-recap/skills/video-script/scripts/narration_lint.py +63 -39
  472. package/lib/video-recap/skills/video-script/scripts/review.py +0 -2
  473. package/lib/video-recap/skills/video-script/scripts/review_grounding.py +35 -59
  474. package/lib/video-recap/skills/video-script/scripts/review_response.py +66 -128
  475. package/lib/video-recap/skills/video-script/scripts/review_runner.py +12 -20
  476. package/lib/video-recap/skills/video-script/scripts/speech_ownership.py +4 -4
  477. package/lib/video-recap/skills/video-script/scripts/validate.py +53 -42
  478. package/lib/video-recap/skills/video-understanding/SKILL.md +6 -4
  479. package/lib/video-recap/skills/video-understanding/references/data-schema.md +50 -156
  480. package/lib/video-recap/skills/video-understanding/references/research-guide.md +4 -4
  481. package/lib/video-recap/skills/video-understanding/scripts/asr.py +85 -65
  482. package/lib/video-recap/skills/video-understanding/scripts/asr_timing_evidence.py +270 -0
  483. package/lib/video-recap/skills/video-understanding/scripts/brief.py +2 -5
  484. package/lib/video-recap/skills/video-understanding/scripts/briefing/__init__.py +1 -0
  485. package/lib/video-recap/skills/{video-script/scripts/agent_brief.py → video-understanding/scripts/briefing/builder.py} +38 -35
  486. package/lib/video-recap/skills/video-understanding/scripts/{brief_context.py → briefing/context.py} +4 -35
  487. package/lib/video-recap/skills/{video-script/scripts/brief_inputs.py → video-understanding/scripts/briefing/inputs.py} +9 -31
  488. package/lib/video-recap/skills/{video-script/scripts/brief_timeline.py → video-understanding/scripts/briefing/timeline.py} +5 -6
  489. package/lib/video-recap/skills/video-understanding/scripts/consolidate.py +65 -116
  490. package/lib/video-recap/skills/video-understanding/scripts/detect.py +31 -40
  491. package/lib/video-recap/skills/video-understanding/scripts/lib.py +30 -86
  492. package/lib/video-recap/skills/video-understanding/scripts/narration_lint.py +63 -39
  493. package/lib/video-recap/skills/video-understanding/scripts/speech_ownership.py +4 -4
  494. package/lib/video-recap/skills/video-understanding/scripts/storyboard.py +17 -79
  495. package/lib/video-recap/skills/video-understanding/scripts/understanding_brief.py +14 -40
  496. package/lib/video-recap/skills/video-understanding/scripts/understanding_cache.py +64 -46
  497. package/lib/video-recap/skills/video-understanding/scripts/understanding_runner.py +31 -11
  498. package/lib/video-recap/skills/video-understanding/scripts/understanding_storyboard.py +19 -14
  499. package/lib/video-recap/skills/video-understanding/scripts/vlm.py +80 -108
  500. package/lib/video-recap/skills/video-voiceover/SKILL.md +29 -19
  501. package/lib/video-recap/skills/video-voiceover/references/index-tts.md +31 -0
  502. package/lib/video-recap/skills/video-voiceover/scripts/approved_text_policy.py +123 -0
  503. package/lib/video-recap/skills/video-voiceover/scripts/dub.py +51 -59
  504. package/lib/video-recap/skills/video-voiceover/scripts/lib.py +8 -44
  505. package/lib/video-recap/skills/video-voiceover/scripts/providers/__init__.py +1 -0
  506. package/lib/video-recap/skills/video-voiceover/scripts/providers/index_tts.py +184 -0
  507. package/lib/video-recap/skills/video-voiceover/scripts/voiceover.py +212 -134
  508. package/package.json +45 -45
  509. package/lib/novel-to-game/skills/game-world-design/references/dialogue-design-method.md +0 -58
  510. package/lib/novel-to-game/skills/game-world-design/references/game-writing-craft.md +0 -53
  511. package/lib/novel-to-game/skills/novel-to-game/references/intake-benchmark-reference.md +0 -38
  512. package/lib/oh-story/skills/story-long-analyze/references/material-decomposition.md +0 -530
  513. package/lib/oh-story/skills/story-long-analyze/references/output-templates.md +0 -559
  514. package/lib/oh-story/skills/story-long-scan/references/scan-output-format.md +0 -207
  515. package/lib/oh-story/skills/story-long-write/references/state-tracking.md +0 -108
  516. package/lib/oh-story/skills/story-short-analyze/references/material-decomposition.md +0 -678
  517. package/lib/oh-story/skills/story-short-analyze/references/output-templates.md +0 -561
  518. package/lib/video-recap/skills/video-assemble/scripts/jianying_schema.py +0 -98
  519. package/lib/video-recap/skills/video-recap/references/creative-editing-playbook.md +0 -225
  520. package/lib/video-recap/skills/video-recap/references/research-guide.md +0 -74
  521. package/lib/video-recap/skills/video-recap/references/timeline-and-jianying.md +0 -250
  522. package/lib/video-recap/skills/video-script/scripts/brief_context.py +0 -348
  523. package/lib/video-recap/skills/video-script/scripts/narration.py +0 -12
  524. package/lib/video-recap/skills/video-understanding/scripts/agent_brief.py +0 -399
  525. package/lib/video-recap/skills/video-understanding/scripts/brief_inputs.py +0 -290
  526. package/lib/video-recap/skills/video-understanding/scripts/brief_timeline.py +0 -327
  527. /package/lib/video-recap/skills/video-assemble/scripts/{jianying_tracks.py → jianying/tracks.py} +0 -0
  528. /package/lib/video-recap/skills/video-recap/scripts/{mimo_qc_contract.py → qc/mimo_contract.py} +0 -0
  529. /package/lib/video-recap/skills/video-voiceover/scripts/{fish_audio.py → providers/fish_audio.py} +0 -0
@@ -0,0 +1,151 @@
1
+ # 资源库、模板与样片
2
+
3
+ 资源库是你自己的目录,与素材库共用同一个根目录(`--material-library-dir` / `VIDEO_RECAP_MATERIAL_LIBRARY_DIR`)。
4
+ 仓库不内置任何真实 BGM、音效、音色、字体或包装;合成示例见仓库的 `examples/resource-library/`。
5
+
6
+ ```text
7
+ <library>/
8
+ library.json # {"schema": "video-recap.library.v1", "name": "…"}
9
+ materials/… # 理解分析库(见 data-schema.md),不变
10
+ resources/<kind>/<id>/resource.json (+ 文件)
11
+ templates/<kind>/<id>/v<version>/template.json
12
+ samples/<id>/sample.json (+ 样片文件,或指向库外的绝对路径)
13
+ ```
14
+
15
+ 只读工具(本技能目录下):
16
+
17
+ ```bash
18
+ python3 scripts/library.py --library-dir <library> check # 有错误时退出码 1;--json 输出机器可读报告
19
+ python3 scripts/library.py --library-dir <library> list [--kind bgm]
20
+ python3 scripts/library.py --library-dir <library> show <id|id@vN>
21
+ ```
22
+
23
+ 浏览资源、模板与样片(含图片、音频与样片预览)可用只读 dashboard:`python3 scripts/dashboard_server.py --root <library 或其上层目录>`。
24
+
25
+ 工具从不写库。新增或修改记录时直接编辑 JSON,再跑 `check`。**错误**表示该条目不能用;**警告**表示能用但需要人看一眼
26
+ (授权未确认、声音授权未确认、样片不在本机、模板采用后资源文件已变化)。
27
+
28
+ ## 通用规则
29
+
30
+ - `id` 与所在目录名一致,只用小写字母、数字和 `. _ -`;模板目录名为 `v<version>`。
31
+ - 顶层字段严格:出现未列出的字段即报错,避免拼错的字段被静默忽略。
32
+ - 文件路径相对记录所在目录,解析后必须仍在库根目录内(`..` 越界、绝对路径和指向库外的符号链接都报错)。
33
+ 唯一例外是样片可以写绝对路径,因为成片常放在别的盘上。
34
+ - 文件身份是 `{size, mtime_ns}`,不计算内容哈希。
35
+ - 派生文件(归一化 WAV、转码片段)只出现在 work_dir,不回写为资源。
36
+
37
+ ## 资源 `resource.json`
38
+
39
+ ```json
40
+ {
41
+ "schema": "video-recap.resource.v1",
42
+ "id": "pulse-demo",
43
+ "kind": "bgm",
44
+ "title": "合成脉冲底噪(演示)",
45
+ "files": [{"role": "main", "path": "pulse-demo.wav"}],
46
+ "origin": {"creator": "…", "url": "…"},
47
+ "license": {"status": "owned", "terms": "…", "evidence": "…"},
48
+ "tags": ["低频"],
49
+ "notes": ""
50
+ }
51
+ ```
52
+
53
+ | `kind` | 文件 | 额外字段 |
54
+ |---|---|---|
55
+ | `bgm` / `sfx` | 至少一个音频文件(wav / mp3 / m4a / aac / flac / ogg) | — |
56
+ | `voice` | 可选参考音频 | `voice.provider` ∈ `mimo-tts` / `fish-audio` / `index-tts`,以及 `voice.voice_id` 或一个参考音频;有参考音频时必须写 `consent.status` ∈ `unknown` / `granted` / `denied` |
57
+ | `font` | 至少一个字体文件(ttf / otf / ttc) | 可选 `font.family`、`font.index` |
58
+ | `image` | 至少一个图片(png / jpg / webp),用于 logo、包框、片尾卡 | — |
59
+
60
+ `license.status` ∈ `unknown` / `owned` / `licensed` / `restricted`,只能由人填写;工具不会因为文件放在库里就认为有授权。
61
+ `unknown` 与 `restricted` 在 `check` 中是警告。
62
+
63
+ ## 模板 `template.json`
64
+
65
+ ```json
66
+ {
67
+ "schema": "video-recap.template.v1",
68
+ "id": "clean-white",
69
+ "version": 1,
70
+ "kind": "subtitle_style",
71
+ "title": "白字细描边",
72
+ "canvas": {"width": 900, "height": 1600},
73
+ "params": {
74
+ "font": {"family": "Arial"},
75
+ "size_px": {"value": 52, "provenance": "specified"},
76
+ "max_chars": {"value": 15, "provenance": "measured"},
77
+ "band": {"value": {"y_top": 1280, "y_bot": 1440}, "provenance": "measured"}
78
+ },
79
+ "samples": ["demo-sample"],
80
+ "status": "adopted",
81
+ "adoption": {"date": "2026-09-27", "by": "user", "statement": "用户原话", "scope": "适用范围"}
82
+ }
83
+ ```
84
+
85
+ - 模板只对 `canvas` 声明的画布有效;换画幅就是新模板,不自动缩放套用。
86
+ - 任何带 `provenance` 的参数都要有 `value`,`provenance` ∈ `measured`(从成片实测)/ `fitted`(反复调出来的)/
87
+ `specified`(人直接给的数值)/ `unknown`。编辑器面板上的读数不是像素,按 `specified` 或 `unknown` 记。
88
+ - 引用资源写 `{"resource": "<id>"}`:`params.font` 必须指向 `font` 资源,图层的 `image` 必须指向 `image` 资源。
89
+ - `subtitle_style` 需要 `params.font`(`resource` 或 `family`)、`params.size_px` 与 `params.max_chars`(每行最多字数,用最长一行在这块画布上校准);
90
+ `size_px × max_chars` 超过画布宽减去两侧各 40px 默认边距时报错。可选 `outline_px`、`shadow_px`、`primary_color`、`outline_color`、`max_lines`、`band`,其他参数名报错;`params.band.value` 若给出,需满足
91
+ `0 <= y_top < y_bot <= canvas.height`。
92
+ - `packaging` 需要非空 `params.layers`,每层有唯一 `name`、`image` 引用与画布内的整数 `rect {x, y, width, height}`;
93
+ 可选 `params.safe_rect`。
94
+ - `status` ∈ `draft` / `adopted` / `retired`。`adopted` 必须有 `adoption.date`(YYYY-MM-DD)、`by`、`statement`(用户原话)
95
+ 与 `scope`。可选 `adoption.resources` 记录采用时所用资源文件的身份:
96
+
97
+ ```json
98
+ "resources": {"frame-demo": [{"path": "resources/image/frame-demo/frame-demo.png", "size": 6063, "mtime_ns": 0}]}
99
+ ```
100
+
101
+ 之后文件的大小或修改时间变化,`check` 给出 `changed_since_adoption` 警告:重新采用,或出一个新版本。
102
+ 修改时间是本机事实,把库拷到另一台机器会让所有快照都显示为已变化。
103
+
104
+ ## 样片 `sample.json`
105
+
106
+ ```json
107
+ {
108
+ "schema": "video-recap.sample.v1",
109
+ "id": "demo-sample",
110
+ "title": "纯色演示片",
111
+ "file": {"path": "demo-sample.mp4"},
112
+ "canvas": {"width": 900, "height": 1600},
113
+ "demonstrates": ["字幕带位置", "画布尺寸"],
114
+ "not_reusable": "这条样片里哪些东西不能照搬",
115
+ "templates": ["clean-white@v1"]
116
+ }
117
+ ```
118
+
119
+ 样片是证据,不是模板:`demonstrates` 写它示范了什么,`not_reusable` 写不能照搬什么(人物、字幕内容、时间码……)。
120
+ `templates` 用 `id@vN` 指回它所示范的模板版本。
121
+
122
+ ## 项目绑定 `recap_project.json`
123
+
124
+ ```json
125
+ {
126
+ "schema": "video-recap.project.v1",
127
+ "name": "某系列竖屏解说",
128
+ "library": "../video-library",
129
+ "bindings": {"subtitle_style": "clean-white@v1", "voice": "narrator-demo", "bgm": "pulse-demo"}
130
+ }
131
+ ```
132
+
133
+ `python3 scripts/recap.py <video> --project <recap_project.json 或所在目录> …` 在任何阶段开始前解析绑定:`library` 相对项目文件;
134
+ 模板必须是 `adopted`;资源与模板必须通过 `check`。解析结果只以各阶段已有的设置下发,阶段技能不读资源库:
135
+
136
+ | 绑定 | 下发为 |
137
+ |---|---|
138
+ | `subtitle_style` | `SUBTITLE_PLAY_RES_X/Y` = 模板画布,`SUBTITLE_FONT_SIZE` ← `size_px`,`SUBTITLE_OUTLINE` ← `outline_px`,`SUBTITLE_SHADOW` ← `shadow_px`,`SUBTITLE_PRIMARY_COLOR` / `SUBTITLE_OUTLINE_COLOR`(ASS `&HAABBGGRR`),`SUBTITLE_MAX_CHARS` / `SUBTITLE_MAX_LINES`;`band` → 底对齐 `SUBTITLE_ALIGNMENT=2` 且 `SUBTITLE_MARGIN_V` = 画布高 − `y_bot`;`font.family` → `SUBTITLE_FONT_NAME`,字体资源 → 再加 `SUBTITLE_FONT_FILE` |
139
+ | `voice` | provider → `--tts-provider`;MiMo 预置音色 → `--mimo-tts-voice`,参考音频 → `--voice-ref`;Fish Audio → `FISH_TTS_REFERENCE_ID`;index-tts → `INDEX_TTS_VOICE` |
140
+ | `bgm` | `BGM_PATH` ← 该资源的第一个文件 |
141
+ | `packaging` | 合成前写出 `work_dir/packaging_layers.json`:每个图层的图片资源第一个文件 + `rect`,由 video-assemble 叠加到成片并写进 `timeline.json` 的 image 轨 |
142
+
143
+ - 你已经显式设置的参数或环境变量与绑定不一致时,运行在开始前停止并指出是哪一项,不会静默覆盖。
144
+ - 合成前核对模板画布与实际成片画布;不一致即停止——换画幅要用另一个模板。
145
+ - 参考音频的 `consent.status` 为 `denied` 时拒绝绑定;dub 模式与本地采用三件套不接受 `--project`。
146
+ - 续跑命令只带 `--project`,不重复写出由绑定得到的值,改了绑定后续跑会按新绑定解析。
147
+
148
+ ## 运行记录
149
+
150
+ 每次 full / cut 合成后,`work_dir/resource_lock.json` 记下这次用到的原片、音色、BGM 与字幕字体,并对上资源库里的登记和授权状态;
151
+ 格式见 `data-schema.md` 的 resource_lock.json 一节。
@@ -9,7 +9,7 @@
9
9
  - `stage`:只能是 `pre_cut`、`post_cut`、`pre_tts`、`post_tts`、`pre_assemble`、`post_render`、`golden`。
10
10
  - 不得使用 `pre_voiceover`、`post_voiceover`、`pre_export`、`post_export`、`final`、`golden_eval` 或 `mimo_qc` 作为阶段值。
11
11
  - `mimo_qc.json` 是产物名;MiMo finding 必须挂在 `post_tts`、`pre_assemble` 等真实阶段上。
12
- - `findings[]`:每项必须包含 `finding_id`、`stage`、`severity`、`blocking`、`deterministic`、`confidence`、`rule_id`、`decision_reason`、`location`、`evidence`、`sample_policy`、`model_used`、`artifact_fingerprints` 与 `next_action`。
12
+ - `findings[]`:每项必须包含 `finding_id`、`stage`、`severity`、`blocking`、`deterministic`、`confidence`、`rule_id`、`decision_reason`、`location`、`evidence`、`sample_policy`、`model_used` 与 `next_action`。
13
13
  - `sample_policy`:至少包含 `type`;其值只能是 `all`、`deterministic`、`sampled`、`semantic` 或 `aesthetic`。
14
14
  - `location.timecode` 与 `location.source_span` 必须存在;剪辑前阶段可以把任一字段设为 `null`。
15
15
  - 为兼容与诊断,当前辅助函数还可能写出 `id`、`category`、`code`、`message`、`source` 与 `objective_corroboration`。
@@ -1,15 +1,18 @@
1
1
  #!/usr/bin/env python3
2
2
  """Environment doctor for the video-recap skill bundle.
3
3
 
4
- The pipeline runs on ffmpeg + MiMo for understanding; voiceover may use MiMo or Fish Audio.
4
+ The pipeline runs on ffmpeg + MiMo for understanding; voiceover may explicitly use
5
+ MiMo, Fish Audio, or a privately configured Index TTS endpoint.
5
6
  """
6
7
  from __future__ import annotations
7
8
 
8
9
  import argparse
9
10
  import json
11
+ import os
10
12
  import shutil
11
13
  import subprocess
12
14
  import sys
15
+ import urllib.parse
13
16
  from pathlib import Path
14
17
 
15
18
  from lib import CONFIG
@@ -17,7 +20,7 @@ from lib import CONFIG
17
20
 
18
21
  SCRIPT_DIR = Path(__file__).resolve().parent
19
22
  DEGRADED_GROUP = "warnings/degraded"
20
- TTS_PROVIDERS = {"auto", "mimo-tts", "fish-audio"}
23
+ TTS_PROVIDERS = ("auto", "mimo-tts", "fish-audio", "index-tts")
21
24
 
22
25
 
23
26
  def _command_path(name: str) -> str | None:
@@ -25,6 +28,10 @@ def _command_path(name: str) -> str | None:
25
28
 
26
29
 
27
30
  def _ffmpeg_filters() -> set[str]:
31
+ """Filters the installed ffmpeg lists; empty when ffmpeg is absent.
32
+
33
+ A present ffmpeg whose `-filters` fails or hangs is an environment fault and raises,
34
+ so it is never misreported downstream as "filter absent"."""
28
35
  ffmpeg = _command_path("ffmpeg")
29
36
  if not ffmpeg:
30
37
  return set()
@@ -32,10 +39,11 @@ def _ffmpeg_filters() -> set[str]:
32
39
  result = subprocess.run(
33
40
  [ffmpeg, "-hide_banner", "-filters"], text=True, capture_output=True, timeout=20
34
41
  )
35
- except (OSError, subprocess.SubprocessError):
36
- return set()
42
+ except (OSError, subprocess.SubprocessError) as exc:
43
+ raise RuntimeError(f"`ffmpeg -filters` failed or hung: {exc}") from exc
37
44
  if result.returncode != 0:
38
- return set()
45
+ detail = (result.stderr or result.stdout or "").strip()[:300]
46
+ raise RuntimeError(f"`ffmpeg -filters` failed (exit {result.returncode}): {detail}")
39
47
  filters = set()
40
48
  for line in result.stdout.splitlines():
41
49
  parts = line.split()
@@ -62,11 +70,44 @@ def _asr_status() -> dict[str, object]:
62
70
  "mimo_asr_api_url": CONFIG["mimo_asr_api_url"],
63
71
  "mimo_asr_api_url_source": CONFIG["mimo_asr_api_url_source"],
64
72
  "mimo_asr_language": CONFIG["mimo_asr_language"],
65
- "mimo_asr_api_key_source": CONFIG["mimo_asr_api_key_source"],
73
+ "mimo_asr_env_var": CONFIG["mimo_asr_env_var"],
66
74
  "note": "ASR uses MiMo (mimo-v2.5-asr); set MIMO_API_KEY, or run with --skip-asr.",
67
75
  }
68
76
 
69
77
 
78
+ def _index_tts_status() -> dict[str, object]:
79
+ """Validate private Index settings locally without exposing or contacting them."""
80
+ endpoint = os.environ.get("INDEX_TTS_ENDPOINT", "")
81
+ voice = os.environ.get("INDEX_TTS_VOICE", "").strip()
82
+ has_forbidden_control = any(
83
+ ord(char) < 32 or ord(char) == 127 for char in endpoint
84
+ )
85
+ try:
86
+ parsed = urllib.parse.urlsplit(endpoint) if endpoint else None
87
+ port = parsed.port if parsed else None
88
+ except ValueError:
89
+ parsed = None
90
+ port = None
91
+ endpoint_format_valid = bool(
92
+ parsed
93
+ and not has_forbidden_control
94
+ and parsed.scheme in {"http", "https"}
95
+ and parsed.hostname
96
+ and "@" not in parsed.netloc
97
+ and not parsed.query
98
+ and not parsed.fragment
99
+ and (port is None or 1 <= port <= 65535)
100
+ )
101
+ return {
102
+ "index_tts_endpoint_set": bool(endpoint),
103
+ "index_tts_endpoint_format_valid": endpoint_format_valid,
104
+ "index_tts_voice_set": bool(voice),
105
+ "index_tts_configured": endpoint_format_valid and bool(voice),
106
+ "connectivity_checked": False,
107
+ "validation_scope": "offline configuration only; connectivity and acoustic quality not checked",
108
+ }
109
+
110
+
70
111
  def _capability(name: str, summary: str, *, detail: str = "", action: str = "") -> dict[str, str]:
71
112
  item = {"name": name, "summary": summary}
72
113
  if detail:
@@ -126,7 +167,7 @@ def _build_capability_menu(checks: dict) -> dict[str, list[dict[str, str]]]:
126
167
  _capability(
127
168
  "mimo_credentials",
128
169
  "MiMo API key is configured",
129
- detail=f"Source: {api['api_key_source']}",
170
+ detail=f"Source: {api['api_env_var']}",
130
171
  )
131
172
  )
132
173
  else:
@@ -156,24 +197,37 @@ def _build_capability_menu(checks: dict) -> dict[str, list[dict[str, str]]]:
156
197
  )
157
198
 
158
199
  tts_provider = tts["provider"]
200
+ if tts_provider == "index-tts":
201
+ capability_name = "index_tts_configuration"
202
+ action = "Set valid INDEX_TTS_ENDPOINT and INDEX_TTS_VOICE values before voiceover."
203
+ elif tts_provider == "fish-audio":
204
+ capability_name = "fish_audio_tts"
205
+ action = "Set FISH_API_KEY before voiceover."
206
+ else:
207
+ capability_name = "mimo_tts"
208
+ action = "Set MIMO_TTS_API_KEY or the shared MIMO_API_KEY before voiceover."
159
209
  if tts_ready:
160
210
  menu["ready"].append(
161
211
  _capability(
162
- "fish_audio_tts" if tts_provider == "fish-audio" else "mimo_tts",
163
- f"{tts_provider} is configured",
164
- detail=f"Model: {tts['model']}",
212
+ capability_name,
213
+ (
214
+ "index-tts configuration is present"
215
+ if tts_provider == "index-tts"
216
+ else f"{tts_provider} is configured"
217
+ ),
218
+ detail=(
219
+ tts["validation_scope"]
220
+ if tts_provider == "index-tts"
221
+ else f"Model: {tts['model']}"
222
+ ),
165
223
  )
166
224
  )
167
225
  elif api_key_set:
168
226
  menu["blocked"].append(
169
227
  _capability(
170
- "fish_audio_tts" if tts_provider == "fish-audio" else "mimo_tts",
228
+ capability_name,
171
229
  f"{tts_provider} is not configured",
172
- action=(
173
- "Set FISH_API_KEY before voiceover."
174
- if tts_provider == "fish-audio"
175
- else "Set MIMO_TTS_API_KEY or the shared MIMO_API_KEY before voiceover."
176
- ),
230
+ action=action,
177
231
  )
178
232
  )
179
233
 
@@ -217,7 +271,19 @@ def _build_capability_menu(checks: dict) -> dict[str, list[dict[str, str]]]:
217
271
  )
218
272
  elif asr_ready and subtitles_ready:
219
273
  menu["ready"].append(
220
- _capability("default_recap_pipeline", "Default recap run is ready", detail="ASR, VLM, TTS, and media tools are configured.")
274
+ _capability(
275
+ "default_recap_pipeline",
276
+ (
277
+ "Recap prerequisites are configured"
278
+ if tts_provider == "index-tts"
279
+ else "Default recap run is ready"
280
+ ),
281
+ detail=(
282
+ "ASR, VLM, and media tools are configured; Index TTS passed offline configuration checks only."
283
+ if tts_provider == "index-tts"
284
+ else "ASR, VLM, TTS, and media tools are configured."
285
+ ),
286
+ )
221
287
  )
222
288
  else:
223
289
  actions = []
@@ -259,15 +325,25 @@ def build_report(*, tts_provider: str | None = None) -> dict[str, object]:
259
325
  mimo_video_configured = bool(CONFIG["mimo_video_api_key"])
260
326
  mimo_tts_configured = bool(CONFIG["mimo_tts_api_key"])
261
327
  fish_tts_configured = bool(CONFIG["fish_api_key"])
328
+ index_tts = _index_tts_status()
262
329
  requested_tts_provider = tts_provider or CONFIG["tts_provider"]
263
330
  effective_tts_provider = requested_tts_provider
264
331
  if requested_tts_provider == "auto":
265
332
  effective_tts_provider = (
266
333
  "mimo-tts" if mimo_tts_configured or not fish_tts_configured else "fish-audio"
267
334
  )
268
- tts_configured = (
269
- fish_tts_configured if effective_tts_provider == "fish-audio" else mimo_tts_configured
270
- )
335
+ if effective_tts_provider == "fish-audio":
336
+ tts_configured = fish_tts_configured
337
+ elif effective_tts_provider == "index-tts":
338
+ tts_configured = index_tts["index_tts_configured"]
339
+ else:
340
+ tts_configured = mimo_tts_configured
341
+ if effective_tts_provider == "fish-audio":
342
+ tts_model = CONFIG["fish_tts_model"]
343
+ elif effective_tts_provider == "index-tts":
344
+ tts_model = "provider-managed"
345
+ else:
346
+ tts_model = CONFIG["mimo_tts_model"]
271
347
  subtitle_filter = "subtitles" in filters
272
348
  checks = {
273
349
  "system_tools": {
@@ -294,11 +370,8 @@ def build_report(*, tts_provider: str | None = None) -> dict[str, object]:
294
370
  "fish_tts_model": CONFIG["fish_tts_model"],
295
371
  "fish_tts_reference_id_set": bool(CONFIG["fish_tts_reference_id"]),
296
372
  "fish_tts_reference_id_source": CONFIG["fish_tts_reference_id_source"],
297
- "model": (
298
- CONFIG["fish_tts_model"]
299
- if effective_tts_provider == "fish-audio"
300
- else CONFIG["mimo_tts_model"]
301
- ),
373
+ **index_tts,
374
+ "model": tts_model,
302
375
  "available": tts_configured,
303
376
  },
304
377
  "asr": _asr_status(),
@@ -306,7 +379,7 @@ def build_report(*, tts_provider: str | None = None) -> dict[str, object]:
306
379
  "api_provider": CONFIG["api_provider"],
307
380
  "api_url": CONFIG["api_url"],
308
381
  "api_url_source": CONFIG["api_url_source"],
309
- "api_key_source": CONFIG["api_key_source"],
382
+ "api_env_var": CONFIG["api_env_var"],
310
383
  "api_key_set": bool(CONFIG["api_key"]),
311
384
  "vlm_model": CONFIG["vlm_model"],
312
385
  "vlm_model_source": CONFIG["vlm_model_source"],
@@ -330,8 +403,17 @@ def build_report(*, tts_provider: str | None = None) -> dict[str, object]:
330
403
  failures.append(f"Missing system tool: {name}")
331
404
  if requested_tts_provider not in TTS_PROVIDERS:
332
405
  failures.append(
333
- "TTS_PROVIDER must be one of: auto, mimo-tts, fish-audio"
406
+ "TTS_PROVIDER must be one of: " + ", ".join(TTS_PROVIDERS)
334
407
  )
408
+ elif requested_tts_provider == "index-tts":
409
+ if not index_tts["index_tts_endpoint_set"]:
410
+ failures.append("INDEX_TTS_ENDPOINT is not set")
411
+ elif not index_tts["index_tts_endpoint_format_valid"]:
412
+ failures.append(
413
+ "INDEX_TTS_ENDPOINT must be an http/https URL with a hostname and no credentials, query, or fragment"
414
+ )
415
+ if not index_tts["index_tts_voice_set"]:
416
+ failures.append("INDEX_TTS_VOICE is not set")
335
417
  if tools["ffmpeg"] and not tools["ffmpeg_subtitles_filter"]:
336
418
  warnings.append("ffmpeg lacks subtitles/libass filter; --burn-subtitles will fail")
337
419
  if not checks["api_config"]["api_key_set"]:
@@ -375,7 +457,7 @@ def _print_human(report: dict) -> None:
375
457
  print(f"✓ API URL: {api['api_url']} (source: {api['api_url_source']})")
376
458
  print(
377
459
  f"{_status_icon(api['api_key_set'])} "
378
- f"{api['api_key_source']}: {'set' if api['api_key_set'] else 'not set'}"
460
+ f"{api['api_env_var']}: {'set' if api['api_key_set'] else 'not set'}"
379
461
  )
380
462
  print(f"✓ VLM model: {api['vlm_model']} (source: {api['vlm_model_source']})")
381
463
  print(f"✓ VLM_WORKERS: {api['vlm_workers']}")
@@ -385,7 +467,7 @@ def _print_human(report: dict) -> None:
385
467
  print(
386
468
  f"{_status_icon(asr['available'], warning=True)} "
387
469
  f"MiMo ASR: {'configured' if asr['available'] else 'not configured'} "
388
- f"(key: {asr['mimo_asr_api_key_source']})"
470
+ f"(key: {asr['mimo_asr_env_var']})"
389
471
  )
390
472
  print(f"✓ ASR model: {asr['mimo_asr_model']}")
391
473
  print(f"✓ ASR API URL: {asr['mimo_asr_api_url']} (source: {asr['mimo_asr_api_url_source']})")
@@ -407,6 +489,17 @@ def _print_human(report: dict) -> None:
407
489
  f"(source: {tts['fish_tts_reference_id_source']})"
408
490
  )
409
491
  print(f"✓ TTS API URL: {tts['fish_tts_api_url']}")
492
+ elif tts["provider"] == "index-tts":
493
+ print(
494
+ f"{_status_icon(tts['index_tts_endpoint_format_valid'])} "
495
+ "Index TTS endpoint: "
496
+ f"{'configured with valid format' if tts['index_tts_endpoint_format_valid'] else 'missing or invalid'}"
497
+ )
498
+ print(
499
+ f"{_status_icon(tts['index_tts_voice_set'])} Index TTS voice: "
500
+ f"{'configured' if tts['index_tts_voice_set'] else 'not set'}"
501
+ )
502
+ print(f"! Validation scope: {tts['validation_scope']}")
410
503
  else:
411
504
  print(f"✓ TTS voice: {tts['mimo_tts_voice']} (source: {tts['mimo_tts_voice_source']})")
412
505
  print(f"✓ TTS API URL: {tts['mimo_tts_api_url']} (source: {tts['mimo_tts_api_url_source']})")
@@ -444,7 +537,7 @@ def main() -> int:
444
537
  parser.add_argument("--json", action="store_true", help="Print machine-readable JSON")
445
538
  parser.add_argument(
446
539
  "--tts-provider",
447
- choices=("auto", "mimo-tts", "fish-audio"),
540
+ choices=TTS_PROVIDERS,
448
541
  default=None,
449
542
  help="override the TTS provider for this preflight report",
450
543
  )