@oh-story/dsh 0.1.8 → 0.1.10
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 +14 -14
- package/lib/client.js +237 -84
- package/lib/client.js.map +3 -3
- package/lib/drama/manifest.json +183 -77
- package/lib/drama/skills/short-drama/SKILL.md +5 -1
- package/lib/drama/skills/short-drama/scripts/creator_markdown_check.py +140 -9
- package/lib/drama/skills/short-drama/scripts/project_tool.py +11 -0
- package/lib/drama/skills/short-drama-assets/references/character-and-look.md +28 -0
- package/lib/drama/skills/short-drama-assets/references/continuity-lock.md +8 -2
- package/lib/drama/skills/short-drama-assets/references/voice-direction.md +28 -0
- package/lib/drama/skills/short-drama-edit/SKILL.md +146 -0
- package/lib/drama/skills/short-drama-edit/agents/openai.yaml +4 -0
- package/lib/drama/skills/short-drama-edit/assets/remotion/README.md +60 -0
- package/lib/drama/skills/short-drama-edit/assets/remotion/package.json +15 -0
- package/lib/drama/skills/short-drama-edit/assets/remotion/remotion.config.ts +6 -0
- package/lib/drama/skills/short-drama-edit/assets/remotion/src/Root.tsx +26 -0
- package/lib/drama/skills/short-drama-edit/assets/remotion/src/Subtitles.tsx +88 -0
- package/lib/drama/skills/short-drama-edit/assets/remotion/src/font.ts +46 -0
- package/lib/drama/skills/short-drama-edit/assets/remotion/src/index.ts +4 -0
- package/lib/drama/skills/short-drama-edit/assets/remotion/src/schema.ts +32 -0
- package/lib/drama/skills/short-drama-edit/assets/remotion/tsconfig.json +13 -0
- package/lib/drama/skills/short-drama-edit/assets//345/211/252/350/276/221/345/215/225.md +43 -0
- package/lib/drama/skills/short-drama-edit/references/cut-craft.md +38 -0
- package/lib/drama/skills/short-drama-edit/references/delivery-verify.md +29 -0
- package/lib/drama/skills/short-drama-edit/references/generated-footage.md +54 -0
- package/lib/drama/skills/short-drama-edit/references/sound-and-subtitles.md +60 -0
- package/lib/drama/skills/short-drama-edit/references/stage-contract.md +51 -0
- package/lib/drama/skills/short-drama-edit/scripts/edit_tool.py +1156 -0
- package/lib/drama/skills/short-drama-edit/scripts/selftest.py +520 -0
- package/lib/drama/skills/short-drama-image-prompts/SKILL.md +2 -0
- package/lib/drama/skills/short-drama-image-prompts/assets/image-prompts.md +5 -0
- package/lib/drama/skills/short-drama-image-prompts/assets/lookdev-prompts.md +3 -0
- package/lib/drama/skills/short-drama-image-prompts/references/common-recipe.md +11 -0
- package/lib/drama/skills/short-drama-novel-analyze/references/aggregation-and-entities.md +2 -2
- package/lib/drama/skills/short-drama-novel-analyze/references/chapter-extraction.md +4 -1
- package/lib/drama/skills/short-drama-produce/SKILL.md +29 -4
- package/lib/drama/skills/short-drama-produce/references/adapter-contract.md +22 -0
- package/lib/drama/skills/short-drama-produce/references/providers/minimax-h3-video.md +13 -12
- package/lib/drama/skills/short-drama-produce/references/providers/minimax-speech.md +41 -0
- package/lib/drama/skills/short-drama-produce/references/providers/seedance.md +7 -0
- package/lib/drama/skills/short-drama-produce/scripts/fixture_adapter.py +18 -1
- package/lib/drama/skills/short-drama-produce/scripts/production_tool.py +181 -2
- package/lib/drama/skills/short-drama-produce/scripts/provider_adapters.py +199 -3
- package/lib/drama/skills/short-drama-review/SKILL.md +2 -0
- package/lib/drama/skills/short-drama-review/references/production-quality-gates.md +7 -0
- package/lib/drama/skills/short-drama-review/references/rubric-visual-motion.md +10 -0
- package/lib/drama/skills/short-drama-storyboard/SKILL.md +12 -1
- package/lib/drama/skills/short-drama-storyboard/assets/keyframe-prompts.md +4 -0
- package/lib/drama/skills/short-drama-storyboard/references/lighting-craft.md +39 -0
- package/lib/drama/skills/short-drama-storyboard/references/shot-craft.md +78 -2
- package/lib/drama/skills/short-drama-storyboard/references/stage-contract.md +2 -0
- package/lib/drama/skills/short-drama-video-prompts/SKILL.md +12 -5
- package/lib/drama/skills/short-drama-video-prompts/references/camera-audio-continuity.md +17 -0
- package/lib/drama/skills/short-drama-video-prompts/references/minimax-h3.md +76 -7
- package/lib/drama/skills/short-drama-video-prompts/references/motion-recipe.md +5 -2
- package/lib/drama/skills/short-drama-video-prompts/references/performance-action-timing.md +21 -0
- package/lib/drama/skills/short-drama-video-prompts/references/production-prompt-grammar.md +6 -17
- package/lib/drama/skills/short-drama-video-prompts/references/seedance-2.0.md +12 -3
- package/lib/drama/skills/short-drama-video-prompts/references/seedance-2.5.md +61 -5
- package/lib/drama/skills/short-drama-video-prompts/references/stage-contract.md +3 -3
- package/lib/drama/skills/short-drama-write/SKILL.md +11 -2
- package/lib/drama/skills/short-drama-write/references/screenplay-format.md +6 -0
- package/lib/drama/skills/short-drama-write/references/stage-contract.md +1 -0
- package/lib/index.js +290 -90
- package/lib/index.js.map +4 -4
- package/lib/novel-to-game/README.md +299 -59
- package/lib/novel-to-game/README_ZH.md +299 -56
- package/lib/novel-to-game/VERSION +1 -1
- package/lib/novel-to-game/examples/jin-ping-mei/build/BUILD_BRIEF.md +3 -1
- package/lib/novel-to-game/examples/jin-ping-mei/build/app/RUN.md +11 -3
- package/lib/novel-to-game/examples/jin-ping-mei/build/app/css/new-guofeng.css +397 -8
- package/lib/novel-to-game/examples/jin-ping-mei/build/app/css/style.css +0 -31
- package/lib/novel-to-game/examples/jin-ping-mei/build/app/js/data.js +71 -73
- package/lib/novel-to-game/examples/jin-ping-mei/build/app/js/engine.js +78 -89
- package/lib/novel-to-game/examples/jin-ping-mei/build/app/js/main.js +37 -14
- package/lib/novel-to-game/examples/jin-ping-mei/build/app/js/text.js +5 -5
- package/lib/novel-to-game/examples/jin-ping-mei/build/app/package.json +2 -1
- package/lib/novel-to-game/examples/jin-ping-mei/qa/README.md +11 -16
- package/lib/novel-to-game/examples/jin-ping-mei/qa/verification.json +11 -11
- package/lib/novel-to-game/examples/jin-ping-mei/qa/verify_playable_model.mjs +23 -0
- package/lib/novel-to-game/manifest.json +77 -87
- package/lib/novel-to-game/skills/game-art-direction/SKILL.md +9 -35
- package/lib/novel-to-game/skills/game-art-direction/references/art-direction-method.md +27 -106
- package/lib/novel-to-game/skills/game-build/SKILL.md +17 -35
- package/lib/novel-to-game/skills/game-build/references/blender-asset-workflow.md +24 -0
- package/lib/novel-to-game/skills/game-build/references/build-brief-contract.md +45 -82
- package/lib/novel-to-game/skills/game-build/references/generative-media-pipeline.md +14 -45
- package/lib/novel-to-game/skills/game-build/references/playable-model-contract.md +30 -65
- package/lib/novel-to-game/skills/game-build/references/tts-production-contract.md +13 -27
- package/lib/novel-to-game/skills/game-concept/SKILL.md +16 -34
- package/lib/novel-to-game/skills/game-concept/references/concept-method.md +28 -75
- package/lib/novel-to-game/skills/game-qa/SKILL.md +9 -20
- package/lib/novel-to-game/skills/game-qa/references/test-design-method.md +10 -6
- package/lib/novel-to-game/skills/game-world-design/SKILL.md +19 -32
- package/lib/novel-to-game/skills/game-world-design/references/narrative-design-method.md +23 -72
- package/lib/novel-to-game/skills/game-world-design/references/numeric-design-method.md +14 -48
- package/lib/novel-to-game/skills/game-world-design/references/world-design-method.md +36 -103
- package/lib/novel-to-game/skills/novel-game-analyze/SKILL.md +9 -18
- package/lib/novel-to-game/skills/novel-game-analyze/references/gameability-protocol.md +4 -4
- package/lib/novel-to-game/skills/novel-to-game/SKILL.md +10 -27
- package/lib/novel-to-game/skills/novel-to-game/references/intake-method.md +5 -6
- package/lib/novel-to-game/skills/novel-to-game/references/pipeline-contract.md +6 -11
- package/lib/oh-story/manifest.json +419 -254
- package/lib/oh-story/roles/chapter-extractor.md +177 -237
- package/lib/oh-story/roles/character-designer.md +1 -1
- package/lib/oh-story/roles/consistency-checker.md +4 -4
- package/lib/oh-story/roles/narrative-writer.md +56 -243
- package/lib/oh-story/roles/story-architect.md +6 -6
- package/lib/oh-story/roles/story-explorer.md +11 -11
- package/lib/oh-story/skills/story/SKILL.md +13 -7
- package/lib/oh-story/skills/story/VERSION +1 -1
- package/lib/oh-story/skills/story/references/author-memory.md +61 -29
- package/lib/oh-story/skills/story/scripts/author_memory_commit.py +934 -170
- package/lib/oh-story/skills/story-cover/SKILL.md +10 -1
- package/lib/oh-story/skills/story-deslop/SKILL.md +54 -229
- package/lib/oh-story/skills/story-deslop/references/anti-ai-writing.md +29 -56
- package/lib/oh-story/skills/story-deslop/references/author-memory.md +61 -29
- package/lib/oh-story/skills/story-deslop/references/banned-words.md +3 -1
- package/lib/oh-story/skills/story-deslop/references/deslop-gates.md +154 -0
- package/lib/oh-story/skills/story-deslop/references/style-resolution.md +27 -0
- package/lib/oh-story/skills/story-deslop/scripts/author_memory_commit.py +934 -170
- package/lib/oh-story/skills/story-deslop/scripts/check-ai-patterns.js +6 -1
- package/lib/oh-story/skills/story-deslop/scripts/check-degeneration.js +39 -20
- package/lib/oh-story/skills/story-deslop/scripts/normalize-punctuation.js +10 -5
- package/lib/oh-story/skills/story-deslop/scripts/style-whitelist.js +39 -0
- package/lib/oh-story/skills/story-import/SKILL.md +78 -82
- package/lib/oh-story/skills/story-import/references/character-state-reverse.md +1 -1
- package/lib/oh-story/skills/story-import/references/format-and-structure.md +2 -2
- package/lib/oh-story/skills/story-import/references/state-tracking.md +4 -69
- package/lib/oh-story/skills/story-import/references/structure-mapping-long.md +10 -8
- package/lib/oh-story/skills/story-import/references/tracking-initialization.md +31 -0
- package/lib/oh-story/skills/story-import/references/tracking-transaction.md +9 -34
- package/lib/oh-story/skills/story-import/scripts/check-outline-contract.js +197 -15
- package/lib/oh-story/skills/story-import/scripts/tracking_commit.py +210 -2
- package/lib/oh-story/skills/story-import/scripts/wordcount_core.py +3 -0
- package/lib/oh-story/skills/story-long-analyze/SKILL.md +91 -258
- package/lib/oh-story/skills/story-long-analyze/references/author-facing.md +245 -0
- package/lib/oh-story/skills/story-long-analyze/references/deconstruction-notes.md +2 -2
- package/lib/oh-story/skills/story-long-analyze/references/inspiration-library.md +105 -0
- package/lib/oh-story/skills/story-long-analyze/references/material-decomposition.md +113 -105
- package/lib/oh-story/skills/story-long-analyze/references/output-templates.md +169 -125
- package/lib/oh-story/skills/story-long-analyze/references/pipeline-ops.md +172 -64
- package/lib/oh-story/skills/story-long-analyze/references/semantic-acceptance-fixtures.md +84 -0
- package/lib/oh-story/skills/story-long-analyze/references/style-profile-generator.md +42 -132
- package/lib/oh-story/skills/story-long-analyze/references/style-profile-protocol.md +5 -5
- package/lib/oh-story/skills/story-long-analyze/scripts/build_chapter_index.py +466 -0
- package/lib/oh-story/skills/story-long-analyze/scripts/inspect_existing_assets.py +702 -0
- package/lib/oh-story/skills/story-long-analyze/scripts/inspiration_index.py +864 -0
- package/lib/oh-story/skills/story-long-analyze/scripts/manage_analysis_run.py +1106 -0
- package/lib/oh-story/skills/story-long-analyze/scripts/render_relation_chart.py +425 -0
- package/lib/oh-story/skills/story-long-scan/SKILL.md +4 -1
- package/lib/oh-story/skills/story-long-write/SKILL.md +52 -216
- package/lib/oh-story/skills/story-long-write/references/anti-ai-writing.md +29 -56
- package/lib/oh-story/skills/story-long-write/references/artifact-protocols.md +72 -12
- package/lib/oh-story/skills/story-long-write/references/author-memory.md +61 -29
- package/lib/oh-story/skills/story-long-write/references/banned-words.md +3 -1
- package/lib/oh-story/skills/story-long-write/references/benchmark-recall.md +20 -0
- package/lib/oh-story/skills/story-long-write/references/cross-book-recall.md +26 -0
- package/lib/oh-story/skills/story-long-write/references/dialogue-mastery.md +10 -4
- package/lib/oh-story/skills/story-long-write/references/emotional-methods.md +2 -2
- package/lib/oh-story/skills/story-long-write/references/long-chapter-quality.md +6 -15
- package/lib/oh-story/skills/story-long-write/references/long-format.md +2 -0
- package/lib/oh-story/skills/story-long-write/references/outline-structure-theory.md +2 -0
- package/lib/oh-story/skills/story-long-write/references/project-files.md +110 -0
- package/lib/oh-story/skills/story-long-write/references/reader-contract-and-progression.md +12 -4
- package/lib/oh-story/skills/story-long-write/references/reference-index.md +86 -0
- package/lib/oh-story/skills/story-long-write/references/style-combat-face.md +1 -1
- package/lib/oh-story/skills/story-long-write/references/style-craft.md +9 -29
- package/lib/oh-story/skills/story-long-write/references/style-genre-modules.md +1 -1
- package/lib/oh-story/skills/story-long-write/references/style-resolution.md +27 -0
- package/lib/oh-story/skills/story-long-write/references/tracking-initialization.md +31 -0
- package/lib/oh-story/skills/story-long-write/references/tracking-transaction.md +9 -34
- package/lib/oh-story/skills/story-long-write/references/workflow-chapter.md +88 -118
- package/lib/oh-story/skills/story-long-write/references/workflow-daily.md +55 -119
- package/lib/oh-story/skills/story-long-write/references/workflow-revision.md +15 -11
- package/lib/oh-story/skills/story-long-write/references/workflow-setup.md +73 -54
- package/lib/oh-story/skills/story-long-write/references/writer-prompt-fallback.md +22 -0
- package/lib/oh-story/skills/story-long-write/references/writing-craft.md +63 -4
- package/lib/oh-story/skills/story-long-write/scripts/author_memory_commit.py +934 -170
- package/lib/oh-story/skills/story-long-write/scripts/build_writer_prompt.py +531 -0
- package/lib/oh-story/skills/story-long-write/scripts/check-ai-patterns.js +6 -1
- package/lib/oh-story/skills/story-long-write/scripts/check-degeneration.js +39 -20
- package/lib/oh-story/skills/story-long-write/scripts/check-outline-contract.js +197 -15
- package/lib/oh-story/skills/story-long-write/scripts/check-outline-copy.js +90 -23
- package/lib/oh-story/skills/story-long-write/scripts/normalize-punctuation.js +10 -5
- package/lib/oh-story/skills/story-long-write/scripts/outline_view.py +285 -0
- package/lib/oh-story/skills/story-long-write/scripts/storyctl.py +58 -0
- package/lib/oh-story/skills/story-long-write/scripts/style-whitelist.js +39 -0
- package/lib/oh-story/skills/story-long-write/scripts/tracking_commit.py +210 -2
- package/lib/oh-story/skills/story-long-write/scripts/wordcount_core.py +3 -0
- package/lib/oh-story/skills/story-review/SKILL.md +80 -87
- package/lib/oh-story/skills/story-review/references/anti-ai-writing.md +29 -56
- package/lib/oh-story/skills/story-review/references/author-memory.md +61 -29
- package/lib/oh-story/skills/story-review/references/banned-words.md +3 -1
- package/lib/oh-story/skills/story-review/references/dialogue-mastery.md +10 -4
- package/lib/oh-story/skills/story-review/references/review-quality.md +6 -12
- package/lib/oh-story/skills/story-review/references/style-resolution.md +27 -0
- package/lib/oh-story/skills/story-review/references/tracking-initialization.md +31 -0
- package/lib/oh-story/skills/story-review/references/tracking-transaction.md +9 -34
- package/lib/oh-story/skills/story-review/scripts/author_memory_commit.py +934 -170
- package/lib/oh-story/skills/story-review/scripts/check-ai-patterns.js +6 -1
- package/lib/oh-story/skills/story-review/scripts/check-degeneration.js +39 -20
- package/lib/oh-story/skills/story-review/scripts/normalize-punctuation.js +10 -5
- package/lib/oh-story/skills/story-review/scripts/style-whitelist.js +39 -0
- package/lib/oh-story/skills/story-review/scripts/tracking_commit.py +210 -2
- package/lib/oh-story/skills/story-review/scripts/wordcount_core.py +3 -0
- package/lib/oh-story/skills/story-setup/SKILL.md +58 -43
- package/lib/oh-story/skills/story-setup/references/agent-references/anti-ai-writing.md +29 -56
- package/lib/oh-story/skills/story-setup/references/agent-references/banned-words.md +3 -1
- package/lib/oh-story/skills/story-setup/references/agent-references/deslop-gates.md +154 -0
- package/lib/oh-story/skills/story-setup/references/agent-references/dialogue-mastery.md +10 -4
- package/lib/oh-story/skills/story-setup/references/agent-references/format-and-structure.md +2 -2
- package/lib/oh-story/skills/story-setup/references/agent-references/long-emotional-methods.md +2 -2
- package/lib/oh-story/skills/story-setup/references/agent-references/long-quality.md +1 -1
- package/lib/oh-story/skills/story-setup/references/agent-references/short-genre-formulas.md +1 -1
- package/lib/oh-story/skills/story-setup/references/agent-references/style-combat-face.md +1 -1
- 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/style-resolution.md +27 -0
- package/lib/oh-story/skills/story-setup/references/agent-references/writing-craft.md +63 -4
- package/lib/oh-story/skills/story-setup/references/diagnostics.md +38 -0
- package/lib/oh-story/skills/story-short-analyze/SKILL.md +22 -3
- package/lib/oh-story/skills/story-short-analyze/references/analysis-writing-techniques.md +1 -1
- package/lib/oh-story/skills/story-short-analyze/references/material-decomposition.md +5 -1
- package/lib/oh-story/skills/story-short-analyze/references/source-story-quality.md +2 -2
- package/lib/oh-story/skills/story-short-scan/SKILL.md +5 -1
- package/lib/oh-story/skills/story-short-write/SKILL.md +15 -324
- package/lib/oh-story/skills/story-short-write/references/author-memory.md +61 -29
- package/lib/oh-story/skills/story-short-write/references/banned-words.md +3 -1
- package/lib/oh-story/skills/story-short-write/references/benchmark-recall.md +60 -0
- package/lib/oh-story/skills/story-short-write/references/dialogue-mastery.md +10 -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 +2 -2
- package/lib/oh-story/skills/story-short-write/references/genre-styles//345/217/214/347/224/267/344/270/273.md +1 -1
- 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 +3 -3
- 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 +5 -5
- package/lib/oh-story/skills/story-short-write/references/genre-styles//346/260/221/344/277/227/346/200/252/350/260/210.md +4 -4
- package/lib/oh-story/skills/story-short-write/references/genre-styles//347/224/234/345/256/240.md +5 -5
- 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 +1 -1
- package/lib/oh-story/skills/story-short-write/references/genre-writing-techniques.md +1 -1
- package/lib/oh-story/skills/story-short-write/references/reference-index.md +55 -0
- package/lib/oh-story/skills/story-short-write/references/short-craft.md +12 -14
- package/lib/oh-story/skills/story-short-write/references/short-deslop.md +10 -10
- package/lib/oh-story/skills/story-short-write/references/short-format.md +3 -1
- package/lib/oh-story/skills/story-short-write/references/short-prose-quality.md +2 -2
- package/lib/oh-story/skills/story-short-write/references/style-resolution.md +27 -0
- package/lib/oh-story/skills/story-short-write/references/workflow-design.md +78 -0
- package/lib/oh-story/skills/story-short-write/references/workflow-draft.md +126 -0
- package/lib/oh-story/skills/story-short-write/references/workflow-revision.md +32 -0
- package/lib/oh-story/skills/story-short-write/references/writing-workflow.md +5 -5
- package/lib/oh-story/skills/story-short-write/scripts/author_memory_commit.py +934 -170
- package/lib/oh-story/skills/story-short-write/scripts/check-ai-patterns.js +6 -1
- package/lib/oh-story/skills/story-short-write/scripts/check-degeneration.js +39 -20
- package/lib/oh-story/skills/story-short-write/scripts/check-delivery-contract.js +34 -5
- package/lib/oh-story/skills/story-short-write/scripts/check-outline-copy.js +90 -23
- package/lib/oh-story/skills/story-short-write/scripts/normalize-punctuation.js +10 -5
- package/lib/oh-story/skills/story-short-write/scripts/style-whitelist.js +39 -0
- package/lib/types/client/drama-production-view.d.ts.map +1 -1
- package/lib/types/client/file-activity.d.ts +19 -1
- package/lib/types/client/file-activity.d.ts.map +1 -1
- package/lib/types/client/index.d.ts.map +1 -1
- package/lib/types/client/production-prompts.d.ts +7 -0
- package/lib/types/client/production-prompts.d.ts.map +1 -1
- package/lib/types/client/production-runtime.d.ts +33 -0
- package/lib/types/client/production-runtime.d.ts.map +1 -1
- package/lib/types/drama-adapters.d.ts +5 -3
- package/lib/types/drama-adapters.d.ts.map +1 -1
- package/lib/types/native-hooks.d.ts +52 -0
- package/lib/types/native-hooks.d.ts.map +1 -1
- package/lib/types/role-identity.d.ts +17 -0
- package/lib/types/role-identity.d.ts.map +1 -0
- package/lib/types/role-tool.d.ts.map +1 -1
- package/lib/types/skill-provider.d.ts.map +1 -1
- package/lib/video-recap/CHANGELOG.md +31 -1
- package/lib/video-recap/manifest.json +162 -162
- package/lib/video-recap/skills/video-assemble/scripts/artifacts.py +4 -9
- package/lib/video-recap/skills/video-assemble/scripts/assemble.py +47 -60
- package/lib/video-recap/skills/video-assemble/scripts/assembly_contract.py +77 -115
- package/lib/video-recap/skills/video-assemble/scripts/assembly_settings.py +41 -40
- package/lib/video-recap/skills/video-assemble/scripts/audio_automation.py +22 -32
- package/lib/video-recap/skills/video-assemble/scripts/audio_mix.py +102 -192
- package/lib/video-recap/skills/video-assemble/scripts/jianying_builders.py +14 -35
- package/lib/video-recap/skills/video-assemble/scripts/jianying_model.py +14 -12
- package/lib/video-recap/skills/video-assemble/scripts/jianying_optional.py +8 -9
- package/lib/video-recap/skills/video-assemble/scripts/jianying_schema.py +3 -14
- package/lib/video-recap/skills/video-assemble/scripts/jianying_timeline_contract.py +23 -12
- package/lib/video-recap/skills/video-assemble/scripts/jianying_tracks.py +1 -4
- package/lib/video-recap/skills/video-assemble/scripts/jianying_writer.py +24 -25
- package/lib/video-recap/skills/video-assemble/scripts/lib.py +31 -85
- package/lib/video-recap/skills/video-assemble/scripts/media.py +100 -144
- package/lib/video-recap/skills/video-assemble/scripts/narration_audio.py +101 -195
- package/lib/video-recap/skills/video-assemble/scripts/render_preflight.py +10 -21
- package/lib/video-recap/skills/video-assemble/scripts/source_subtitles.py +90 -169
- package/lib/video-recap/skills/video-assemble/scripts/subtitle_core.py +69 -122
- package/lib/video-recap/skills/video-assemble/scripts/subtitle_render.py +10 -17
- package/lib/video-recap/skills/video-assemble/scripts/timeline.py +33 -48
- package/lib/video-recap/skills/video-assemble/scripts/timeline_emit.py +14 -20
- package/lib/video-recap/skills/video-assemble/scripts/visual_render.py +135 -213
- package/lib/video-recap/skills/video-cut/scripts/cut_cli.py +49 -57
- package/lib/video-recap/skills/video-cut/scripts/cut_contract.py +38 -74
- package/lib/video-recap/skills/video-cut/scripts/cut_render.py +46 -95
- package/lib/video-recap/skills/video-cut/scripts/lib.py +23 -25
- package/lib/video-recap/skills/video-cut/scripts/media_geometry.py +70 -173
- package/lib/video-recap/skills/video-cut/scripts/narration_mapping.py +28 -53
- package/lib/video-recap/skills/video-cut/scripts/sentence_boundaries.py +162 -322
- package/lib/video-recap/skills/video-recap/references/timeline-and-jianying.md +6 -7
- package/lib/video-recap/skills/video-recap/scripts/doctor.py +104 -124
- package/lib/video-recap/skills/video-recap/scripts/final_qc.py +255 -412
- package/lib/video-recap/skills/video-recap/scripts/lib.py +30 -52
- package/lib/video-recap/skills/video-recap/scripts/materials.py +97 -120
- package/lib/video-recap/skills/video-recap/scripts/mimo_qc_client.py +7 -12
- package/lib/video-recap/skills/video-recap/scripts/mimo_qc_evidence.py +46 -97
- package/lib/video-recap/skills/video-recap/scripts/mimo_qc_observations.py +18 -36
- package/lib/video-recap/skills/video-recap/scripts/mimo_qc_payload.py +29 -47
- package/lib/video-recap/skills/video-recap/scripts/mimo_qc_report.py +43 -76
- package/lib/video-recap/skills/video-recap/scripts/mimo_qc_runner.py +2 -1
- package/lib/video-recap/skills/video-recap/scripts/qc_contract.py +2 -1
- package/lib/video-recap/skills/video-recap/scripts/recap_cli.py +2 -2
- package/lib/video-recap/skills/video-recap/scripts/recap_inspect.py +129 -145
- package/lib/video-recap/skills/video-recap/scripts/recap_review.py +27 -20
- package/lib/video-recap/skills/video-recap/scripts/recap_runner.py +20 -31
- package/lib/video-recap/skills/video-recap/scripts/recap_runtime.py +31 -106
- package/lib/video-recap/skills/video-recap/scripts/recap_stage_qc.py +43 -113
- package/lib/video-recap/skills/video-recap/scripts/recap_timeline.py +196 -377
- package/lib/video-recap/skills/video-script/scripts/agent_brief.py +1 -1
- package/lib/video-recap/skills/video-script/scripts/agent_text.py +63 -172
- package/lib/video-recap/skills/video-script/scripts/brief_context.py +80 -135
- package/lib/video-recap/skills/video-script/scripts/brief_inputs.py +125 -167
- package/lib/video-recap/skills/video-script/scripts/brief_timeline.py +93 -208
- package/lib/video-recap/skills/video-script/scripts/deslop_qc.py +20 -46
- package/lib/video-recap/skills/video-script/scripts/lib.py +30 -26
- package/lib/video-recap/skills/video-script/scripts/narration_lint.py +145 -140
- package/lib/video-recap/skills/video-script/scripts/review_response.py +12 -42
- package/lib/video-recap/skills/video-script/scripts/review_runner.py +0 -6
- package/lib/video-recap/skills/video-script/scripts/speech_ownership.py +39 -100
- package/lib/video-recap/skills/video-script/scripts/timeline_fusion.py +33 -124
- package/lib/video-recap/skills/video-understanding/scripts/agent_brief.py +1 -1
- package/lib/video-recap/skills/video-understanding/scripts/agent_text.py +63 -172
- package/lib/video-recap/skills/video-understanding/scripts/asr.py +1 -2
- package/lib/video-recap/skills/video-understanding/scripts/brief_context.py +80 -135
- package/lib/video-recap/skills/video-understanding/scripts/brief_inputs.py +125 -167
- package/lib/video-recap/skills/video-understanding/scripts/brief_timeline.py +93 -208
- package/lib/video-recap/skills/video-understanding/scripts/consolidate.py +1 -1
- package/lib/video-recap/skills/video-understanding/scripts/deslop_qc.py +20 -46
- package/lib/video-recap/skills/video-understanding/scripts/lib.py +31 -26
- package/lib/video-recap/skills/video-understanding/scripts/narration_lint.py +145 -140
- package/lib/video-recap/skills/video-understanding/scripts/speech_ownership.py +39 -100
- package/lib/video-recap/skills/video-understanding/scripts/timeline_fusion.py +33 -124
- package/lib/video-recap/skills/video-understanding/scripts/vlm.py +1 -4
- package/lib/video-recap/skills/video-voiceover/scripts/dub.py +7 -13
- package/lib/video-recap/skills/video-voiceover/scripts/fish_audio.py +12 -30
- package/lib/video-recap/skills/video-voiceover/scripts/lib.py +98 -131
- package/lib/video-recap/skills/video-voiceover/scripts/tts_audio.py +17 -28
- package/lib/video-recap/skills/video-voiceover/scripts/voiceover.py +151 -240
- package/package.json +45 -45
- package/lib/novel-to-game/skills/game-world-design/references/dialogue-design-method.md +0 -59
- package/lib/novel-to-game/skills/game-world-design/references/game-writing-craft.md +0 -53
- package/lib/novel-to-game/skills/novel-to-game/references/intake-benchmark-reference.md +0 -42
- package/lib/oh-story/skills/story-long-write/references/state-tracking.md +0 -108
|
@@ -8,6 +8,7 @@ from artifacts import _explicit_source_video, _value_fingerprint
|
|
|
8
8
|
from lib import log, run_cmd
|
|
9
9
|
|
|
10
10
|
def _load_cut_timeline_plan(work_dir):
|
|
11
|
+
"""The cut plan, preferring clip_plan_validated.json when it matches the raw plan; None in full mode."""
|
|
11
12
|
raw_plan_path = Path(work_dir) / "clip_plan.json"
|
|
12
13
|
validated_plan_path = Path(work_dir) / "clip_plan_validated.json"
|
|
13
14
|
if not validated_plan_path.exists():
|
|
@@ -16,73 +17,79 @@ def _load_cut_timeline_plan(work_dir):
|
|
|
16
17
|
return json.loads(validated_plan_path.read_text(encoding="utf-8"))
|
|
17
18
|
raw_plan = json.loads(raw_plan_path.read_text(encoding="utf-8"))
|
|
18
19
|
validated_plan = json.loads(validated_plan_path.read_text(encoding="utf-8"))
|
|
19
|
-
if (
|
|
20
|
-
isinstance(validated_plan, dict)
|
|
21
|
-
and validated_plan.get("raw_plan_fingerprint") == _value_fingerprint(raw_plan)
|
|
22
|
-
):
|
|
20
|
+
if validated_plan.get("raw_plan_fingerprint") == _value_fingerprint(raw_plan):
|
|
23
21
|
return validated_plan
|
|
24
22
|
return raw_plan
|
|
25
23
|
|
|
26
24
|
|
|
27
|
-
def
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
25
|
+
def _plan_clip_spans(work_dir):
|
|
26
|
+
"""Cut-mode clip spans [{source_start, source_end, output_start, output_end, entry}], or None.
|
|
27
|
+
|
|
28
|
+
clip_plan.json is either a bare list or {"clips": [...]}; a clip names its source range as
|
|
29
|
+
source_start/source_end or start/end. Clips without explicit output_start/output_end are laid
|
|
30
|
+
out back to back on the output timeline.
|
|
31
|
+
"""
|
|
32
|
+
plan = _load_cut_timeline_plan(work_dir)
|
|
33
|
+
if plan is None:
|
|
34
|
+
return None
|
|
35
|
+
entries = plan["clips"] if isinstance(plan, dict) else plan
|
|
36
|
+
spans, cursor = [], 0.0
|
|
37
|
+
for entry in entries:
|
|
38
|
+
ss = float(entry.get("source_start", entry.get("start")))
|
|
39
|
+
se = float(entry.get("source_end", entry.get("end")))
|
|
40
|
+
if "output_start" in entry:
|
|
41
|
+
out_s, out_e = float(entry["output_start"]), float(entry["output_end"])
|
|
42
|
+
cursor = max(cursor, out_e)
|
|
36
43
|
else:
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
44
|
+
out_s, out_e = cursor, cursor + (se - ss)
|
|
45
|
+
cursor = out_e
|
|
46
|
+
spans.append({
|
|
47
|
+
"source_start": ss, "source_end": se,
|
|
48
|
+
"output_start": out_s, "output_end": out_e,
|
|
49
|
+
"entry": entry,
|
|
50
|
+
})
|
|
51
|
+
return spans
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def _ratio_to_float(value, default=1.0):
|
|
55
|
+
"""Parse an ffprobe ratio ("4:3", "16/9" or a bare number); unknown ratios yield `default`."""
|
|
56
|
+
value = value.strip()
|
|
57
|
+
if value in {"", "0:1", "0/1", "N/A"}:
|
|
41
58
|
return default
|
|
59
|
+
if ":" in value:
|
|
60
|
+
num, den = value.split(":", 1)
|
|
61
|
+
elif "/" in value:
|
|
62
|
+
num, den = value.split("/", 1)
|
|
63
|
+
else:
|
|
64
|
+
return float(value)
|
|
65
|
+
return float(num) / float(den) if float(den) else default
|
|
42
66
|
|
|
43
67
|
|
|
44
68
|
def _fps_from_rate(value, default=30.0):
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
return round(float(value), 3)
|
|
51
|
-
except (TypeError, ValueError, ZeroDivisionError):
|
|
52
|
-
return default
|
|
69
|
+
"""Parse an ffprobe frame rate ("30000/1001" or a bare number); a 0/0 rate yields `default`."""
|
|
70
|
+
if "/" in value:
|
|
71
|
+
num, den = value.split("/", 1)
|
|
72
|
+
return round(float(num) / float(den), 3) if float(den) else default
|
|
73
|
+
return round(float(value), 3)
|
|
53
74
|
|
|
54
75
|
|
|
55
76
|
def _stream_rotation(stream):
|
|
56
77
|
"""Extract rotation from tags or side_data_list in ffprobe JSON."""
|
|
57
|
-
|
|
58
|
-
return 0
|
|
59
|
-
for source in (
|
|
60
|
-
(stream.get("tags") or {}).get("rotate"),
|
|
61
|
-
stream.get("rotation"),
|
|
62
|
-
):
|
|
78
|
+
for source in (stream.get("tags", {}).get("rotate"), stream.get("rotation")):
|
|
63
79
|
if source not in (None, ""):
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
for item in stream.get("side_data_list") or []:
|
|
69
|
-
if not isinstance(item, dict):
|
|
70
|
-
continue
|
|
71
|
-
for key in ("rotation", "displaymatrix"):
|
|
72
|
-
if item.get(key) not in (None, ""):
|
|
73
|
-
try:
|
|
74
|
-
return int(round(float(item.get(key)))) % 360
|
|
75
|
-
except (TypeError, ValueError):
|
|
76
|
-
pass
|
|
80
|
+
return int(round(float(source))) % 360
|
|
81
|
+
for item in stream.get("side_data_list", []):
|
|
82
|
+
if item.get("rotation") not in (None, ""):
|
|
83
|
+
return int(round(float(item["rotation"]))) % 360
|
|
77
84
|
return 0
|
|
78
85
|
|
|
79
86
|
|
|
80
|
-
def _canvas_from_stream(stream
|
|
81
|
-
storage_w =
|
|
82
|
-
storage_h =
|
|
83
|
-
fps = _fps_from_rate(stream
|
|
84
|
-
sar_text = stream.get("sample_aspect_ratio"
|
|
85
|
-
dar_text = stream.get("display_aspect_ratio"
|
|
87
|
+
def _canvas_from_stream(stream):
|
|
88
|
+
storage_w = stream["width"]
|
|
89
|
+
storage_h = stream["height"]
|
|
90
|
+
fps = _fps_from_rate(stream["r_frame_rate"])
|
|
91
|
+
sar_text = stream.get("sample_aspect_ratio", "1:1")
|
|
92
|
+
dar_text = stream.get("display_aspect_ratio", "")
|
|
86
93
|
sar = _ratio_to_float(sar_text, 1.0)
|
|
87
94
|
rotation = _stream_rotation(stream)
|
|
88
95
|
|
|
@@ -91,9 +98,9 @@ def _canvas_from_stream(stream, *, default_width=1280, default_height=720, defau
|
|
|
91
98
|
if dar_text and dar_text not in {"0:1", "N/A"}:
|
|
92
99
|
dar = _ratio_to_float(dar_text, 0.0)
|
|
93
100
|
# ffprobe sources are not consistent: some report DAR before rotation
|
|
94
|
-
# (landscape value > 1 for a 90° stream), while
|
|
95
|
-
#
|
|
96
|
-
#
|
|
101
|
+
# (landscape value > 1 for a 90° stream), while some containers report the
|
|
102
|
+
# already-rotated portrait DAR (< 1). Only apply DAR before swapping when it
|
|
103
|
+
# describes the stored orientation.
|
|
97
104
|
if dar > 0 and not (rotation in {90, 270} and dar < 1.0):
|
|
98
105
|
# Preserve height and adjust width. This keeps legacy square-pixel landscape
|
|
99
106
|
# byte-identical while honoring non-square pixel DAR metadata.
|
|
@@ -110,10 +117,6 @@ def _canvas_from_stream(stream, *, default_width=1280, default_height=720, defau
|
|
|
110
117
|
"rotation": rotation,
|
|
111
118
|
"sample_aspect_ratio": sar_text,
|
|
112
119
|
"display_aspect_ratio": dar_text or f"{display_w}:{display_h}",
|
|
113
|
-
"sar": sar_text,
|
|
114
|
-
"dar": dar_text or f"{display_w}:{display_h}",
|
|
115
|
-
"display_width": display_w,
|
|
116
|
-
"display_height": display_h,
|
|
117
120
|
}
|
|
118
121
|
|
|
119
122
|
|
|
@@ -122,44 +125,19 @@ def _probe_canvas(video_path, *, command_runner=run_cmd):
|
|
|
122
125
|
|
|
123
126
|
``width``/``height`` are the display canvas used by subtitle/overlay geometry.
|
|
124
127
|
For legacy square-pixel landscape sources, these remain the raw storage dimensions.
|
|
125
|
-
Extra storage/rotation/SAR/DAR fields are visual QC facts and are safe for callers
|
|
126
|
-
that only consume width/height/fps.
|
|
127
128
|
"""
|
|
128
|
-
defaults = {"width": 1280, "height": 720, "fps": 30.0}
|
|
129
129
|
res = command_runner([
|
|
130
130
|
"ffprobe", "-v", "error", "-select_streams", "v:0",
|
|
131
131
|
"-show_entries",
|
|
132
132
|
"stream=width,height,r_frame_rate,avg_frame_rate,sample_aspect_ratio,display_aspect_ratio:stream_tags=rotate:stream_side_data=rotation",
|
|
133
133
|
"-of", "json", str(video_path),
|
|
134
134
|
])
|
|
135
|
-
if res.returncode
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
except (ValueError, TypeError, KeyError):
|
|
142
|
-
pass
|
|
143
|
-
# Tests and older mocks may still feed default=nw=1:nk=0 style lines.
|
|
144
|
-
stream = {}
|
|
145
|
-
for line in (res.stdout or "").splitlines():
|
|
146
|
-
line = line.strip()
|
|
147
|
-
if not line or "=" not in line:
|
|
148
|
-
continue
|
|
149
|
-
key, value = line.split("=", 1)
|
|
150
|
-
stream[key] = value
|
|
151
|
-
if stream:
|
|
152
|
-
return _canvas_from_stream(stream)
|
|
153
|
-
return {
|
|
154
|
-
**defaults,
|
|
155
|
-
"storage_width": defaults["width"],
|
|
156
|
-
"storage_height": defaults["height"],
|
|
157
|
-
"rotation": 0,
|
|
158
|
-
"sample_aspect_ratio": "1:1",
|
|
159
|
-
"display_aspect_ratio": "16:9",
|
|
160
|
-
"display_width": defaults["width"],
|
|
161
|
-
"display_height": defaults["height"],
|
|
162
|
-
}
|
|
135
|
+
if res.returncode != 0:
|
|
136
|
+
raise RuntimeError(f"ffprobe 无法读取视频流 {video_path}: {res.stderr}")
|
|
137
|
+
streams = json.loads(res.stdout)["streams"]
|
|
138
|
+
if not streams:
|
|
139
|
+
raise RuntimeError(f"{video_path} 没有视频流")
|
|
140
|
+
return _canvas_from_stream(streams[0])
|
|
163
141
|
|
|
164
142
|
|
|
165
143
|
def _has_audio_stream(video_path, *, command_runner=run_cmd):
|
|
@@ -183,61 +161,39 @@ def _build_video_clips(
|
|
|
183
161
|
|
|
184
162
|
In cut mode each plan entry becomes a clip referencing the ORIGINAL source
|
|
185
163
|
range. Multi-source validated plans carry per-clip source_path and do not
|
|
186
|
-
require an explicit ambient --source-video.
|
|
164
|
+
require an explicit ambient --source-video. Without any declared source (full
|
|
165
|
+
mode, or cut mode rendered without --source-video) the rendered input is one clip.
|
|
187
166
|
"""
|
|
188
167
|
explicit_source_video = source_video_getter()
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
# instead of collapsing the whole multi-source timeline.
|
|
222
|
-
seg = max(0.0, float(timeline_end) - float(timeline_start))
|
|
223
|
-
logger(f" 时间线: source_path 不存在,该片段降级为剪后成片片段: {source_path or '(unset)'}")
|
|
224
|
-
clips.append({"source_id": c.get("source_id"),
|
|
225
|
-
"source_path": str(input_video),
|
|
226
|
-
"source_start": float(timeline_start),
|
|
227
|
-
"source_end": float(timeline_start) + seg,
|
|
228
|
-
"timeline_start": float(timeline_start),
|
|
229
|
-
"timeline_end": float(timeline_end),
|
|
230
|
-
"provenance_degraded": True,
|
|
231
|
-
"provenance_reason": f"missing_source_path:{source_path or 'unset'}"})
|
|
232
|
-
continue
|
|
233
|
-
clips.append({"source_id": c.get("source_id"),
|
|
234
|
-
"source_path": source_path, "source_start": ss,
|
|
235
|
-
"source_end": se, "timeline_start": timeline_start,
|
|
236
|
-
"timeline_end": timeline_end})
|
|
237
|
-
if clips:
|
|
238
|
-
return clips
|
|
239
|
-
except (TypeError, ValueError, KeyError, OSError) as exc:
|
|
240
|
-
logger(f" 时间线: clip_plan 解析失败,回退单片 ({exc})")
|
|
241
|
-
return [{"source_path": str(input_video), "source_start": 0.0,
|
|
242
|
-
"source_end": float(duration_s), "timeline_start": 0.0,
|
|
243
|
-
"timeline_end": float(duration_s)}]
|
|
168
|
+
spans = _plan_clip_spans(work_dir)
|
|
169
|
+
multi_source = spans is not None and any(span["entry"].get("source_path") for span in spans)
|
|
170
|
+
if spans is None or not (explicit_source_video or multi_source):
|
|
171
|
+
return [{"source_path": str(input_video), "source_start": 0.0,
|
|
172
|
+
"source_end": float(duration_s), "timeline_start": 0.0,
|
|
173
|
+
"timeline_end": float(duration_s)}]
|
|
174
|
+
clips = []
|
|
175
|
+
for span in spans:
|
|
176
|
+
entry = span["entry"]
|
|
177
|
+
source_path = entry.get("source_path") or explicit_source_video
|
|
178
|
+
timeline_start, timeline_end = span["output_start"], span["output_end"]
|
|
179
|
+
if not source_path or not os.path.exists(source_path):
|
|
180
|
+
# Degrade ONLY this clip — point it at the rendered cut for its own output
|
|
181
|
+
# window — and keep real provenance for every present source, instead of
|
|
182
|
+
# collapsing the whole multi-source timeline.
|
|
183
|
+
logger(f" 时间线: source_path 不存在,该片段降级为剪后成片片段: {source_path or '(unset)'}")
|
|
184
|
+
clips.append({"source_id": entry.get("source_id"),
|
|
185
|
+
"source_path": str(input_video),
|
|
186
|
+
"source_start": timeline_start,
|
|
187
|
+
"source_end": timeline_end,
|
|
188
|
+
"timeline_start": timeline_start,
|
|
189
|
+
"timeline_end": timeline_end,
|
|
190
|
+
"provenance_degraded": True,
|
|
191
|
+
"provenance_reason": f"missing_source_path:{source_path or 'unset'}"})
|
|
192
|
+
continue
|
|
193
|
+
clips.append({"source_id": entry.get("source_id"),
|
|
194
|
+
"source_path": source_path,
|
|
195
|
+
"source_start": span["source_start"],
|
|
196
|
+
"source_end": span["source_end"],
|
|
197
|
+
"timeline_start": timeline_start,
|
|
198
|
+
"timeline_end": timeline_end})
|
|
199
|
+
return clips
|