@oh-story/dsh 0.1.10 → 0.1.12

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 (444) hide show
  1. package/README.md +11 -11
  2. package/lib/client.js +7 -3
  3. package/lib/client.js.map +2 -2
  4. package/lib/drama/manifest.json +212 -142
  5. package/lib/drama/skills/short-drama/SKILL.md +14 -2
  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/project_tool.py +131 -0
  10. package/lib/drama/skills/short-drama-assets/SKILL.md +2 -1
  11. package/lib/drama/skills/short-drama-assets/references/asset-review-checklist.md +2 -0
  12. package/lib/drama/skills/short-drama-assets/references/era-anchors.md +37 -0
  13. package/lib/drama/skills/short-drama-assets/references/stage-contract.md +2 -0
  14. package/lib/drama/skills/short-drama-develop/SKILL.md +10 -4
  15. package/lib/drama/skills/short-drama-develop/assets/adaptation-map.example.jsonl +1 -1
  16. package/lib/drama/skills/short-drama-develop/assets/creative-brief.md +8 -0
  17. package/lib/drama/skills/short-drama-develop/references/adaptation-craft.md +80 -13
  18. package/lib/drama/skills/short-drama-develop/references/episode-design.md +95 -12
  19. package/lib/drama/skills/short-drama-develop/references/genre-and-hook-playbook.md +9 -5
  20. 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
  21. package/lib/drama/skills/short-drama-develop/references/genre-cards//347/263/273/347/273/237/346/265/201.md +51 -0
  22. package/lib/drama/skills/short-drama-develop/references/genre-cards//351/200/206/350/242/255.md +51 -0
  23. 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
  24. package/lib/drama/skills/short-drama-develop/references/genre-cards.md +10 -7
  25. package/lib/drama/skills/short-drama-develop/references/premise-devices.md +15 -9
  26. package/lib/drama/skills/short-drama-develop/references/serial-character-and-memory.md +3 -2
  27. package/lib/drama/skills/short-drama-develop/references/stage-contract.md +14 -7
  28. package/lib/drama/skills/short-drama-develop/references/story-craft.md +7 -3
  29. package/lib/drama/skills/short-drama-edit/SKILL.md +43 -20
  30. package/lib/drama/skills/short-drama-edit/assets/remotion/README.md +49 -13
  31. package/lib/drama/skills/short-drama-edit/assets/remotion/package.json +4 -2
  32. package/lib/drama/skills/short-drama-edit/assets/remotion/src/Overlay.tsx +31 -0
  33. package/lib/drama/skills/short-drama-edit/assets/remotion/src/Root.tsx +5 -5
  34. package/lib/drama/skills/short-drama-edit/assets/remotion/src/Subtitles.tsx +68 -69
  35. package/lib/drama/skills/short-drama-edit/assets/remotion/src/font.ts +39 -29
  36. package/lib/drama/skills/short-drama-edit/assets/remotion/src/rules.mjs +188 -0
  37. package/lib/drama/skills/short-drama-edit/assets/remotion/src/schema.ts +26 -13
  38. package/lib/drama/skills/short-drama-edit/assets/remotion/src/screen/Card.tsx +72 -0
  39. package/lib/drama/skills/short-drama-edit/assets/remotion/src/screen/CornerChip.tsx +39 -0
  40. package/lib/drama/skills/short-drama-edit/assets/remotion/src/screen/ScreenText.tsx +36 -0
  41. package/lib/drama/skills/short-drama-edit/assets/remotion/src/screen/SystemPanel.tsx +44 -0
  42. package/lib/drama/skills/short-drama-edit/assets/remotion/src/screen/TaskPanel.tsx +100 -0
  43. package/lib/drama/skills/short-drama-edit/assets/remotion/src/screen/chrome.tsx +197 -0
  44. package/lib/drama/skills/short-drama-edit/assets/remotion/src/screen/tokens.ts +62 -0
  45. package/lib/drama/skills/short-drama-edit/assets/remotion/tsconfig.json +1 -0
  46. package/lib/drama/skills/short-drama-edit/assets//345/211/252/350/276/221/345/215/225.md +4 -2
  47. package/lib/drama/skills/short-drama-edit/references/cut-craft.md +3 -1
  48. package/lib/drama/skills/short-drama-edit/references/delivery-verify.md +6 -2
  49. package/lib/drama/skills/short-drama-edit/references/generated-footage.md +12 -6
  50. package/lib/drama/skills/short-drama-edit/references/sound-and-subtitles.md +13 -8
  51. package/lib/drama/skills/short-drama-edit/references/stage-contract.md +2 -0
  52. package/lib/drama/skills/short-drama-edit/scripts/edit_tool.py +1153 -121
  53. package/lib/drama/skills/short-drama-edit/scripts/selftest.py +49 -9
  54. package/lib/drama/skills/short-drama-novel-analyze/SKILL.md +3 -3
  55. package/lib/drama/skills/short-drama-novel-analyze/assets/episode-candidate.example.jsonl +2 -2
  56. package/lib/drama/skills/short-drama-novel-analyze/references/adaptation-triage.md +8 -4
  57. package/lib/drama/skills/short-drama-novel-analyze/references/adaptation-value.md +10 -3
  58. package/lib/drama/skills/short-drama-novel-analyze/references/aggregation-and-entities.md +25 -1
  59. package/lib/drama/skills/short-drama-novel-analyze/references/stage-contract.md +1 -0
  60. package/lib/drama/skills/short-drama-review/SKILL.md +2 -2
  61. package/lib/drama/skills/short-drama-review/references/review-method.md +6 -1
  62. package/lib/drama/skills/short-drama-review/references/rubric-assets-prompts.md +11 -0
  63. package/lib/drama/skills/short-drama-review/references/rubric-story-script.md +77 -3
  64. package/lib/drama/skills/short-drama-review/references/rubric-visual-motion.md +15 -0
  65. package/lib/drama/skills/short-drama-review/references/stage-contract.md +3 -0
  66. package/lib/drama/skills/short-drama-storyboard/SKILL.md +13 -5
  67. package/lib/drama/skills/short-drama-storyboard/references/blocking-playbooks.md +1 -1
  68. package/lib/drama/skills/short-drama-storyboard/references/production-shot-grammar.md +2 -2
  69. package/lib/drama/skills/short-drama-storyboard/references/shot-craft.md +82 -14
  70. package/lib/drama/skills/short-drama-storyboard/references/stage-contract.md +4 -2
  71. package/lib/drama/skills/short-drama-video-prompts/SKILL.md +5 -3
  72. package/lib/drama/skills/short-drama-video-prompts/references/camera-audio-continuity.md +12 -0
  73. package/lib/drama/skills/short-drama-video-prompts/references/delivery-profile.md +4 -5
  74. package/lib/drama/skills/short-drama-video-prompts/references/generability.md +4 -2
  75. package/lib/drama/skills/short-drama-video-prompts/references/minimax-h3.md +40 -1
  76. package/lib/drama/skills/short-drama-video-prompts/references/motion-recipe.md +20 -14
  77. package/lib/drama/skills/short-drama-video-prompts/references/performance-action-timing.md +1 -1
  78. package/lib/drama/skills/short-drama-video-prompts/references/production-prompt-grammar.md +8 -7
  79. package/lib/drama/skills/short-drama-video-prompts/references/review-and-fixtures.md +1 -1
  80. package/lib/drama/skills/short-drama-video-prompts/references/stage-contract.md +1 -0
  81. package/lib/drama/skills/short-drama-video-prompts/references/target-model-profile.md +8 -1
  82. package/lib/drama/skills/short-drama-video-prompts/references/wan-3.0.md +103 -0
  83. package/lib/drama/skills/short-drama-video-prompts/scripts/motion_timing_check.py +8 -7
  84. package/lib/drama/skills/short-drama-write/SKILL.md +8 -3
  85. package/lib/drama/skills/short-drama-write/references/dialogue-craft.md +1 -1
  86. package/lib/drama/skills/short-drama-write/references/script-craft.md +56 -3
  87. package/lib/drama/skills/short-drama-write/references/stage-contract.md +4 -0
  88. package/lib/drama/skills/short-drama-write/scripts/duration_estimate.py +48 -2
  89. package/lib/index.js +71 -21
  90. package/lib/index.js.map +3 -3
  91. package/lib/oh-story/manifest.json +545 -310
  92. package/lib/oh-story/roles/chapter-extractor.md +11 -11
  93. package/lib/oh-story/roles/character-designer.md +1 -2
  94. package/lib/oh-story/roles/consistency-checker.md +11 -9
  95. package/lib/oh-story/roles/narrative-writer.md +24 -25
  96. package/lib/oh-story/roles/story-architect.md +9 -61
  97. package/lib/oh-story/roles/story-explorer.md +20 -125
  98. package/lib/oh-story/roles/story-researcher.md +0 -1
  99. package/lib/oh-story/skills/story/SKILL.md +6 -6
  100. package/lib/oh-story/skills/story/VERSION +1 -1
  101. package/lib/oh-story/skills/story/references/author-memory-maintenance.md +75 -0
  102. package/lib/oh-story/skills/story/references/author-memory.md +40 -118
  103. package/lib/oh-story/skills/story/scripts/author_memory_commit.py +3 -3
  104. package/lib/oh-story/skills/story-deslop/SKILL.md +24 -25
  105. package/lib/oh-story/skills/story-deslop/references/agent-calls.md +5 -0
  106. package/lib/oh-story/skills/story-deslop/references/anti-ai-writing.md +1 -1
  107. package/lib/oh-story/skills/story-deslop/references/author-memory-maintenance.md +75 -0
  108. package/lib/oh-story/skills/story-deslop/references/author-memory.md +40 -118
  109. package/lib/oh-story/skills/story-deslop/references/banned-words.md +2 -2
  110. package/lib/oh-story/skills/story-deslop/references/deslop-gates.md +21 -4
  111. package/lib/oh-story/skills/story-deslop/references/style-resolution.md +4 -4
  112. package/lib/oh-story/skills/story-deslop/scripts/author_memory_commit.py +3 -3
  113. package/lib/oh-story/skills/story-deslop/scripts/check-ai-patterns.js +155 -8
  114. package/lib/oh-story/skills/story-import/SKILL.md +63 -579
  115. package/lib/oh-story/skills/story-import/references/deep-analysis.md +47 -0
  116. package/lib/oh-story/skills/story-import/references/format-and-structure.md +1 -1
  117. package/lib/oh-story/skills/story-import/references/import-report.md +64 -0
  118. package/lib/oh-story/skills/story-import/references/import-special-cases.md +34 -0
  119. package/lib/oh-story/skills/story-import/references/import-tracking.md +95 -0
  120. package/lib/oh-story/skills/story-import/references/length-routing.md +1 -1
  121. package/lib/oh-story/skills/story-import/references/outline-reverse-rules.md +79 -0
  122. package/lib/oh-story/skills/story-import/references/outline-reverse.md +24 -0
  123. package/lib/oh-story/skills/story-import/references/structure-mapping-long.md +95 -91
  124. package/lib/oh-story/skills/story-import/references/structure-mapping-short.md +24 -12
  125. package/lib/oh-story/skills/story-import/references/tracking-initialization.md +1 -1
  126. package/lib/oh-story/skills/story-import/references/tracking-transaction.md +11 -9
  127. package/lib/oh-story/skills/story-import/scripts/build_outline_brief.py +332 -0
  128. package/lib/oh-story/skills/story-import/scripts/check-outline-contract.js +101 -14
  129. package/lib/oh-story/skills/story-import/scripts/tracking_commit.py +278 -23
  130. package/lib/oh-story/skills/story-import/scripts/wordcount_core.py +179 -23
  131. package/lib/oh-story/skills/story-long-analyze/SKILL.md +28 -50
  132. package/lib/oh-story/skills/story-long-analyze/references/author-facing.md +12 -5
  133. package/lib/oh-story/skills/story-long-analyze/references/deconstruction-notes.md +1 -1
  134. package/lib/oh-story/skills/story-long-analyze/references/final-checks.md +19 -0
  135. package/lib/oh-story/skills/story-long-analyze/references/index-rebuild.md +11 -0
  136. package/lib/oh-story/skills/story-long-analyze/references/pipeline-ops.md +21 -55
  137. package/lib/oh-story/skills/story-long-analyze/references/stage1-golden-chapters.md +128 -0
  138. package/lib/oh-story/skills/story-long-analyze/references/stage2-extraction.md +229 -0
  139. package/lib/oh-story/skills/story-long-analyze/references/stage3-plot-rhythm.md +480 -0
  140. package/lib/oh-story/skills/story-long-analyze/references/stage4-characters-settings.md +195 -0
  141. package/lib/oh-story/skills/story-long-analyze/references/stage5-report.md +33 -0
  142. package/lib/oh-story/skills/story-long-analyze/references/style-profile-generator.md +17 -0
  143. package/lib/oh-story/skills/story-long-analyze/references/style-profile-protocol.md +1 -1
  144. package/lib/oh-story/skills/story-long-analyze/references/synthesis-inputs.md +39 -0
  145. package/lib/oh-story/skills/story-long-analyze/scripts/manage_analysis_run.py +47 -8
  146. package/lib/oh-story/skills/story-long-scan/SKILL.md +41 -193
  147. package/lib/oh-story/skills/story-long-scan/references/platform-ciweimao.md +19 -0
  148. package/lib/oh-story/skills/story-long-scan/references/platform-fanqie.md +45 -0
  149. package/lib/oh-story/skills/story-long-scan/references/platform-jjwxc.md +28 -0
  150. package/lib/oh-story/skills/story-long-scan/references/platform-qidian.md +35 -0
  151. package/lib/oh-story/skills/story-long-scan/references/platform-qimao.md +27 -0
  152. package/lib/oh-story/skills/story-long-scan/references/topic-decision.md +6 -2
  153. package/lib/oh-story/skills/story-long-write/SKILL.md +32 -73
  154. package/lib/oh-story/skills/story-long-write/references/agent-calls.md +47 -0
  155. package/lib/oh-story/skills/story-long-write/references/anti-ai-writing.md +1 -1
  156. package/lib/oh-story/skills/story-long-write/references/artifact-protocols.md +18 -201
  157. package/lib/oh-story/skills/story-long-write/references/author-memory-maintenance.md +75 -0
  158. package/lib/oh-story/skills/story-long-write/references/author-memory.md +40 -118
  159. package/lib/oh-story/skills/story-long-write/references/banned-words.md +2 -2
  160. package/lib/oh-story/skills/story-long-write/references/benchmark-recall.md +6 -10
  161. package/lib/oh-story/skills/story-long-write/references/character-relations.md +49 -1
  162. package/lib/oh-story/skills/story-long-write/references/deslop-gates.md +171 -0
  163. package/lib/oh-story/skills/story-long-write/references/emotion-on-page.md +116 -0
  164. package/lib/oh-story/skills/story-long-write/references/emotional-arc-design.md +1 -114
  165. package/lib/oh-story/skills/story-long-write/references/genre-prose-cards.md +1 -1
  166. package/lib/oh-story/skills/story-long-write/references/long-chapter-quality.md +3 -2
  167. package/lib/oh-story/skills/story-long-write/references/long-format.md +0 -8
  168. package/lib/oh-story/skills/story-long-write/references/long-genre-catalog.md +1 -1
  169. package/lib/oh-story/skills/story-long-write/references/long-genre-mechanics.md +3 -3
  170. package/lib/oh-story/skills/story-long-write/references/opening-design.md +2 -2
  171. package/lib/oh-story/skills/story-long-write/references/outline-conflict.md +4 -4
  172. package/lib/oh-story/skills/story-long-write/references/outline-methods.md +7 -7
  173. package/lib/oh-story/skills/story-long-write/references/outline-rhythm.md +3 -3
  174. package/lib/oh-story/skills/story-long-write/references/outline-structure-theory.md +14 -69
  175. package/lib/oh-story/skills/story-long-write/references/plot-frameworks.md +1 -1
  176. package/lib/oh-story/skills/story-long-write/references/plot-special-topics.md +2 -2
  177. package/lib/oh-story/skills/story-long-write/references/project-files.md +10 -6
  178. package/lib/oh-story/skills/story-long-write/references/reader-contract-and-progression.md +1 -1
  179. package/lib/oh-story/skills/story-long-write/references/reference-index.md +4 -4
  180. package/lib/oh-story/skills/story-long-write/references/stop-and-fix.md +9 -0
  181. package/lib/oh-story/skills/story-long-write/references/style-combat-face.md +1 -58
  182. package/lib/oh-story/skills/story-long-write/references/style-genre-modules.md +1 -1
  183. package/lib/oh-story/skills/story-long-write/references/style-resolution.md +4 -4
  184. package/lib/oh-story/skills/story-long-write/references/tracking-initialization.md +1 -1
  185. package/lib/oh-story/skills/story-long-write/references/tracking-transaction.md +11 -9
  186. package/lib/oh-story/skills/story-long-write/references/workflow-chapter.md +33 -44
  187. package/lib/oh-story/skills/story-long-write/references/workflow-daily.md +18 -51
  188. package/lib/oh-story/skills/story-long-write/references/workflow-outline.md +157 -0
  189. package/lib/oh-story/skills/story-long-write/references/workflow-revision.md +53 -67
  190. package/lib/oh-story/skills/story-long-write/references/workflow-setup.md +112 -251
  191. package/lib/oh-story/skills/story-long-write/references/workflow-volume.md +142 -0
  192. package/lib/oh-story/skills/story-long-write/references/writer-prompt-fallback.md +5 -3
  193. package/lib/oh-story/skills/story-long-write/references/writing-craft.md +18 -56
  194. package/lib/oh-story/skills/story-long-write/scripts/author_memory_commit.py +3 -3
  195. package/lib/oh-story/skills/story-long-write/scripts/build_architect_brief.py +260 -0
  196. package/lib/oh-story/skills/story-long-write/scripts/build_writer_prompt.py +96 -16
  197. package/lib/oh-story/skills/story-long-write/scripts/check-ai-patterns.js +155 -8
  198. package/lib/oh-story/skills/story-long-write/scripts/check-outline-contract.js +101 -14
  199. package/lib/oh-story/skills/story-long-write/scripts/check-outline-copy.js +7 -2
  200. package/lib/oh-story/skills/story-long-write/scripts/outline_view.py +2 -1
  201. package/lib/oh-story/skills/story-long-write/scripts/storyctl.py +250 -50
  202. package/lib/oh-story/skills/story-long-write/scripts/tracking_commit.py +278 -23
  203. package/lib/oh-story/skills/story-long-write/scripts/wordcount_core.py +179 -23
  204. package/lib/oh-story/skills/story-review/SKILL.md +19 -273
  205. package/lib/oh-story/skills/story-review/references/agent-prompts.md +184 -0
  206. package/lib/oh-story/skills/story-review/references/anti-ai-writing.md +1 -1
  207. package/lib/oh-story/skills/story-review/references/author-memory-maintenance.md +75 -0
  208. package/lib/oh-story/skills/story-review/references/author-memory.md +40 -118
  209. package/lib/oh-story/skills/story-review/references/banned-words.md +2 -2
  210. package/lib/oh-story/skills/story-review/references/batch-review.md +19 -0
  211. package/lib/oh-story/skills/story-review/references/character-relations.md +49 -1
  212. package/lib/oh-story/skills/story-review/references/review-quality.md +2 -1
  213. package/lib/oh-story/skills/story-review/references/review-tracking.md +10 -0
  214. package/lib/oh-story/skills/story-review/references/solo.md +52 -0
  215. package/lib/oh-story/skills/story-review/references/style-resolution.md +4 -4
  216. package/lib/oh-story/skills/story-review/references/tracking-initialization.md +1 -1
  217. package/lib/oh-story/skills/story-review/references/tracking-transaction.md +11 -9
  218. package/lib/oh-story/skills/story-review/scripts/author_memory_commit.py +3 -3
  219. package/lib/oh-story/skills/story-review/scripts/check-ai-patterns.js +155 -8
  220. package/lib/oh-story/skills/story-review/scripts/tracking_commit.py +278 -23
  221. package/lib/oh-story/skills/story-review/scripts/wordcount_core.py +179 -23
  222. package/lib/oh-story/skills/story-setup/SKILL.md +69 -458
  223. package/lib/oh-story/skills/story-setup/references/agent-references/agent-quality.md +4 -4
  224. package/lib/oh-story/skills/story-setup/references/agent-references/anti-ai-writing.md +1 -1
  225. package/lib/oh-story/skills/story-setup/references/agent-references/banned-words.md +2 -2
  226. package/lib/oh-story/skills/story-setup/references/agent-references/benchmark-style-load.md +107 -0
  227. package/lib/oh-story/skills/story-setup/references/agent-references/character-relations.md +49 -1
  228. package/lib/oh-story/skills/story-setup/references/agent-references/deslop-gates.md +21 -4
  229. package/lib/oh-story/skills/story-setup/references/agent-references/emotion-on-page.md +116 -0
  230. package/lib/oh-story/skills/story-setup/references/agent-references/emotional-arc-design.md +1 -114
  231. package/lib/oh-story/skills/story-setup/references/agent-references/format-and-structure.md +1 -1
  232. package/lib/oh-story/skills/story-setup/references/agent-references/genre-prose-cards.md +1 -1
  233. package/lib/oh-story/skills/story-setup/references/agent-references/long-genre-catalog.md +1 -1
  234. package/lib/oh-story/skills/story-setup/references/agent-references/long-genre-mechanics.md +3 -3
  235. package/lib/oh-story/skills/story-setup/references/agent-references/long-quality.md +7 -5
  236. package/lib/oh-story/skills/story-setup/references/agent-references/opening-design.md +2 -2
  237. package/lib/oh-story/skills/story-setup/references/agent-references/outline-conflict.md +4 -4
  238. package/lib/oh-story/skills/story-setup/references/agent-references/outline-methods.md +7 -7
  239. package/lib/oh-story/skills/story-setup/references/agent-references/outline-rhythm.md +3 -3
  240. package/lib/oh-story/skills/story-setup/references/agent-references/short-emotional-methods.md +1 -1
  241. package/lib/oh-story/skills/story-setup/references/agent-references/short-genre-formulas.md +0 -15
  242. package/lib/oh-story/skills/story-setup/references/agent-references/short-reversal.md +1 -1
  243. package/lib/oh-story/skills/story-setup/references/agent-references/style-combat-face.md +1 -58
  244. package/lib/oh-story/skills/story-setup/references/agent-references/style-genre-modules.md +1 -1
  245. package/lib/oh-story/skills/story-setup/references/agent-references/style-resolution.md +4 -4
  246. package/lib/oh-story/skills/story-setup/references/agent-references/writing-craft.md +18 -56
  247. package/lib/oh-story/skills/story-setup/references/diagnostics.md +3 -3
  248. package/lib/oh-story/skills/story-short-analyze/SKILL.md +37 -110
  249. package/lib/oh-story/skills/story-short-analyze/references/analysis-character-relations.md +1 -1
  250. package/lib/oh-story/skills/story-short-analyze/references/analysis-method.md +42 -0
  251. package/lib/oh-story/skills/story-short-analyze/references/optional-modules.md +97 -0
  252. package/lib/oh-story/skills/story-short-analyze/references/output-contract.md +9 -47
  253. package/lib/oh-story/skills/story-short-analyze/references/quality-checklist.md +80 -0
  254. package/lib/oh-story/skills/story-short-analyze/references/source-story-quality.md +4 -4
  255. package/lib/oh-story/skills/story-short-analyze/references/stage2-3-structure-emotion.md +308 -0
  256. package/lib/oh-story/skills/story-short-analyze/references/{material-decomposition.md → stage4-6-reversal-summary.md} +303 -374
  257. package/lib/oh-story/skills/story-short-scan/SKILL.md +30 -64
  258. package/lib/oh-story/skills/story-short-scan/references/manual-rank-input.md +36 -0
  259. package/lib/oh-story/skills/story-short-scan/references/platform-dianzhong.md +24 -0
  260. package/lib/oh-story/skills/story-short-scan/references/platform-heiyan.md +21 -0
  261. package/lib/oh-story/skills/story-short-scan/references/topic-match.md +38 -0
  262. package/lib/oh-story/skills/story-short-write/SKILL.md +23 -34
  263. package/lib/oh-story/skills/story-short-write/references/agent-calls.md +13 -0
  264. package/lib/oh-story/skills/story-short-write/references/author-memory-maintenance.md +75 -0
  265. package/lib/oh-story/skills/story-short-write/references/author-memory.md +40 -118
  266. package/lib/oh-story/skills/story-short-write/references/banned-words.md +2 -2
  267. package/lib/oh-story/skills/story-short-write/references/benchmark-recall.md +1 -21
  268. package/lib/oh-story/skills/story-short-write/references/emotional-methods.md +1 -1
  269. package/lib/oh-story/skills/story-short-write/references/genre-writing-formulas.md +0 -15
  270. package/lib/oh-story/skills/story-short-write/references/output-contract.md +9 -47
  271. package/lib/oh-story/skills/story-short-write/references/reference-index.md +17 -49
  272. package/lib/oh-story/skills/story-short-write/references/scene-craft.md +40 -0
  273. package/lib/oh-story/skills/story-short-write/references/short-craft.md +7 -43
  274. package/lib/oh-story/skills/story-short-write/references/short-format.md +3 -3
  275. package/lib/oh-story/skills/story-short-write/references/short-prose-quality.md +2 -1
  276. package/lib/oh-story/skills/story-short-write/references/short-reversal.md +1 -1
  277. package/lib/oh-story/skills/story-short-write/references/style-resolution.md +4 -4
  278. package/lib/oh-story/skills/story-short-write/references/submission-craft.md +1 -1
  279. package/lib/oh-story/skills/story-short-write/references/villain-and-reveal.md +5 -10
  280. package/lib/oh-story/skills/story-short-write/references/workflow-design.md +19 -12
  281. package/lib/oh-story/skills/story-short-write/references/workflow-draft.md +22 -32
  282. package/lib/oh-story/skills/story-short-write/references/workflow-revision.md +84 -17
  283. package/lib/oh-story/skills/story-short-write/references/writing-workflow.md +7 -119
  284. package/lib/oh-story/skills/story-short-write/scripts/author_memory_commit.py +3 -3
  285. package/lib/oh-story/skills/story-short-write/scripts/check-ai-patterns.js +155 -8
  286. package/lib/oh-story/skills/story-short-write/scripts/check-outline-copy.js +7 -2
  287. package/lib/types/client/video-studio.d.ts.map +1 -1
  288. package/lib/types/native-hooks.d.ts +2 -2
  289. package/lib/types/native-hooks.d.ts.map +1 -1
  290. package/lib/types/role-tool.d.ts.map +1 -1
  291. package/lib/types/skill-provider.d.ts.map +1 -1
  292. package/lib/types/video-project.d.ts.map +1 -1
  293. package/lib/types/workspace-route.d.ts.map +1 -1
  294. package/lib/video-recap/CHANGELOG.md +60 -1
  295. package/lib/video-recap/README.en.md +348 -137
  296. package/lib/video-recap/README.md +340 -136
  297. package/lib/video-recap/manifest.json +406 -251
  298. package/lib/video-recap/skills/video-assemble/SKILL.md +30 -15
  299. package/lib/video-recap/skills/video-assemble/references/audio-modes.md +63 -0
  300. package/lib/video-recap/skills/video-assemble/references/explicit-audio-mix.md +75 -0
  301. package/lib/video-recap/skills/video-assemble/references/foreground-compose.md +118 -0
  302. package/lib/video-recap/skills/video-assemble/references/narration-adoption.md +103 -0
  303. package/lib/video-recap/skills/video-assemble/references/packaging.md +45 -0
  304. package/lib/video-recap/skills/video-assemble/references/pair-media.md +74 -0
  305. package/lib/video-recap/skills/video-assemble/references/source-score.md +147 -0
  306. package/lib/video-recap/skills/video-assemble/references/subtitle-track.md +202 -0
  307. package/lib/video-recap/skills/video-assemble/scripts/adoption/__init__.py +1 -0
  308. package/lib/video-recap/skills/video-assemble/scripts/adoption/audio_mix_binding.py +279 -0
  309. package/lib/video-recap/skills/video-assemble/scripts/adoption/frozen_audio.py +187 -0
  310. package/lib/video-recap/skills/video-assemble/scripts/adoption/narration_binding.py +323 -0
  311. package/lib/video-recap/skills/video-assemble/scripts/adoption/strict_inputs.py +109 -0
  312. package/lib/video-recap/skills/video-assemble/scripts/adoption/strict_publish.py +130 -0
  313. package/lib/video-recap/skills/video-assemble/scripts/artifacts.py +10 -46
  314. package/lib/video-recap/skills/video-assemble/scripts/assemble.py +378 -119
  315. package/lib/video-recap/skills/video-assemble/scripts/assemble_constants.py +29 -12
  316. package/lib/video-recap/skills/video-assemble/scripts/assembly_contract.py +95 -44
  317. package/lib/video-recap/skills/video-assemble/scripts/assembly_settings.py +75 -32
  318. package/lib/video-recap/skills/video-assemble/scripts/audio_mix.py +11 -11
  319. package/lib/video-recap/skills/video-assemble/scripts/compose_foreground.py +293 -0
  320. package/lib/video-recap/skills/video-assemble/scripts/export_jianying.py +71 -78
  321. package/lib/video-recap/skills/video-assemble/scripts/jianying/__init__.py +1 -0
  322. package/lib/video-recap/skills/video-assemble/scripts/{jianying_builders.py → jianying/builders.py} +39 -67
  323. package/lib/video-recap/skills/video-assemble/scripts/{jianying_model.py → jianying/model.py} +3 -11
  324. package/lib/video-recap/skills/video-assemble/scripts/{jianying_optional.py → jianying/optional.py} +1 -1
  325. package/lib/video-recap/skills/video-assemble/scripts/jianying/schema.py +53 -0
  326. package/lib/video-recap/skills/video-assemble/scripts/{jianying_templates.py → jianying/templates.py} +1 -1
  327. package/lib/video-recap/skills/video-assemble/scripts/{jianying_timeline_contract.py → jianying/timeline_contract.py} +34 -13
  328. package/lib/video-recap/skills/video-assemble/scripts/{jianying_writer.py → jianying/writer.py} +7 -17
  329. package/lib/video-recap/skills/video-assemble/scripts/lib.py +37 -4
  330. package/lib/video-recap/skills/video-assemble/scripts/media.py +12 -21
  331. package/lib/video-recap/skills/video-assemble/scripts/narration_audio.py +64 -34
  332. package/lib/video-recap/skills/video-assemble/scripts/packaging.py +122 -0
  333. package/lib/video-recap/skills/video-assemble/scripts/pair_media.py +216 -0
  334. package/lib/video-recap/skills/video-assemble/scripts/render_preflight.py +1 -3
  335. package/lib/video-recap/skills/video-assemble/scripts/source_score.py +469 -0
  336. package/lib/video-recap/skills/video-assemble/scripts/source_subtitles.py +25 -9
  337. package/lib/video-recap/skills/video-assemble/scripts/subtitles/__init__.py +1 -0
  338. package/lib/video-recap/skills/video-assemble/scripts/{subtitle_core.py → subtitles/core.py} +13 -6
  339. package/lib/video-recap/skills/video-assemble/scripts/{subtitle_render.py → subtitles/render.py} +5 -4
  340. package/lib/video-recap/skills/video-assemble/scripts/subtitles/track.py +324 -0
  341. package/lib/video-recap/skills/video-assemble/scripts/subtitles/track_binding.py +200 -0
  342. package/lib/video-recap/skills/video-assemble/scripts/timeline.py +30 -46
  343. package/lib/video-recap/skills/video-assemble/scripts/timeline_emit.py +91 -7
  344. package/lib/video-recap/skills/video-assemble/scripts/visual_render.py +22 -8
  345. package/lib/video-recap/skills/video-cut/SKILL.md +34 -16
  346. package/lib/video-recap/skills/video-cut/references/shot-review.md +50 -0
  347. package/lib/video-recap/skills/video-cut/scripts/cut.py +2 -28
  348. package/lib/video-recap/skills/video-cut/scripts/cut_cli.py +58 -62
  349. package/lib/video-recap/skills/video-cut/scripts/cut_contract.py +21 -106
  350. package/lib/video-recap/skills/video-cut/scripts/cut_render.py +14 -9
  351. package/lib/video-recap/skills/video-cut/scripts/lib.py +39 -0
  352. package/lib/video-recap/skills/video-cut/scripts/narration_mapping.py +2 -155
  353. package/lib/video-recap/skills/video-cut/scripts/narrative_selection.py +244 -0
  354. package/lib/video-recap/skills/video-cut/scripts/shot_review.py +357 -0
  355. package/lib/video-recap/skills/video-recap/SKILL.md +86 -42
  356. package/lib/video-recap/skills/video-recap/references/audio-routing.md +126 -0
  357. package/lib/video-recap/skills/video-recap/references/config-playbook.md +12 -8
  358. package/lib/video-recap/skills/video-recap/references/data-schema.md +44 -33
  359. package/lib/video-recap/skills/video-recap/references/resource-library.md +151 -0
  360. package/lib/video-recap/skills/video-recap/references/shift-left-qc-schema.md +1 -1
  361. package/lib/video-recap/skills/video-recap/scripts/doctor.py +123 -30
  362. package/lib/video-recap/skills/video-recap/scripts/final_qc.py +22 -75
  363. package/lib/video-recap/skills/video-recap/scripts/lib.py +3 -3
  364. package/lib/video-recap/skills/video-recap/scripts/library.py +509 -0
  365. package/lib/video-recap/skills/video-recap/scripts/materials.py +63 -91
  366. package/lib/video-recap/skills/video-recap/scripts/mimo_qc.py +8 -70
  367. package/lib/video-recap/skills/video-recap/scripts/project_binding.py +286 -0
  368. package/lib/video-recap/skills/video-recap/scripts/qc/__init__.py +1 -0
  369. package/lib/video-recap/skills/video-recap/scripts/{mimo_qc_client.py → qc/mimo_client.py} +1 -1
  370. package/lib/video-recap/skills/video-recap/scripts/{mimo_qc_evidence.py → qc/mimo_evidence.py} +33 -66
  371. package/lib/video-recap/skills/video-recap/scripts/{mimo_qc_observations.py → qc/mimo_observations.py} +3 -11
  372. package/lib/video-recap/skills/video-recap/scripts/{mimo_qc_payload.py → qc/mimo_payload.py} +4 -7
  373. package/lib/video-recap/skills/video-recap/scripts/{mimo_qc_report.py → qc/mimo_report.py} +17 -28
  374. package/lib/video-recap/skills/video-recap/scripts/{mimo_qc_runner.py → qc/mimo_runner.py} +2 -2
  375. package/lib/video-recap/skills/video-recap/scripts/qc_contract.py +0 -19
  376. package/lib/video-recap/skills/video-recap/scripts/recap_cli.py +119 -50
  377. package/lib/video-recap/skills/video-recap/scripts/recap_inspect.py +32 -114
  378. package/lib/video-recap/skills/video-recap/scripts/recap_review.py +9 -23
  379. package/lib/video-recap/skills/video-recap/scripts/recap_runner.py +387 -334
  380. package/lib/video-recap/skills/video-recap/scripts/recap_runtime.py +23 -23
  381. package/lib/video-recap/skills/video-recap/scripts/recap_source.py +278 -0
  382. package/lib/video-recap/skills/video-recap/scripts/recap_stage_qc.py +25 -12
  383. package/lib/video-recap/skills/video-recap/scripts/recap_timeline.py +59 -52
  384. package/lib/video-recap/skills/video-recap/scripts/resource_lock.py +162 -0
  385. package/lib/video-recap/skills/video-script/SKILL.md +16 -13
  386. package/lib/video-recap/skills/video-script/references/creative-editing-playbook.md +9 -5
  387. package/lib/video-recap/skills/video-script/references/promotional-copy.md +68 -0
  388. package/lib/video-recap/skills/video-script/references/research-guide.md +1 -1
  389. package/lib/video-recap/skills/video-script/scripts/evidence_bundle.py +24 -76
  390. package/lib/video-recap/skills/video-script/scripts/lib.py +10 -87
  391. package/lib/video-recap/skills/video-script/scripts/narration_lint.py +63 -39
  392. package/lib/video-recap/skills/video-script/scripts/review.py +0 -2
  393. package/lib/video-recap/skills/video-script/scripts/review_grounding.py +35 -59
  394. package/lib/video-recap/skills/video-script/scripts/review_response.py +66 -128
  395. package/lib/video-recap/skills/video-script/scripts/review_runner.py +12 -20
  396. package/lib/video-recap/skills/video-script/scripts/speech_ownership.py +4 -4
  397. package/lib/video-recap/skills/video-script/scripts/validate.py +53 -42
  398. package/lib/video-recap/skills/video-understanding/SKILL.md +6 -4
  399. package/lib/video-recap/skills/video-understanding/references/data-schema.md +50 -156
  400. package/lib/video-recap/skills/video-understanding/references/research-guide.md +4 -4
  401. package/lib/video-recap/skills/video-understanding/scripts/asr.py +85 -65
  402. package/lib/video-recap/skills/video-understanding/scripts/asr_timing_evidence.py +270 -0
  403. package/lib/video-recap/skills/video-understanding/scripts/brief.py +2 -5
  404. package/lib/video-recap/skills/video-understanding/scripts/briefing/__init__.py +1 -0
  405. package/lib/video-recap/skills/video-understanding/scripts/{agent_brief.py → briefing/builder.py} +38 -35
  406. package/lib/video-recap/skills/{video-script/scripts/brief_context.py → video-understanding/scripts/briefing/context.py} +4 -35
  407. package/lib/video-recap/skills/{video-script/scripts/brief_inputs.py → video-understanding/scripts/briefing/inputs.py} +9 -31
  408. package/lib/video-recap/skills/video-understanding/scripts/{brief_timeline.py → briefing/timeline.py} +5 -6
  409. package/lib/video-recap/skills/video-understanding/scripts/consolidate.py +65 -116
  410. package/lib/video-recap/skills/video-understanding/scripts/detect.py +31 -40
  411. package/lib/video-recap/skills/video-understanding/scripts/lib.py +30 -86
  412. package/lib/video-recap/skills/video-understanding/scripts/narration_lint.py +63 -39
  413. package/lib/video-recap/skills/video-understanding/scripts/speech_ownership.py +4 -4
  414. package/lib/video-recap/skills/video-understanding/scripts/storyboard.py +17 -79
  415. package/lib/video-recap/skills/video-understanding/scripts/understanding_brief.py +14 -40
  416. package/lib/video-recap/skills/video-understanding/scripts/understanding_cache.py +64 -46
  417. package/lib/video-recap/skills/video-understanding/scripts/understanding_runner.py +31 -11
  418. package/lib/video-recap/skills/video-understanding/scripts/understanding_storyboard.py +19 -14
  419. package/lib/video-recap/skills/video-understanding/scripts/vlm.py +80 -108
  420. package/lib/video-recap/skills/video-voiceover/SKILL.md +29 -19
  421. package/lib/video-recap/skills/video-voiceover/references/index-tts.md +31 -0
  422. package/lib/video-recap/skills/video-voiceover/scripts/approved_text_policy.py +123 -0
  423. package/lib/video-recap/skills/video-voiceover/scripts/dub.py +51 -59
  424. package/lib/video-recap/skills/video-voiceover/scripts/lib.py +8 -44
  425. package/lib/video-recap/skills/video-voiceover/scripts/providers/__init__.py +1 -0
  426. package/lib/video-recap/skills/video-voiceover/scripts/providers/index_tts.py +184 -0
  427. package/lib/video-recap/skills/video-voiceover/scripts/voiceover.py +212 -134
  428. package/package.json +41 -41
  429. package/lib/oh-story/skills/story-long-analyze/references/material-decomposition.md +0 -538
  430. package/lib/oh-story/skills/story-long-analyze/references/output-templates.md +0 -603
  431. package/lib/oh-story/skills/story-long-scan/references/scan-output-format.md +0 -207
  432. package/lib/oh-story/skills/story-short-analyze/references/output-templates.md +0 -561
  433. package/lib/video-recap/skills/video-assemble/scripts/jianying_schema.py +0 -98
  434. package/lib/video-recap/skills/video-recap/references/creative-editing-playbook.md +0 -225
  435. package/lib/video-recap/skills/video-recap/references/research-guide.md +0 -74
  436. package/lib/video-recap/skills/video-recap/references/timeline-and-jianying.md +0 -250
  437. package/lib/video-recap/skills/video-script/scripts/agent_brief.py +0 -399
  438. package/lib/video-recap/skills/video-script/scripts/brief_timeline.py +0 -327
  439. package/lib/video-recap/skills/video-script/scripts/narration.py +0 -12
  440. package/lib/video-recap/skills/video-understanding/scripts/brief_context.py +0 -348
  441. package/lib/video-recap/skills/video-understanding/scripts/brief_inputs.py +0 -290
  442. /package/lib/video-recap/skills/video-assemble/scripts/{jianying_tracks.py → jianying/tracks.py} +0 -0
  443. /package/lib/video-recap/skills/video-recap/scripts/{mimo_qc_contract.py → qc/mimo_contract.py} +0 -0
  444. /package/lib/video-recap/skills/video-voiceover/scripts/{fish_audio.py → providers/fish_audio.py} +0 -0
