@oh-story/dsh 0.1.3 → 0.1.5
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.
- package/README.md +58 -12
- package/lib/client.js +2970 -537
- package/lib/client.js.map +4 -4
- package/lib/drama/manifest.json +218 -178
- package/lib/drama/skills/short-drama/SKILL.md +110 -117
- package/lib/drama/skills/short-drama/references/audience-reveal.md +14 -67
- package/lib/drama/skills/short-drama/references/contract-and-ownership.md +26 -77
- package/lib/drama/skills/short-drama/references/creator-documents.md +204 -0
- package/lib/drama/skills/short-drama/references/creator-workflow.md +73 -63
- package/lib/drama/skills/short-drama/references/knowhow-index.md +5 -0
- package/lib/drama/skills/short-drama/references/look-development.md +2 -3
- package/lib/drama/skills/short-drama/references/pickup-and-alternate.md +14 -48
- package/lib/drama/skills/short-drama/references/production-form-profiles.md +1 -1
- package/lib/drama/skills/short-drama/references/reference-roles.md +32 -135
- package/lib/drama/skills/short-drama/references/runtime-preflight.md +16 -19
- package/lib/drama/skills/short-drama/scripts/creator_markdown_check.py +1002 -0
- package/lib/drama/skills/short-drama/scripts/project_tool.py +485 -5
- package/lib/drama/skills/short-drama-assets/SKILL.md +59 -170
- package/lib/drama/skills/short-drama-assets/references/asset-review-checklist.md +18 -25
- package/lib/drama/skills/short-drama-assets/references/character-and-look.md +13 -15
- package/lib/drama/skills/short-drama-assets/references/continuity-delta.md +11 -14
- package/lib/drama/skills/short-drama-assets/references/continuity-lock.md +116 -0
- package/lib/drama/skills/short-drama-assets/references/identity-vs-variant.md +6 -12
- package/lib/drama/skills/short-drama-assets/references/occurrence-extraction.md +8 -11
- package/lib/drama/skills/short-drama-assets/references/prop-and-state.md +21 -2
- package/lib/drama/skills/short-drama-assets/references/stage-contract.md +12 -105
- package/lib/drama/skills/short-drama-assets/references/voice-direction.md +12 -32
- package/lib/drama/skills/short-drama-assets/scripts/asset_check.py +1 -1
- package/lib/drama/skills/short-drama-image-prompts/SKILL.md +45 -155
- package/lib/drama/skills/short-drama-image-prompts/references/character-and-look.md +12 -13
- package/lib/drama/skills/short-drama-image-prompts/references/common-recipe.md +12 -13
- package/lib/drama/skills/short-drama-image-prompts/references/edit-and-revision.md +39 -51
- package/lib/drama/skills/short-drama-image-prompts/references/location-plate.md +3 -4
- package/lib/drama/skills/short-drama-image-prompts/references/look-and-state-variant.md +15 -14
- package/lib/drama/skills/short-drama-image-prompts/references/lookdev-frame.md +11 -15
- package/lib/drama/skills/short-drama-image-prompts/references/production-sheet-recipes.md +1 -1
- package/lib/drama/skills/short-drama-image-prompts/references/prop-plate.md +4 -7
- package/lib/drama/skills/short-drama-image-prompts/references/review-and-fixtures.md +23 -23
- package/lib/drama/skills/short-drama-image-prompts/references/stage-contract.md +8 -65
- package/lib/drama/skills/short-drama-image-prompts/scripts/image_prompt_check.py +8 -8
- package/lib/drama/skills/short-drama-image-prompts/scripts/selftest.py +4 -2
- package/lib/drama/skills/short-drama-produce/SKILL.md +67 -15
- package/lib/drama/skills/short-drama-produce/references/adapter-contract.md +65 -8
- package/lib/drama/skills/short-drama-produce/references/providers/minimax-h3-video.md +85 -0
- package/lib/drama/skills/short-drama-produce/references/providers/seedance.md +27 -10
- package/lib/drama/skills/short-drama-produce/scripts/production_tool.py +362 -3
- package/lib/drama/skills/short-drama-produce/scripts/provider_adapters.py +627 -40
- package/lib/drama/skills/short-drama-produce/scripts/selftest.py +5 -4
- package/lib/drama/skills/short-drama-review/SKILL.md +61 -123
- package/lib/drama/skills/short-drama-review/references/anti-template-repair.md +10 -15
- package/lib/drama/skills/short-drama-review/references/production-quality-gates.md +15 -16
- package/lib/drama/skills/short-drama-review/references/project-calibration.md +7 -9
- package/lib/drama/skills/short-drama-review/references/review-method.md +8 -9
- package/lib/drama/skills/short-drama-review/references/rubric-assets-prompts.md +9 -13
- package/lib/drama/skills/short-drama-review/references/rubric-story-script.md +104 -4
- package/lib/drama/skills/short-drama-review/references/rubric-visual-motion.md +27 -19
- package/lib/drama/skills/short-drama-review/references/stage-contract.md +4 -63
- package/lib/drama/skills/short-drama-review/scripts/review_check.py +1 -1
- package/lib/drama/skills/short-drama-storyboard/SKILL.md +116 -238
- package/lib/drama/skills/short-drama-storyboard/assets/shot-template.jsonl +1 -1
- package/lib/drama/skills/short-drama-storyboard/references/blocking-playbooks.md +9 -34
- package/lib/drama/skills/short-drama-storyboard/references/comic-keyframe-lexicon.md +156 -0
- package/lib/drama/skills/short-drama-storyboard/references/coverage-audition.md +5 -10
- package/lib/drama/skills/short-drama-storyboard/references/keyframe-craft.md +12 -7
- package/lib/drama/skills/short-drama-storyboard/references/production-shot-grammar.md +19 -4
- package/lib/drama/skills/short-drama-storyboard/references/review-and-fixtures.md +27 -62
- package/lib/drama/skills/short-drama-storyboard/references/scene-visual-plan.md +16 -25
- package/lib/drama/skills/short-drama-storyboard/references/screenplay-to-keyframe-example.md +21 -23
- package/lib/drama/skills/short-drama-storyboard/references/shot-craft.md +8 -10
- package/lib/drama/skills/short-drama-storyboard/references/shot-revision-identity.md +9 -13
- package/lib/drama/skills/short-drama-storyboard/references/stage-contract.md +16 -71
- package/lib/drama/skills/short-drama-storyboard/scripts/storyboard_check.py +1 -1
- package/lib/drama/skills/short-drama-video-prompts/SKILL.md +123 -230
- package/lib/drama/skills/short-drama-video-prompts/assets/motion-spec.jsonl.md +6 -1
- package/lib/drama/skills/short-drama-video-prompts/assets/video-prompts.md +17 -1
- package/lib/drama/skills/short-drama-video-prompts/references/camera-audio-continuity.md +10 -8
- package/lib/drama/skills/short-drama-video-prompts/references/delivery-profile.md +24 -6
- package/lib/drama/skills/short-drama-video-prompts/references/generability.md +2 -2
- package/lib/drama/skills/short-drama-video-prompts/references/minimax-h3.md +154 -0
- package/lib/drama/skills/short-drama-video-prompts/references/motion-recipe.md +35 -27
- package/lib/drama/skills/short-drama-video-prompts/references/performance-action-timing.md +8 -11
- package/lib/drama/skills/short-drama-video-prompts/references/production-prompt-grammar.md +13 -10
- package/lib/drama/skills/short-drama-video-prompts/references/review-and-fixtures.md +34 -63
- package/lib/drama/skills/short-drama-video-prompts/references/seedance-2.0.md +41 -0
- package/lib/drama/skills/short-drama-video-prompts/references/seedance-2.5.md +66 -0
- package/lib/drama/skills/short-drama-video-prompts/references/stage-contract.md +17 -73
- package/lib/drama/skills/short-drama-video-prompts/references/target-model-profile.md +115 -0
- package/lib/drama/skills/short-drama-video-prompts/scripts/container_check.py +1 -1
- package/lib/drama/skills/short-drama-video-prompts/scripts/music_spec_check.py +1 -1
- package/lib/drama/skills/short-drama-write/SKILL.md +74 -268
- package/lib/drama/skills/short-drama-write/references/dialogue-craft.md +7 -0
- package/lib/drama/skills/short-drama-write/references/scene-handoff-capsule.md +17 -43
- package/lib/drama/skills/short-drama-write/references/screenplay-format.md +15 -15
- package/lib/drama/skills/short-drama-write/references/script-craft.md +208 -21
- package/lib/drama/skills/short-drama-write/references/stage-contract.md +11 -70
- package/lib/drama/skills/short-drama-write/scripts/duration_estimate.py +1 -1
- package/lib/drama/skills/short-drama-write/scripts/screenplay_index.py +2 -2
- package/lib/drama/skills/short-drama-write/scripts/voice_sheet_check.py +1 -1
- package/lib/index.js +971 -46
- package/lib/index.js.map +4 -4
- package/lib/novel-to-game/LICENSE +21 -0
- package/lib/novel-to-game/README.md +180 -0
- package/lib/novel-to-game/README_ZH.md +178 -0
- package/lib/novel-to-game/VERSION +1 -0
- package/lib/novel-to-game/examples/jin-ping-mei/build/BUILD_BRIEF.md +217 -0
- package/lib/novel-to-game/examples/jin-ping-mei/build/app/.vercelignore +3 -0
- package/lib/novel-to-game/examples/jin-ping-mei/build/app/RUN.md +130 -0
- package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/bg/compound_new_guofeng.webp +0 -0
- package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/cg/finale/fate_coda.webp +0 -0
- package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/cg/finale/meng.webp +0 -0
- package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/cg/finale/pan.webp +0 -0
- package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/cg/finale/pinger.webp +0 -0
- package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/cg/finale/xuee.webp +0 -0
- package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/cg/finale/yue.webp +0 -0
- package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/cg/group/inner_court_accord_five.webp +0 -0
- package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/cg/group/inner_court_afterglow_five.webp +0 -0
- package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/cg/group/inner_court_alliance.webp +0 -0
- package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/cg/group/public_day10.webp +0 -0
- package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/cg/group/public_day15.webp +0 -0
- package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/cg/group/public_day5.webp +0 -0
- package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/cg/group/title_new_guofeng.webp +0 -0
- package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/cg/joint/pan_pinger.webp +0 -0
- package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/cg/joint/pan_xuee.webp +0 -0
- package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/cg/joint/yue_meng.webp +0 -0
- package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/cg/joint/yue_pan.webp +0 -0
- package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/cg/joint/yue_pinger.webp +0 -0
- package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/cg/meng/explicit.webp +0 -0
- package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/cg/meng/prelude.webp +0 -0
- package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/cg/milestone/meng.webp +0 -0
- package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/cg/milestone/pan.webp +0 -0
- package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/cg/milestone/pinger.webp +0 -0
- package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/cg/milestone/xuee.webp +0 -0
- package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/cg/milestone/yue.webp +0 -0
- package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/cg/pan/explicit.webp +0 -0
- package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/cg/pan/prelude.webp +0 -0
- package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/cg/pinger/explicit.webp +0 -0
- package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/cg/pinger/prelude.webp +0 -0
- package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/cg/xuee/explicit.webp +0 -0
- package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/cg/xuee/prelude.webp +0 -0
- package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/cg/yue/explicit.webp +0 -0
- package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/cg/yue/prelude.webp +0 -0
- package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/heroine/meng/night.webp +0 -0
- package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/heroine/pan/night.webp +0 -0
- package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/heroine/pinger/night.webp +0 -0
- package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/heroine/xuee/night.webp +0 -0
- package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/heroine/yue/night.webp +0 -0
- package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/household/li_jiaoer.webp +0 -0
- package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/scene/gate_collector.webp +0 -0
- package/lib/novel-to-game/examples/jin-ping-mei/build/app/css/new-guofeng.css +1105 -0
- package/lib/novel-to-game/examples/jin-ping-mei/build/app/css/style.css +2539 -0
- package/lib/novel-to-game/examples/jin-ping-mei/build/app/index.html +18 -0
- package/lib/novel-to-game/examples/jin-ping-mei/build/app/js/assets.js +147 -0
- package/lib/novel-to-game/examples/jin-ping-mei/build/app/js/audio.js +332 -0
- package/lib/novel-to-game/examples/jin-ping-mei/build/app/js/data.js +7472 -0
- package/lib/novel-to-game/examples/jin-ping-mei/build/app/js/engine.js +13077 -0
- package/lib/novel-to-game/examples/jin-ping-mei/build/app/js/main.js +3028 -0
- package/lib/novel-to-game/examples/jin-ping-mei/build/app/js/text.js +32 -0
- package/lib/novel-to-game/examples/jin-ping-mei/build/app/package.json +10 -0
- package/lib/novel-to-game/examples/jin-ping-mei/build/app/vercel.json +23 -0
- package/lib/novel-to-game/examples/jin-ping-mei/build/art/generated-art.json +161 -0
- package/lib/novel-to-game/examples/jin-ping-mei/example.json +12 -0
- package/lib/novel-to-game/examples/jin-ping-mei/qa/README.md +31 -0
- package/lib/novel-to-game/examples/jin-ping-mei/qa/playable-model.json +99 -0
- package/lib/novel-to-game/examples/jin-ping-mei/qa/verification.json +41 -0
- package/lib/novel-to-game/examples/jin-ping-mei/qa/verify_playable_model.mjs +129 -0
- package/lib/novel-to-game/manifest.json +508 -0
- package/lib/novel-to-game/skills/game-art-direction/SKILL.md +73 -0
- package/lib/novel-to-game/skills/game-art-direction/agents/openai.yaml +4 -0
- package/lib/novel-to-game/skills/game-art-direction/references/art-direction-method.md +119 -0
- package/lib/novel-to-game/skills/game-build/SKILL.md +84 -0
- package/lib/novel-to-game/skills/game-build/agents/openai.yaml +4 -0
- package/lib/novel-to-game/skills/game-build/references/build-brief-contract.md +109 -0
- package/lib/novel-to-game/skills/game-build/references/generative-media-pipeline.md +56 -0
- package/lib/novel-to-game/skills/game-build/references/playable-model-contract.md +81 -0
- package/lib/novel-to-game/skills/game-build/references/tts-production-contract.md +37 -0
- package/lib/novel-to-game/skills/game-concept/SKILL.md +72 -0
- package/lib/novel-to-game/skills/game-concept/agents/openai.yaml +4 -0
- package/lib/novel-to-game/skills/game-concept/references/concept-method.md +94 -0
- package/lib/novel-to-game/skills/game-qa/SKILL.md +50 -0
- package/lib/novel-to-game/skills/game-qa/agents/openai.yaml +4 -0
- package/lib/novel-to-game/skills/game-qa/references/qa-contract.md +66 -0
- package/lib/novel-to-game/skills/game-qa/references/test-design-method.md +45 -0
- package/lib/novel-to-game/skills/game-world-design/SKILL.md +63 -0
- package/lib/novel-to-game/skills/game-world-design/agents/openai.yaml +4 -0
- package/lib/novel-to-game/skills/game-world-design/references/dialogue-design-method.md +59 -0
- package/lib/novel-to-game/skills/game-world-design/references/game-writing-craft.md +53 -0
- package/lib/novel-to-game/skills/game-world-design/references/narrative-design-method.md +84 -0
- package/lib/novel-to-game/skills/game-world-design/references/numeric-design-method.md +56 -0
- package/lib/novel-to-game/skills/game-world-design/references/world-design-method.md +124 -0
- package/lib/novel-to-game/skills/novel-game-analyze/SKILL.md +77 -0
- package/lib/novel-to-game/skills/novel-game-analyze/agents/openai.yaml +4 -0
- package/lib/novel-to-game/skills/novel-game-analyze/references/gameability-protocol.md +65 -0
- package/lib/novel-to-game/skills/novel-to-game/SKILL.md +71 -0
- package/lib/novel-to-game/skills/novel-to-game/agents/openai.yaml +4 -0
- package/lib/novel-to-game/skills/novel-to-game/references/intake-benchmark-reference.md +42 -0
- package/lib/novel-to-game/skills/novel-to-game/references/intake-method.md +51 -0
- package/lib/novel-to-game/skills/novel-to-game/references/pipeline-contract.md +65 -0
- package/lib/oh-story/manifest.json +419 -309
- package/lib/oh-story/roles/character-designer.md +4 -4
- package/lib/oh-story/roles/consistency-checker.md +1 -1
- package/lib/oh-story/roles/narrative-writer.md +41 -42
- package/lib/oh-story/roles/story-architect.md +19 -23
- package/lib/oh-story/roles/story-explorer.md +8 -5
- package/lib/oh-story/skills/browser-cdp/SKILL.md +1 -1
- package/lib/oh-story/skills/story/SKILL.md +16 -9
- package/lib/oh-story/skills/story/VERSION +1 -1
- package/lib/oh-story/skills/story/references/author-memory.md +163 -0
- package/lib/oh-story/skills/story/scripts/author_memory_commit.py +871 -0
- package/lib/oh-story/skills/story-cover/SKILL.md +1 -1
- package/lib/oh-story/skills/story-deslop/SKILL.md +10 -5
- package/lib/oh-story/skills/story-deslop/references/anti-ai-writing.md +2 -1
- package/lib/oh-story/skills/story-deslop/references/author-memory.md +163 -0
- package/lib/oh-story/skills/story-deslop/references/banned-words.md +6 -4
- package/lib/oh-story/skills/story-deslop/scripts/author_memory_commit.py +871 -0
- package/lib/oh-story/skills/story-deslop/scripts/check-ai-patterns.js +64 -1
- package/lib/oh-story/skills/story-import/SKILL.md +21 -8
- package/lib/oh-story/skills/story-import/references/format-and-structure.md +9 -10
- package/lib/oh-story/skills/story-import/references/structure-mapping-long.md +2 -2
- package/lib/oh-story/skills/story-import/references/structure-mapping-short.md +1 -1
- package/lib/oh-story/skills/story-import/references/tracking-transaction.md +14 -6
- package/lib/oh-story/skills/story-import/scripts/check-outline-contract.js +251 -0
- package/lib/oh-story/skills/story-import/scripts/tracking_commit.py +98 -9
- package/lib/oh-story/skills/story-import/scripts/wordcount_core.py +246 -0
- package/lib/oh-story/skills/story-long-analyze/SKILL.md +4 -4
- package/lib/oh-story/skills/story-long-scan/SKILL.md +1 -1
- package/lib/oh-story/skills/story-long-write/SKILL.md +35 -21
- package/lib/oh-story/skills/story-long-write/references/anti-ai-writing.md +2 -1
- package/lib/oh-story/skills/story-long-write/references/artifact-protocols.md +7 -3
- package/lib/oh-story/skills/story-long-write/references/author-memory.md +163 -0
- package/lib/oh-story/skills/story-long-write/references/banned-words.md +6 -4
- package/lib/oh-story/skills/story-long-write/references/cross-book-recall.md +6 -6
- package/lib/oh-story/skills/story-long-write/references/genre-prose-cards.md +1 -1
- package/lib/oh-story/skills/story-long-write/references/genre-readers.md +1 -1
- package/lib/oh-story/skills/{story-setup/references/agent-references/hooks-chapter.md → story-long-write/references/long-chapter-hooks.md} +5 -5
- package/lib/oh-story/skills/story-long-write/references/{quality-checklist.md → long-chapter-quality.md} +2 -1
- package/lib/oh-story/skills/story-long-write/references/long-format.md +42 -0
- package/lib/oh-story/skills/{story-setup/references/agent-references/genre-catalog.md → story-long-write/references/long-genre-catalog.md} +11 -97
- package/lib/oh-story/skills/story-long-write/references/{genre-core-mechanics.md → long-genre-mechanics.md} +1 -1
- package/lib/oh-story/skills/story-long-write/references/{reversal-toolkit.md → long-reversal.md} +18 -32
- package/lib/oh-story/skills/story-long-write/references/{hooks-suspense.md → long-suspense.md} +6 -6
- package/lib/oh-story/skills/story-long-write/references/opening-design.md +1 -1
- package/lib/oh-story/skills/story-long-write/references/outline-structure-theory.md +1 -1
- package/lib/oh-story/skills/story-long-write/references/style-genre-modules.md +1 -1
- package/lib/oh-story/skills/story-long-write/references/tracking-transaction.md +14 -6
- package/lib/oh-story/skills/story-long-write/references/workflow-chapter.md +32 -27
- package/lib/oh-story/skills/story-long-write/references/workflow-daily.md +5 -4
- package/lib/oh-story/skills/story-long-write/references/workflow-revision.md +2 -2
- package/lib/oh-story/skills/story-long-write/references/workflow-setup.md +17 -11
- package/lib/oh-story/skills/story-long-write/references/writing-craft.md +54 -54
- package/lib/oh-story/skills/story-long-write/scripts/author_memory_commit.py +871 -0
- package/lib/oh-story/skills/story-long-write/scripts/check-ai-patterns.js +64 -1
- package/lib/oh-story/skills/story-long-write/scripts/check-outline-contract.js +251 -0
- package/lib/oh-story/skills/story-long-write/scripts/storyctl.py +303 -0
- package/lib/oh-story/skills/story-long-write/scripts/tracking_commit.py +98 -9
- package/lib/oh-story/skills/story-long-write/scripts/wordcount_core.py +246 -0
- package/lib/oh-story/skills/story-review/SKILL.md +26 -17
- package/lib/oh-story/skills/story-review/references/anti-ai-writing.md +2 -1
- package/lib/oh-story/skills/story-review/references/author-memory.md +163 -0
- package/lib/oh-story/skills/story-review/references/banned-words.md +6 -4
- package/lib/oh-story/skills/story-review/references/{quality-checklist.md → review-quality.md} +22 -21
- package/lib/oh-story/skills/story-review/references/tracking-transaction.md +14 -6
- package/lib/oh-story/skills/story-review/scripts/author_memory_commit.py +871 -0
- package/lib/oh-story/skills/story-review/scripts/check-ai-patterns.js +64 -1
- package/lib/oh-story/skills/story-review/scripts/tracking_commit.py +98 -9
- package/lib/oh-story/skills/story-review/scripts/wordcount_core.py +246 -0
- package/lib/oh-story/skills/story-setup/SKILL.md +85 -41
- package/lib/oh-story/skills/story-setup/references/agent-references/agent-quality.md +72 -0
- package/lib/oh-story/skills/story-setup/references/agent-references/agent-reference-profiles.md +55 -0
- package/lib/oh-story/skills/story-setup/references/agent-references/anti-ai-writing.md +2 -1
- package/lib/oh-story/skills/story-setup/references/agent-references/banned-words.md +6 -4
- package/lib/oh-story/skills/story-setup/references/agent-references/format-and-structure.md +9 -10
- package/lib/oh-story/skills/story-setup/references/agent-references/genre-prose-cards.md +1 -1
- package/lib/oh-story/skills/story-setup/references/agent-references/genre-readers.md +1 -1
- package/lib/oh-story/skills/{story-short-analyze/references/hooks-chapter.md → story-setup/references/agent-references/long-chapter-hooks.md} +5 -5
- package/lib/oh-story/skills/story-setup/references/agent-references/long-emotional-methods.md +209 -0
- package/lib/oh-story/skills/{story-long-write/references/genre-catalog.md → story-setup/references/agent-references/long-genre-catalog.md} +11 -97
- package/lib/oh-story/skills/story-setup/references/agent-references/{genre-core-mechanics.md → long-genre-mechanics.md} +1 -1
- package/lib/oh-story/skills/story-setup/references/agent-references/long-quality.md +40 -0
- package/lib/oh-story/skills/{story-short-write/references/reversal-toolkit.md → story-setup/references/agent-references/long-reversal.md} +18 -32
- package/lib/oh-story/skills/{story-short-write/references/hooks-suspense.md → story-setup/references/agent-references/long-suspense.md} +6 -6
- package/lib/oh-story/skills/story-setup/references/agent-references/opening-design.md +1 -1
- package/lib/oh-story/skills/story-setup/references/agent-references/{emotional-methods.md → short-emotional-methods.md} +4 -4
- package/lib/oh-story/skills/{story-long-write/references/genre-writing-formulas.md → story-setup/references/agent-references/short-genre-formulas.md} +32 -44
- package/lib/oh-story/skills/story-setup/references/agent-references/short-quality.md +39 -0
- package/lib/oh-story/skills/story-setup/references/agent-references/{reversal-toolkit.md → short-reversal.md} +29 -23
- package/lib/oh-story/skills/story-setup/references/agent-references/{hooks-suspense.md → short-suspense.md} +31 -31
- package/lib/oh-story/skills/story-setup/references/agent-references/style-genre-modules.md +1 -1
- package/lib/oh-story/skills/story-setup/references/agent-references/writing-craft.md +55 -55
- package/lib/oh-story/skills/story-short-analyze/SKILL.md +28 -28
- package/lib/oh-story/skills/story-short-analyze/references/{character-basics.md → analysis-character-basics.md} +1 -1
- package/lib/oh-story/skills/story-short-analyze/references/{character-design-methods.md → analysis-character-design.md} +1 -1
- package/lib/oh-story/skills/story-short-analyze/references/{character-relations.md → analysis-character-relations.md} +1 -1
- package/lib/oh-story/skills/story-short-analyze/references/{hooks-paragraph.md → analysis-paragraph-hooks.md} +1 -1
- package/lib/oh-story/skills/story-short-analyze/references/{genre-readers.md → analysis-reader-profile.md} +2 -2
- package/lib/oh-story/skills/story-short-analyze/references/analysis-report-style.md +45 -0
- package/lib/oh-story/skills/story-short-analyze/references/analysis-short-genres.md +65 -0
- package/lib/oh-story/skills/story-short-analyze/references/analysis-short-hooks.md +77 -0
- package/lib/oh-story/skills/story-short-analyze/references/analysis-short-mechanics.md +82 -0
- package/lib/oh-story/skills/story-short-analyze/references/analysis-short-patterns.md +50 -0
- package/lib/oh-story/skills/story-short-analyze/references/analysis-short-suspense.md +98 -0
- package/lib/oh-story/skills/story-short-analyze/references/{genre-writing-techniques.md → analysis-writing-techniques.md} +21 -19
- package/lib/oh-story/skills/story-short-analyze/references/deconstruction-examples.md +1 -1
- package/lib/oh-story/skills/story-short-analyze/references/material-decomposition.md +21 -28
- package/lib/oh-story/skills/story-short-analyze/references/output-contract.md +1 -1
- package/lib/oh-story/skills/story-short-analyze/references/output-templates.md +17 -17
- package/lib/oh-story/skills/story-short-analyze/references/{quality-checklist.md → source-story-quality.md} +28 -49
- package/lib/oh-story/skills/story-short-analyze/references/zhihu-style.md +2 -2
- package/lib/oh-story/skills/story-short-scan/SKILL.md +1 -1
- package/lib/oh-story/skills/story-short-write/SKILL.md +78 -55
- package/lib/oh-story/skills/story-short-write/references/author-memory.md +163 -0
- package/lib/oh-story/skills/story-short-write/references/banned-words.md +6 -4
- package/lib/oh-story/skills/story-short-write/references/cross-book-recall.md +3 -3
- package/lib/oh-story/skills/story-short-write/references/emotional-methods.md +4 -4
- package/lib/oh-story/skills/story-short-write/references/genre-styles//344/270/226/346/203/205/346/211/223/350/204/270.md +3 -3
- package/lib/oh-story/skills/story-short-write/references/genre-styles//345/217/214/347/224/267/344/270/273.md +2 -2
- package/lib/oh-story/skills/story-short-write/references/genre-styles//345/244/215/344/273/207/346/211/223/350/204/270.md +3 -3
- package/lib/oh-story/skills/story-short-write/references/genre-styles//345/256/205/346/226/227/345/256/253/346/226/227.md +6 -6
- package/lib/oh-story/skills/story-short-write/references/genre-styles//346/200/273/350/243/201/350/261/252/351/227/250.md +3 -3
- package/lib/oh-story/skills/story-short-write/references/genre-styles//346/202/254/347/226/221.md +4 -4
- package/lib/oh-story/skills/story-short-write/references/genre-styles//346/260/221/344/277/227/346/200/252/350/260/210.md +7 -7
- package/lib/oh-story/skills/story-short-write/references/genre-styles//346/262/231/351/233/225/350/204/221/346/264/236.md +5 -5
- package/lib/oh-story/skills/story-short-write/references/genre-styles//347/224/234/345/256/240.md +4 -4
- package/lib/oh-story/skills/story-short-write/references/genre-styles//350/277/275/345/246/273/347/201/253/350/221/254/345/234/272.md +3 -3
- package/lib/oh-story/skills/story-short-write/references/genre-writing-formulas.md +32 -44
- package/lib/oh-story/skills/story-short-write/references/genre-writing-techniques.md +20 -18
- package/lib/oh-story/skills/story-short-write/references/output-contract.md +1 -1
- package/lib/oh-story/skills/story-short-write/references/short-craft.md +18 -18
- package/lib/oh-story/skills/story-short-write/references/short-deslop.md +1 -1
- package/lib/oh-story/skills/story-short-write/references/short-format.md +38 -8
- package/lib/oh-story/skills/story-short-write/references/{quality-checklist.md → short-prose-quality.md} +22 -21
- package/lib/oh-story/skills/story-short-write/references/short-reversal.md +355 -0
- package/lib/oh-story/skills/{story-short-analyze/references/hooks-suspense.md → story-short-write/references/short-suspense.md} +31 -31
- package/lib/oh-story/skills/story-short-write/references/submission-craft.md +2 -2
- package/lib/oh-story/skills/story-short-write/references/writing-workflow.md +31 -22
- package/lib/oh-story/skills/story-short-write/scripts/author_memory_commit.py +871 -0
- package/lib/oh-story/skills/story-short-write/scripts/check-ai-patterns.js +64 -1
- package/lib/oh-story/skills/story-short-write/scripts/check-delivery-contract.js +212 -0
- package/lib/oh-story/skills/story-short-write/scripts/check-phase2-contract.js +363 -0
- package/lib/types/client/drama-production-view.d.ts +34 -0
- package/lib/types/client/drama-production-view.d.ts.map +1 -0
- package/lib/types/client/drama-production.d.ts +92 -0
- package/lib/types/client/drama-production.d.ts.map +1 -0
- package/lib/types/client/file-activity.d.ts +9 -2
- package/lib/types/client/file-activity.d.ts.map +1 -1
- package/lib/types/client/index.d.ts +1 -1
- package/lib/types/client/index.d.ts.map +1 -1
- package/lib/types/client/production-intents.d.ts +9 -0
- package/lib/types/client/production-intents.d.ts.map +1 -0
- package/lib/types/client/production-prompts.d.ts +9 -0
- package/lib/types/client/production-prompts.d.ts.map +1 -0
- package/lib/types/client/production-runtime.d.ts +58 -0
- package/lib/types/client/production-runtime.d.ts.map +1 -0
- package/lib/types/client/video-studio.d.ts +41 -0
- package/lib/types/client/video-studio.d.ts.map +1 -0
- package/lib/types/client/workbench-ui.d.ts +5 -0
- package/lib/types/client/workbench-ui.d.ts.map +1 -0
- package/lib/types/game-verification.d.ts +16 -0
- package/lib/types/game-verification.d.ts.map +1 -0
- package/lib/types/index.d.ts +5 -2
- package/lib/types/index.d.ts.map +1 -1
- package/lib/types/production-intent.d.ts +21 -0
- package/lib/types/production-intent.d.ts.map +1 -0
- package/lib/types/production-tool.d.ts +5 -0
- package/lib/types/production-tool.d.ts.map +1 -0
- package/lib/types/reference-tool.d.ts +6 -0
- package/lib/types/reference-tool.d.ts.map +1 -0
- package/lib/types/role-provider.d.ts.map +1 -1
- package/lib/types/role-tool.d.ts +3 -1
- package/lib/types/role-tool.d.ts.map +1 -1
- package/lib/types/skill-provider.d.ts +7 -0
- package/lib/types/skill-provider.d.ts.map +1 -1
- package/lib/types/video-project.d.ts +42 -0
- package/lib/types/video-project.d.ts.map +1 -0
- package/lib/types/workspace-request-trust.d.ts +6 -0
- package/lib/types/workspace-request-trust.d.ts.map +1 -1
- package/lib/types/workspace-route.d.ts +20 -0
- package/lib/types/workspace-route.d.ts.map +1 -1
- package/lib/video-recap/CHANGELOG.md +282 -0
- package/lib/video-recap/LICENSE +21 -0
- package/lib/video-recap/README.en.md +257 -0
- package/lib/video-recap/README.md +255 -0
- package/lib/video-recap/manifest.json +684 -0
- package/lib/video-recap/skills/video-assemble/SKILL.md +97 -0
- package/lib/video-recap/skills/video-assemble/references/jianying/LICENSE.duo-video +21 -0
- package/lib/video-recap/skills/video-assemble/references/jianying/SOURCE.md +15 -0
- package/lib/video-recap/skills/video-assemble/references/jianying/empty_draft_meta_info.json +69 -0
- package/lib/video-recap/skills/video-assemble/references/jianying/empty_jy_combination_segment.json +84 -0
- package/lib/video-recap/skills/video-assemble/references/jianying/empty_jy_combination_video_material.json +98 -0
- package/lib/video-recap/skills/video-assemble/references/jianying/empty_jy_draft.json +204 -0
- package/lib/video-recap/skills/video-assemble/references/jianying/empty_jy_material_video.json +83 -0
- package/lib/video-recap/skills/video-assemble/references/jianying/empty_jy_meta_material_value.json +23 -0
- package/lib/video-recap/skills/video-assemble/references/jianying/empty_jy_project_info.json +133 -0
- package/lib/video-recap/skills/video-assemble/references/jianying/empty_jy_segment.json +70 -0
- package/lib/video-recap/skills/video-assemble/references/jianying/empty_jy_text_styles.json +30 -0
- package/lib/video-recap/skills/video-assemble/references/jianying/empty_yj_material_audio.json +41 -0
- package/lib/video-recap/skills/video-assemble/references/jianying/empty_yj_material_text.json +109 -0
- package/lib/video-recap/skills/video-assemble/scripts/artifacts.py +88 -0
- package/lib/video-recap/skills/video-assemble/scripts/assemble.py +345 -0
- package/lib/video-recap/skills/video-assemble/scripts/assemble_constants.py +34 -0
- package/lib/video-recap/skills/video-assemble/scripts/assembly_contract.py +305 -0
- package/lib/video-recap/skills/video-assemble/scripts/assembly_settings.py +94 -0
- package/lib/video-recap/skills/video-assemble/scripts/audio_automation.py +205 -0
- package/lib/video-recap/skills/video-assemble/scripts/audio_mix.py +555 -0
- package/lib/video-recap/skills/video-assemble/scripts/export_jianying.py +261 -0
- package/lib/video-recap/skills/video-assemble/scripts/jianying_builders.py +767 -0
- package/lib/video-recap/skills/video-assemble/scripts/jianying_model.py +111 -0
- package/lib/video-recap/skills/video-assemble/scripts/jianying_optional.py +24 -0
- package/lib/video-recap/skills/video-assemble/scripts/jianying_schema.py +109 -0
- package/lib/video-recap/skills/video-assemble/scripts/jianying_templates.py +37 -0
- package/lib/video-recap/skills/video-assemble/scripts/jianying_timeline_contract.py +191 -0
- package/lib/video-recap/skills/video-assemble/scripts/jianying_tracks.py +75 -0
- package/lib/video-recap/skills/video-assemble/scripts/jianying_writer.py +394 -0
- package/lib/video-recap/skills/video-assemble/scripts/lib.py +239 -0
- package/lib/video-recap/skills/video-assemble/scripts/media.py +243 -0
- package/lib/video-recap/skills/video-assemble/scripts/narration_audio.py +477 -0
- package/lib/video-recap/skills/video-assemble/scripts/render_preflight.py +46 -0
- package/lib/video-recap/skills/video-assemble/scripts/source_subtitles.py +486 -0
- package/lib/video-recap/skills/video-assemble/scripts/subtitle_core.py +376 -0
- package/lib/video-recap/skills/video-assemble/scripts/subtitle_render.py +88 -0
- package/lib/video-recap/skills/video-assemble/scripts/timeline.py +248 -0
- package/lib/video-recap/skills/video-assemble/scripts/timeline_emit.py +89 -0
- package/lib/video-recap/skills/video-assemble/scripts/visual_render.py +512 -0
- package/lib/video-recap/skills/video-cut/SKILL.md +90 -0
- package/lib/video-recap/skills/video-cut/scripts/cut.py +67 -0
- package/lib/video-recap/skills/video-cut/scripts/cut_cli.py +320 -0
- package/lib/video-recap/skills/video-cut/scripts/cut_contract.py +545 -0
- package/lib/video-recap/skills/video-cut/scripts/cut_render.py +348 -0
- package/lib/video-recap/skills/video-cut/scripts/lib.py +77 -0
- package/lib/video-recap/skills/video-cut/scripts/media_geometry.py +341 -0
- package/lib/video-recap/skills/video-cut/scripts/narration_mapping.py +249 -0
- package/lib/video-recap/skills/video-cut/scripts/sentence_boundaries.py +745 -0
- package/lib/video-recap/skills/video-recap/SKILL.md +216 -0
- package/lib/video-recap/skills/video-recap/references/config-playbook.md +61 -0
- package/lib/video-recap/skills/video-recap/references/creative-editing-playbook.md +225 -0
- package/lib/video-recap/skills/video-recap/references/data-schema.md +534 -0
- package/lib/video-recap/skills/video-recap/references/research-guide.md +74 -0
- package/lib/video-recap/skills/video-recap/references/shift-left-qc-schema.md +23 -0
- package/lib/video-recap/skills/video-recap/references/timeline-and-jianying.md +251 -0
- package/lib/video-recap/skills/video-recap/scripts/doctor.py +483 -0
- package/lib/video-recap/skills/video-recap/scripts/final_qc.py +737 -0
- package/lib/video-recap/skills/video-recap/scripts/lib.py +242 -0
- package/lib/video-recap/skills/video-recap/scripts/materials.py +457 -0
- package/lib/video-recap/skills/video-recap/scripts/mimo_qc.py +95 -0
- package/lib/video-recap/skills/video-recap/scripts/mimo_qc_client.py +18 -0
- package/lib/video-recap/skills/video-recap/scripts/mimo_qc_contract.py +9 -0
- package/lib/video-recap/skills/video-recap/scripts/mimo_qc_evidence.py +371 -0
- package/lib/video-recap/skills/video-recap/scripts/mimo_qc_observations.py +201 -0
- package/lib/video-recap/skills/video-recap/scripts/mimo_qc_payload.py +227 -0
- package/lib/video-recap/skills/video-recap/scripts/mimo_qc_report.py +362 -0
- package/lib/video-recap/skills/video-recap/scripts/mimo_qc_runner.py +129 -0
- package/lib/video-recap/skills/video-recap/scripts/qc_contract.py +338 -0
- package/lib/video-recap/skills/video-recap/scripts/recap.py +9 -0
- package/lib/video-recap/skills/video-recap/scripts/recap_cli.py +140 -0
- package/lib/video-recap/skills/video-recap/scripts/recap_inspect.py +550 -0
- package/lib/video-recap/skills/video-recap/scripts/recap_review.py +77 -0
- package/lib/video-recap/skills/video-recap/scripts/recap_runner.py +654 -0
- package/lib/video-recap/skills/video-recap/scripts/recap_runtime.py +335 -0
- package/lib/video-recap/skills/video-recap/scripts/recap_stage_qc.py +217 -0
- package/lib/video-recap/skills/video-recap/scripts/recap_timeline.py +795 -0
- package/lib/video-recap/skills/video-script/SKILL.md +248 -0
- package/lib/video-recap/skills/video-script/references/creative-editing-playbook.md +225 -0
- package/lib/video-recap/skills/video-script/references/research-guide.md +75 -0
- package/lib/video-recap/skills/video-script/scripts/agent_brief.py +399 -0
- package/lib/video-recap/skills/video-script/scripts/agent_text.py +410 -0
- package/lib/video-recap/skills/video-script/scripts/brief_context.py +403 -0
- package/lib/video-recap/skills/video-script/scripts/brief_inputs.py +332 -0
- package/lib/video-recap/skills/video-script/scripts/brief_timeline.py +442 -0
- package/lib/video-recap/skills/video-script/scripts/deslop_qc.py +237 -0
- package/lib/video-recap/skills/video-script/scripts/evidence_bundle.py +492 -0
- package/lib/video-recap/skills/video-script/scripts/lib.py +327 -0
- package/lib/video-recap/skills/video-script/scripts/narration.py +12 -0
- package/lib/video-recap/skills/video-script/scripts/narration_lint.py +678 -0
- package/lib/video-recap/skills/video-script/scripts/review.py +42 -0
- package/lib/video-recap/skills/video-script/scripts/review_grounding.py +262 -0
- package/lib/video-recap/skills/video-script/scripts/review_response.py +761 -0
- package/lib/video-recap/skills/video-script/scripts/review_runner.py +200 -0
- package/lib/video-recap/skills/video-script/scripts/speech_ownership.py +204 -0
- package/lib/video-recap/skills/video-script/scripts/timeline_fusion.py +199 -0
- package/lib/video-recap/skills/video-script/scripts/validate.py +164 -0
- package/lib/video-recap/skills/video-understanding/SKILL.md +75 -0
- package/lib/video-recap/skills/video-understanding/references/data-schema.md +299 -0
- package/lib/video-recap/skills/video-understanding/references/prompt-templates.md +37 -0
- package/lib/video-recap/skills/video-understanding/references/research-guide.md +74 -0
- package/lib/video-recap/skills/video-understanding/scripts/agent_brief.py +399 -0
- package/lib/video-recap/skills/video-understanding/scripts/agent_text.py +410 -0
- package/lib/video-recap/skills/video-understanding/scripts/asr.py +260 -0
- package/lib/video-recap/skills/video-understanding/scripts/brief.py +12 -0
- package/lib/video-recap/skills/video-understanding/scripts/brief_context.py +403 -0
- package/lib/video-recap/skills/video-understanding/scripts/brief_inputs.py +332 -0
- package/lib/video-recap/skills/video-understanding/scripts/brief_timeline.py +442 -0
- package/lib/video-recap/skills/video-understanding/scripts/consolidate.py +647 -0
- package/lib/video-recap/skills/video-understanding/scripts/deslop_qc.py +237 -0
- package/lib/video-recap/skills/video-understanding/scripts/detect.py +513 -0
- package/lib/video-recap/skills/video-understanding/scripts/extract.py +62 -0
- package/lib/video-recap/skills/video-understanding/scripts/lib.py +470 -0
- package/lib/video-recap/skills/video-understanding/scripts/narration_lint.py +678 -0
- package/lib/video-recap/skills/video-understanding/scripts/speech_ownership.py +204 -0
- package/lib/video-recap/skills/video-understanding/scripts/storyboard.py +507 -0
- package/lib/video-recap/skills/video-understanding/scripts/timeline_fusion.py +199 -0
- package/lib/video-recap/skills/video-understanding/scripts/understand.py +9 -0
- package/lib/video-recap/skills/video-understanding/scripts/understanding_brief.py +216 -0
- package/lib/video-recap/skills/video-understanding/scripts/understanding_cache.py +327 -0
- package/lib/video-recap/skills/video-understanding/scripts/understanding_runner.py +367 -0
- package/lib/video-recap/skills/video-understanding/scripts/understanding_storyboard.py +162 -0
- package/lib/video-recap/skills/video-understanding/scripts/vlm.py +705 -0
- package/lib/video-recap/skills/video-voiceover/SKILL.md +81 -0
- package/lib/video-recap/skills/video-voiceover/scripts/dub.py +637 -0
- package/lib/video-recap/skills/video-voiceover/scripts/fish_audio.py +109 -0
- package/lib/video-recap/skills/video-voiceover/scripts/lib.py +421 -0
- package/lib/video-recap/skills/video-voiceover/scripts/tts_audio.py +113 -0
- package/lib/video-recap/skills/video-voiceover/scripts/voiceover.py +782 -0
- package/package.json +57 -41
- package/lib/drama/skills/short-drama/references/lifecycle-commands.md +0 -130
- package/lib/oh-story/skills/story-deslop/scripts/check-outline-copy.js +0 -241
- package/lib/oh-story/skills/story-long-write/references/format-and-structure.md +0 -169
- package/lib/oh-story/skills/story-setup/references/agent-references/genre-writing-formulas.md +0 -444
- package/lib/oh-story/skills/story-setup/references/agent-references/quality-checklist.md +0 -247
- package/lib/oh-story/skills/story-short-analyze/references/anti-ai-writing.md +0 -582
- package/lib/oh-story/skills/story-short-analyze/references/banned-words.md +0 -147
- package/lib/oh-story/skills/story-short-analyze/references/genre-catalog.md +0 -490
- package/lib/oh-story/skills/story-short-analyze/references/genre-core-mechanics.md +0 -425
- package/lib/oh-story/skills/story-short-analyze/references/genre-writing-formulas.md +0 -453
- /package/lib/oh-story/skills/{story-long-write/references/hooks-chapter.md → story-setup/references/agent-references/short-chapter-hooks.md} +0 -0
- /package/lib/oh-story/skills/{story-long-write/references/hooks-paragraph.md → story-setup/references/agent-references/short-paragraph-hooks.md} +0 -0
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""video-script validation entrypoint.
|
|
3
|
+
|
|
4
|
+
Validate an agent-written narration.json against the local understanding index.
|
|
5
|
+
Writes narration_lint.json and, in full mode, rewrites only normalized fields plus
|
|
6
|
+
the measured overlaps_speech flag; authored start/end timing is preserved exactly.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
import argparse
|
|
10
|
+
import json
|
|
11
|
+
import math
|
|
12
|
+
from pathlib import Path
|
|
13
|
+
|
|
14
|
+
from lib import CONFIG, log, stable_hash
|
|
15
|
+
from narration_lint import (
|
|
16
|
+
_validate_narration_budget,
|
|
17
|
+
validate_narration_or_raise,
|
|
18
|
+
)
|
|
19
|
+
from speech_ownership import measure_narration_speech_ownership
|
|
20
|
+
from timeline_fusion import _align_narration_to_quiet
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def _load(path):
|
|
24
|
+
path = Path(path)
|
|
25
|
+
return json.loads(path.read_text(encoding="utf-8")) if path.exists() else None
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def _load_cut_clip_plan(work_dir):
|
|
29
|
+
raw_plan = Path(work_dir) / "clip_plan.json"
|
|
30
|
+
validated_plan = Path(work_dir) / "clip_plan_validated.json"
|
|
31
|
+
if not validated_plan.exists():
|
|
32
|
+
return _load(raw_plan)
|
|
33
|
+
if not raw_plan.exists():
|
|
34
|
+
return _load(validated_plan)
|
|
35
|
+
|
|
36
|
+
raw = _load(raw_plan)
|
|
37
|
+
validated = _load(validated_plan)
|
|
38
|
+
if isinstance(validated, dict) and validated.get(
|
|
39
|
+
"raw_plan_fingerprint"
|
|
40
|
+
) == stable_hash(raw):
|
|
41
|
+
return validated
|
|
42
|
+
# Validation may run before the cut stage refreshes clip_plan_validated.json.
|
|
43
|
+
# Without a matching raw-plan provenance fingerprint, lint against the current
|
|
44
|
+
# raw plan even when mtimes are equal or misleading.
|
|
45
|
+
return raw
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def _validate_output_timeline_bounds(narration, output_duration, tolerance=0.05):
|
|
49
|
+
"""Hard-gate cut_output narration against the rendered output timeline.
|
|
50
|
+
|
|
51
|
+
cut_output narration is authored in edited_source.mp4 time. If any segment falls outside
|
|
52
|
+
that media duration, fail before TTS/render instead of spending time on unusable audio.
|
|
53
|
+
"""
|
|
54
|
+
try:
|
|
55
|
+
duration = float(output_duration)
|
|
56
|
+
except (TypeError, ValueError):
|
|
57
|
+
raise SystemExit(f"output_duration must be numeric, got {output_duration!r}")
|
|
58
|
+
if not math.isfinite(duration) or duration <= 0:
|
|
59
|
+
raise SystemExit(
|
|
60
|
+
f"output_duration must be finite and positive, got output_duration={duration:.3f}"
|
|
61
|
+
)
|
|
62
|
+
if not isinstance(narration, list):
|
|
63
|
+
return
|
|
64
|
+
|
|
65
|
+
problems = []
|
|
66
|
+
for idx, seg in enumerate(narration):
|
|
67
|
+
if not isinstance(seg, dict):
|
|
68
|
+
continue
|
|
69
|
+
try:
|
|
70
|
+
start = float(seg.get("start"))
|
|
71
|
+
end = float(seg.get("end"))
|
|
72
|
+
except (TypeError, ValueError):
|
|
73
|
+
continue
|
|
74
|
+
if not math.isfinite(start) or not math.isfinite(end):
|
|
75
|
+
problems.append(f"segment {idx} has non-finite time [{start!r},{end!r}]")
|
|
76
|
+
continue
|
|
77
|
+
if end <= -tolerance or start >= duration + tolerance:
|
|
78
|
+
problems.append(
|
|
79
|
+
f"segment {idx} [{start:.3f},{end:.3f}] fully outside output_duration={duration:.3f}"
|
|
80
|
+
)
|
|
81
|
+
continue
|
|
82
|
+
if start < -tolerance:
|
|
83
|
+
problems.append(
|
|
84
|
+
f"segment {idx} start={start:.3f} before output timeline (output_duration={duration:.3f})"
|
|
85
|
+
)
|
|
86
|
+
if end > duration + tolerance:
|
|
87
|
+
problems.append(
|
|
88
|
+
f"segment {idx} end={end:.3f} exceeds output_duration={duration:.3f}"
|
|
89
|
+
)
|
|
90
|
+
if problems:
|
|
91
|
+
raise SystemExit(
|
|
92
|
+
"cut_output narration exceeds rendered output timeline: "
|
|
93
|
+
+ "; ".join(problems)
|
|
94
|
+
)
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
def main():
|
|
98
|
+
ap = argparse.ArgumentParser(
|
|
99
|
+
description="Validate + align agent-written narration.json."
|
|
100
|
+
)
|
|
101
|
+
ap.add_argument("--work-dir", required=True)
|
|
102
|
+
ap.add_argument("--mode", default="full", choices=["full", "cut", "cut_output"])
|
|
103
|
+
ap.add_argument(
|
|
104
|
+
"--output-duration",
|
|
105
|
+
type=float,
|
|
106
|
+
default=None,
|
|
107
|
+
help="cut_output: rendered edited_source.mp4 duration in seconds",
|
|
108
|
+
)
|
|
109
|
+
args = ap.parse_args()
|
|
110
|
+
|
|
111
|
+
work_dir = Path(args.work_dir)
|
|
112
|
+
CONFIG["edit_mode"] = args.mode
|
|
113
|
+
narration_path = work_dir / "narration.json"
|
|
114
|
+
narration = _load(narration_path)
|
|
115
|
+
if narration is None:
|
|
116
|
+
raise SystemExit(f"缺少 {narration_path};请先按 video-script 规则写解说词")
|
|
117
|
+
vlm_analysis = _load(work_dir / "vlm_analysis.json")
|
|
118
|
+
silence_periods = _load(work_dir / "silence_periods.json") or []
|
|
119
|
+
if args.mode == "cut_output":
|
|
120
|
+
# Two-pass cut: narration is authored in OUTPUT time against edited_source.mp4 — there is
|
|
121
|
+
# no source-time clip membership check. Derive speech ownership from the mapped output
|
|
122
|
+
# evidence, then persist that measured flag for voiceover/assemble instead of trusting JSON.
|
|
123
|
+
narration = measure_narration_speech_ownership(
|
|
124
|
+
narration, work_dir, mode="cut_output"
|
|
125
|
+
)
|
|
126
|
+
validate_narration_or_raise(
|
|
127
|
+
narration, None, clip_plan=None, mode="cut_output", work_dir=work_dir
|
|
128
|
+
)
|
|
129
|
+
if args.output_duration is None:
|
|
130
|
+
raise SystemExit("--output-duration is required when --mode cut_output")
|
|
131
|
+
_validate_output_timeline_bounds(narration, args.output_duration)
|
|
132
|
+
narration_path.write_text(
|
|
133
|
+
json.dumps(narration, ensure_ascii=False, indent=2), encoding="utf-8"
|
|
134
|
+
)
|
|
135
|
+
elif args.mode == "cut":
|
|
136
|
+
clip_plan = _load_cut_clip_plan(work_dir)
|
|
137
|
+
validate_narration_or_raise(
|
|
138
|
+
narration, vlm_analysis, clip_plan=clip_plan, mode="cut", work_dir=work_dir
|
|
139
|
+
)
|
|
140
|
+
narration = _validate_narration_budget(narration, vlm_analysis)
|
|
141
|
+
else:
|
|
142
|
+
validate_narration_or_raise(
|
|
143
|
+
narration, vlm_analysis, clip_plan=None, mode="full", work_dir=work_dir
|
|
144
|
+
)
|
|
145
|
+
narration = _align_narration_to_quiet(narration, vlm_analysis, silence_periods)
|
|
146
|
+
narration_path.write_text(
|
|
147
|
+
json.dumps(narration, ensure_ascii=False, indent=2), encoding="utf-8"
|
|
148
|
+
)
|
|
149
|
+
|
|
150
|
+
log(f"解说词验证完成: {len(narration)} 段")
|
|
151
|
+
print(
|
|
152
|
+
json.dumps(
|
|
153
|
+
{
|
|
154
|
+
"status": "validated",
|
|
155
|
+
"segments": len(narration),
|
|
156
|
+
"lint": str(work_dir / "narration_lint.json"),
|
|
157
|
+
},
|
|
158
|
+
ensure_ascii=False,
|
|
159
|
+
)
|
|
160
|
+
)
|
|
161
|
+
|
|
162
|
+
|
|
163
|
+
if __name__ == "__main__":
|
|
164
|
+
main()
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: video-understanding
|
|
3
|
+
user-invocable: false
|
|
4
|
+
description: >
|
|
5
|
+
把视频分析为结构化理解索引:场景检测、ASR 转写、逐场景 VLM 观察、静音窗口、融合时间线和写作 brief。
|
|
6
|
+
用于理解、索引或总结视频,也作为后续创作前的分析阶段。输入视频文件;输出 scenes.json、
|
|
7
|
+
asr_result.json、vlm_analysis.json、silence_periods.json、timeline_fusion.json、agent_narration_brief.md。
|
|
8
|
+
触发词:视频理解、视频分析、视频索引、video understanding、analyze video、看懂视频。
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## 1. 定位
|
|
12
|
+
|
|
13
|
+
本技能把源视频转成 Agent 与下游阶段可读取的理解索引。它的创作角色是**素材观察员 / 场记**,不是导演:
|
|
14
|
+
|
|
15
|
+
- 先观察,再解释;事实与推断分开。
|
|
16
|
+
- 除了“发生了什么”,还要让下游看见知识、权力、目标、关系或情绪在哪一刻变化。
|
|
17
|
+
- 标出由谁的 POV 承载变化、哪个反应或表演不可替代,以及哪里存在完整台词/动作的自然剪辑边界。
|
|
18
|
+
- 证据不足时保留不确定性,不制造戏剧结论。
|
|
19
|
+
|
|
20
|
+
## 2. 处理阶段
|
|
21
|
+
|
|
22
|
+
1. **场景检测**:写 `scenes.json`,包含切点、时长和废片段过滤结果。
|
|
23
|
+
2. **抽帧**:为视觉分析提取代表帧。
|
|
24
|
+
3. **ASR**:通过 `mimo-v2.5-asr` 写时间戳对白 `asr_result.json`。
|
|
25
|
+
4. **静音检测**:写 `silence_periods.json`,标注安静窗口与 `has_speech`。
|
|
26
|
+
5. **VLM 观察**:写 `vlm_analysis.json`,包含场景描述、深层分析和 `frame_facts`。
|
|
27
|
+
6. **时间线融合与创作 brief**:写 `timeline_fusion.json`、`asr_writing_chunks.json` 和 `agent_narration_brief.md`。
|
|
28
|
+
|
|
29
|
+
各阶段只有在输出产物与 provenance sidecar 同时匹配当前视频及影响结果的设置时才会复用;`--force` 强制重算。
|
|
30
|
+
|
|
31
|
+
## 3. 环境要求
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
# ffmpeg: brew install ffmpeg | apt install ffmpeg | choco install ffmpeg
|
|
35
|
+
export MIMO_API_KEY=***
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
ASR 使用 `mimo-v2.5-asr`;VLM 使用 `mimo-v2.5`。`--skip-asr` 可跳过对白转写,但完整理解仍需要 `MIMO_API_KEY` 运行 VLM。`--mimo-video-overview` 可开启按场景块的视频概览。
|
|
39
|
+
|
|
40
|
+
若 `work_dir/background_research.json` 存在,本技能会把剧情梗概和角色名折入 VLM 上下文;`--context` 可补充一条简短提示。
|
|
41
|
+
|
|
42
|
+
下面的 `scripts/...` 均相对于本技能目录。若执行器从仓库根目录启动,请给脚本路径加上本技能的绝对目录。脚本不从其他技能目录读取文件;外部输入仅限命令显式传入的视频、参数与 `work_dir` 产物。
|
|
43
|
+
|
|
44
|
+
## 4. 运行命令
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
python3 scripts/understand.py <video> --work-dir <work_dir> \
|
|
48
|
+
[--context "节目名/角色名"] [--scene-threshold 0.1] [--skip-asr] [--mimo-video-overview] [--force]
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## 5. 输出契约
|
|
52
|
+
|
|
53
|
+
| 文件 | 内容 |
|
|
54
|
+
|------|------|
|
|
55
|
+
| `scenes.json` | 场景切点、起止时间与时长 |
|
|
56
|
+
| `asr_result.json` | `[{start, end, text}]` 时间戳对白 |
|
|
57
|
+
| `vlm_analysis.json` | 逐场景描述、深层分析与 `frame_facts` |
|
|
58
|
+
| `silence_periods.json` | `[{start, end, duration, has_speech}]` 安静窗口 |
|
|
59
|
+
| `timeline_fusion.json` | VLM、ASR 与静音信息的统一时间线 |
|
|
60
|
+
| `asr_writing_chunks.json` | 按句界和场景切分的 ASR 写作块 |
|
|
61
|
+
| `agent_narration_brief.md` | Agent 首先阅读的创作简报 |
|
|
62
|
+
|
|
63
|
+
后续写作阶段根据创作简报与索引制定方案并写 `narration.json`。
|
|
64
|
+
|
|
65
|
+
## 6. 参考资料
|
|
66
|
+
|
|
67
|
+
- 背景调研:`references/research-guide.md`,产出 `background_research.json`。
|
|
68
|
+
- JSON 结构:`references/data-schema.md`。
|
|
69
|
+
|
|
70
|
+
## 7. 能力边界
|
|
71
|
+
|
|
72
|
+
- 不写解说词,也不做解说评分;只负责生成理解索引与创作简报。
|
|
73
|
+
- 不剪辑、不配音、不合成视频。
|
|
74
|
+
- 不编造信号无法支持的剧情;当 ASR / VLM 过薄时输出素材警告。
|
|
75
|
+
- 不发布、不调度,只向 `work_dir` 写产物并停止。
|
|
@@ -0,0 +1,299 @@
|
|
|
1
|
+
# 数据格式(中间 JSON)
|
|
2
|
+
|
|
3
|
+
所有中间文件均在 pipeline 工作目录(work_dir/)下。
|
|
4
|
+
|
|
5
|
+
## vlm_analysis.json
|
|
6
|
+
|
|
7
|
+
每场景的 VLM 分析结果,数组格式:
|
|
8
|
+
|
|
9
|
+
```json
|
|
10
|
+
[
|
|
11
|
+
{
|
|
12
|
+
"scene_id": 1,
|
|
13
|
+
"start": 5.0,
|
|
14
|
+
"end": 15.0,
|
|
15
|
+
"description": "男子闯入房间",
|
|
16
|
+
"depth_analysis": "角色情绪分析...",
|
|
17
|
+
"frame_facts": {
|
|
18
|
+
"5.0": ["男子闯入房间, 头发蓬乱表情紧张"],
|
|
19
|
+
"10.0": ["男子俯身盯着床上男孩, 男孩睁眼惊醒"]
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
]
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
| 字段 | 类型 | 说明 |
|
|
26
|
+
|------|------|------|
|
|
27
|
+
| `scene_id` | int | 场景编号 |
|
|
28
|
+
| `start` | float | 开始时间(秒) |
|
|
29
|
+
| `end` | float | 结束时间(秒) |
|
|
30
|
+
| `description` | string | 画面简述(≤80字) |
|
|
31
|
+
| `depth_analysis` | string | 深层分析(情绪/关系/潜台词) |
|
|
32
|
+
| `frame_facts` | object | 帧级事实,key 为时间戳字符串 |
|
|
33
|
+
|
|
34
|
+
## asr_result.json
|
|
35
|
+
|
|
36
|
+
语音转文字结果:
|
|
37
|
+
|
|
38
|
+
```json
|
|
39
|
+
[
|
|
40
|
+
{"start": 0.0, "end": 3.5, "text": "What are you doing here?"}
|
|
41
|
+
]
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## asr_writing_chunks.json
|
|
45
|
+
|
|
46
|
+
由 CLI 在生成 `agent_narration_brief.md` 时自动写出。它把长 ASR 按句子边界拆成适合 Agent 消化的语义块;中文按字符计数,非 CJK 文本按词数计数,并尽量保留 scene 对齐。
|
|
47
|
+
|
|
48
|
+
```json
|
|
49
|
+
[
|
|
50
|
+
{
|
|
51
|
+
"chunk_id": 0,
|
|
52
|
+
"start": 0.0,
|
|
53
|
+
"end": 28.5,
|
|
54
|
+
"scene_ids": [0, 1],
|
|
55
|
+
"char_count": 642,
|
|
56
|
+
"text": "第一段对白……",
|
|
57
|
+
"segments": [
|
|
58
|
+
{"start": 0.0, "end": 3.5, "text": "第一句。", "char_count": 4}
|
|
59
|
+
]
|
|
60
|
+
}
|
|
61
|
+
]
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## silence_periods.json
|
|
65
|
+
|
|
66
|
+
静音窗口列表(适合放解说):
|
|
67
|
+
|
|
68
|
+
```json
|
|
69
|
+
[
|
|
70
|
+
{"start": 2.0, "end": 8.5, "duration": 6.5, "has_speech": false}
|
|
71
|
+
]
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
`has_speech` 标记该窗口是否与检测到的 ASR 语音重叠;下游(pipeline / narration)只把 `has_speech=false` 的窗口当作可放解说的安静窗口。
|
|
75
|
+
|
|
76
|
+
## timeline_fusion.json
|
|
77
|
+
|
|
78
|
+
由 CLI 在生成 brief 时自动写出。它把 VLM 场景、ASR 对白和静音窗口按时间轴 overlap 合并,减少写稿时手工推断“这一幕有没有对白/能不能插解说”的成本。
|
|
79
|
+
|
|
80
|
+
```json
|
|
81
|
+
[
|
|
82
|
+
{
|
|
83
|
+
"scene_id": 0,
|
|
84
|
+
"time_range": [0.0, 10.0],
|
|
85
|
+
"visual_description": "两人在门口对峙",
|
|
86
|
+
"depth_analysis": "关系紧张",
|
|
87
|
+
"frame_facts": {"1.0": ["女子回头"]},
|
|
88
|
+
"dialogue_segments": [
|
|
89
|
+
{"start": 2.0, "end": 4.0, "overlap_seconds": 2.0, "text": "你到底是谁"}
|
|
90
|
+
],
|
|
91
|
+
"dialogue_overlap_seconds": 2.0,
|
|
92
|
+
"narration_slots": [
|
|
93
|
+
{"start": 5.0, "end": 7.0, "duration": 2.0, "char_budget": 5}
|
|
94
|
+
],
|
|
95
|
+
"recommended_mode": "ducked-bed"
|
|
96
|
+
}
|
|
97
|
+
]
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
## narration.json
|
|
101
|
+
|
|
102
|
+
Agent 撰写的解说词。full 模式下使用原视频时间;**两阶段 cut 编排流程**在第二次暂停前已经剪出 `edited_source.mp4`,因此 `narration.json` 必须直接使用剪后成片的 OUTPUT 时间轴(0..成片总时长),不会再生成或消费 `narration_mapped.json`。只有旧版直接单阶段剪辑路径才会把原视频时间的 narration remap 成 `narration_mapped.json`:
|
|
103
|
+
|
|
104
|
+
```json
|
|
105
|
+
[
|
|
106
|
+
{"start": 2.5, "end": 7.0, "narration": "解说文本", "pause_after_ms": 250, "overlaps_speech": true}
|
|
107
|
+
]
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
## narration_lint.json
|
|
111
|
+
|
|
112
|
+
续跑验证 `narration.json` 时生成的预检结果。它检查写稿、时间安全和解说覆盖。`metrics` 为 full 模式下的诊断指标(cut 模式为空对象),不是要求命中某个旁白比例的创作配额;低覆盖 warning 应检查是否为有意的原声/沉默选择。
|
|
113
|
+
|
|
114
|
+
```json
|
|
115
|
+
{
|
|
116
|
+
"ok": false,
|
|
117
|
+
"error_count": 1,
|
|
118
|
+
"warning_count": 1,
|
|
119
|
+
"metrics": {
|
|
120
|
+
"segment_count": 12,
|
|
121
|
+
"narration_coverage": 0.68,
|
|
122
|
+
"narration_seconds": 61.2,
|
|
123
|
+
"timeline_seconds": 90.0,
|
|
124
|
+
"avg_block_chars": 48,
|
|
125
|
+
"original_block_count": 4
|
|
126
|
+
},
|
|
127
|
+
"errors": [
|
|
128
|
+
{"level": "error", "index": 2, "code": "time_overlap", "message": "Segment overlaps the previous narration segment"}
|
|
129
|
+
],
|
|
130
|
+
"warnings": [
|
|
131
|
+
{"level": "warning", "index": 0, "code": "over_budget", "budget_chars": 28, "actual_chars": 42}
|
|
132
|
+
]
|
|
133
|
+
}
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
常见 code:`invalid_time`、`empty_narration`、`time_overlap`、`outside_clip_plan`、`over_budget`、`incomplete_sentence`、`slot_too_short`、`under_narrated`、`over_narrated`、`fragmented_beats`、`no_original_blocks`。
|
|
137
|
+
|
|
138
|
+
## style_card.json(Agent 撰写,可选/按 brief 要求)
|
|
139
|
+
|
|
140
|
+
`style_card.json` 是表达层契约:由 Agent 根据 `--style`、`--context`、素材证据、ASR 和用户偏好信号综合撰写。`--style` 是 freeform verbatim guidance(原样自由文本指导),不是枚举、preset、switch,也不是一组可穷举风格名;不要把它翻译成固定档位。它是当前版本的活动契约:用户对声音、节奏、字幕阅读或禁忌提出新反馈后,更新原文件并移除过期偏好,不要只改 `narration.json`。
|
|
141
|
+
|
|
142
|
+
这个文件记录声音、节奏、回收意图和证据支撑的表达判断;字段可以随项目增减,下游只把它当 JSON object 读取,不要求固定键名。它不负责标题、封面、首句承诺或卖点包装。
|
|
143
|
+
|
|
144
|
+
```json
|
|
145
|
+
{
|
|
146
|
+
"voice": "冷静但有压迫感,少讲大道理,多用人物动作和台词里的证据推进",
|
|
147
|
+
"pacing": "前 15 秒紧凑建立冲突,每个 beat 连续说完一个思路;中段留原声喘息,结尾回收开头疑问",
|
|
148
|
+
"payoff_intent": "让观众先看到误会,再看到人物选择的代价",
|
|
149
|
+
"subtitle_read_posture": "TTS 保持连续口语,字幕按阅读宽度拆 cue,不用字幕换行切碎朗读",
|
|
150
|
+
"evidence_intent": ["优先引用画面动作", "关键转折保留原声"]
|
|
151
|
+
}
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
## packaging_plan.json(Agent 撰写,可选)
|
|
155
|
+
|
|
156
|
+
`packaging_plan.json` 是内容锁定后的可选包装层契约:标题、封面帧/视觉钩子、首句、观众承诺、卖点和发布包装信息。它帮助 review 判断“包装承诺”和正文前 15 秒是否对齐;不应反过来驱动故事取舍。
|
|
157
|
+
|
|
158
|
+
它不是文风策略,不覆盖 `style_card.json` 的声音、节奏或表达规则;如果包装需要某个承诺,正文仍要用素材证据兑现。
|
|
159
|
+
|
|
160
|
+
```json
|
|
161
|
+
{
|
|
162
|
+
"title": "一句能对外展示的标题",
|
|
163
|
+
"cover_frame": {"time": 12.4, "reason": "人物第一次正面做出关键选择"},
|
|
164
|
+
"first_line": "开场第一句解说",
|
|
165
|
+
"viewer_promise": "观众看完会明白的冲突/反转/信息增量",
|
|
166
|
+
"selling_points": ["强冲突", "原声高光"],
|
|
167
|
+
"packaging_notes": "发布侧备注,不写文风规则"
|
|
168
|
+
}
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
## deslop_qc_requirements.json(工具/brief 生成的运行契约)
|
|
172
|
+
|
|
173
|
+
`deslop_qc_requirements.json` 是 tool/brief generated run contract:工具或 brief 生成本次运行的 QC 要求,供 `deslop_qc` 读取,不由 Agent 手写。字段为 `schema_version` 与 `style_card_required`。
|
|
174
|
+
|
|
175
|
+
`style_card_required` 默认 `false`(advisory):缺少 `style_card.json` 只是 warning,不阻断出片。将来的 opt-in 运行可把它设为 `true`,让 `style_card.json` 成为硬性要求——`deslop_qc` 只读这个字段判断缺少 `style_card.json` 是否是 blocker,不扫描 `agent_narration_brief.md` 的 prompt wording 来推断。如果 requirements 文件缺失或损坏,按 legacy/migration advisory 处理,不作为 hard failure。
|
|
176
|
+
|
|
177
|
+
该契约不改变 `--style`:`--style` 仍是 freeform verbatim guidance,不增加固定风格档位。它也不改变 `deslop_qc` 边界:仍然是 report-only,不是 AIGC detector,不自动改写。
|
|
178
|
+
|
|
179
|
+
最小示例:
|
|
180
|
+
|
|
181
|
+
```json
|
|
182
|
+
{
|
|
183
|
+
"schema_version": 1,
|
|
184
|
+
"style_card_required": false
|
|
185
|
+
}
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
## deslop_qc.json(CLI 生成,报告型 QC)
|
|
189
|
+
|
|
190
|
+
`deslop_qc.json` 由本地 deterministic scanner 生成,Agent 不手写。它只是 report-only QC:不是 AIGC detector,不判断文本是不是 AI 写的,不会自动改写。修改仍由 Agent/人工根据报告回到 `narration.json`、`style_card.json` 或字幕源里处理。
|
|
191
|
+
|
|
192
|
+
报告分两层:
|
|
193
|
+
|
|
194
|
+
- `blockers`:客观阻断项,会并入 `narration_lint.json` 的 error,例如 requirements 要求但缺少/损坏 `style_card.json`、破折号、占位符泄漏。
|
|
195
|
+
- `advisories`:建议项,只提示可读性/口语化风险,例如模板化“不是……而是……”转折、套话密度、抽象总结词、解释链、比喻标记、过长段落;它们不自动阻断,也不自动改写。
|
|
196
|
+
|
|
197
|
+
```json
|
|
198
|
+
{
|
|
199
|
+
"ok": false,
|
|
200
|
+
"contract": "Local readability/QC report only: this is not an AIGC detector, does not claim AI-generation accuracy, and never rewrites text. Corrections remain human/agent rewrite work.",
|
|
201
|
+
"scanner": "deslop_qc.py",
|
|
202
|
+
"style_card_required": true,
|
|
203
|
+
"blocker_count": 1,
|
|
204
|
+
"advisory_count": 1,
|
|
205
|
+
"blockers": [
|
|
206
|
+
{"severity": "blocker", "code": "missing_style_card", "source": "style_card", "index": null, "message": "style_card.json is required by this expression/packaging run but is missing"}
|
|
207
|
+
],
|
|
208
|
+
"advisories": [
|
|
209
|
+
{"severity": "advisory", "code": "cliche_density", "source": "narration", "index": null, "message": "套话/高频抽象词偏密,建议换成具体行动、选择和后果"}
|
|
210
|
+
],
|
|
211
|
+
"metrics": {"segments_scanned": 12, "text_units": 860, "sentence_count": 38}
|
|
212
|
+
}
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
## clip_plan.json
|
|
216
|
+
|
|
217
|
+
cut 模式下 Agent 选择要保留的原片片段,数组或 `{ "clips": [...] }` 都可接受。默认片段不能重叠,避免同一原片时间映射到多个输出位置:
|
|
218
|
+
|
|
219
|
+
```json
|
|
220
|
+
{
|
|
221
|
+
"target_duration": "10m",
|
|
222
|
+
"clips": [
|
|
223
|
+
{"start": 12.0, "end": 38.0, "reason": "b01 | hook | knowledge: unknown→threat | POV=主角 | 保留倾听反应 | 入点=问题已问出 | 出点=沉默落地"}
|
|
224
|
+
]
|
|
225
|
+
}
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
| 字段 | 类型 | 说明 |
|
|
229
|
+
|------|------|------|
|
|
230
|
+
| `start` | float | 原视频片段开始秒数 |
|
|
231
|
+
| `end` | float | 原视频片段结束秒数 |
|
|
232
|
+
| `reason` | string | 选择该片段的剧情/信息原因 |
|
|
233
|
+
|
|
234
|
+
## clip_plan_validated.json
|
|
235
|
+
|
|
236
|
+
CLI 校验 `clip_plan.json` 后写出,额外包含输出时间轴:
|
|
237
|
+
|
|
238
|
+
```json
|
|
239
|
+
{
|
|
240
|
+
"clips": [
|
|
241
|
+
{
|
|
242
|
+
"clip_id": 0,
|
|
243
|
+
"source_start": 12.0,
|
|
244
|
+
"source_end": 38.0,
|
|
245
|
+
"output_start": 0.0,
|
|
246
|
+
"output_end": 26.0,
|
|
247
|
+
"duration": 26.0,
|
|
248
|
+
"reason": "b01 | hook | knowledge: unknown→threat | POV=主角 | 保留倾听反应 | 入点=问题已问出 | 出点=沉默落地"
|
|
249
|
+
}
|
|
250
|
+
],
|
|
251
|
+
"total_duration": 26.0,
|
|
252
|
+
"target_duration": 600.0
|
|
253
|
+
}
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
## narration_mapped.json
|
|
257
|
+
|
|
258
|
+
仅旧版直接单阶段剪辑路径会生成。两阶段 cut 编排流程不使用它:Agent 在第二阶段直接按剪后成片 OUTPUT 时间轴写 `narration.json`。启用旧版路径时,`start/end` 已变成短视频输出时间,`source_start/source_end` 保留原视频时间:
|
|
259
|
+
|
|
260
|
+
```json
|
|
261
|
+
[
|
|
262
|
+
{
|
|
263
|
+
"start": 2.0,
|
|
264
|
+
"end": 7.0,
|
|
265
|
+
"source_start": 14.0,
|
|
266
|
+
"source_end": 19.0,
|
|
267
|
+
"source_clip_id": 0,
|
|
268
|
+
"narration": "解说文本"
|
|
269
|
+
}
|
|
270
|
+
]
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
## background_research.json
|
|
274
|
+
|
|
275
|
+
可选的背景调研结果(由 Agent 使用任意可用搜索/浏览方式整理):
|
|
276
|
+
|
|
277
|
+
```json
|
|
278
|
+
{
|
|
279
|
+
"synopsis": "剧情概要",
|
|
280
|
+
"characters": {"角色名": "角色简介"},
|
|
281
|
+
"worldbuilding": "世界观设定",
|
|
282
|
+
"episode_context": "集数上下文",
|
|
283
|
+
"character_details": {
|
|
284
|
+
"角色名": {
|
|
285
|
+
"aliases": ["别名/昵称"],
|
|
286
|
+
"role": "主角|配角|反派|次要角色",
|
|
287
|
+
"relationships": ["与XX是夫妻", "与YY是师徒"]
|
|
288
|
+
}
|
|
289
|
+
},
|
|
290
|
+
"plot_arcs": [
|
|
291
|
+
{"name": "线索名称", "description": "简要描述", "status": "进行中|已解决|伏笔"}
|
|
292
|
+
],
|
|
293
|
+
"cultural_notes": [
|
|
294
|
+
{"item": "文化梗/典故/时代背景", "explanation": "解释"}
|
|
295
|
+
]
|
|
296
|
+
}
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
> `character_details`、`plot_arcs`、`cultural_notes` 为(可选,新增)字段。仅含 `synopsis`、`characters`、`worldbuilding`、`episode_context` 四个原始字段的旧 JSON 仍然有效。
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# Prompt 模板
|
|
2
|
+
|
|
3
|
+
> 本文件被 `load_prompt()` 按 `### NAME` 切片读取。当前 CLI 只读取 VLM 模板;解说词由 Agent 根据 `agent_narration_brief.md` 撰写。
|
|
4
|
+
|
|
5
|
+
## 目录
|
|
6
|
+
|
|
7
|
+
| 模板名 | 用途 | 使用阶段 |
|
|
8
|
+
|--------|------|----------|
|
|
9
|
+
| VLM_DEPTH_PROMPT | 场景画面深度分析 | VLM 分析 |
|
|
10
|
+
|
|
11
|
+
### VLM_DEPTH_PROMPT
|
|
12
|
+
仔细观察这些视频帧,分析这个场景。分三部分输出:
|
|
13
|
+
|
|
14
|
+
【描述】
|
|
15
|
+
不超过80字,描述画面中正在发生什么(场景、人物、动作、表情、文字、事件)。
|
|
16
|
+
|
|
17
|
+
【帧标签】
|
|
18
|
+
逐帧列出每帧可见的人物动作和物品关系。每帧一行,格式:
|
|
19
|
+
时间点 | 该帧可见的关键动作(1-2个完整短句,包含谁在做什么、物品如何被使用,如有字幕/文字也一并列出)
|
|
20
|
+
示例:
|
|
21
|
+
5.0s | 男子闯入房间, 头发蓬乱表情紧张
|
|
22
|
+
10.0s | 男子俯身盯着床上男孩, 男孩睁眼惊醒
|
|
23
|
+
15.0s | 男孩从床上坐起双手抱住头上的瓷枕准备防御
|
|
24
|
+
|
|
25
|
+
【深层分析】
|
|
26
|
+
不超过180字,分析:
|
|
27
|
+
1. 角色的真实情绪或心理状态(通过表情、肢体语言、眼神判断)
|
|
28
|
+
2. 人物之间的关系动态(亲密、紧张、疏离、试探等)
|
|
29
|
+
3. 从场景开头到结尾发生了什么变化(知识、权力、目标、关系或情绪)
|
|
30
|
+
4. 谁的视角最能承载这次变化;说话者、倾听者或旁观者中,谁的反应最值得保留
|
|
31
|
+
5. 对话背后的潜台词(他们没说出口但由可见证据支持的东西)
|
|
32
|
+
|
|
33
|
+
要求:
|
|
34
|
+
- 必须基于画面可见的证据推断,不做无根据的猜测
|
|
35
|
+
- 不要用"象征""隐喻"等文学词汇
|
|
36
|
+
- 用口语化表达:"他明显是在试探她的反应"
|
|
37
|
+
- 如果画面信息不足,直接说"信息不足"
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
# 背景调研指南(可选)
|
|
2
|
+
|
|
3
|
+
Agent 在跑视频理解(video-understanding)**之前**先做背景调研,确认作品名、角色关系、剧情背景或科普概念,写入 `work_dir/background_research.json`。理解阶段会把它并入 VLM 的画面分析上下文,让场景描述能直接叫出人物名字、带着剧情读画面,而不是把人都标成「黑衣男子」。**调研不是必需步骤**;没有浏览器工具、网络不可用或用户未提供明确片名时,直接跳过,不阻塞视频生成。
|
|
4
|
+
|
|
5
|
+
## 工具选择
|
|
6
|
+
|
|
7
|
+
使用当前环境里可用的任意检索方式即可,例如:
|
|
8
|
+
|
|
9
|
+
- Codex / Claude 自带的联网搜索或网页浏览工具
|
|
10
|
+
- 用户已经配置好的浏览器自动化或页面读取工具
|
|
11
|
+
- 普通浏览器手动查找后把结果整理进 JSON
|
|
12
|
+
- 已知资料、用户给的剧情背景或项目内已有文档
|
|
13
|
+
|
|
14
|
+
## 通用流程
|
|
15
|
+
|
|
16
|
+
1. 从 `--context`、文件名或用户描述里提取可搜索关键词。
|
|
17
|
+
2. 搜索 1-3 个高价值问题,不要过度调研。
|
|
18
|
+
3. 只记录对解说有帮助的事实:人物关系、剧情前提、世界观、当前集上下文、术语解释。
|
|
19
|
+
4. 写入 `work_dir/background_research.json`。
|
|
20
|
+
5. 如果查不到可靠信息,跳过并继续写 `narration.json`。
|
|
21
|
+
|
|
22
|
+
## 按视频类型搜索策略
|
|
23
|
+
|
|
24
|
+
### 短剧 / 电视剧
|
|
25
|
+
|
|
26
|
+
| 搜索关键词 | 目标字段 |
|
|
27
|
+
|-----------|---------|
|
|
28
|
+
| `{作品名} 剧情 介绍 人物` | synopsis, characters |
|
|
29
|
+
| `{作品名} 人物 关系` | characters |
|
|
30
|
+
| `{作品名} 第{N}集 剧情` | episode_context |
|
|
31
|
+
|
|
32
|
+
### 电影
|
|
33
|
+
|
|
34
|
+
| 搜索关键词 | 目标字段 |
|
|
35
|
+
|-----------|---------|
|
|
36
|
+
| `{电影名} 剧情 简介` | synopsis |
|
|
37
|
+
| `{电影名} 影评 解读` | cultural_notes |
|
|
38
|
+
|
|
39
|
+
### 纪录片 / 科普视频
|
|
40
|
+
|
|
41
|
+
| 搜索关键词 | 目标字段 |
|
|
42
|
+
|-----------|---------|
|
|
43
|
+
| `{主题} 背景 知识` | worldbuilding |
|
|
44
|
+
| `{核心概念} 解释` | synopsis |
|
|
45
|
+
| `{主题} 最新 进展` | cultural_notes |
|
|
46
|
+
|
|
47
|
+
## 写入格式
|
|
48
|
+
|
|
49
|
+
写入 `work_dir/background_research.json`,只填搜到的字段,未搜到的字段省略,不要写 `null` 或空字符串。
|
|
50
|
+
|
|
51
|
+
```json
|
|
52
|
+
{
|
|
53
|
+
"synopsis": "...",
|
|
54
|
+
"characters": {
|
|
55
|
+
"角色名": "简介或关系"
|
|
56
|
+
},
|
|
57
|
+
"worldbuilding": "...",
|
|
58
|
+
"episode_context": "...",
|
|
59
|
+
"cultural_notes": [
|
|
60
|
+
{"item": "...", "explanation": "..."}
|
|
61
|
+
]
|
|
62
|
+
}
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## 错误处理
|
|
66
|
+
|
|
67
|
+
| 场景 | 处理 |
|
|
68
|
+
|------|------|
|
|
69
|
+
| 没有浏览器 / 搜索工具 | 跳过调研,直接写解说词 |
|
|
70
|
+
| 搜索无结果 | 换一组关键词重试一次,仍无结果则跳过 |
|
|
71
|
+
| 结果互相矛盾 | 只使用用户提供的上下文或画面/ASR 可验证的信息 |
|
|
72
|
+
| 信息可能剧透后续 | 只用于理解人物关系,不在解说里剧透用户没要求的后续剧情 |
|
|
73
|
+
|
|
74
|
+
**原则**:背景资料只能补上下文,不能替代 `vlm_analysis.json` / `asr_result.json` 里的画面和对白证据。
|