@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
|
@@ -346,9 +346,17 @@ function renderAgeGate() {
|
|
|
346
346
|
function renderTitle() {
|
|
347
347
|
const saved = loadSave();
|
|
348
348
|
const hasSave = !!saved;
|
|
349
|
+
const titleCast = [
|
|
350
|
+
['月娘', '定账'],
|
|
351
|
+
['金莲', '识谎'],
|
|
352
|
+
['瓶儿', '私钥'],
|
|
353
|
+
['玉楼', '名帖'],
|
|
354
|
+
['雪娥', '灶权'],
|
|
355
|
+
];
|
|
349
356
|
app.innerHTML = `
|
|
350
357
|
<main class="title-screen">
|
|
351
358
|
<div class="title-art" style="background-image:url('${urlFor('cover')}')" role="img" aria-label="月娘、金莲、瓶儿、玉楼与雪娥各据一处,五道视线都落在你身上"></div>
|
|
359
|
+
<aside class="title-folio" aria-hidden="true"><b>风月总账</b><span>二十日 · 四幕</span></aside>
|
|
352
360
|
<section class="title-copy">
|
|
353
361
|
<p class="eyebrow">成人后宫关系游戏 · 二十日四幕</p>
|
|
354
362
|
<h1>${TEXT.title}</h1>
|
|
@@ -362,6 +370,9 @@ function renderTitle() {
|
|
|
362
370
|
<p class="rating-line">${TEXT.rating}</p>
|
|
363
371
|
<p class="save-note">${TEXT.saveNote}</p>
|
|
364
372
|
</section>
|
|
373
|
+
<ol class="title-cast" aria-label="五院与各自握有的权力">
|
|
374
|
+
${titleCast.map(([name, role], index) => `<li><i>${index + 1}</i><span>${name}</span><b>${role}</b></li>`).join('')}
|
|
375
|
+
</ol>
|
|
365
376
|
</main>`;
|
|
366
377
|
if (newGameConfirmOpen && hasSave) appendNewGameConfirm(saved);
|
|
367
378
|
if (galleryOpen) appendGallery();
|
|
@@ -903,8 +914,9 @@ function renderOpening() {
|
|
|
903
914
|
return `
|
|
904
915
|
<div class="opening-scene visual-stage" style="--scene-bg:url('${urlFor('cover')}')">
|
|
905
916
|
<div class="decision-panel opening-panel">
|
|
906
|
-
|
|
907
|
-
|
|
917
|
+
<div class="opening-case" aria-hidden="true"><span>初日</span><b>一</b><i>正堂·灯下</i></div>
|
|
918
|
+
${phaseHeader('正堂 · 五更尽', '账上空了五十两', '窗纸还没有亮。月娘把两本账摊在灯下,其中一页有一行新墨。金莲坐在桌另一头,指尖还按着一只没人喝的酒杯。')}
|
|
919
|
+
<p class="speaker-line"><b>月娘</b>“你先看账。”<br/><b>金莲</b>“也先听听人怎么说。”</p>
|
|
908
920
|
<div class="choice-grid">${OPENING_CHOICES.map((choice) => choiceButton(choice, 'opening')).join('')}</div>
|
|
909
921
|
</div>
|
|
910
922
|
</div>`;
|
|
@@ -1262,7 +1274,8 @@ function renderDay() {
|
|
|
1262
1274
|
return `
|
|
1263
1275
|
<div class="hub-stage visual-stage" style="--scene-bg:url('${urlFor('compound')}')">
|
|
1264
1276
|
<div class="decision-panel day-panel">
|
|
1265
|
-
|
|
1277
|
+
<div class="day-scene-mark" aria-hidden="true"><span>DAY</span><b>${String(state.day).padStart(2, '0')}</b><i>${escapeHtml(def.act)}</i></div>
|
|
1278
|
+
${phaseHeader(`第 ${state.day} 日 · 院中`, def.name, `${def.pressure} ${def.tell}`)}
|
|
1266
1279
|
${contextSection}
|
|
1267
1280
|
${renderEvidenceBoard()}
|
|
1268
1281
|
<div class="day-actions">${dayOptions.map((choice) => choiceButton({ ...choice, hint: `${choice.actor ? `${HEROINES[choice.actor].short} · ` : ''}${choice.hint}`, meta: '' }, 'day-action')).join('')}</div>
|
|
@@ -1289,7 +1302,7 @@ function renderDayAftermath() {
|
|
|
1289
1302
|
return `<figure class="${row.delta > 0 ? 'accepts' : 'resists'}"><img src="${urlFor(heroine.portrait)}" alt="${heroine.name}"/><figcaption><span>${escapeHtml(row.tone)}</span><b>${heroine.name}</b><p>${escapeHtml(row.text)}</p></figcaption></figure>`;
|
|
1290
1303
|
}).join('')}</div>`
|
|
1291
1304
|
: '';
|
|
1292
|
-
const consequence = beat.resolved === null ? '' : `<div class="day-consequence ${beat.resolved ? 'resolved' : 'missed'}"><span>${beat.resolved ? '
|
|
1305
|
+
const consequence = beat.resolved === null ? '' : `<div class="day-consequence ${beat.resolved ? 'resolved' : 'missed'}"><span>${beat.resolved ? '这件事暂时稳住了' : '还有一处没有堵住'}</span><b>${beat.resolved ? '人、物和原话都留在眼前,明日还能顺着查下去。' : '眼前的好处拿到了,门外那只手却已经换了一条路。'}</b></div>`;
|
|
1293
1306
|
return `
|
|
1294
1307
|
<div class="day-aftermath-stage visual-stage dialogue-${story.actor} beat-${beat.id}" data-day-aftermath="${beat.id}" style="--scene-bg:url('${urlFor(actor.close || actor.portrait)}')">
|
|
1295
1308
|
<div class="day-aftermath-lead" aria-hidden="true" style="background-image:url('${urlFor(actor.close || actor.portrait)}')"></div>
|
|
@@ -1642,9 +1655,9 @@ function renderSharedNight() {
|
|
|
1642
1655
|
return `
|
|
1643
1656
|
<div class="shared-stage visual-stage" style="--scene-bg:url('${urlFor(backdrop)}')">
|
|
1644
1657
|
<div class="decision-panel shared-panel">
|
|
1645
|
-
${phaseHeader('第二十夜 · 五人都没走', '
|
|
1658
|
+
${phaseHeader('第二十夜 · 五人都没走', '茶还热着,五把钥匙各在主人手里', TEXT.sharedNightLead)}
|
|
1646
1659
|
<div class="accord-seals shared-seals">${rows.map((row) => `<span class="accord-seal ${row.complete ? 'complete' : ''}" data-accord="${row.key}"><i>${row.glyph}</i>${row.label}</span>`).join('')}</div>
|
|
1647
|
-
<p class="shared-proof">${narrativeProgress(Math.min(E.jointActionCount(state), E.JOINT_ACTION_TARGET), E.JOINT_ACTION_TARGET, ['
|
|
1660
|
+
<p class="shared-proof">${narrativeProgress(Math.min(E.jointActionCount(state), E.JOINT_ACTION_TARGET), E.JOINT_ACTION_TARGET, ['她们还没有一起做过事', '已有人并肩做完一桩事', '五组搭档都真正共过事'])} · ${narrativeProgress(state.resolvedPressures.length, E.PRESSURE_TARGET, ['门外的事还在逼近', '她们已一起撑过几回', '今夜终于有余地谈自己'])}</p>
|
|
1648
1661
|
<div class="choice-grid">${E.sharedNightOptions(state).map((choice) => choiceButton(choice, 'shared-night')).join('')}</div>
|
|
1649
1662
|
</div>
|
|
1650
1663
|
</div>`;
|
|
@@ -1657,7 +1670,7 @@ function renderSharedAfterglow() {
|
|
|
1657
1670
|
<div class="afterglow-stage visual-stage" data-shared-beat="${beat.id}" style="--scene-bg:url('${urlFor('cg/group/inner_court_accord')}')">
|
|
1658
1671
|
<div class="decision-panel afterglow-panel">
|
|
1659
1672
|
${phaseHeader(beat.kicker, beat.title, beat.body)}
|
|
1660
|
-
<p class="shared-proof"
|
|
1673
|
+
<p class="shared-proof">灯还亮着 · ${narrativeStep(state.sharedAfterglowChoices.length + 1, SHARED_AFTERGLOW_BEATS.length)} · 这一步要等五个人都开口</p>
|
|
1661
1674
|
<div class="choice-grid">${E.sharedAfterglowOptions(state).map((choice) => choiceButton(choice, 'shared-afterglow')).join('')}</div>
|
|
1662
1675
|
</div>
|
|
1663
1676
|
</div>`;
|
|
@@ -1771,9 +1784,10 @@ function renderVisit() {
|
|
|
1771
1784
|
<div class="dialogue-stage visual-stage dialogue-${id}">
|
|
1772
1785
|
<div class="close-cg" style="background-image:url('${urlFor(h.close)}')" role="img" aria-label="${h.name}近景"></div>
|
|
1773
1786
|
<div class="decision-panel dialogue-panel">
|
|
1774
|
-
|
|
1775
|
-
|
|
1776
|
-
|
|
1787
|
+
<div class="character-seal" aria-hidden="true"><i>${h.glyph}</i><span>${h.house}</span></div>
|
|
1788
|
+
${phaseHeader(`第 ${state.day} 夜 · ${h.house}`, h.name, h.voice)}
|
|
1789
|
+
<p class="want-line"><b>她今夜要你回答</b>${h.want}<br/><span>${h.gives}</span><br/><small>${stance.covenant === stance.private ? (stance.covenant ? '你们既谈家中的事,也留过只在门内的话。' : '这是你们第一次认真谈今后怎样相处。') : stance.covenant > stance.private ? '她记得你更常在人前接住她的事。' : '她记得你更常把话留在门内。'}</small></p>
|
|
1790
|
+
${branch ? `<aside class="route-branch-memory branch-${branch.lane}" data-route-branch="${branch.lane}:${branch.step}"><span>${escapeHtml(branch.label)} · ${branch.lane === 'covenant' ? '她记得你在人前怎样做' : '她记得你在门内怎样说'}</span><b>今夜从这件旧事往下谈</b><p>${escapeHtml(branch.body)}</p></aside>` : ''}
|
|
1777
1791
|
${favorReckoningMemory(id)}
|
|
1778
1792
|
${routeReckoningMemory(id)}
|
|
1779
1793
|
${intimacyMemory(id)}
|
|
@@ -1848,7 +1862,7 @@ function renderRouteAftermath() {
|
|
|
1848
1862
|
${phaseHeader(event.milestone ? '再次进门的关键章' : `路线小章 · ${narrativeStep(event.act, 4)}`, event.title, event.body)}
|
|
1849
1863
|
<p class="aftermath-echo"><span>上一拍</span><b>${escapeHtml(event.sourceLabel)}</b><small>${escapeHtml(event.sourceText)}</small></p>
|
|
1850
1864
|
${routeContinuityCard(event)}
|
|
1851
|
-
<p class="aftermath-question"
|
|
1865
|
+
<p class="aftermath-question">另一处院门已经听见了。你是把话拿到人前,让她们当面说,还是只护住今夜这扇门?</p>
|
|
1852
1866
|
<div class="choice-stack">${E.routeAftermathOptions(state).map((choice) => choiceButton(choice, 'route-aftermath')).join('')}</div>
|
|
1853
1867
|
</div>
|
|
1854
1868
|
</div>`;
|
|
@@ -1886,7 +1900,7 @@ function renderNight() {
|
|
|
1886
1900
|
${phaseHeader(`第 ${state.day} 夜 · 夜谈${narrativeProgress(conversation.chapter, 4, ['刚刚起话', '正在接续', '已成条款'])} · 回答后章${narrativeStep(result.beat + 1, result.count)}`, result.current.title, result.current.body)}
|
|
1887
1901
|
${intimacyMemory(id)}
|
|
1888
1902
|
${result.beat === 0 && conversation.memoryEcho ? `<aside class="night-talk-memory"><span>上一章没有消失</span><p>${escapeHtml(conversation.memoryEcho)}</p></aside>` : ''}
|
|
1889
|
-
<aside class="night-talk-stake" data-night-stake="${result.mode}"><span
|
|
1903
|
+
<aside class="night-talk-stake" data-night-stake="${result.mode}"><span>天亮以后会留下</span><b>${escapeHtml(result.stake.label)} · ${escapeHtml(narrativeChoiceMeta(result.stake.resourceText))}</b><p>${escapeHtml(result.stake.text)}</p></aside>
|
|
1890
1904
|
${result.beat > 0 ? `<p class="night-result-origin"><span>你刚才回答</span><b>${escapeHtml(result.label)}</b></p>` : ''}
|
|
1891
1905
|
${previousBeats.length ? `<ol class="night-result-transcript" aria-label="这次回答已经发生的后果">${previousBeats.map((beat, index) => `<li><span>${narrativeBeatMark(index)}</span><div><b>${escapeHtml(beat.title)}</b><p>${escapeHtml(beat.body)}</p></div></li>`).join('')}</ol>` : ''}
|
|
1892
1906
|
${result.beat + 1 === result.count ? `<div class="night-talk-continuity continuity-${result.continuity.kind}">
|
|
@@ -1924,7 +1938,8 @@ function renderNight() {
|
|
|
1924
1938
|
<div class="dialogue-stage visual-stage night dialogue-${id}">
|
|
1925
1939
|
<div class="close-cg closer" style="background-image:url('${urlFor(h.close)}')" role="img" aria-label="${h.name}夜间近景"></div>
|
|
1926
1940
|
<div class="decision-panel dialogue-panel">
|
|
1927
|
-
|
|
1941
|
+
<div class="character-seal" aria-hidden="true"><i>${h.glyph}</i><span>${h.house}</span></div>
|
|
1942
|
+
${phaseHeader(`第 ${state.day} 夜 · 灯下`, h.name, TEXT.nightLead)}
|
|
1928
1943
|
${intimacyMemory(id)}
|
|
1929
1944
|
<div class="choice-stack">${choices.map((choice) => choiceButton(choice, 'night')).join('')}</div>
|
|
1930
1945
|
<p class="consent-note">她往前一步,才有下一步。她若停下,门便停在这里。</p>
|
|
@@ -2289,6 +2304,13 @@ function renderPersonalAfterglowAftermath() {
|
|
|
2289
2304
|
function renderEnding() {
|
|
2290
2305
|
const end = state.ending;
|
|
2291
2306
|
const top = HEROINE_IDS.slice().sort((a, b) => state.relations[b].qing - state.relations[a].qing)[0];
|
|
2307
|
+
const endingLead = ({
|
|
2308
|
+
balanced: '天亮时,五盏灯还在同一张桌边。月娘合上总账,金莲把最后一句假话撤掉,瓶儿、玉楼与雪娥各自收回钥匙、名帖和工簿。她们愿意留下,不等于把自己交给一本总账。',
|
|
2309
|
+
alliance: '天亮时,留在桌边的人只答应了自己亲手做过的那一部分。没有坐进来的院门仍各自收着钥匙;今夜的亲近,不替任何人补一个没说出口的“愿意”。',
|
|
2310
|
+
exclusive: `天亮时,${HEROINES[top].name}的门还开着。其余四院没有因为你做了选择就自动原谅;她们把各自的原话、钥匙和去处收回,留下的人也不替你遮掉这份代价。`,
|
|
2311
|
+
intrigue: '天亮时,门外的账暂时压住了,门里却没有因此重新热起来。你用银子、名字和口供换来一口气;谁被暴露,谁收回了手,仍然一笔笔留在桌上。',
|
|
2312
|
+
unstable: '天亮时,五处院门依次灭了灯。月娘封账,金莲收走你说过的话,瓶儿扣回钥匙,玉楼把名帖收进匣里,雪娥合上工簿。门外的债还在,这一回没有人再替你把空话接下去。',
|
|
2313
|
+
})[end.id] ?? end.text;
|
|
2292
2314
|
const relationshipSummary = end.id === 'balanced'
|
|
2293
2315
|
? '<span>五院关系 <b>都还在桌上</b></span>'
|
|
2294
2316
|
: end.id === 'alliance'
|
|
@@ -2329,7 +2351,8 @@ function renderEnding() {
|
|
|
2329
2351
|
<p class="eyebrow">第 20 日 · 风月总账</p>
|
|
2330
2352
|
<h1 tabindex="-1">${end.title}</h1>
|
|
2331
2353
|
<p class="ending-tag">${end.tag}${end.heroineName ? ` · ${end.heroineName}` : ''}${end.reckoningResult ? ` · ${end.reckoningResult}` : ''}${end.routeResult ? ` · ${end.routeResult}` : ''}</p>
|
|
2332
|
-
<p>${
|
|
2354
|
+
<p>${endingLead}</p>
|
|
2355
|
+
<details class="ending-old-account"><summary>翻看这二十日的来路</summary><p>${end.text}</p></details>
|
|
2333
2356
|
<div class="ending-ledger">
|
|
2334
2357
|
${relationshipSummary}
|
|
2335
2358
|
<span>结局总账 <b>${loadEndingArchive().length ? '已有旧卷' : '首卷落定'}</b></span>
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
export const TEXT = Object.freeze({
|
|
4
4
|
title: '金瓶梅·风月总账',
|
|
5
|
-
subtitle: '
|
|
6
|
-
identity: '
|
|
5
|
+
subtitle: '二十日,五扇门。你说过的话,她们都记得。',
|
|
6
|
+
identity: '你是西门庆。门外的债已经追到家门,门里有五个人等你把银子、谎话和旧承诺一件件说清。你可以偏爱,但不能叫她们替你撒谎。',
|
|
7
7
|
rating: '18+ · 仅限成年人 · 含成人关系、轻度裸露与亲密内容',
|
|
8
8
|
ageTitle: '十八岁以下,止步',
|
|
9
9
|
ageBody: '本作只供成年人,含成人关系、肩背与腿部等轻度裸露、亲密场景与成熟主题。所有可进入亲密路线的人物均为成年虚构角色。',
|
|
@@ -15,10 +15,10 @@ export const TEXT = Object.freeze({
|
|
|
15
15
|
restart: '从头再来',
|
|
16
16
|
muteOn: '开声',
|
|
17
17
|
muteOff: '静音',
|
|
18
|
-
dayLead: '
|
|
19
|
-
chooseVisit: '
|
|
18
|
+
dayLead: '院里的事已摆到眼前。你先动哪一只手?',
|
|
19
|
+
chooseVisit: '暮鼓响过,五处院门仍留着灯。今夜你去见谁?',
|
|
20
20
|
sharedNightLead: '五个人都没走。账还没凉,酒已经热了——今夜是各回各院,还是在每个人都独立点头之后让五盏灯留在一处,就等你开口。',
|
|
21
|
-
nightLead: '
|
|
21
|
+
nightLead: '茶还热着,她的手在门闩上停了一会儿。接下来怎样,听她的。',
|
|
22
22
|
morningLead: '天刚透进窗纸,昨夜没说尽的话已经到了门外。',
|
|
23
23
|
banquetLead: '五只杯子都等着。这一次若把功劳、财权或证词分偏了,夜里就有一扇门先落闩。',
|
|
24
24
|
galleryEmpty: '册子还是空的。等有人肯把门留给你,再来看。',
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
"description": "《金瓶梅·风月总账》20日男性第一人称成人后宫关系模拟:五条深线、五院共约、联院协力与公开问责",
|
|
6
6
|
"scripts": {
|
|
7
7
|
"start": "python3 -m http.server 5173",
|
|
8
|
-
"verify:model": "node ../../qa/verify_playable_model.mjs"
|
|
8
|
+
"verify:model": "node ../../qa/verify_playable_model.mjs",
|
|
9
|
+
"verify:visual": "python3 test/verify_visual.py --write-evidence"
|
|
9
10
|
}
|
|
10
11
|
}
|
|
@@ -1,24 +1,19 @@
|
|
|
1
1
|
# QA 证据说明
|
|
2
2
|
|
|
3
|
-
本 example
|
|
3
|
+
本 example 的当前权威 QA 命令是:
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
- 390×844、768×1024、1024×768、1280×800、1920×1080、2048×973 六个视口都走到结局;主游玩面板实际溢出为 0,浏览器错误数组为空。
|
|
10
|
-
- 年龄确认前只请求封面与宅院两张启动图,共 653,950 bytes;成人内容资源请求为 0。
|
|
11
|
-
- 临时请求拦截分别阻断一张安全关键图和一张持久场景册成人图,两条路径都进入 `#asset-error`,没有继续显示残页。
|
|
5
|
+
```bash
|
|
6
|
+
cd examples/jin-ping-mei/build/app
|
|
7
|
+
python3 test/verify_visual.py --write-evidence
|
|
8
|
+
```
|
|
12
9
|
|
|
13
|
-
|
|
10
|
+
命令开始时先把 `verification.json` 原子写为未运行的失败态,完整路径成功后才原子更新
|
|
11
|
+
`verification.json` 与严格 schema-v1 `evidence/run.json`。浏览器由脚本自启临时本地服务;全部推进使用
|
|
12
|
+
Playwright `locator.click` 且不使用 `force`,DOM 只负责读取下一项可见可行控件的 selector。
|
|
14
13
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
失败。仓内 `final-screen.webp` 保留表现层复核前的终局基线;复核后的桌面角色抉择、桌面终局和
|
|
19
|
-
390×844 终局分别见 `evidence/visual-review-dialogue-after.jpg`、
|
|
20
|
-
`evidence/visual-review-ending-after.jpg` 与 `evidence/visual-review-ending-mobile-after.jpg`。权威正常速度
|
|
21
|
-
完整路径仍明确属于上面的 2026-08-22 候选。
|
|
14
|
+
当前路径覆盖年龄门、五院标题、五档标题/首日布局、首日真实夜访与选择后章,再以每屏第一项可行
|
|
15
|
+
主动作快速到达一个第二十日失稳结局并换 seed 重开。只保留标题、首日、夜访和结局四张代表图;该路径不
|
|
16
|
+
穷举其他结局,不复测全键盘或五档完整二十日矩阵,也不证明主观吸引力。
|
|
22
17
|
|
|
23
18
|
仓内另提供一条不依赖浏览器的可执行改编合同:
|
|
24
19
|
|
|
@@ -2,14 +2,14 @@
|
|
|
2
2
|
"schemaVersion": 3,
|
|
3
3
|
"status": "PASS",
|
|
4
4
|
"verify": {
|
|
5
|
-
"command": "
|
|
5
|
+
"command": "cd examples/jin-ping-mei/build/app && python3 test/verify_visual.py --write-evidence",
|
|
6
6
|
"exitCode": 0
|
|
7
7
|
},
|
|
8
8
|
"completeRun": {
|
|
9
|
-
"id": "jin-ping-mei-
|
|
9
|
+
"id": "jin-ping-mei-visual-reconstruction-2026-09-05",
|
|
10
10
|
"cleanContext": true,
|
|
11
11
|
"terminal": "day-20-unstable-ending",
|
|
12
|
-
"restart": "day-1-opening",
|
|
12
|
+
"restart": "day-1-opening-new-seed",
|
|
13
13
|
"evidence": "qa/evidence/run.json"
|
|
14
14
|
},
|
|
15
15
|
"checks": {
|
|
@@ -22,20 +22,20 @@
|
|
|
22
22
|
},
|
|
23
23
|
"limitations": [
|
|
24
24
|
{
|
|
25
|
-
"scope": "
|
|
26
|
-
"reason": "
|
|
25
|
+
"scope": "路径覆盖",
|
|
26
|
+
"reason": "快速路径在每屏选择第一项可行主动作,只到达一个失稳结局;没有穷举其他选项或结局。"
|
|
27
27
|
},
|
|
28
28
|
{
|
|
29
|
-
"scope": "
|
|
30
|
-
"reason": "
|
|
29
|
+
"scope": "输入覆盖",
|
|
30
|
+
"reason": "本次使用 Playwright locator.click 且不使用 force;没有复测 2026-08 的全键盘正常速度路径。"
|
|
31
31
|
},
|
|
32
32
|
{
|
|
33
|
-
"scope": "
|
|
34
|
-
"reason": "
|
|
33
|
+
"scope": "响应式覆盖",
|
|
34
|
+
"reason": "五档视口覆盖标题与首日,390×844 和 1280×800 覆盖夜访,1280×800 覆盖本次结局;未声明五档完整二十日矩阵。"
|
|
35
35
|
},
|
|
36
36
|
{
|
|
37
|
-
"scope": "
|
|
38
|
-
"reason": "
|
|
37
|
+
"scope": "体验判断",
|
|
38
|
+
"reason": "自动化只证明当前候选可启动、渲染、输入、走到结果并重开,不判断主观吸引力、长期平衡或其他浏览器。"
|
|
39
39
|
}
|
|
40
40
|
]
|
|
41
41
|
}
|
|
@@ -11,6 +11,28 @@ const engine = await import(resolve(here, '../build/app/js/engine.js'));
|
|
|
11
11
|
|
|
12
12
|
const digest = (value) => createHash('sha256').update(JSON.stringify(value)).digest('hex');
|
|
13
13
|
const assertText = (value, label) => assert.equal(typeof value === 'string' && value.length > 0, true, label);
|
|
14
|
+
const ROUTE_RULES_DIGEST = '3b3c6bd6dc565ff05825d16738ef3a76ad87bd1392d7d149794dc55ff8c005fa';
|
|
15
|
+
|
|
16
|
+
function routeRulesProjection() {
|
|
17
|
+
const route = Object.fromEntries(Object.entries(data.ROUTE_CHOICES).map(([heroine, steps]) => [
|
|
18
|
+
heroine,
|
|
19
|
+
steps.map((choices) => choices.map((choice) => ({
|
|
20
|
+
id: choice.id,
|
|
21
|
+
effects: choice.effects,
|
|
22
|
+
condition: choice.condition ?? null,
|
|
23
|
+
}))),
|
|
24
|
+
]));
|
|
25
|
+
const accord = Object.fromEntries(Object.entries(data.ACCORD_CHOICES).map(([heroine, choice]) => [
|
|
26
|
+
heroine,
|
|
27
|
+
{ id: choice.id, effects: choice.effects, condition: choice.condition ?? null },
|
|
28
|
+
]));
|
|
29
|
+
const shared = data.SHARED_NIGHT_CHOICES.map((choice) => ({
|
|
30
|
+
id: choice.id,
|
|
31
|
+
effects: choice.effects ?? null,
|
|
32
|
+
condition: choice.condition ?? null,
|
|
33
|
+
}));
|
|
34
|
+
return { route, accord, shared };
|
|
35
|
+
}
|
|
14
36
|
|
|
15
37
|
function finishOpening(state) {
|
|
16
38
|
let beats = 0;
|
|
@@ -119,6 +141,7 @@ for (const [index, path] of Object.values(contract.validationPaths).entries()) {
|
|
|
119
141
|
assert.deepEqual(Object.keys(data.DAY_ACTIONS), contract.stateSurface.dayActions);
|
|
120
142
|
assert.deepEqual(data.HEROINE_IDS, contract.stateSurface.relationshipActors);
|
|
121
143
|
assert.deepEqual(data.OPENING_CHOICES.map(({ id }) => id), contract.openingActions.map(({ id }) => id));
|
|
144
|
+
assert.equal(digest(routeRulesProjection()), ROUTE_RULES_DIGEST, '文案改写不得改动五条路线、五院约或共享终夜的 id/condition/effects');
|
|
122
145
|
|
|
123
146
|
const firstRuns = contract.openingActions.map(runOpening);
|
|
124
147
|
const replayRuns = contract.openingActions.map(runOpening);
|