@@ -3,7 +3,6 @@
3
3
  from __future__ import annotations
4
4
 
5
5
  import base64
6
- import hashlib
7
6
  import json
8
7
  import math
9
8
  import os
@@ -14,18 +13,17 @@ from typing import Any
14
13
  from collections.abc import Callable, Mapping, Sequence
15
14
 
16
15
  import qc_contract
17
- from mimo_qc_client import mimo_qc_api_call
18
- from mimo_qc_evidence import (
16
+ from qc.mimo_client import mimo_qc_api_call
17
+ from qc.mimo_evidence import (
19
18
  _cache_evidence,
20
19
  _effective_config,
21
20
  _existing_final_output,
22
- _fingerprint_value,
23
21
  collect_evidence,
24
22
  safe_mimo_config,
25
23
  )
26
- from mimo_qc_observations import normalize_observations
27
- from mimo_qc_payload import _request_payload, _validated_live_output, build_payload
28
- from mimo_qc_contract import (
24
+ from qc.mimo_observations import normalize_observations
25
+ from qc.mimo_payload import _request_payload, _validated_live_output, build_payload
26
+ from qc.mimo_contract import (
29
27
  ARTIFACT_NAME,
30
28
  DEFAULT_STAGE,
31
29
  FRAME_SAMPLER_VERSION,
@@ -121,7 +119,7 @@ def sample_video_frames(
121
119
  {
122
120
  "data_url": "data:image/jpeg;base64,"
123
121
  + base64.b64encode(raw).decode("ascii"),
124
- "sha256": hashlib.sha256(raw).hexdigest(),
122
+ "bytes": len(raw),
125
123
  "timestamp": round(timestamp, 3),
126
124
  }
127
125
  )
@@ -135,7 +133,7 @@ def _frame_metadata(samples: Sequence[Mapping[str, Any]]) -> dict[str, Any]:
135
133
  "max_dimension": MAX_FRAME_DIMENSION,
136
134
  "sampler_version": FRAME_SAMPLER_VERSION,
137
135
  "samples": [
138
- {"sha256": sample["sha256"], "timestamp": sample["timestamp"]}
136
+ {"bytes": sample["bytes"], "timestamp": sample["timestamp"]}
139
137
  for sample in samples
140
138
  ],
141
139
  }
@@ -147,10 +145,13 @@ def _cache_input(
147
145
  evidence: Mapping[str, Any],
148
146
  frames: Mapping[str, Any],
149
147
  ) -> dict[str, Any]:
148
+ """Everything a stage report depends on; an existing report whose stored cache_input
149
+ equals this dict is reused instead of a new request."""
150
150
  return {
151
151
  "stage": stage,
152
152
  "model": payload["model"],
153
- "payload_fingerprint": payload["payload_fingerprint"],
153
+ "config": payload["config"],
154
+ "instructions": payload["instructions"],
154
155
  "evidence": _cache_evidence(evidence),
155
156
  "frames": frames,
156
157
  "contract": qc_contract.SCHEMA_VERSION,
@@ -158,23 +159,13 @@ def _cache_input(
158
159
 
159
160
 
160
161
  def _stage_reports(path: Path) -> dict[str, dict[str, Any]]:
161
- """Per-stage reports from an existing aggregate mimo_qc.json, or {} before the first stage."""
162
+ """Per-stage reports from an existing aggregate mimo_qc.json, or {} before the first stage.
163
+
164
+ The aggregate is this module's own atomically written, contract-validated report, so a
165
+ corrupt one raises (recap_stage_qc keeps the pipeline fail-open around the whole stage)."""
162
166
  if not path.is_file():
163
167
  return {}
164
- try:
165
- stages = json.loads(path.read_text(encoding="utf-8"))["metadata"]["stages"]
166
- for report in stages.values():
167
- qc_contract.validate_report(report)
168
- return dict(stages)
169
- except (
170
- OSError,
171
- ValueError,
172
- TypeError,
173
- KeyError,
174
- AttributeError,
175
- qc_contract.QCContractError,
176
- ):
177
- return {}
168
+ return dict(json.loads(path.read_text(encoding="utf-8"))["metadata"]["stages"])
178
169
 
179
170
 
180
171
  def _error_name(exc: Exception) -> str:
@@ -211,12 +202,11 @@ def build_report(
211
202
  )[:MAX_FRAMES]
212
203
  frame_meta = _frame_metadata(samples)
213
204
  cache_input = _cache_input(stage, payload, evidence, frame_meta)
214
- cache_key = _fingerprint_value(cache_input)
215
205
 
216
206
  if (
217
207
  not refresh
218
208
  and existing is not None
219
- and existing.get("metadata", {}).get("cache_key") == cache_key
209
+ and existing["metadata"]["cache_input"] == cache_input
220
210
  ):
221
211
  cached = json.loads(json.dumps(existing))
222
212
  cached["metadata"].update(status="cached", mode="live_cache", request_count=0)
@@ -271,7 +261,6 @@ def build_report(
271
261
  "request_count": 1
272
262
  if mode == "live" and status in {"completed", "failed"}
273
263
  else 0,
274
- "cache_key": cache_key,
275
264
  "cache_input": cache_input,
276
265
  "frame_samples": frame_meta,
277
266
  "evidence": evidence,
@@ -15,8 +15,8 @@ from collections.abc import Callable, Mapping, Sequence
15
15
 
16
16
  import qc_contract
17
17
 
18
- from mimo_qc_report import _stage_reports, build_report, write_report
19
- from mimo_qc_contract import ARTIFACT_NAME, DEFAULT_STAGE
18
+ from qc.mimo_report import _stage_reports, build_report, write_report
19
+ from qc.mimo_contract import ARTIFACT_NAME, DEFAULT_STAGE
20
20
 
21
21
  JudgeCallable = Callable[
22
22
  [Mapping[str, Any]], Mapping[str, Any] | Sequence[Mapping[str, Any]]
@@ -6,7 +6,6 @@ pipeline, or attempt automatic fixes.
6
6
  """
7
7
  from __future__ import annotations
8
8
 
9
- import hashlib
10
9
  import re
11
10
  from pathlib import Path
12
11
  from typing import Any
@@ -32,7 +31,6 @@ ARTIFACTS = frozenset({"final_qc.json", "golden_eval.json", "mimo_qc.json", "pre
32
31
 
33
32
  DETERMINISTIC_CATEGORIES = frozenset({
34
33
  "missing_artifact",
35
- "stale_fingerprint",
36
34
  "duration",
37
35
  "stream",
38
36
  "subtitle",
@@ -107,7 +105,6 @@ _REQUIRED_FINDING_FIELDS = frozenset({
107
105
  "evidence",
108
106
  "sample_policy",
109
107
  "model_used",
110
- "artifact_fingerprints",
111
108
  "next_action",
112
109
  # Helper fields kept for current rule semantics and compatibility.
113
110
  "category",
@@ -132,15 +129,6 @@ class QCContractError(ValueError):
132
129
  """Raised when a QC report or finding violates the shared contract."""
133
130
 
134
131
 
135
- def artifact_fingerprint(path: str | Path) -> str:
136
- """Return a stable sha256 hex digest for an artifact file."""
137
- h = hashlib.sha256()
138
- with Path(path).open("rb") as f:
139
- for chunk in iter(lambda: f.read(1024 * 1024), b""):
140
- h.update(chunk)
141
- return h.hexdigest()
142
-
143
-
144
132
  def build_finding(
145
133
  *,
146
134
  stage: str,
@@ -155,7 +143,6 @@ def build_finding(
155
143
  rule_id: str | None = None,
156
144
  decision_reason: str | None = None,
157
145
  model_used: str | None = None,
158
- artifact_fingerprints: Mapping[str, Any] | None = None,
159
146
  next_action: str | None = None,
160
147
  deterministic: bool | None = None,
161
148
  blocking: bool | None = None,
@@ -181,8 +168,6 @@ def build_finding(
181
168
  decision_reason = message
182
169
  if model_used is None:
183
170
  model_used = "local_deterministic"
184
- if artifact_fingerprints is None:
185
- artifact_fingerprints = {}
186
171
  if next_action is None:
187
172
  next_action = "manual_review"
188
173
  if isinstance(sample_policy, str):
@@ -200,7 +185,6 @@ def build_finding(
200
185
  if evidence is None:
201
186
  evidence = {}
202
187
  evidence = redact_secrets(evidence)
203
- artifact_fingerprints = redact_secrets(artifact_fingerprints)
204
188
  objective_corroboration = redact_secrets(objective_corroboration or {})
205
189
 
206
190
  is_non_deterministic = (not deterministic) or category in NON_DETERMINISTIC_CATEGORIES
@@ -226,7 +210,6 @@ def build_finding(
226
210
  "evidence": dict(evidence),
227
211
  "sample_policy": dict(sample_policy),
228
212
  "model_used": model_used,
229
- "artifact_fingerprints": dict(artifact_fingerprints),
230
213
  "next_action": next_action,
231
214
  "category": category,
232
215
  "code": code,
@@ -324,8 +307,6 @@ def _validate_finding(finding: Mapping[str, Any]) -> None:
324
307
  raise QCContractError("source must be an object")
325
308
  if finding["evidence"] is None or not isinstance(finding["evidence"], Mapping):
326
309
  raise QCContractError("evidence must be an object")
327
- if finding["artifact_fingerprints"] is None or not isinstance(finding["artifact_fingerprints"], Mapping):
328
- raise QCContractError("artifact_fingerprints must be an object")
329
310
  if finding["objective_corroboration"] is None or not isinstance(finding["objective_corroboration"], Mapping):
330
311
  raise QCContractError("objective_corroboration must be an object")
331
312
  for field in ("finding_id", "rule_id", "decision_reason", "model_used", "next_action"):
@@ -4,137 +4,206 @@ import argparse
4
4
  import os
5
5
 
6
6
  from lib import env_bool
7
+ from recap_source import AUDIO_MODES
7
8
 
8
- TTS_PROVIDERS = ("auto", "mimo-tts", "fish-audio")
9
+ TTS_PROVIDERS = ("auto", "mimo-tts", "fish-audio", "index-tts")
9
10
 
10
11
 
11
- def parse_args():
12
+ class _RecordExplicit:
13
+ """Record the option argparse actually consumed, not the raw argv spelling."""
14
+
15
+ def __call__(self, parser, namespace, values, option_string=None):
16
+ if option_string is not None:
17
+ recorded = getattr(namespace, "_explicit_options", None)
18
+ if recorded is None:
19
+ recorded = set()
20
+ setattr(namespace, "_explicit_options", recorded)
21
+ recorded.add(option_string)
22
+ super().__call__(parser, namespace, values, option_string)
23
+
24
+
25
+ def _record_explicit_options(parser):
26
+ """Make every optional action report itself, so guards never re-parse sys.argv."""
27
+ tracked = {}
28
+ for action in parser._actions:
29
+ if not action.option_strings:
30
+ continue
31
+ base = type(action)
32
+ if not issubclass(base, _RecordExplicit):
33
+ action.__class__ = tracked.setdefault(
34
+ base, type(base.__name__, (_RecordExplicit, base), {})
35
+ )
36
+
37
+
38
+ def parse_args(argv=None):
12
39
  parser = argparse.ArgumentParser(
13
- description="Full video recap orchestrator (video-* skill bundle)."
40
+ description="Full video recap orchestrator (video-* skill bundle).",
41
+ allow_abbrev=False,
14
42
  )
15
43
  parser.add_argument("video", nargs="*")
16
- parser.add_argument("--work-dir", default=None)
17
- parser.add_argument("--context", default="")
18
- parser.add_argument("--scene-threshold", type=float, default=None)
19
- parser.add_argument("--style", default="纪录片")
20
- parser.add_argument(
44
+
45
+ core = parser.add_argument_group("核心流程")
46
+ core.add_argument("--work-dir", default=None)
47
+ core.add_argument("--context", default="")
48
+ core.add_argument("--scene-threshold", type=float, default=None)
49
+ core.add_argument("--style", default="纪录片")
50
+ core.add_argument(
21
51
  "--edit-mode",
22
52
  default=os.environ.get("EDIT_MODE", "full"),
23
53
  choices=["full", "cut", "dub"],
24
54
  )
25
- parser.add_argument(
55
+ core.add_argument(
26
56
  "--target-duration", default=os.environ.get("TARGET_DURATION") or None
27
57
  )
28
- parser.add_argument(
58
+ core.add_argument(
29
59
  "--allow-duration-drift",
30
60
  action="store_true",
31
61
  help="cut mode: accept clip duration drift from --target-duration (primary override)",
32
62
  )
33
- parser.add_argument(
34
- "--allow-sparse-cut",
35
- action="store_true",
36
- help="compatibility: accept sparse cut mapping and legacy duration drift override",
37
- )
38
- parser.add_argument("--skip-asr", action="store_true")
39
- parser.add_argument("--mimo-video-overview", action="store_true")
40
- parser.add_argument(
41
- "--mimo-qc",
42
- default=os.environ.get("MIMO_QC", "off"),
43
- choices=["off", "pre-assemble", "post-render", "both"],
44
- help="optional advisory MiMo QC stage(s); never blocks the pipeline",
45
- )
46
- parser.add_argument(
47
- "--mimo-qc-refresh",
48
- action="store_true",
49
- default=env_bool("MIMO_QC_REFRESH", False),
50
- help="ignore a matching MiMo QC stage cache",
51
- )
52
- parser.add_argument(
63
+ core.add_argument("--output-dir", default=None)
64
+ core.add_argument("--skip-asr", action="store_true")
65
+ core.add_argument("--mimo-video-overview", action="store_true")
66
+ core.add_argument(
53
67
  "--consolidate",
54
68
  action=argparse.BooleanOptionalAction,
55
69
  default=True,
56
70
  help="build the understanding story index (Pass B); default ON, --no-consolidate to skip",
57
71
  )
58
- parser.add_argument(
72
+ core.add_argument(
59
73
  "--consolidate-asr", action="store_true", help="also clean ASR (Pass A)"
60
74
  )
61
- parser.add_argument("--mimo-tts-voice", default=None, help="MiMo TTS voice")
62
- parser.add_argument(
75
+
76
+ voice = parser.add_argument_group("声音策略与配音")
77
+ voice.add_argument("--audio-mode", choices=AUDIO_MODES, default="narration")
78
+ voice.add_argument("--audio-stream-index", type=int, default=0)
79
+ voice.add_argument(
63
80
  "--tts-provider",
64
81
  default=os.environ.get("TTS_PROVIDER", "auto"),
65
82
  choices=TTS_PROVIDERS,
66
- help="voiceover provider; auto prefers configured MiMo, then Fish Audio",
83
+ help="voiceover provider; auto prefers configured MiMo, then Fish Audio; Index is explicit",
67
84
  )
68
- parser.add_argument(
85
+ voice.add_argument("--mimo-tts-voice", default=None, help="MiMo TTS voice")
86
+ voice.add_argument(
69
87
  "--voice-ref",
70
88
  default=None,
71
89
  help="reference audio for cloned narration voice (mimo-v2.5-tts-voiceclone)",
72
90
  )
73
- parser.add_argument(
91
+ voice.add_argument(
92
+ "--preserve-approved-text",
93
+ action="store_true",
94
+ help="forward strict approved-text preservation to narration voiceover",
95
+ )
96
+ voice.add_argument(
74
97
  "--allow-partial-tts",
75
98
  action="store_true",
76
99
  help="allow video-voiceover to continue when some narration segments fail TTS",
77
100
  )
78
- parser.add_argument(
101
+ voice.add_argument(
79
102
  "--burn-subtitles",
80
103
  action=argparse.BooleanOptionalAction,
81
104
  default=None,
82
105
  help="burn narration subtitles into the video (default on; --no-burn-subtitles to disable)",
83
106
  )
84
- parser.add_argument(
107
+ voice.add_argument(
85
108
  "--subtitle-y-top",
86
109
  type=int,
87
110
  default=None,
88
111
  help="inclusive auto-rotated display-frame Y at the top of the measured subtitle band",
89
112
  )
90
- parser.add_argument(
113
+ voice.add_argument(
91
114
  "--subtitle-y-bot",
92
115
  type=int,
93
116
  default=None,
94
117
  help="exclusive auto-rotated display-frame Y at the bottom of the measured subtitle band",
95
118
  )
96
- parser.add_argument(
119
+
120
+ adoption = parser.add_argument_group("本地采用三件套(assembly-only)")
121
+ adoption.add_argument(
122
+ "--tts-meta", default=None,
123
+ help="local adopted tts_meta.json; requires both adoption flags",
124
+ )
125
+ adoption.add_argument(
126
+ "--narration-adoption", default=None,
127
+ help="local narration_adoption v1; requires --tts-meta and --audio-mix-adoption",
128
+ )
129
+ adoption.add_argument(
130
+ "--audio-mix-adoption", default=None,
131
+ help="local audio_mix_adoption v1 for assembly-only full-sound rendering",
132
+ )
133
+
134
+ review = parser.add_argument_group("评审、QC 与导出")
135
+ review.add_argument(
97
136
  "--review-narration",
98
137
  action=argparse.BooleanOptionalAction,
99
138
  default=None,
100
139
  help="run advisory narration quality review before TTS (default on; fail-open)",
101
140
  )
102
- parser.add_argument(
141
+ review.add_argument(
103
142
  "--require-narration-review",
104
143
  action="store_true",
105
144
  help="make narration review a strict pre-TTS gate (also REQUIRE_NARRATION_REVIEW=1)",
106
145
  )
107
- parser.add_argument("--output-dir", default=None)
108
- parser.add_argument(
146
+ review.add_argument(
147
+ "--mimo-qc",
148
+ default=os.environ.get("MIMO_QC", "off"),
149
+ choices=["off", "pre-assemble", "post-render", "both"],
150
+ help="optional advisory MiMo QC stage(s); never blocks the pipeline",
151
+ )
152
+ review.add_argument(
153
+ "--mimo-qc-refresh",
154
+ action="store_true",
155
+ default=env_bool("MIMO_QC_REFRESH", False),
156
+ help="ignore a matching MiMo QC stage cache",
157
+ )
158
+ review.add_argument(
159
+ "--require-final-qc",
160
+ action="store_true",
161
+ help="full/cut: require literal passing final_qc and golden_eval summaries",
162
+ )
163
+ review.add_argument(
109
164
  "--export-jianying",
110
165
  action="store_true",
111
166
  help="also export an OPTIONAL 剪映/JianYing draft (decoupled; never required)",
112
167
  )
113
- parser.add_argument(
168
+ review.add_argument(
114
169
  "--jianying-bundle-media",
115
170
  action="store_true",
116
171
  help="copy media into the 剪映 draft (default on; portable to another machine)",
117
172
  )
118
- parser.add_argument(
173
+ review.add_argument(
119
174
  "--jianying-no-bundle-media",
120
175
  action="store_true",
121
176
  help="reference media in place instead of copying it into the draft",
122
177
  )
123
- parser.add_argument(
178
+
179
+ materials = parser.add_argument_group("素材库")
180
+ materials.add_argument(
124
181
  "--material-library-dir",
125
182
  default=None,
126
183
  help="filesystem material library dir (or VIDEO_RECAP_MATERIAL_LIBRARY_DIR)",
127
184
  )
128
- parser.add_argument(
185
+ materials.add_argument(
129
186
  "--use-materials",
130
187
  action=argparse.BooleanOptionalAction,
131
188
  default=False,
132
189
  help="restore compatible analyzed artifacts from the material library",
133
190
  )
134
- parser.add_argument(
191
+ materials.add_argument(
135
192
  "--save-materials",
136
193
  action="store_true",
137
194
  help="save analyzed JSON/MD artifacts into the material library",
138
195
  )
139
- parser.add_argument("--doctor", action="store_true")
140
- return parser, parser.parse_args()
196
+
197
+ materials.add_argument(
198
+ "--project",
199
+ default=None,
200
+ help="recap_project.json(或其所在目录):绑定资源库里已采用的字幕样式、包装模板、音色与 BGM",
201
+ )
202
+
203
+ selfcheck = parser.add_argument_group("自检")
204
+ selfcheck.add_argument("--doctor", action="store_true")
205
+
206
+ _record_explicit_options(parser)
207
+ args = parser.parse_args(argv)
208
+ args._explicit_options = frozenset(getattr(args, "_explicit_options", ()))
209
+ return parser, args