@oh-story/dsh 0.1.10 → 0.1.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -7
- package/lib/client.js +7 -3
- package/lib/client.js.map +2 -2
- package/lib/drama/manifest.json +212 -142
- package/lib/drama/skills/short-drama/SKILL.md +14 -2
- package/lib/drama/skills/short-drama/assets/project-template/short-drama.json +3 -0
- package/lib/drama/skills/short-drama/references/creator-documents.md +3 -0
- package/lib/drama/skills/short-drama/references/knowhow-index.md +15 -0
- package/lib/drama/skills/short-drama/scripts/project_tool.py +131 -0
- package/lib/drama/skills/short-drama-assets/SKILL.md +2 -1
- package/lib/drama/skills/short-drama-assets/references/asset-review-checklist.md +2 -0
- package/lib/drama/skills/short-drama-assets/references/era-anchors.md +37 -0
- package/lib/drama/skills/short-drama-assets/references/stage-contract.md +2 -0
- package/lib/drama/skills/short-drama-develop/SKILL.md +10 -4
- package/lib/drama/skills/short-drama-develop/assets/adaptation-map.example.jsonl +1 -1
- package/lib/drama/skills/short-drama-develop/assets/creative-brief.md +8 -0
- package/lib/drama/skills/short-drama-develop/references/adaptation-craft.md +80 -13
- package/lib/drama/skills/short-drama-develop/references/episode-design.md +95 -12
- package/lib/drama/skills/short-drama-develop/references/genre-and-hook-playbook.md +9 -5
- package/lib/drama/skills/short-drama-develop/references/genre-cards//345/244/215/344/273/207/346/211/223/350/204/270.md +1 -1
- package/lib/drama/skills/short-drama-develop/references/genre-cards//347/263/273/347/273/237/346/265/201.md +51 -0
- package/lib/drama/skills/short-drama-develop/references/genre-cards//351/200/206/350/242/255.md +51 -0
- package/lib/drama/skills/short-drama-develop/references/genre-cards//351/207/215/347/224/237/347/251/277/350/266/212.md +51 -0
- package/lib/drama/skills/short-drama-develop/references/genre-cards.md +10 -7
- package/lib/drama/skills/short-drama-develop/references/premise-devices.md +15 -9
- package/lib/drama/skills/short-drama-develop/references/serial-character-and-memory.md +3 -2
- package/lib/drama/skills/short-drama-develop/references/stage-contract.md +14 -7
- package/lib/drama/skills/short-drama-develop/references/story-craft.md +7 -3
- package/lib/drama/skills/short-drama-edit/SKILL.md +43 -20
- package/lib/drama/skills/short-drama-edit/assets/remotion/README.md +49 -13
- package/lib/drama/skills/short-drama-edit/assets/remotion/package.json +4 -2
- package/lib/drama/skills/short-drama-edit/assets/remotion/src/Overlay.tsx +31 -0
- package/lib/drama/skills/short-drama-edit/assets/remotion/src/Root.tsx +5 -5
- package/lib/drama/skills/short-drama-edit/assets/remotion/src/Subtitles.tsx +68 -69
- package/lib/drama/skills/short-drama-edit/assets/remotion/src/font.ts +39 -29
- package/lib/drama/skills/short-drama-edit/assets/remotion/src/rules.mjs +188 -0
- package/lib/drama/skills/short-drama-edit/assets/remotion/src/schema.ts +26 -13
- package/lib/drama/skills/short-drama-edit/assets/remotion/src/screen/Card.tsx +72 -0
- package/lib/drama/skills/short-drama-edit/assets/remotion/src/screen/CornerChip.tsx +39 -0
- package/lib/drama/skills/short-drama-edit/assets/remotion/src/screen/ScreenText.tsx +36 -0
- package/lib/drama/skills/short-drama-edit/assets/remotion/src/screen/SystemPanel.tsx +44 -0
- package/lib/drama/skills/short-drama-edit/assets/remotion/src/screen/TaskPanel.tsx +100 -0
- package/lib/drama/skills/short-drama-edit/assets/remotion/src/screen/chrome.tsx +197 -0
- package/lib/drama/skills/short-drama-edit/assets/remotion/src/screen/tokens.ts +62 -0
- package/lib/drama/skills/short-drama-edit/assets/remotion/tsconfig.json +1 -0
- package/lib/drama/skills/short-drama-edit/assets//345/211/252/350/276/221/345/215/225.md +4 -2
- package/lib/drama/skills/short-drama-edit/references/cut-craft.md +3 -1
- package/lib/drama/skills/short-drama-edit/references/delivery-verify.md +6 -2
- package/lib/drama/skills/short-drama-edit/references/generated-footage.md +12 -6
- package/lib/drama/skills/short-drama-edit/references/sound-and-subtitles.md +13 -8
- package/lib/drama/skills/short-drama-edit/references/stage-contract.md +2 -0
- package/lib/drama/skills/short-drama-edit/scripts/edit_tool.py +1153 -121
- package/lib/drama/skills/short-drama-edit/scripts/selftest.py +49 -9
- package/lib/drama/skills/short-drama-novel-analyze/SKILL.md +3 -3
- package/lib/drama/skills/short-drama-novel-analyze/assets/episode-candidate.example.jsonl +2 -2
- package/lib/drama/skills/short-drama-novel-analyze/references/adaptation-triage.md +8 -4
- package/lib/drama/skills/short-drama-novel-analyze/references/adaptation-value.md +10 -3
- package/lib/drama/skills/short-drama-novel-analyze/references/aggregation-and-entities.md +25 -1
- package/lib/drama/skills/short-drama-novel-analyze/references/stage-contract.md +1 -0
- package/lib/drama/skills/short-drama-review/SKILL.md +2 -2
- package/lib/drama/skills/short-drama-review/references/review-method.md +6 -1
- package/lib/drama/skills/short-drama-review/references/rubric-assets-prompts.md +11 -0
- package/lib/drama/skills/short-drama-review/references/rubric-story-script.md +77 -3
- package/lib/drama/skills/short-drama-review/references/rubric-visual-motion.md +15 -0
- package/lib/drama/skills/short-drama-review/references/stage-contract.md +3 -0
- package/lib/drama/skills/short-drama-storyboard/SKILL.md +13 -5
- package/lib/drama/skills/short-drama-storyboard/references/blocking-playbooks.md +1 -1
- package/lib/drama/skills/short-drama-storyboard/references/production-shot-grammar.md +2 -2
- package/lib/drama/skills/short-drama-storyboard/references/shot-craft.md +82 -14
- package/lib/drama/skills/short-drama-storyboard/references/stage-contract.md +4 -2
- package/lib/drama/skills/short-drama-video-prompts/SKILL.md +5 -3
- package/lib/drama/skills/short-drama-video-prompts/references/camera-audio-continuity.md +12 -0
- package/lib/drama/skills/short-drama-video-prompts/references/delivery-profile.md +4 -5
- package/lib/drama/skills/short-drama-video-prompts/references/generability.md +4 -2
- package/lib/drama/skills/short-drama-video-prompts/references/minimax-h3.md +40 -1
- package/lib/drama/skills/short-drama-video-prompts/references/motion-recipe.md +20 -14
- package/lib/drama/skills/short-drama-video-prompts/references/performance-action-timing.md +1 -1
- package/lib/drama/skills/short-drama-video-prompts/references/production-prompt-grammar.md +8 -7
- package/lib/drama/skills/short-drama-video-prompts/references/review-and-fixtures.md +1 -1
- package/lib/drama/skills/short-drama-video-prompts/references/stage-contract.md +1 -0
- package/lib/drama/skills/short-drama-video-prompts/references/target-model-profile.md +8 -1
- package/lib/drama/skills/short-drama-video-prompts/references/wan-3.0.md +103 -0
- package/lib/drama/skills/short-drama-video-prompts/scripts/motion_timing_check.py +8 -7
- package/lib/drama/skills/short-drama-write/SKILL.md +8 -3
- package/lib/drama/skills/short-drama-write/references/dialogue-craft.md +1 -1
- package/lib/drama/skills/short-drama-write/references/script-craft.md +56 -3
- package/lib/drama/skills/short-drama-write/references/stage-contract.md +4 -0
- package/lib/drama/skills/short-drama-write/scripts/duration_estimate.py +48 -2
- package/lib/index.js +71 -21
- package/lib/index.js.map +3 -3
- package/lib/oh-story/manifest.json +545 -310
- package/lib/oh-story/roles/chapter-extractor.md +11 -11
- package/lib/oh-story/roles/character-designer.md +1 -2
- package/lib/oh-story/roles/consistency-checker.md +11 -9
- package/lib/oh-story/roles/narrative-writer.md +24 -25
- package/lib/oh-story/roles/story-architect.md +9 -61
- package/lib/oh-story/roles/story-explorer.md +20 -125
- package/lib/oh-story/roles/story-researcher.md +0 -1
- package/lib/oh-story/skills/story/SKILL.md +6 -6
- package/lib/oh-story/skills/story/VERSION +1 -1
- package/lib/oh-story/skills/story/references/author-memory-maintenance.md +75 -0
- package/lib/oh-story/skills/story/references/author-memory.md +40 -118
- package/lib/oh-story/skills/story/scripts/author_memory_commit.py +3 -3
- package/lib/oh-story/skills/story-deslop/SKILL.md +24 -25
- package/lib/oh-story/skills/story-deslop/references/agent-calls.md +5 -0
- package/lib/oh-story/skills/story-deslop/references/anti-ai-writing.md +1 -1
- package/lib/oh-story/skills/story-deslop/references/author-memory-maintenance.md +75 -0
- package/lib/oh-story/skills/story-deslop/references/author-memory.md +40 -118
- package/lib/oh-story/skills/story-deslop/references/banned-words.md +2 -2
- package/lib/oh-story/skills/story-deslop/references/deslop-gates.md +21 -4
- package/lib/oh-story/skills/story-deslop/references/style-resolution.md +4 -4
- package/lib/oh-story/skills/story-deslop/scripts/author_memory_commit.py +3 -3
- package/lib/oh-story/skills/story-deslop/scripts/check-ai-patterns.js +155 -8
- package/lib/oh-story/skills/story-import/SKILL.md +63 -579
- package/lib/oh-story/skills/story-import/references/deep-analysis.md +47 -0
- package/lib/oh-story/skills/story-import/references/format-and-structure.md +1 -1
- package/lib/oh-story/skills/story-import/references/import-report.md +64 -0
- package/lib/oh-story/skills/story-import/references/import-special-cases.md +34 -0
- package/lib/oh-story/skills/story-import/references/import-tracking.md +95 -0
- package/lib/oh-story/skills/story-import/references/length-routing.md +1 -1
- package/lib/oh-story/skills/story-import/references/outline-reverse-rules.md +79 -0
- package/lib/oh-story/skills/story-import/references/outline-reverse.md +24 -0
- package/lib/oh-story/skills/story-import/references/structure-mapping-long.md +95 -91
- package/lib/oh-story/skills/story-import/references/structure-mapping-short.md +24 -12
- package/lib/oh-story/skills/story-import/references/tracking-initialization.md +1 -1
- package/lib/oh-story/skills/story-import/references/tracking-transaction.md +11 -9
- package/lib/oh-story/skills/story-import/scripts/build_outline_brief.py +332 -0
- package/lib/oh-story/skills/story-import/scripts/check-outline-contract.js +101 -14
- package/lib/oh-story/skills/story-import/scripts/tracking_commit.py +278 -23
- package/lib/oh-story/skills/story-import/scripts/wordcount_core.py +179 -23
- package/lib/oh-story/skills/story-long-analyze/SKILL.md +28 -50
- package/lib/oh-story/skills/story-long-analyze/references/author-facing.md +12 -5
- package/lib/oh-story/skills/story-long-analyze/references/deconstruction-notes.md +1 -1
- package/lib/oh-story/skills/story-long-analyze/references/final-checks.md +19 -0
- package/lib/oh-story/skills/story-long-analyze/references/index-rebuild.md +11 -0
- package/lib/oh-story/skills/story-long-analyze/references/pipeline-ops.md +21 -55
- package/lib/oh-story/skills/story-long-analyze/references/stage1-golden-chapters.md +128 -0
- package/lib/oh-story/skills/story-long-analyze/references/stage2-extraction.md +229 -0
- package/lib/oh-story/skills/story-long-analyze/references/stage3-plot-rhythm.md +480 -0
- package/lib/oh-story/skills/story-long-analyze/references/stage4-characters-settings.md +195 -0
- package/lib/oh-story/skills/story-long-analyze/references/stage5-report.md +33 -0
- package/lib/oh-story/skills/story-long-analyze/references/style-profile-generator.md +17 -0
- package/lib/oh-story/skills/story-long-analyze/references/style-profile-protocol.md +1 -1
- package/lib/oh-story/skills/story-long-analyze/references/synthesis-inputs.md +39 -0
- package/lib/oh-story/skills/story-long-analyze/scripts/manage_analysis_run.py +47 -8
- package/lib/oh-story/skills/story-long-scan/SKILL.md +41 -193
- package/lib/oh-story/skills/story-long-scan/references/platform-ciweimao.md +19 -0
- package/lib/oh-story/skills/story-long-scan/references/platform-fanqie.md +45 -0
- package/lib/oh-story/skills/story-long-scan/references/platform-jjwxc.md +28 -0
- package/lib/oh-story/skills/story-long-scan/references/platform-qidian.md +35 -0
- package/lib/oh-story/skills/story-long-scan/references/platform-qimao.md +27 -0
- package/lib/oh-story/skills/story-long-scan/references/topic-decision.md +6 -2
- package/lib/oh-story/skills/story-long-write/SKILL.md +32 -73
- package/lib/oh-story/skills/story-long-write/references/agent-calls.md +47 -0
- package/lib/oh-story/skills/story-long-write/references/anti-ai-writing.md +1 -1
- package/lib/oh-story/skills/story-long-write/references/artifact-protocols.md +18 -201
- package/lib/oh-story/skills/story-long-write/references/author-memory-maintenance.md +75 -0
- package/lib/oh-story/skills/story-long-write/references/author-memory.md +40 -118
- package/lib/oh-story/skills/story-long-write/references/banned-words.md +2 -2
- package/lib/oh-story/skills/story-long-write/references/benchmark-recall.md +6 -10
- package/lib/oh-story/skills/story-long-write/references/character-relations.md +49 -1
- package/lib/oh-story/skills/story-long-write/references/deslop-gates.md +171 -0
- package/lib/oh-story/skills/story-long-write/references/emotion-on-page.md +116 -0
- package/lib/oh-story/skills/story-long-write/references/emotional-arc-design.md +1 -114
- package/lib/oh-story/skills/story-long-write/references/genre-prose-cards.md +1 -1
- package/lib/oh-story/skills/story-long-write/references/long-chapter-quality.md +3 -2
- package/lib/oh-story/skills/story-long-write/references/long-format.md +0 -8
- package/lib/oh-story/skills/story-long-write/references/long-genre-catalog.md +1 -1
- package/lib/oh-story/skills/story-long-write/references/long-genre-mechanics.md +3 -3
- package/lib/oh-story/skills/story-long-write/references/opening-design.md +2 -2
- package/lib/oh-story/skills/story-long-write/references/outline-conflict.md +4 -4
- package/lib/oh-story/skills/story-long-write/references/outline-methods.md +7 -7
- package/lib/oh-story/skills/story-long-write/references/outline-rhythm.md +3 -3
- package/lib/oh-story/skills/story-long-write/references/outline-structure-theory.md +14 -69
- package/lib/oh-story/skills/story-long-write/references/plot-frameworks.md +1 -1
- package/lib/oh-story/skills/story-long-write/references/plot-special-topics.md +2 -2
- package/lib/oh-story/skills/story-long-write/references/project-files.md +10 -6
- package/lib/oh-story/skills/story-long-write/references/reader-contract-and-progression.md +1 -1
- package/lib/oh-story/skills/story-long-write/references/reference-index.md +4 -4
- package/lib/oh-story/skills/story-long-write/references/stop-and-fix.md +9 -0
- package/lib/oh-story/skills/story-long-write/references/style-combat-face.md +1 -58
- 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 +4 -4
- package/lib/oh-story/skills/story-long-write/references/tracking-initialization.md +1 -1
- package/lib/oh-story/skills/story-long-write/references/tracking-transaction.md +11 -9
- package/lib/oh-story/skills/story-long-write/references/workflow-chapter.md +33 -44
- package/lib/oh-story/skills/story-long-write/references/workflow-daily.md +18 -51
- package/lib/oh-story/skills/story-long-write/references/workflow-outline.md +157 -0
- package/lib/oh-story/skills/story-long-write/references/workflow-revision.md +53 -67
- package/lib/oh-story/skills/story-long-write/references/workflow-setup.md +112 -251
- package/lib/oh-story/skills/story-long-write/references/workflow-volume.md +142 -0
- package/lib/oh-story/skills/story-long-write/references/writer-prompt-fallback.md +5 -3
- package/lib/oh-story/skills/story-long-write/references/writing-craft.md +18 -56
- package/lib/oh-story/skills/story-long-write/scripts/author_memory_commit.py +3 -3
- package/lib/oh-story/skills/story-long-write/scripts/build_architect_brief.py +260 -0
- package/lib/oh-story/skills/story-long-write/scripts/build_writer_prompt.py +96 -16
- package/lib/oh-story/skills/story-long-write/scripts/check-ai-patterns.js +155 -8
- package/lib/oh-story/skills/story-long-write/scripts/check-outline-contract.js +101 -14
- package/lib/oh-story/skills/story-long-write/scripts/check-outline-copy.js +7 -2
- package/lib/oh-story/skills/story-long-write/scripts/outline_view.py +2 -1
- package/lib/oh-story/skills/story-long-write/scripts/storyctl.py +250 -50
- package/lib/oh-story/skills/story-long-write/scripts/tracking_commit.py +278 -23
- package/lib/oh-story/skills/story-long-write/scripts/wordcount_core.py +179 -23
- package/lib/oh-story/skills/story-review/SKILL.md +19 -273
- package/lib/oh-story/skills/story-review/references/agent-prompts.md +184 -0
- package/lib/oh-story/skills/story-review/references/anti-ai-writing.md +1 -1
- package/lib/oh-story/skills/story-review/references/author-memory-maintenance.md +75 -0
- package/lib/oh-story/skills/story-review/references/author-memory.md +40 -118
- package/lib/oh-story/skills/story-review/references/banned-words.md +2 -2
- package/lib/oh-story/skills/story-review/references/batch-review.md +19 -0
- package/lib/oh-story/skills/story-review/references/character-relations.md +49 -1
- package/lib/oh-story/skills/story-review/references/review-quality.md +2 -1
- package/lib/oh-story/skills/story-review/references/review-tracking.md +10 -0
- package/lib/oh-story/skills/story-review/references/solo.md +52 -0
- package/lib/oh-story/skills/story-review/references/style-resolution.md +4 -4
- package/lib/oh-story/skills/story-review/references/tracking-initialization.md +1 -1
- package/lib/oh-story/skills/story-review/references/tracking-transaction.md +11 -9
- package/lib/oh-story/skills/story-review/scripts/author_memory_commit.py +3 -3
- package/lib/oh-story/skills/story-review/scripts/check-ai-patterns.js +155 -8
- package/lib/oh-story/skills/story-review/scripts/tracking_commit.py +278 -23
- package/lib/oh-story/skills/story-review/scripts/wordcount_core.py +179 -23
- package/lib/oh-story/skills/story-setup/SKILL.md +69 -458
- package/lib/oh-story/skills/story-setup/references/agent-references/agent-quality.md +4 -4
- package/lib/oh-story/skills/story-setup/references/agent-references/anti-ai-writing.md +1 -1
- package/lib/oh-story/skills/story-setup/references/agent-references/banned-words.md +2 -2
- package/lib/oh-story/skills/story-setup/references/agent-references/benchmark-style-load.md +107 -0
- package/lib/oh-story/skills/story-setup/references/agent-references/character-relations.md +49 -1
- package/lib/oh-story/skills/story-setup/references/agent-references/deslop-gates.md +21 -4
- package/lib/oh-story/skills/story-setup/references/agent-references/emotion-on-page.md +116 -0
- package/lib/oh-story/skills/story-setup/references/agent-references/emotional-arc-design.md +1 -114
- package/lib/oh-story/skills/story-setup/references/agent-references/format-and-structure.md +1 -1
- 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/long-genre-catalog.md +1 -1
- package/lib/oh-story/skills/story-setup/references/agent-references/long-genre-mechanics.md +3 -3
- package/lib/oh-story/skills/story-setup/references/agent-references/long-quality.md +7 -5
- package/lib/oh-story/skills/story-setup/references/agent-references/opening-design.md +2 -2
- package/lib/oh-story/skills/story-setup/references/agent-references/outline-conflict.md +4 -4
- package/lib/oh-story/skills/story-setup/references/agent-references/outline-methods.md +7 -7
- package/lib/oh-story/skills/story-setup/references/agent-references/outline-rhythm.md +3 -3
- package/lib/oh-story/skills/story-setup/references/agent-references/short-emotional-methods.md +1 -1
- package/lib/oh-story/skills/story-setup/references/agent-references/short-genre-formulas.md +0 -15
- package/lib/oh-story/skills/story-setup/references/agent-references/short-reversal.md +1 -1
- package/lib/oh-story/skills/story-setup/references/agent-references/style-combat-face.md +1 -58
- 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 +4 -4
- package/lib/oh-story/skills/story-setup/references/agent-references/writing-craft.md +18 -56
- package/lib/oh-story/skills/story-setup/references/diagnostics.md +3 -3
- package/lib/oh-story/skills/story-short-analyze/SKILL.md +37 -110
- package/lib/oh-story/skills/story-short-analyze/references/analysis-character-relations.md +1 -1
- package/lib/oh-story/skills/story-short-analyze/references/analysis-method.md +42 -0
- package/lib/oh-story/skills/story-short-analyze/references/optional-modules.md +97 -0
- package/lib/oh-story/skills/story-short-analyze/references/output-contract.md +9 -47
- package/lib/oh-story/skills/story-short-analyze/references/quality-checklist.md +80 -0
- package/lib/oh-story/skills/story-short-analyze/references/source-story-quality.md +4 -4
- package/lib/oh-story/skills/story-short-analyze/references/stage2-3-structure-emotion.md +308 -0
- package/lib/oh-story/skills/story-short-analyze/references/{material-decomposition.md → stage4-6-reversal-summary.md} +303 -374
- package/lib/oh-story/skills/story-short-scan/SKILL.md +30 -64
- package/lib/oh-story/skills/story-short-scan/references/manual-rank-input.md +36 -0
- package/lib/oh-story/skills/story-short-scan/references/platform-dianzhong.md +24 -0
- package/lib/oh-story/skills/story-short-scan/references/platform-heiyan.md +21 -0
- package/lib/oh-story/skills/story-short-scan/references/topic-match.md +38 -0
- package/lib/oh-story/skills/story-short-write/SKILL.md +23 -34
- package/lib/oh-story/skills/story-short-write/references/agent-calls.md +13 -0
- package/lib/oh-story/skills/story-short-write/references/author-memory-maintenance.md +75 -0
- package/lib/oh-story/skills/story-short-write/references/author-memory.md +40 -118
- package/lib/oh-story/skills/story-short-write/references/banned-words.md +2 -2
- package/lib/oh-story/skills/story-short-write/references/benchmark-recall.md +1 -21
- package/lib/oh-story/skills/story-short-write/references/emotional-methods.md +1 -1
- package/lib/oh-story/skills/story-short-write/references/genre-writing-formulas.md +0 -15
- package/lib/oh-story/skills/story-short-write/references/output-contract.md +9 -47
- package/lib/oh-story/skills/story-short-write/references/reference-index.md +17 -49
- package/lib/oh-story/skills/story-short-write/references/scene-craft.md +40 -0
- package/lib/oh-story/skills/story-short-write/references/short-craft.md +7 -43
- package/lib/oh-story/skills/story-short-write/references/short-format.md +3 -3
- package/lib/oh-story/skills/story-short-write/references/short-prose-quality.md +2 -1
- package/lib/oh-story/skills/story-short-write/references/short-reversal.md +1 -1
- package/lib/oh-story/skills/story-short-write/references/style-resolution.md +4 -4
- package/lib/oh-story/skills/story-short-write/references/submission-craft.md +1 -1
- package/lib/oh-story/skills/story-short-write/references/villain-and-reveal.md +5 -10
- package/lib/oh-story/skills/story-short-write/references/workflow-design.md +19 -12
- package/lib/oh-story/skills/story-short-write/references/workflow-draft.md +22 -32
- package/lib/oh-story/skills/story-short-write/references/workflow-revision.md +84 -17
- package/lib/oh-story/skills/story-short-write/references/writing-workflow.md +7 -119
- package/lib/oh-story/skills/story-short-write/scripts/author_memory_commit.py +3 -3
- package/lib/oh-story/skills/story-short-write/scripts/check-ai-patterns.js +155 -8
- package/lib/oh-story/skills/story-short-write/scripts/check-outline-copy.js +7 -2
- package/lib/types/client/video-studio.d.ts.map +1 -1
- package/lib/types/native-hooks.d.ts +2 -2
- package/lib/types/native-hooks.d.ts.map +1 -1
- package/lib/types/role-tool.d.ts.map +1 -1
- package/lib/types/skill-provider.d.ts.map +1 -1
- package/lib/types/video-project.d.ts.map +1 -1
- package/lib/types/workspace-route.d.ts.map +1 -1
- package/lib/video-recap/CHANGELOG.md +60 -1
- package/lib/video-recap/README.en.md +348 -137
- package/lib/video-recap/README.md +340 -136
- package/lib/video-recap/manifest.json +406 -251
- package/lib/video-recap/skills/video-assemble/SKILL.md +30 -15
- package/lib/video-recap/skills/video-assemble/references/audio-modes.md +63 -0
- package/lib/video-recap/skills/video-assemble/references/explicit-audio-mix.md +75 -0
- package/lib/video-recap/skills/video-assemble/references/foreground-compose.md +118 -0
- package/lib/video-recap/skills/video-assemble/references/narration-adoption.md +103 -0
- package/lib/video-recap/skills/video-assemble/references/packaging.md +45 -0
- package/lib/video-recap/skills/video-assemble/references/pair-media.md +74 -0
- package/lib/video-recap/skills/video-assemble/references/source-score.md +147 -0
- package/lib/video-recap/skills/video-assemble/references/subtitle-track.md +202 -0
- package/lib/video-recap/skills/video-assemble/scripts/adoption/__init__.py +1 -0
- package/lib/video-recap/skills/video-assemble/scripts/adoption/audio_mix_binding.py +279 -0
- package/lib/video-recap/skills/video-assemble/scripts/adoption/frozen_audio.py +187 -0
- package/lib/video-recap/skills/video-assemble/scripts/adoption/narration_binding.py +323 -0
- package/lib/video-recap/skills/video-assemble/scripts/adoption/strict_inputs.py +109 -0
- package/lib/video-recap/skills/video-assemble/scripts/adoption/strict_publish.py +130 -0
- package/lib/video-recap/skills/video-assemble/scripts/artifacts.py +10 -46
- package/lib/video-recap/skills/video-assemble/scripts/assemble.py +378 -119
- package/lib/video-recap/skills/video-assemble/scripts/assemble_constants.py +29 -12
- package/lib/video-recap/skills/video-assemble/scripts/assembly_contract.py +95 -44
- package/lib/video-recap/skills/video-assemble/scripts/assembly_settings.py +75 -32
- package/lib/video-recap/skills/video-assemble/scripts/audio_mix.py +11 -11
- package/lib/video-recap/skills/video-assemble/scripts/compose_foreground.py +293 -0
- package/lib/video-recap/skills/video-assemble/scripts/export_jianying.py +71 -78
- package/lib/video-recap/skills/video-assemble/scripts/jianying/__init__.py +1 -0
- package/lib/video-recap/skills/video-assemble/scripts/{jianying_builders.py → jianying/builders.py} +39 -67
- package/lib/video-recap/skills/video-assemble/scripts/{jianying_model.py → jianying/model.py} +3 -11
- package/lib/video-recap/skills/video-assemble/scripts/{jianying_optional.py → jianying/optional.py} +1 -1
- package/lib/video-recap/skills/video-assemble/scripts/jianying/schema.py +53 -0
- package/lib/video-recap/skills/video-assemble/scripts/{jianying_templates.py → jianying/templates.py} +1 -1
- package/lib/video-recap/skills/video-assemble/scripts/{jianying_timeline_contract.py → jianying/timeline_contract.py} +34 -13
- package/lib/video-recap/skills/video-assemble/scripts/{jianying_writer.py → jianying/writer.py} +7 -17
- package/lib/video-recap/skills/video-assemble/scripts/lib.py +37 -4
- package/lib/video-recap/skills/video-assemble/scripts/media.py +12 -21
- package/lib/video-recap/skills/video-assemble/scripts/narration_audio.py +64 -34
- package/lib/video-recap/skills/video-assemble/scripts/packaging.py +122 -0
- package/lib/video-recap/skills/video-assemble/scripts/pair_media.py +216 -0
- package/lib/video-recap/skills/video-assemble/scripts/render_preflight.py +1 -3
- package/lib/video-recap/skills/video-assemble/scripts/source_score.py +469 -0
- package/lib/video-recap/skills/video-assemble/scripts/source_subtitles.py +25 -9
- package/lib/video-recap/skills/video-assemble/scripts/subtitles/__init__.py +1 -0
- package/lib/video-recap/skills/video-assemble/scripts/{subtitle_core.py → subtitles/core.py} +13 -6
- package/lib/video-recap/skills/video-assemble/scripts/{subtitle_render.py → subtitles/render.py} +5 -4
- package/lib/video-recap/skills/video-assemble/scripts/subtitles/track.py +324 -0
- package/lib/video-recap/skills/video-assemble/scripts/subtitles/track_binding.py +200 -0
- package/lib/video-recap/skills/video-assemble/scripts/timeline.py +30 -46
- package/lib/video-recap/skills/video-assemble/scripts/timeline_emit.py +91 -7
- package/lib/video-recap/skills/video-assemble/scripts/visual_render.py +22 -8
- package/lib/video-recap/skills/video-cut/SKILL.md +34 -16
- package/lib/video-recap/skills/video-cut/references/shot-review.md +50 -0
- package/lib/video-recap/skills/video-cut/scripts/cut.py +2 -28
- package/lib/video-recap/skills/video-cut/scripts/cut_cli.py +58 -62
- package/lib/video-recap/skills/video-cut/scripts/cut_contract.py +21 -106
- package/lib/video-recap/skills/video-cut/scripts/cut_render.py +14 -9
- package/lib/video-recap/skills/video-cut/scripts/lib.py +39 -0
- package/lib/video-recap/skills/video-cut/scripts/narration_mapping.py +2 -155
- package/lib/video-recap/skills/video-cut/scripts/narrative_selection.py +244 -0
- package/lib/video-recap/skills/video-cut/scripts/shot_review.py +357 -0
- package/lib/video-recap/skills/video-recap/SKILL.md +86 -42
- package/lib/video-recap/skills/video-recap/references/audio-routing.md +126 -0
- package/lib/video-recap/skills/video-recap/references/config-playbook.md +12 -8
- package/lib/video-recap/skills/video-recap/references/data-schema.md +44 -33
- package/lib/video-recap/skills/video-recap/references/resource-library.md +151 -0
- package/lib/video-recap/skills/video-recap/references/shift-left-qc-schema.md +1 -1
- package/lib/video-recap/skills/video-recap/scripts/doctor.py +123 -30
- package/lib/video-recap/skills/video-recap/scripts/final_qc.py +22 -75
- package/lib/video-recap/skills/video-recap/scripts/lib.py +3 -3
- package/lib/video-recap/skills/video-recap/scripts/library.py +509 -0
- package/lib/video-recap/skills/video-recap/scripts/materials.py +63 -91
- package/lib/video-recap/skills/video-recap/scripts/mimo_qc.py +8 -70
- package/lib/video-recap/skills/video-recap/scripts/project_binding.py +286 -0
- package/lib/video-recap/skills/video-recap/scripts/qc/__init__.py +1 -0
- package/lib/video-recap/skills/video-recap/scripts/{mimo_qc_client.py → qc/mimo_client.py} +1 -1
- package/lib/video-recap/skills/video-recap/scripts/{mimo_qc_evidence.py → qc/mimo_evidence.py} +33 -66
- package/lib/video-recap/skills/video-recap/scripts/{mimo_qc_observations.py → qc/mimo_observations.py} +3 -11
- package/lib/video-recap/skills/video-recap/scripts/{mimo_qc_payload.py → qc/mimo_payload.py} +4 -7
- package/lib/video-recap/skills/video-recap/scripts/{mimo_qc_report.py → qc/mimo_report.py} +17 -28
- package/lib/video-recap/skills/video-recap/scripts/{mimo_qc_runner.py → qc/mimo_runner.py} +2 -2
- package/lib/video-recap/skills/video-recap/scripts/qc_contract.py +0 -19
- package/lib/video-recap/skills/video-recap/scripts/recap_cli.py +119 -50
- package/lib/video-recap/skills/video-recap/scripts/recap_inspect.py +32 -114
- package/lib/video-recap/skills/video-recap/scripts/recap_review.py +9 -23
- package/lib/video-recap/skills/video-recap/scripts/recap_runner.py +387 -334
- package/lib/video-recap/skills/video-recap/scripts/recap_runtime.py +23 -23
- package/lib/video-recap/skills/video-recap/scripts/recap_source.py +278 -0
- package/lib/video-recap/skills/video-recap/scripts/recap_stage_qc.py +25 -12
- package/lib/video-recap/skills/video-recap/scripts/recap_timeline.py +59 -52
- package/lib/video-recap/skills/video-recap/scripts/resource_lock.py +162 -0
- package/lib/video-recap/skills/video-script/SKILL.md +16 -13
- package/lib/video-recap/skills/video-script/references/creative-editing-playbook.md +9 -5
- package/lib/video-recap/skills/video-script/references/promotional-copy.md +68 -0
- package/lib/video-recap/skills/video-script/references/research-guide.md +1 -1
- package/lib/video-recap/skills/video-script/scripts/evidence_bundle.py +24 -76
- package/lib/video-recap/skills/video-script/scripts/lib.py +10 -87
- package/lib/video-recap/skills/video-script/scripts/narration_lint.py +63 -39
- package/lib/video-recap/skills/video-script/scripts/review.py +0 -2
- package/lib/video-recap/skills/video-script/scripts/review_grounding.py +35 -59
- package/lib/video-recap/skills/video-script/scripts/review_response.py +66 -128
- package/lib/video-recap/skills/video-script/scripts/review_runner.py +12 -20
- package/lib/video-recap/skills/video-script/scripts/speech_ownership.py +4 -4
- package/lib/video-recap/skills/video-script/scripts/validate.py +53 -42
- package/lib/video-recap/skills/video-understanding/SKILL.md +6 -4
- package/lib/video-recap/skills/video-understanding/references/data-schema.md +50 -156
- package/lib/video-recap/skills/video-understanding/references/research-guide.md +4 -4
- package/lib/video-recap/skills/video-understanding/scripts/asr.py +85 -65
- package/lib/video-recap/skills/video-understanding/scripts/asr_timing_evidence.py +270 -0
- package/lib/video-recap/skills/video-understanding/scripts/brief.py +2 -5
- package/lib/video-recap/skills/video-understanding/scripts/briefing/__init__.py +1 -0
- package/lib/video-recap/skills/video-understanding/scripts/{agent_brief.py → briefing/builder.py} +38 -35
- package/lib/video-recap/skills/{video-script/scripts/brief_context.py → video-understanding/scripts/briefing/context.py} +4 -35
- package/lib/video-recap/skills/{video-script/scripts/brief_inputs.py → video-understanding/scripts/briefing/inputs.py} +9 -31
- package/lib/video-recap/skills/video-understanding/scripts/{brief_timeline.py → briefing/timeline.py} +5 -6
- package/lib/video-recap/skills/video-understanding/scripts/consolidate.py +65 -116
- package/lib/video-recap/skills/video-understanding/scripts/detect.py +31 -40
- package/lib/video-recap/skills/video-understanding/scripts/lib.py +30 -86
- package/lib/video-recap/skills/video-understanding/scripts/narration_lint.py +63 -39
- package/lib/video-recap/skills/video-understanding/scripts/speech_ownership.py +4 -4
- package/lib/video-recap/skills/video-understanding/scripts/storyboard.py +17 -79
- package/lib/video-recap/skills/video-understanding/scripts/understanding_brief.py +14 -40
- package/lib/video-recap/skills/video-understanding/scripts/understanding_cache.py +64 -46
- package/lib/video-recap/skills/video-understanding/scripts/understanding_runner.py +31 -11
- package/lib/video-recap/skills/video-understanding/scripts/understanding_storyboard.py +19 -14
- package/lib/video-recap/skills/video-understanding/scripts/vlm.py +80 -108
- package/lib/video-recap/skills/video-voiceover/SKILL.md +29 -19
- package/lib/video-recap/skills/video-voiceover/references/index-tts.md +31 -0
- package/lib/video-recap/skills/video-voiceover/scripts/approved_text_policy.py +123 -0
- package/lib/video-recap/skills/video-voiceover/scripts/dub.py +51 -59
- package/lib/video-recap/skills/video-voiceover/scripts/lib.py +8 -44
- package/lib/video-recap/skills/video-voiceover/scripts/providers/__init__.py +1 -0
- package/lib/video-recap/skills/video-voiceover/scripts/providers/index_tts.py +184 -0
- package/lib/video-recap/skills/video-voiceover/scripts/voiceover.py +212 -134
- package/package.json +1 -1
- package/lib/oh-story/skills/story-long-analyze/references/material-decomposition.md +0 -538
- package/lib/oh-story/skills/story-long-analyze/references/output-templates.md +0 -603
- package/lib/oh-story/skills/story-long-scan/references/scan-output-format.md +0 -207
- package/lib/oh-story/skills/story-short-analyze/references/output-templates.md +0 -561
- package/lib/video-recap/skills/video-assemble/scripts/jianying_schema.py +0 -98
- package/lib/video-recap/skills/video-recap/references/creative-editing-playbook.md +0 -225
- package/lib/video-recap/skills/video-recap/references/research-guide.md +0 -74
- package/lib/video-recap/skills/video-recap/references/timeline-and-jianying.md +0 -250
- package/lib/video-recap/skills/video-script/scripts/agent_brief.py +0 -399
- package/lib/video-recap/skills/video-script/scripts/brief_timeline.py +0 -327
- package/lib/video-recap/skills/video-script/scripts/narration.py +0 -12
- package/lib/video-recap/skills/video-understanding/scripts/brief_context.py +0 -348
- package/lib/video-recap/skills/video-understanding/scripts/brief_inputs.py +0 -290
- /package/lib/video-recap/skills/video-assemble/scripts/{jianying_tracks.py → jianying/tracks.py} +0 -0
- /package/lib/video-recap/skills/video-recap/scripts/{mimo_qc_contract.py → qc/mimo_contract.py} +0 -0
- /package/lib/video-recap/skills/video-voiceover/scripts/{fish_audio.py → providers/fish_audio.py} +0 -0
|
@@ -40,10 +40,6 @@ def _load_fixture(value: Any) -> Any:
|
|
|
40
40
|
return load_json(value)
|
|
41
41
|
|
|
42
42
|
|
|
43
|
-
def fingerprint_file(path: Path) -> str | None:
|
|
44
|
-
return qc_contract.artifact_fingerprint(path) if path.is_file() else None
|
|
45
|
-
|
|
46
|
-
|
|
47
43
|
def _resolve_in_work_dir(work_dir: Path, path: str | Path) -> Path:
|
|
48
44
|
p = Path(path)
|
|
49
45
|
return p if p.is_absolute() else work_dir / p
|
|
@@ -57,28 +53,21 @@ def _read_json_mapping(path: Path) -> Mapping[str, Any] | None:
|
|
|
57
53
|
return data if isinstance(data, Mapping) else None
|
|
58
54
|
|
|
59
55
|
|
|
60
|
-
def
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
candidates += [work_dir / name for name in ("output.mp4", "recap.mp4", "final.mp4")]
|
|
71
|
-
return list(dict.fromkeys(candidates))
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
def _select_final_output(work_dir: Path, final_output: str | Path | None) -> Path:
|
|
75
|
-
candidates = _candidate_final_outputs(work_dir, final_output)
|
|
76
|
-
if final_output is not None:
|
|
77
|
-
return candidates[0]
|
|
78
|
-
return next((path for path in candidates if path.is_file() and path.stat().st_size > 0), candidates[0])
|
|
56
|
+
def _final_output_path(work_dir: Path, final_output: str | Path | None) -> Path | None:
|
|
57
|
+
"""The rendered final output: the caller's path, else assembly_manifest.final_output
|
|
58
|
+
(video-assemble always writes it; output.mp4 is only the assembler's intermediate).
|
|
59
|
+
None when neither exists yet, which the report surfaces as a missing final output."""
|
|
60
|
+
if final_output is None:
|
|
61
|
+
manifest = work_dir / "assembly_manifest.json"
|
|
62
|
+
if not manifest.is_file():
|
|
63
|
+
return None
|
|
64
|
+
final_output = load_json(manifest)["final_output"]
|
|
65
|
+
return _resolve_in_work_dir(work_dir, final_output)
|
|
79
66
|
|
|
80
67
|
|
|
81
|
-
def _file_metadata(path: Path, work_dir: Path) -> dict[str, Any]:
|
|
68
|
+
def _file_metadata(path: Path | None, work_dir: Path) -> dict[str, Any]:
|
|
69
|
+
if path is None:
|
|
70
|
+
return {"path": "(assembly_manifest.json missing)", "exists": False, "bytes": 0}
|
|
82
71
|
try:
|
|
83
72
|
display = path.relative_to(work_dir).as_posix()
|
|
84
73
|
except ValueError: # final outputs normally live next to work_dir, not inside it
|
|
@@ -88,7 +77,6 @@ def _file_metadata(path: Path, work_dir: Path) -> dict[str, Any]:
|
|
|
88
77
|
"path": display,
|
|
89
78
|
"exists": exists,
|
|
90
79
|
"bytes": path.stat().st_size if exists else 0,
|
|
91
|
-
"fingerprint": fingerprint_file(path),
|
|
92
80
|
}
|
|
93
81
|
|
|
94
82
|
|
|
@@ -107,13 +95,9 @@ def _artifact_summary(work_dir: Path, name: str) -> dict[str, Any]:
|
|
|
107
95
|
return meta
|
|
108
96
|
|
|
109
97
|
|
|
110
|
-
def _artifact_fingerprints(*paths: Path) -> dict[str, str]:
|
|
111
|
-
return {path.name: fp for path in paths if (fp := fingerprint_file(path))}
|
|
112
|
-
|
|
113
|
-
|
|
114
98
|
def _finding(*, finding_id: str, code: str, message: str, category: str = "schema_invalid",
|
|
115
99
|
stage: str = POST_RENDER_STAGE, source: Mapping[str, Any] | None = None,
|
|
116
|
-
evidence: Mapping[str, Any] | None = None,
|
|
100
|
+
evidence: Mapping[str, Any] | None = None,
|
|
117
101
|
next_action: str = "manual_review") -> dict[str, Any]:
|
|
118
102
|
return qc_contract.build_finding(
|
|
119
103
|
finding_id=finding_id,
|
|
@@ -128,7 +112,6 @@ def _finding(*, finding_id: str, code: str, message: str, category: str = "schem
|
|
|
128
112
|
blocking=True,
|
|
129
113
|
source=source,
|
|
130
114
|
evidence=evidence,
|
|
131
|
-
artifact_fingerprints=fingerprints,
|
|
132
115
|
next_action=next_action,
|
|
133
116
|
model_used="local_deterministic_final_qc_v1",
|
|
134
117
|
)
|
|
@@ -235,7 +218,7 @@ def _probe_fps(video_stream: Mapping[str, Any] | None) -> tuple[float | None, st
|
|
|
235
218
|
])
|
|
236
219
|
|
|
237
220
|
|
|
238
|
-
def _probe_contract_findings(probe: Mapping[str, Any], *, final_meta: Mapping[str, Any]
|
|
221
|
+
def _probe_contract_findings(probe: Mapping[str, Any], *, final_meta: Mapping[str, Any]) -> list[dict[str, Any]]:
|
|
239
222
|
findings: list[dict[str, Any]] = []
|
|
240
223
|
source = {"artifact": final_meta["path"]}
|
|
241
224
|
video_stream = _first_video_stream(probe)
|
|
@@ -247,7 +230,6 @@ def _probe_contract_findings(probe: Mapping[str, Any], *, final_meta: Mapping[st
|
|
|
247
230
|
category="stream",
|
|
248
231
|
source=source,
|
|
249
232
|
evidence={"streams": probe.get("streams")},
|
|
250
|
-
fingerprints=fingerprints,
|
|
251
233
|
next_action="rerender_final_output_with_video_stream",
|
|
252
234
|
))
|
|
253
235
|
|
|
@@ -260,7 +242,6 @@ def _probe_contract_findings(probe: Mapping[str, Any], *, final_meta: Mapping[st
|
|
|
260
242
|
category="duration",
|
|
261
243
|
source=source,
|
|
262
244
|
evidence={"duration": raw},
|
|
263
|
-
fingerprints=fingerprints,
|
|
264
245
|
next_action="rerender_final_output_with_valid_duration",
|
|
265
246
|
))
|
|
266
247
|
|
|
@@ -272,7 +253,6 @@ def _probe_contract_findings(probe: Mapping[str, Any], *, final_meta: Mapping[st
|
|
|
272
253
|
category="stream",
|
|
273
254
|
source=source,
|
|
274
255
|
evidence={"video_stream": video_stream},
|
|
275
|
-
fingerprints=fingerprints,
|
|
276
256
|
next_action="rerender_final_output_with_video_codec",
|
|
277
257
|
))
|
|
278
258
|
|
|
@@ -285,7 +265,6 @@ def _probe_contract_findings(probe: Mapping[str, Any], *, final_meta: Mapping[st
|
|
|
285
265
|
category="stream",
|
|
286
266
|
source=source,
|
|
287
267
|
evidence={"fps": raw, "video_stream": video_stream},
|
|
288
|
-
fingerprints=fingerprints,
|
|
289
268
|
next_action="rerender_final_output_with_valid_fps",
|
|
290
269
|
))
|
|
291
270
|
return findings
|
|
@@ -297,35 +276,13 @@ def _upstream_blockers(work_dir: Path, artifact_name: str) -> list[dict[str, Any
|
|
|
297
276
|
if not path.exists():
|
|
298
277
|
return []
|
|
299
278
|
data = _read_json_mapping(path)
|
|
300
|
-
|
|
301
|
-
invalid = data is None
|
|
302
|
-
codes = data.get("blocking_codes") if data is not None else None
|
|
303
|
-
if not invalid and codes is None:
|
|
304
|
-
findings = data.get("findings")
|
|
305
|
-
invalid = not isinstance(findings, list) or any(
|
|
306
|
-
not isinstance(finding, Mapping)
|
|
307
|
-
or not isinstance(finding.get("blocking"), bool)
|
|
308
|
-
or not isinstance(finding.get("code"), str)
|
|
309
|
-
or not finding["code"]
|
|
310
|
-
for finding in findings or []
|
|
311
|
-
)
|
|
312
|
-
if not invalid:
|
|
313
|
-
codes = [finding["code"] for finding in findings if finding["blocking"]]
|
|
314
|
-
elif isinstance(codes, str):
|
|
315
|
-
codes = [codes]
|
|
316
|
-
elif not invalid and (
|
|
317
|
-
not isinstance(codes, list)
|
|
318
|
-
or any(not isinstance(code, str) or not code for code in codes)
|
|
319
|
-
):
|
|
320
|
-
invalid = True
|
|
321
|
-
if invalid:
|
|
279
|
+
if data is None: # unreadable upstream QC is itself a deterministic blocker
|
|
322
280
|
return [_finding(
|
|
323
281
|
finding_id=f"final-qc-invalid-upstream-{artifact_name}",
|
|
324
282
|
code=f"upstream_{artifact_name.replace('.', '_')}_schema_invalid",
|
|
325
283
|
message=f"{artifact_name} is not a valid deterministic QC report",
|
|
326
284
|
source={"artifact": artifact_name},
|
|
327
285
|
evidence={"schema_invalid": True},
|
|
328
|
-
fingerprints={artifact_name: fp},
|
|
329
286
|
next_action="regenerate_upstream_qc",
|
|
330
287
|
)]
|
|
331
288
|
return [
|
|
@@ -334,18 +291,17 @@ def _upstream_blockers(work_dir: Path, artifact_name: str) -> list[dict[str, Any
|
|
|
334
291
|
code=f"upstream_{artifact_name.replace('.', '_')}_{code}",
|
|
335
292
|
message=f"{artifact_name} reported {code}",
|
|
336
293
|
source={"artifact": artifact_name},
|
|
337
|
-
evidence={"upstream_code": code, "upstream_verdict": data
|
|
338
|
-
fingerprints={artifact_name: fp},
|
|
294
|
+
evidence={"upstream_code": code, "upstream_verdict": data["verdict"]},
|
|
339
295
|
next_action="fix_upstream_qc_blocker",
|
|
340
296
|
)
|
|
341
|
-
for idx, code in enumerate(
|
|
297
|
+
for idx, code in enumerate(data["blocking_codes"])
|
|
342
298
|
]
|
|
343
299
|
|
|
344
300
|
|
|
345
301
|
def collect_metadata(work_dir: str | Path, *, final_output: str | Path | None = None,
|
|
346
302
|
probe_fixture: Any = None, probe_runner: ProbeRunner | None = None) -> dict[str, Any]:
|
|
347
303
|
root = Path(work_dir)
|
|
348
|
-
selected =
|
|
304
|
+
selected = _final_output_path(root, final_output)
|
|
349
305
|
probe = probe_error = None
|
|
350
306
|
final_meta = _file_metadata(selected, root)
|
|
351
307
|
if final_meta["exists"] and final_meta["bytes"] > 0:
|
|
@@ -353,7 +309,6 @@ def collect_metadata(work_dir: str | Path, *, final_output: str | Path | None =
|
|
|
353
309
|
return {
|
|
354
310
|
"work_dir": str(root),
|
|
355
311
|
"final_output": final_meta,
|
|
356
|
-
"final_output_candidates": [_file_metadata(p, root) for p in _candidate_final_outputs(root, final_output)],
|
|
357
312
|
"artifacts": {name: _artifact_summary(root, name) for name in _COLLECT_ARTIFACTS},
|
|
358
313
|
"probe": probe,
|
|
359
314
|
"probe_error": probe_error,
|
|
@@ -366,11 +321,10 @@ def build_final_qc(work_dir: str | Path, final_output: str | Path | None = None,
|
|
|
366
321
|
probe_fixture: Any = None, probe_runner: ProbeRunner | None = None,
|
|
367
322
|
decode_runner: Callable[[Path], tuple[bool | None, str | None]] | None = None) -> dict[str, Any]:
|
|
368
323
|
root = Path(work_dir)
|
|
369
|
-
selected =
|
|
324
|
+
selected = _final_output_path(root, final_output)
|
|
370
325
|
metadata = collect_metadata(root, final_output=final_output, probe_fixture=probe_fixture, probe_runner=probe_runner)
|
|
371
326
|
final_meta = metadata["final_output"]
|
|
372
327
|
findings: list[dict[str, Any]] = []
|
|
373
|
-
fps = _artifact_fingerprints(selected)
|
|
374
328
|
if not final_meta["exists"]:
|
|
375
329
|
findings.append(_finding(
|
|
376
330
|
finding_id="final-qc-missing-final-output",
|
|
@@ -379,7 +333,6 @@ def build_final_qc(work_dir: str | Path, final_output: str | Path | None = None,
|
|
|
379
333
|
category="missing_artifact",
|
|
380
334
|
source={"artifact": str(final_output) if final_output else "final_output"},
|
|
381
335
|
evidence={"final_output": final_meta},
|
|
382
|
-
fingerprints=fps,
|
|
383
336
|
next_action="render_final_output",
|
|
384
337
|
))
|
|
385
338
|
elif final_meta["bytes"] == 0:
|
|
@@ -390,7 +343,6 @@ def build_final_qc(work_dir: str | Path, final_output: str | Path | None = None,
|
|
|
390
343
|
category="missing_artifact",
|
|
391
344
|
source={"artifact": final_meta["path"]},
|
|
392
345
|
evidence={"final_output": final_meta},
|
|
393
|
-
fingerprints=fps,
|
|
394
346
|
next_action="rerender_final_output",
|
|
395
347
|
))
|
|
396
348
|
elif metadata["probe_error"] is not None:
|
|
@@ -401,11 +353,10 @@ def build_final_qc(work_dir: str | Path, final_output: str | Path | None = None,
|
|
|
401
353
|
category="stream",
|
|
402
354
|
source={"artifact": final_meta["path"]},
|
|
403
355
|
evidence=metadata["probe_error"],
|
|
404
|
-
fingerprints=fps,
|
|
405
356
|
next_action="inspect_or_rerender_final_output",
|
|
406
357
|
))
|
|
407
358
|
else:
|
|
408
|
-
probe_findings = _probe_contract_findings(metadata["probe"], final_meta=final_meta
|
|
359
|
+
probe_findings = _probe_contract_findings(metadata["probe"], final_meta=final_meta)
|
|
409
360
|
findings.extend(probe_findings)
|
|
410
361
|
# Header probing cannot see a container-valid but media-truncated/corrupt payload.
|
|
411
362
|
# A cheap tail decode catches it; skip for offline fixtures and when ffmpeg is absent
|
|
@@ -420,8 +371,7 @@ def build_final_qc(work_dir: str | Path, final_output: str | Path | None = None,
|
|
|
420
371
|
category="stream",
|
|
421
372
|
source={"artifact": final_meta["path"]},
|
|
422
373
|
evidence={"decode_error": decode_detail},
|
|
423
|
-
|
|
424
|
-
next_action="rerender_final_output",
|
|
374
|
+
next_action="rerender_final_output",
|
|
425
375
|
))
|
|
426
376
|
for name in _UPSTREAM_QC_ARTIFACTS:
|
|
427
377
|
findings.extend(_upstream_blockers(root, name))
|
|
@@ -445,12 +395,10 @@ def build_golden_eval(work_dir: str | Path, final_qc_report: Mapping[str, Any] |
|
|
|
445
395
|
root = Path(work_dir)
|
|
446
396
|
final_report = _load_or_build_final_qc(root, final_qc_report)
|
|
447
397
|
fixture = _load_fixture(golden_fixture) if golden_fixture is not None else {}
|
|
448
|
-
final_fp = fingerprint_file(root / FINAL_QC_ARTIFACT)
|
|
449
398
|
metadata = {
|
|
450
399
|
"work_dir": str(root),
|
|
451
400
|
"fixture": fixture,
|
|
452
401
|
"final_qc": {key: final_report[key] for key in ("ok", "blocker_count", "artifact", "stage")},
|
|
453
|
-
"final_qc_fingerprint": final_fp,
|
|
454
402
|
"auto_repair": False,
|
|
455
403
|
}
|
|
456
404
|
findings: list[dict[str, Any]] = []
|
|
@@ -464,7 +412,6 @@ def build_golden_eval(work_dir: str | Path, final_qc_report: Mapping[str, Any] |
|
|
|
464
412
|
category="schema_invalid",
|
|
465
413
|
source={"artifact": FINAL_QC_ARTIFACT},
|
|
466
414
|
evidence={"expected": expected_ok, "actual": final_report["ok"]},
|
|
467
|
-
fingerprints={FINAL_QC_ARTIFACT: final_fp} if final_fp else {},
|
|
468
415
|
next_action="fix_final_qc_blockers",
|
|
469
416
|
))
|
|
470
417
|
final_meta = final_report["metadata"]["final_output"]
|
|
@@ -113,8 +113,8 @@ CONFIG = {
|
|
|
113
113
|
"api_url": normalize_api_url(_raw_api_url),
|
|
114
114
|
"api_url_source": "env" if os.environ.get("MIMO_API_URL") else "default",
|
|
115
115
|
"api_key": _mimo_api_key,
|
|
116
|
-
"
|
|
117
|
-
# Read through a COPY of CONFIG by
|
|
116
|
+
"api_env_var": "MIMO_API_KEY",
|
|
117
|
+
# Read through a COPY of CONFIG by qc.mimo_evidence._effective_config /
|
|
118
118
|
# safe_mimo_config, which is why neither a `CONFIG.get(...)` grep nor live-dict
|
|
119
119
|
# instrumentation sees them. They drive the QC model fallback chain and the
|
|
120
120
|
# provenance recorded in the QC report.
|
|
@@ -145,7 +145,7 @@ CONFIG = {
|
|
|
145
145
|
os.environ.get("MIMO_ASR_API_URL") or os.environ.get("MIMO_API_URL")
|
|
146
146
|
) else "default",
|
|
147
147
|
"mimo_asr_api_key": _mimo_asr_api_key,
|
|
148
|
-
"
|
|
148
|
+
"mimo_asr_env_var": "MIMO_ASR_API_KEY" if os.environ.get("MIMO_ASR_API_KEY") else "MIMO_API_KEY",
|
|
149
149
|
"mimo_video_model": os.environ.get("MIMO_VIDEO_MODEL") or os.environ.get("MIMO_MODEL", DEFAULT_MIMO_MODEL),
|
|
150
150
|
"mimo_video_model_source": "env" if (
|
|
151
151
|
os.environ.get("MIMO_VIDEO_MODEL") or os.environ.get("MIMO_MODEL")
|