@oh-story/dsh 0.1.9 → 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 +14 -14
- package/lib/client.js +209 -73
- package/lib/client.js.map +3 -3
- package/lib/drama/manifest.json +248 -168
- package/lib/drama/skills/short-drama/SKILL.md +16 -4
- 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/creator_markdown_check.py +14 -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/character-and-look.md +10 -0
- package/lib/drama/skills/short-drama-assets/references/continuity-lock.md +6 -9
- 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-assets/references/voice-direction.md +28 -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 +65 -44
- 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 +6 -4
- package/lib/drama/skills/short-drama-edit/references/cut-craft.md +26 -67
- package/lib/drama/skills/short-drama-edit/references/delivery-verify.md +31 -56
- package/lib/drama/skills/short-drama-edit/references/generated-footage.md +42 -78
- package/lib/drama/skills/short-drama-edit/references/sound-and-subtitles.md +44 -92
- package/lib/drama/skills/short-drama-edit/references/stage-contract.md +14 -16
- package/lib/drama/skills/short-drama-edit/scripts/edit_tool.py +1272 -125
- package/lib/drama/skills/short-drama-edit/scripts/selftest.py +113 -9
- package/lib/drama/skills/short-drama-image-prompts/SKILL.md +2 -0
- package/lib/drama/skills/short-drama-image-prompts/references/common-recipe.md +11 -0
- 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-produce/SKILL.md +5 -1
- package/lib/drama/skills/short-drama-produce/references/adapter-contract.md +14 -20
- package/lib/drama/skills/short-drama-produce/references/providers/minimax-h3-video.md +8 -26
- package/lib/drama/skills/short-drama-produce/references/providers/minimax-speech.md +41 -0
- package/lib/drama/skills/short-drama-produce/scripts/provider_adapters.py +142 -1
- package/lib/drama/skills/short-drama-review/SKILL.md +4 -5
- package/lib/drama/skills/short-drama-review/references/production-quality-gates.md +6 -19
- 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 +24 -35
- package/lib/drama/skills/short-drama-review/references/stage-contract.md +3 -0
- package/lib/drama/skills/short-drama-storyboard/SKILL.md +23 -11
- package/lib/drama/skills/short-drama-storyboard/references/blocking-playbooks.md +1 -1
- package/lib/drama/skills/short-drama-storyboard/references/lighting-craft.md +39 -0
- 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 +139 -34
- package/lib/drama/skills/short-drama-storyboard/references/stage-contract.md +5 -3
- package/lib/drama/skills/short-drama-video-prompts/SKILL.md +15 -12
- package/lib/drama/skills/short-drama-video-prompts/references/camera-audio-continuity.md +29 -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 +52 -39
- package/lib/drama/skills/short-drama-video-prompts/references/motion-recipe.md +24 -21
- package/lib/drama/skills/short-drama-video-prompts/references/performance-action-timing.md +9 -23
- package/lib/drama/skills/short-drama-video-prompts/references/production-prompt-grammar.md +14 -26
- package/lib/drama/skills/short-drama-video-prompts/references/review-and-fixtures.md +1 -1
- package/lib/drama/skills/short-drama-video-prompts/references/seedance-2.0.md +2 -3
- package/lib/drama/skills/short-drama-video-prompts/references/seedance-2.5.md +34 -9
- package/lib/drama/skills/short-drama-video-prompts/references/stage-contract.md +3 -2
- 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 +10 -7
- 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 +346 -98
- 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 +7 -12
- 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 +13 -14
- 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 +13 -15
- package/lib/novel-to-game/skills/game-concept/references/concept-method.md +28 -75
- package/lib/novel-to-game/skills/game-qa/SKILL.md +6 -7
- package/lib/novel-to-game/skills/game-qa/references/test-design-method.md +9 -5
- package/lib/novel-to-game/skills/game-world-design/SKILL.md +12 -16
- 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 +4 -10
- 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 +9 -21
- package/lib/novel-to-game/skills/novel-to-game/references/intake-method.md +5 -4
- package/lib/novel-to-game/skills/novel-to-game/references/pipeline-contract.md +5 -8
- package/lib/oh-story/manifest.json +607 -327
- package/lib/oh-story/roles/chapter-extractor.md +177 -237
- package/lib/oh-story/roles/character-designer.md +1 -2
- package/lib/oh-story/roles/consistency-checker.md +15 -13
- package/lib/oh-story/roles/narrative-writer.md +36 -38
- 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 +15 -9
- 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 +46 -94
- 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 +59 -73
- 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 +12 -11
- 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 +46 -94
- package/lib/oh-story/skills/story-deslop/references/banned-words.md +2 -2
- package/lib/oh-story/skills/story-deslop/references/deslop-gates.md +22 -5
- 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 +934 -170
- package/lib/oh-story/skills/story-deslop/scripts/check-ai-patterns.js +155 -8
- package/lib/oh-story/skills/story-import/SKILL.md +64 -584
- package/lib/oh-story/skills/story-import/references/character-state-reverse.md +1 -1
- 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/state-tracking.md +4 -69
- package/lib/oh-story/skills/story-import/references/structure-mapping-long.md +98 -92
- 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 +15 -11
- 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 +132 -27
- package/lib/oh-story/skills/story-import/scripts/tracking_commit.py +478 -15
- package/lib/oh-story/skills/story-import/scripts/wordcount_core.py +182 -23
- package/lib/oh-story/skills/story-long-analyze/SKILL.md +81 -270
- package/lib/oh-story/skills/story-long-analyze/references/author-facing.md +252 -0
- package/lib/oh-story/skills/story-long-analyze/references/deconstruction-notes.md +3 -3
- 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/inspiration-library.md +105 -0
- package/lib/oh-story/skills/story-long-analyze/references/pipeline-ops.md +138 -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/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 +55 -128
- package/lib/oh-story/skills/story-long-analyze/references/style-profile-protocol.md +6 -6
- package/lib/oh-story/skills/story-long-analyze/references/synthesis-inputs.md +39 -0
- 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 +1145 -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 +45 -194
- 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 +49 -81
- 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 +12 -11
- package/lib/oh-story/skills/story-long-write/references/artifact-protocols.md +24 -202
- 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 +46 -94
- 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 +7 -11
- package/lib/oh-story/skills/story-long-write/references/character-relations.md +49 -1
- package/lib/oh-story/skills/story-long-write/references/cross-book-recall.md +26 -0
- package/lib/oh-story/skills/story-long-write/references/deslop-gates.md +171 -0
- package/lib/oh-story/skills/story-long-write/references/dialogue-mastery.md +4 -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/emotional-methods.md +2 -2
- 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 +7 -15
- 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 +19 -13
- package/lib/oh-story/skills/story-long-write/references/reader-contract-and-progression.md +13 -5
- package/lib/oh-story/skills/story-long-write/references/reference-index.md +5 -6
- 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 +15 -11
- package/lib/oh-story/skills/story-long-write/references/workflow-chapter.md +81 -121
- package/lib/oh-story/skills/story-long-write/references/workflow-daily.md +41 -139
- 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 +57 -67
- package/lib/oh-story/skills/story-long-write/references/workflow-setup.md +112 -253
- 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 +6 -4
- package/lib/oh-story/skills/story-long-write/references/writing-craft.md +19 -65
- 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_architect_brief.py +260 -0
- package/lib/oh-story/skills/story-long-write/scripts/build_writer_prompt.py +226 -25
- 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 +132 -27
- 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 +7 -4
- package/lib/oh-story/skills/story-long-write/scripts/storyctl.py +304 -46
- package/lib/oh-story/skills/story-long-write/scripts/tracking_commit.py +478 -15
- package/lib/oh-story/skills/story-long-write/scripts/wordcount_core.py +182 -23
- package/lib/oh-story/skills/story-review/SKILL.md +31 -302
- 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 +12 -11
- 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 +46 -94
- 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/dialogue-mastery.md +4 -0
- package/lib/oh-story/skills/story-review/references/review-quality.md +6 -11
- 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 +15 -11
- 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 +155 -8
- package/lib/oh-story/skills/story-review/scripts/tracking_commit.py +478 -15
- package/lib/oh-story/skills/story-review/scripts/wordcount_core.py +182 -23
- package/lib/oh-story/skills/story-setup/SKILL.md +71 -452
- 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 +12 -11
- 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 +22 -5
- package/lib/oh-story/skills/story-setup/references/agent-references/dialogue-mastery.md +4 -0
- 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-emotional-methods.md +2 -2
- 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 +19 -65
- package/lib/oh-story/skills/story-setup/references/diagnostics.md +4 -4
- package/lib/oh-story/skills/story-short-analyze/SKILL.md +56 -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/stage4-6-reversal-summary.md +611 -0
- package/lib/oh-story/skills/story-short-scan/SKILL.md +35 -65
- 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 -175
- 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 +46 -94
- 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/dialogue-mastery.md +4 -0
- 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 -47
- 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 +21 -13
- package/lib/oh-story/skills/story-short-write/references/workflow-draft.md +116 -0
- package/lib/oh-story/skills/story-short-write/references/workflow-revision.md +99 -0
- 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 +934 -170
- 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/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 +16 -0
- package/lib/types/client/production-runtime.d.ts.map +1 -1
- package/lib/types/client/video-studio.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 +53 -1
- 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/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-script/scripts/agent_brief.py → video-understanding/scripts/briefing/builder.py} +38 -35
- package/lib/video-recap/skills/video-understanding/scripts/{brief_context.py → 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-script/scripts/brief_timeline.py → video-understanding/scripts/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 +45 -45
- package/lib/novel-to-game/skills/game-world-design/references/dialogue-design-method.md +0 -58
- 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 -38
- package/lib/oh-story/skills/story-long-analyze/references/material-decomposition.md +0 -530
- package/lib/oh-story/skills/story-long-analyze/references/output-templates.md +0 -559
- package/lib/oh-story/skills/story-long-scan/references/scan-output-format.md +0 -207
- package/lib/oh-story/skills/story-long-write/references/state-tracking.md +0 -108
- package/lib/oh-story/skills/story-short-analyze/references/material-decomposition.md +0 -678
- 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/brief_context.py +0 -348
- package/lib/video-recap/skills/video-script/scripts/narration.py +0 -12
- package/lib/video-recap/skills/video-understanding/scripts/agent_brief.py +0 -399
- package/lib/video-recap/skills/video-understanding/scripts/brief_inputs.py +0 -290
- package/lib/video-recap/skills/video-understanding/scripts/brief_timeline.py +0 -327
- /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
package/lib/index.js
CHANGED
|
@@ -35,8 +35,9 @@ var DRAMA_ADAPTERS = [
|
|
|
35
35
|
name: "minimax-h3",
|
|
36
36
|
label: "MiniMax H3",
|
|
37
37
|
modality: "video",
|
|
38
|
-
|
|
39
|
-
|
|
38
|
+
// Every H3 job carries an integer duration, and the adapter refuses it without this range.
|
|
39
|
+
requiredEnv: ["MINIMAX_API_KEY", "MINIMAX_VIDEO_MODEL", "MINIMAX_VIDEO_RESOLUTIONS", "MINIMAX_VIDEO_MIN_DURATION", "MINIMAX_VIDEO_MAX_DURATION"],
|
|
40
|
+
optionalEnv: ["MINIMAX_VIDEO_BASE_URL", "MINIMAX_VIDEO_RATIOS"],
|
|
40
41
|
timeoutSeconds: 3600,
|
|
41
42
|
reference: "short-drama-produce/references/providers/minimax-h3-video.md"
|
|
42
43
|
},
|
|
@@ -48,6 +49,15 @@ var DRAMA_ADAPTERS = [
|
|
|
48
49
|
optionalEnv: ["MINIMAX_BASE_URL"],
|
|
49
50
|
timeoutSeconds: 600,
|
|
50
51
|
reference: "short-drama-produce/references/providers/minimax-music.md"
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
name: "minimax-speech",
|
|
55
|
+
label: "MiniMax Speech",
|
|
56
|
+
modality: "tts",
|
|
57
|
+
requiredEnv: ["MINIMAX_API_KEY"],
|
|
58
|
+
optionalEnv: ["MINIMAX_BASE_URL"],
|
|
59
|
+
timeoutSeconds: 600,
|
|
60
|
+
reference: "short-drama-produce/references/providers/minimax-speech.md"
|
|
51
61
|
}
|
|
52
62
|
];
|
|
53
63
|
function generatedDirectory(temporaryRoot) {
|
|
@@ -118,17 +128,30 @@ var DSH_SKILL_BRIDGE = [
|
|
|
118
128
|
"DSH owns the workspace, model, preset, permissions, Session Log, tools, subagents, cancellation, resume, and Agent UI.",
|
|
119
129
|
"Never start another Agent runtime, session transport, Dashboard, SSE stream, polling loop, or model configuration.",
|
|
120
130
|
"All seven upstream Oh Story specialist Roles are bundled. Invoke one with oh_story_role and a self-contained prompt.",
|
|
121
|
-
"Never inspect .claude/agents, .codex/agents, .opencode/agents, .agents/agents, .zcode, or .story-deployed to decide whether a Role is available
|
|
131
|
+
"Never inspect .claude/agents, .codex/agents, .opencode/agents, .agents/agents, .zcode, or .story-deployed to decide whether a Role is available.",
|
|
132
|
+
"Oh Story Roles are reached only through oh_story_role. Never start one through a generic subagent or Task tool \u2014 not DSH's subagent or subagent_fork tools and not invoke_subagent \u2014 and never pass a Role name as subagent_type, agent_type, agent, or TypeName, even where the upstream text below describes that for another host.",
|
|
122
133
|
"Use only DSH-visible tools. DSH sandbox and permission policy remain authoritative.",
|
|
134
|
+
// Upstream deploys these 「与作者协作」 rules only in its CLAUDE.md/AGENTS.md
|
|
135
|
+
// templates, which DSH does not install.
|
|
136
|
+
"Working with the author: reply and report in the author's writing terms (book, chapter, outline, settings), never in script, field, or state names; attach a raw error only when something failed. A template block marked <!-- author-report --> is only a format reference: output its text directly, without that marker and without a code fence.",
|
|
137
|
+
"Record a writing habit or preference the author asks to remember, forget, or confirm only through the story Skill's author memory, whose scripts/author_memory_commit.py writes .story/\u4F5C\u8005\u8BB0\u5FC6/; never keep it in a host or DSH memory. Simply follow a one-off request without recording it.",
|
|
138
|
+
"Never edit the bundled Skill files (SKILL.md, references/, scripts/). When a Skill script fails, stop and show the author the command you ran and its error instead of patching or working around it.",
|
|
123
139
|
"</oh-story-dsh-integration>"
|
|
124
140
|
].join("\n");
|
|
141
|
+
var DSH_ANALYSIS_BATCHES = [
|
|
142
|
+
"Stage 2 batches in DSH: dispatch each planned batch with oh_story_role, role chapter-extractor, and a self-contained prompt that copies this batch's plan fields verbatim, prefixing paths with {\u62C6\u6587\u76EE\u5F55}/: batch_id, input_kind, source_files (per-chapter source_locator for a raw batch), chapter_chars, min_plot_points, the output file {\u62C6\u6587\u76EE\u5F55}/_analysis_cache/\u8F93\u5165-{\u6279\u6B21ID}.md, and the plan's handoff_cache when it is not empty.",
|
|
143
|
+
"The extractor reads the source itself, writes or edits only that batch input file (DSH denies any other write or edit by a chapter-extractor child), and replies with one receipt line; do not read the file yourself.",
|
|
144
|
+
"Commit it with manage_analysis_run.py commit, one commit at a time in this session. When a commit is rejected, dispatch the same batch to a chapter-extractor again with every field above plus the error code, and have it fix only the broken spots with edit (rewriting the whole file only when its structure is broken), then commit again.",
|
|
145
|
+
"Run manage_analysis_run.py and the other bundled Python 3 scripts through the current DSH execution world, trying python3, python, then py -3. If none is available, stop and tell the author in plain words that this step needs Python 3 on the machine running DSH; never simulate a script's output or hand-write the files it owns.",
|
|
146
|
+
"Keep concurrent oh_story_role calls modest. The default is upstream's \u6709\u9650\u5E76\u884C tier: three batches per round, issued together, the next round only after all three are committed; an unasked, full, multi-book, or import run uses it. DSH runs calls from one step in parallel only up to the host's own limit and may run them one after another, so never promise more. Use \u4E32\u884C or \u4E0D\u9650\u6279\u6B21\u987A\u5E8F only when the author chooses it, and under \u4E0D\u9650\u6279\u6B21\u987A\u5E8F halve the count on any rate limit, timeout, or child error."
|
|
147
|
+
].join(" ");
|
|
125
148
|
var DSH_SKILL_OVERRIDES = {
|
|
126
149
|
story: "The \u5C0F\u8BF4 workspace is an official DSH conversation view. Never start or open a second web application.",
|
|
127
150
|
"story-setup": "Initialize or validate novel project data only. DSH already supplies Skills, Roles, hooks, tools, permissions, sessions, and UI; never deploy Claude/OpenCode/Codex/Antigravity/ZCode/OpenClaw/Reasonix files or a .story-deployed marker.",
|
|
128
|
-
"story-long-analyze":
|
|
129
|
-
"story-long-write": "All named Roles are provided through oh_story_role. Do not check platform agent files. Keep the upstream writing, Tracking, lint, outline, revision, and quality workflows.",
|
|
130
|
-
"story-review": "All named reviewer Roles are provided through oh_story_role. Do not check platform agent files; full/lean review may use the bundled Roles directly.",
|
|
131
|
-
"story-import":
|
|
151
|
+
"story-long-analyze": `Use oh_story_role for chapter extraction or specialist analysis. Never inspect platform agent directories or require a deployed external Agent definition. ${DSH_ANALYSIS_BATCHES}`,
|
|
152
|
+
"story-long-write": "All named Roles are provided through oh_story_role. Do not check platform agent files. Keep the upstream writing, Tracking, lint, outline, revision, and quality workflows. Create and assemble \u6B63\u6587/ chapter files only with the write and edit tools, never through shell redirection, cp, mv, tee, or a script, so that DSH's outline guard, its Tracking reminder, and the \u5C0F\u8BF4 view observe the write; upstream's own in-place chapter fixes such as storyctl.py chapter check --fix-punctuation stay as upstream describes.",
|
|
153
|
+
"story-review": "All named reviewer Roles are provided through oh_story_role. Do not check platform agent files; full/lean review may use the bundled Roles directly. When a review falls back to solo in DSH, the reason is that oh_story_role or DSH's spawn runtime is unavailable in this Session (Fallback agent tool unavailable -> solo) or a Role run failed (Fallback spawn failed -> solo); say that in one plain sentence. Never tell the author that the reviewers are not installed, missing, or outdated, and never tell them to run /story-setup.",
|
|
154
|
+
"story-import": `All named Roles are provided through oh_story_role. Do not require story-setup to deploy them, never inspect platform agent directories or .story-deployed, and never offer the author Step 4's choice to install a writing environment with /story-setup: in DSH record \u5199\u4F5C\u73AF\u5883 in .story/work/\u5BFC\u5165\u8BB0\u5F55.md as installed, with the analysis helper and story-architect both available. Phase 2 runs the story-long-analyze pipeline the DSH way below; an import counts as automatic continuation, so it uses the limited-parallel tier without asking. ${DSH_ANALYSIS_BATCHES} Run the scripts this Skill needs (build_outline_brief.py, tracking_commit.py init and check with Python 3; check-outline-contract.js with Node) the same way. Keep upstream's order: Phase 3-L Step 2 copies the manuscript into \u6B63\u6587/, Step 10 reverse-builds the \u7EC6\u7EB2 in batches, and Phase 4 initialises Tracking. DSH's prose guard mirrors the outline gate of upstream proseBlockReason for books with \u5927\u7EB2/ or \u8FFD\u8E2A/, so open an import window before Step 2 copies any chapter: create .story/work/\u5BFC\u5165\u4E2D.md in the book directory (the workspace root in DSH's usual single-book layout) with one line naming the book being imported, and delete it right after Phase 4's tracking_commit.py init and check both succeed. The window only holds while \u8FFD\u8E2A/_tracking-state.json is absent. \u5BFC\u5165\u4E2D.md is DSH's own marker; keep upstream's \u5BFC\u5165\u8BB0\u5F55.md exactly as the Skill describes.`,
|
|
132
155
|
"story-deslop": "Use the bundled narrative-writer Role through oh_story_role when specialist review is useful. Never inspect platform agent directories.",
|
|
133
156
|
"story-short-analyze": "Use oh_story_role for specialist analysis. Never inspect platform agent directories or require external Agent deployment.",
|
|
134
157
|
"story-short-write": "All named Roles are provided through oh_story_role. Do not inspect platform agent files; preserve the upstream short-fiction workflow and quality gates.",
|
|
@@ -141,7 +164,7 @@ var DSH_DRAMA_BRIDGE = [
|
|
|
141
164
|
"DSH owns the workspace, model, preset, permissions, Session Log, tools, approvals, cancellation, resume, and Agent UI.",
|
|
142
165
|
"The \u77ED\u5267 tab is the creator workspace. Never start dashboard_server.py, another web server, Dashboard, Agent runtime, session transport, or model configuration.",
|
|
143
166
|
"Drama Skills uses a creator-first contract: each episode keeps only the requested documents, up to five creator-facing sources at \u5267\u96C6/<EP>/\u5267\u672C.md, \u89C6\u89C9\u8BBE\u5B9A.md, \u5206\u955C.md, \u56FE\u7247\u63D0\u793A\u8BCD.md, and \u89C6\u9891\u63D0\u793A\u8BCD.md. Never precreate empty documents, backfill nominal stages, or start work the creator did not request. Persisted reviews use creator-readable Markdown under \u5BA1\u67E5/; an oral review writes nothing.",
|
|
144
|
-
"\u5267\u96C6/<EP>/\u526A\u8F91\u5355.md is the v0.7 assembly record, not a sixth creative truth. It is written after footage exists and records
|
|
167
|
+
"\u5267\u96C6/<EP>/\u526A\u8F91\u5355.md is the v0.7 assembly record, not a sixth creative truth: the five creator documents stay the creative truth. It is written after footage exists and records what reaches the cut \u2014 which footage is kept or left unused and why, each cut's in/out timing, its subtitles, \u753B\u9762\u6587\u5B57 overlays and \u97F3\u6548 cues, post-processing such as shot-match correction or an external mix, and the delivery spec including optional \u9897\u7C92 grain and \u63A5\u955C\u5339\u914D. It never changes a line, a shot's job, or a declared duration; changing any of those means returning to the document that owns it.",
|
|
145
168
|
"For a v0.6 project, never create a parallel JSON/JSONL lifecycle truth, indexes, fingerprints, coverage tables, or QA records merely because legacy maintenance scripts and templates remain bundled.",
|
|
146
169
|
"Never upgrade a v0.5 structured project in place or mix both contracts in one project root. Keep legacy production/audit artifacts read-only and pinned to v0.5; migrate only into a new creator-first root with manual per-episode creator confirmation.",
|
|
147
170
|
"Use only tools visible in the current DSH preset and preserve the upstream project ownership, freshness, review, and explicit production-confirmation contracts.",
|
|
@@ -151,8 +174,16 @@ var DSH_DRAMA_BRIDGE = [
|
|
|
151
174
|
].join("\n");
|
|
152
175
|
var DSH_DRAMA_OVERRIDES = {
|
|
153
176
|
"short-drama": "A dashboard request means focus or use the native \u77ED\u5267 tab in this DSH Session. Do not run the bundled standalone Dashboard script. New projects follow only the v0.6 creator-first contract and create only documents required by the current request.",
|
|
154
|
-
"short-drama-produce": (skillRoot) => `Use an upstream adapter only after the creator explicitly confirms the exact current job. Its source must be the current creator-first Markdown and its output belongs under \u5267\u96C6/<EP>/\u5236\u4F5C\u6210\u679C/. DSH permissions and approval UI remain authoritative. When oh_story_production is visible, register
|
|
155
|
-
"short-drama-edit":
|
|
177
|
+
"short-drama-produce": (skillRoot) => `Use an upstream adapter only after the creator explicitly confirms the exact current job. Its source must be the current creator-first Markdown and its output belongs under \u5267\u96C6/<EP>/\u5236\u4F5C\u6210\u679C/. DSH permissions and approval UI remain authoritative. When oh_story_production is visible, register a previewed image or video job with track_job after the confirmation is valid and before run \u2014 never at prepare time \u2014 passing the same job ID, target, modality and count the creator just approved. track_job's jobKind is image, video or composition (the assembled cut), so from this Skill it registers image and video jobs only: speech (tts) and music jobs pass through the same prepare \u2192 explicit creator confirmation \u2192 run gate but are never registered with track_job or relabelled as another kind, and their audio results stay under \u5267\u96C6/<EP>/\u5236\u4F5C\u6210\u679C/. In this DSH integration audio is never bound as a video job's reference: upstream's creator-first path has no audio binding (\u8F93\u5165\u53C2\u8003\u56FE takes png/jpg/webp images only) and audio reaches the cut only at the edit stage, as \u97F3\u6548 lines that render mixes in or as an external mix. DeepSeek generates no media: every image, video, speech, or music result comes from a provider adapter. The bundled adapters are ${dramaAdapterSummary()}; they are registered for this DSH host in ${dramaAdapterConfigPath(skillRoot).path} \u2014 pass that file as --adapter-config unless the creator names another config (${DRAMA_ADAPTER_CONFIG_ENV}). Credentials are read only from the DSH host process environment. Before preparing a paid job, name the adapter that will run it; if its variables are missing, tell the creator exactly which ones to export before starting DSH instead of failing inside run. Never read, print, or write credential values. A submitted video job is already billed, so an interrupted run is recovered, not resubmitted: when audit reports orphaned_provider_job, recover it with collect, passing --job-id \u2014 the drama job the finding names, not its provider_job_id, which collect reads from the run handle itself. collect spends nothing and does not need the confirmation gate \u2014 the gate exists to stop unintended spending \u2014 but re-running the same job does, and would charge the creator twice.`,
|
|
178
|
+
"short-drama-edit": [
|
|
179
|
+
"Assembly runs inside this DSH Session. Write \u5267\u96C6/<EP>/\u526A\u8F91\u5355.md first, then run edit_tool.py check and render through the current DSH execution world; the rendered cut belongs under \u5267\u96C6/<EP>/\u5236\u4F5C\u6210\u679C/\u6210\u7247/ and the \u77ED\u5267 tab shows it there. ffmpeg and ffprobe come from the DSH host \u2014 when one is missing, say so instead of approximating or reporting an untested measurement as a pass.",
|
|
180
|
+
// edit_tool.py 0.7.1 `_unaccounted_shots`: `- 未采用镜头:` is read only outside CUT blocks, split on `;`, and each item must fullmatch `MOTION-…(理由:<non-empty>)`.
|
|
181
|
+
"check blocks until every `## MOTION-*` heading in \u89C6\u9891\u63D0\u793A\u8BCD.md either backs a CUT's \u6765\u6E90 or is listed in the cut list's opening block, before the first `## CUT-` heading, on one line: `- \u672A\u91C7\u7528\u955C\u5934\uFF1AMOTION-\u2026\uFF08\u7406\u7531\uFF1A\u2026\uFF09\uFF1BMOTION-\u2026\uFF08\u7406\u7531\uFF1A\u2026\uFF09`. Join items with a full-width `\uFF1B`; each reason is non-empty, contains no `\uFF1B`, and names \u6587\u4EF6\u7F3A\u5931, \u8D28\u91CF\u4E0D\u53EF\u7528 or \u53D9\u4E8B\u53D6\u820D.",
|
|
182
|
+
"Every cut must share one width, height and frame rate: render hard-joins the encoded segments and never scales or retimes them. When check reports a mismatch, normalise the odd clips to the delivery spec with ffmpeg in the DSH execution world, under approval, preserving the composition. Write them under \u5267\u96C6/<EP>/\u5236\u4F5C\u6210\u679C/\u6210\u7247/\u89C4\u683C\u7EDF\u4E00/, an edit-owned intermediate, never beside the produce-stage originals and never over produced footage, and name them without the original's job-id token (the MOTION ID will do). Record the crop or pad in that CUT's block (not in its \u753B\u9762 line, which accepts only \u4EAE\u5EA6/\u9971\u548C/\u8272\u6E29), point \u6765\u6E90 at the new file, update \u5165\u70B9/\u51FA\u70B9 if the conversion moved them, and rerun check.",
|
|
183
|
+
"The default burned-subtitle route needs an ffmpeg built with libass; when the host's ffmpeg lacks it, say so instead of silently dropping subtitles. Remotion renders every frame through a headless browser from a Node workspace outside the project, ~/.cache/short-drama-edit/remotion, which edit_tool.py rewrites on each run: the optional subtitle route uses it, and any `\u753B\u9762\u6587\u5B57` line in \u526A\u8F91\u5355.md requires it whatever the subtitle route. Install it (npm install in that workspace; an install from before Drama Skills 0.8 must run npm install again) only after the creator approves, through DSH approval. Without that approval write no \u753B\u9762\u6587\u5B57 lines and tell the creator the blank on-screen panels stay empty. Never treat Remotion as a second Agent runtime, dashboard, or session transport.",
|
|
184
|
+
"The \u58F0\u97F3 line in \u526A\u8F91\u5355.md is a record, not an instruction the built-in render executes. render trims, auto-matches adjacent cuts within one scene (a CUT's \u753B\u9762 correction replaces it, `- \u753B\u9762\uFF1A\u4E0D\u6821` skips it, and `- \u63A5\u955C\u5339\u914D\uFF1A\u65E0` in the delivery spec turns it off), hard-joins, mixes in the `\u97F3\u6548` lines, burns subtitles and \u753B\u9762\u6587\u5B57, applies optional \u9897\u7C92, and normalises loudness. A mix beyond the \u97F3\u6548 lines, crossfade, music bed, transition or format conversion is an external ffmpeg step, run under approval, that writes a temporary file, ends as render does with whole-film two-pass loudnorm to the declared \u4EA4\u4ED8\u54CD\u5EA6 (I=<\u4EA4\u4ED8\u54CD\u5EA6>:TP=-1.5:LRA=11, the second pass fed the first pass's measurements with linear=true, audio re-encoded as AAC 192k at 48 kHz), and only then replaces \u5267\u96C6/<EP>/\u5236\u4F5C\u6210\u679C/\u6210\u7247/\u6210\u7247.mp4; record its command in \u526A\u8F91\u5355.md and repeat it after any re-render, which overwrites that file. Run edit_tool.py verify last, on that delivered file, and report every \u672A\u6D4B item as untested, never as passed.",
|
|
185
|
+
"This stage never generates footage and never edits \u5267\u672C.md, \u5206\u955C.md, or \u89C6\u9891\u63D0\u793A\u8BCD.md \u2014 route those back to their owning Skill."
|
|
186
|
+
].join(" "),
|
|
156
187
|
"short-drama-assets": "Keep one stable `- ID\uFF1AVISUAL-*` line on every \u4EBA\u7269/\u9020\u578B/\u5730\u70B9/\u9053\u5177/\u72B6\u6001 entry in \u89C6\u89C9\u8BBE\u5B9A.md, and never change an existing ID when editing its heading or text. The \u751F\u4EA7 view identifies canvas nodes by that ID; entries without one still render, but the workbench reports their node identity as unstable."
|
|
157
188
|
};
|
|
158
189
|
var DSH_GAME_BRIDGE = [
|
|
@@ -171,7 +202,8 @@ var DSH_VIDEO_BRIDGE = [
|
|
|
171
202
|
"This Skill is a native contribution to the current DeepSeek Harness session.",
|
|
172
203
|
"DSH owns the workspace, model, preset, permissions, Session Log, tools, approvals, cancellation, resume, Todo, Chat, and the \u89C6\u9891 preview Studio.",
|
|
173
204
|
"Never start a second Agent runtime, dashboard, session transport, web server, polling loop, or model configuration.",
|
|
174
|
-
"
|
|
205
|
+
"A dashboard request means the native \u89C6\u9891 tab in this DSH Session: dashboard_server.py and its dashboard assets are not bundled, so never try to run them. To inspect a resource library, use the read-only scripts/library.py check, list, or show.",
|
|
206
|
+
"Keep the complete upstream six-Skill pipeline. Put each project under video-recaps/<project>/, copy or import source media under sources/, and use work/ as the upstream work_dir so the Studio can discover authoritative manifests and outputs. A project binding passed with --project belongs at video-recaps/<project>/recap_project.json.",
|
|
175
207
|
"The Video Studio is a preview and artifact surface, not a nonlinear editor. Do not invent a second project-state format, timeline truth, or render queue; recap_run_manifest.json, recap_phase.json, timeline.json, assembly_manifest.json, and the upstream artifacts remain authoritative.",
|
|
176
208
|
"MIMO_API_KEY, FISH_API_KEY, and voice credentials stay in the host environment. Never write secrets into project files, tool arguments shown to the browser, or chat output.",
|
|
177
209
|
"Use only DSH-visible tools and approvals. Run Python and ffmpeg through the current DSH execution world, preserve cancellation, and do not install or upgrade system dependencies without explicit user approval.",
|
|
@@ -184,29 +216,60 @@ var DSH_NATIVE_SKILLS = {
|
|
|
184
216
|
\u5728\u5F53\u524D DSH Session \u5185\u5224\u65AD\u7528\u6237\u610F\u56FE\uFF0C\u5E76\u52A0\u8F7D\u6700\u5339\u914D\u7684 Oh Story Skill\uFF1A
|
|
185
217
|
|
|
186
218
|
- \u65B0\u5EFA\u6216\u4FEE\u590D\u5C0F\u8BF4\u5DE5\u7A0B\uFF1Astory-setup
|
|
187
|
-
- \u957F\u7BC7\
|
|
219
|
+
- \u957F\u7BC7\u89C4\u5212\u4E0E\u5199\u4F5C\uFF08\u8BA8\u8BBA\u957F\u7BC7\u7ED3\u6784\u3001\u89C4\u5212\u5267\u60C5\u3001\u5F00\u4E66\u3001\u5199\u5927\u7EB2\u3001\u8865\u7EC6\u7EB2\u3001\u5199\u6B63\u6587\u3001\u65E5\u66F4\uFF09\uFF1A
|
|
220
|
+
story-long-write\u3002\u53EA\u8981\u7ED3\u6784\u3001\u5927\u7EB2\u3001\u5377\u7EB2\u6216\u7EC6\u7EB2\u65F6\u53EA\u4EA4\u4ED8\u6240\u8BF7\u6C42\u7684\u89C4\u5212\uFF0C\u4E0D\u5199\u6B63\u6587\uFF1B
|
|
221
|
+
\u7528\u6237\u660E\u786E\u8981\u6C42\u5199\u6B63\u6587\u624D\u8FDB\u5165\u6B63\u6587\u6D41\u7A0B
|
|
222
|
+
- \u957F\u7BC7\u9009\u9898/\u626B\u699C\uFF1Astory-long-scan\uFF1B\u957F\u7BC7\u62C6\u6587\uFF1Astory-long-analyze
|
|
223
|
+
- \u7075\u611F\u5E93\u3001\u63D0\u70BC\u7075\u611F\u3001\u8DE8\u4E66\u7075\u611F\u805A\u5408\u3001\u66F4\u65B0\u7075\u611F\u5E93\uFF1Astory-long-analyze \u7684\u53EF\u9009\u7075\u611F\u5E93\u7BA1\u9053
|
|
224
|
+
\uFF08\u5355\u4E66\u62C6\u6587\u4E0D\u81EA\u52A8\u5165\u5E93\uFF09
|
|
188
225
|
- \u77ED\u7BC7\u9009\u9898/\u62C6\u6587/\u5199\u4F5C\uFF1Astory-short-scan\u3001story-short-analyze\u3001story-short-write
|
|
189
226
|
- \u5BFC\u5165\u5DF2\u6709\u4F5C\u54C1\uFF1Astory-import
|
|
190
227
|
- \u5BA1\u7A3F\u4E0E\u53BB AI \u5473\uFF1Astory-review\u3001story-deslop
|
|
191
228
|
- \u5C01\u9762\uFF1Astory-cover
|
|
229
|
+
- \u67E5\u672C\u4E66\u7684\u89D2\u8272\u3001\u4F0F\u7B14\u3001\u8FDB\u5EA6\u6216\u8BBE\u5B9A\uFF1A\u7528 oh_story_role \u8C03\u7528 story-explorer\uFF1B\u67E5\u5916\u90E8\u8D44\u6599\uFF1A
|
|
230
|
+
story-researcher\u3002\u56DE\u7B54\u8BB2\u6545\u4E8B\u91CC\u7684\u4E8B\uFF0C\u7F16\u53F7\u53EA\u8DDF\u7740\u6545\u4E8B\u63CF\u8FF0\u51FA\u73B0
|
|
192
231
|
- \u7BA1\u7406\u4F5C\u8005\u4E60\u60EF\uFF08\u8BB0\u4F4F/\u67E5\u770B/\u786E\u8BA4/\u66FF\u6362/\u5FD8\u6389\u5199\u4F5C\u504F\u597D\uFF09\uFF1A\u52A0\u8F7D\u672C skill \u7684
|
|
193
232
|
references/author-memory.md\uFF0C\u53EA\u7528\u672C skill \u7684 scripts/author_memory_commit.py \u7BA1\u7406
|
|
194
|
-
\u5DE5\u4F5C\u533A
|
|
233
|
+
\u4E24\u7EA7\u4F5C\u8005\u8BB0\u5FC6\uFF1A\u5168\u5C40\u3001\u9898\u6750\u3001\u6D41\u7A0B\u6761\u76EE\u5728\u5DE5\u4F5C\u533A .story/\u4F5C\u8005\u8BB0\u5FC6/\uFF08AP \u7F16\u53F7\uFF09\uFF0C\u672C\u4E66\u6761\u76EE\u5728
|
|
234
|
+
\u4E66\u7EA7 store\uFF08BP \u7F16\u53F7\uFF09\u3002--workspace \u5FC5\u987B\u663E\u5F0F\u4F20\u3002DSH \u7684\u5C0F\u8BF4\u5DE5\u4F5C\u533A\u901A\u5E38\u5C31\u662F\u4E66\u6839
|
|
235
|
+
\uFF08\u6B63\u6587/\u3001\u8BBE\u5B9A/ \u76F4\u63A5\u5728\u5DE5\u4F5C\u533A\u6839\uFF09\uFF1A\u6B64\u65F6 --workspace \u4E0E --book-root \u90FD\u4F20\u5DE5\u4F5C\u533A\u672C\u8EAB\uFF0C
|
|
236
|
+
\u4E66\u7EA7 store \u5728 .story/\u4F5C\u8005\u8BB0\u5FC6/\u4E66\u7EA7/\uFF1B\u4E66\u5728\u5B50\u76EE\u5F55\u65F6 --book-root \u4F20\u90A3\u672C\u4E66\u7684\u76EE\u5F55\u3002
|
|
237
|
+
\u5904\u7406\u67D0\u672C\u4E66\u65F6\u6BCF\u6761\u547D\u4EE4\u90FD\u5E26 --book-root\uFF08\u4E66\u7EA7\u64CD\u4F5C\u7F3A\u5B83\u76F4\u63A5\u62A5\u9519\uFF09\uFF0Cquery \u5FC5\u987B\u5E26
|
|
238
|
+
--kind\uFF08\u53EF\u91CD\u590D\uFF09\u3002\u53EA\u8BB0\u4F5C\u8005\u660E\u786E\u8BF4\u51FA\u7684\u504F\u597D\uFF0C\u4E0D\u4ECE\u53CD\u590D\u4FEE\u6539\u6216\u6210\u7A3F\u63A8\u65AD\u3002\u5DE5\u5177\u672A\u8FD4\u56DE
|
|
239
|
+
Author Memory Receipt \u524D\u4E0D\u5F97\u58F0\u79F0\u5DF2\u8BB0\u4F4F\uFF1B\u544A\u8BC9\u4F5C\u8005\u65F6\u5148\u7528\u4E00\u53E5\u4EBA\u8BDD\u8BF4\u8BB0\u4F4F\u4E86\u4EC0\u4E48\uFF0C
|
|
240
|
+
\u56DE\u6267\u653E\u6700\u540E\u4E00\u884C\u3002\u4F5C\u8005\u8BF4\u300C\u6574\u7406\u4F5C\u8005\u8BB0\u5FC6\u300D\u3001\u56DE\u6267\u63D0\u793A\u4E60\u60EF\u6512\u5F97\u592A\u591A\u3001\u5DE5\u5177\u62A5\u5355\u4E66\u5E03\u5C40\u9519\u8BEF\uFF0C
|
|
241
|
+
\u6216\u5DE5\u4F5C\u533A\u753B\u50CF\u91CC\u8FD8\u6709\u300C\u672C\u4E66\uFF1A\u300D\u6761\u76EE\uFF08\u5347\u7EA7\u524D\u5199\u5165\u7684\u672C\u4E66\u504F\u597D\uFF0C\u5DF2\u4E0D\u53C2\u4E0E\u67E5\u8BE2\uFF09\u65F6\uFF0C\u518D\u52A0\u8F7D
|
|
242
|
+
references/author-memory-maintenance.md\uFF1B\u8FC1\u79FB\u300C\u672C\u4E66\uFF1A\u300D\u6761\u76EE\u5C31\u6309\u5B83\u8FD0\u884C\u4E00\u6B21
|
|
243
|
+
migrate --workspace {\u5DE5\u4F5C\u533A} --book-root {\u4E66\u76EE\u5F55} \u628A\u5B83\u4EEC\u642C\u8FDB\u4E66\u7EA7 store\u3002
|
|
195
244
|
|
|
196
|
-
\
|
|
197
|
-
|
|
198
|
-
\
|
|
245
|
+
\u53EA\u8BF4 /story\u3001\u770B\u4E0D\u51FA\u610F\u56FE\u65F6\uFF0C\u4E0D\u8D34\u8DEF\u7531\u8868\uFF0C\u7ED9\u56DB\u4E2A\u767D\u8BDD\u9009\u9879\uFF1A\u300C\u5F00\u4E00\u672C\u957F\u7BC7\u6216\u63A5\u7740\u5199\u300D\u2192
|
|
246
|
+
story-long-write\uFF1B\u300C\u5199\u4E00\u7BC7\u77ED\u7BC7\u300D\u2192 story-short-write\uFF1B\u300C\u628A\u4E00\u7AE0\u6539\u5F97\u4E0D\u90A3\u4E48 AI\u300D\u2192
|
|
247
|
+
story-deslop\uFF1B\u300C\u66F4\u591A\uFF08\u62C6\u4E66\u3001\u626B\u699C\u3001\u5BFC\u5165\u65E7\u7A3F\u3001\u5BA1\u7A3F\u3001\u5C01\u9762\uFF09\u300D\u2192 \u518D\u5217\u8FDB\u9636\u9879\u3002\u610F\u56FE\u660E\u786E\u65F6
|
|
248
|
+
\u76F4\u63A5\u8FDB\u5165\u5BF9\u5E94 Skill\uFF1B\u53EA\u5DEE\u4E00\u4E2A\u4F1A\u6539\u53D8\u6D41\u7A0B\u7684\u9009\u62E9\u65F6\u53EA\u95EE\u8FD9\u4E00\u4E2A\u95EE\u9898\u3002\u9879\u76EE\u6587\u4EF6\u3001Agent\u3001
|
|
249
|
+
\u6A21\u578B\u3001\u6743\u9650\u3001Session Log \u548C UI \u5747\u7531\u5F53\u524D DSH \u4F1A\u8BDD\u7BA1\u7406\u3002\u5C0F\u8BF4\u6587\u4EF6\u901A\u8FC7\u201C\u5C0F\u8BF4\u201D\u89C6\u56FE\u67E5\u770B\uFF0C
|
|
250
|
+
Agent \u8FC7\u7A0B\u901A\u8FC7\u53F3\u4FA7\u52A8\u6001\u680F\u6216\u5B98\u65B9 Chat \u67E5\u770B\u3002\u7981\u6B62\u542F\u52A8\u72EC\u7ACB Dashboard\u3002`,
|
|
199
251
|
"story-setup": `# story-setup \u2014 DSH \u539F\u751F\u5C0F\u8BF4\u5DE5\u7A0B\u521D\u59CB\u5316
|
|
200
252
|
|
|
201
253
|
\u53EA\u521D\u59CB\u5316\u6216\u6821\u9A8C\u5F53\u524D DSH workspace \u4E2D\u7684\u5C0F\u8BF4\u6570\u636E\uFF0C\u4E0D\u90E8\u7F72\u4EFB\u4F55 Agent \u5E73\u53F0\u6587\u4EF6\u3002
|
|
202
254
|
|
|
203
255
|
1. \u68C0\u67E5\u73B0\u6709\u6B63\u6587\u3001\u8BBE\u5B9A\u3001\u5927\u7EB2\u548C\u8FFD\u8E2A\u6587\u4EF6\uFF0C\u5DF2\u6709\u5185\u5BB9\u7EDD\u4E0D\u8986\u76D6\u3002
|
|
204
256
|
2. \u6839\u636E\u7528\u6237\u58F0\u660E\u4E0E\u73B0\u6709\u7ED3\u6784\u5224\u65AD\u957F\u7BC7/\u77ED\u7BC7\uFF1B\u65E0\u6CD5\u53EF\u9760\u5224\u65AD\u65F6\u8BF7\u6C42\u786E\u8BA4\u3002
|
|
205
|
-
3. \u957F\u7BC7\u6309\u9700\u5EFA\u7ACB \u6B63\u6587/\u3001\u8BBE\u5B9A/\u3001\u5927\u7EB2/\u3001\
|
|
257
|
+
3. \u957F\u7BC7\u6309\u9700\u5EFA\u7ACB \u6B63\u6587/\u3001\u8BBE\u5B9A/\u3001\u5927\u7EB2/\u3002\u521D\u59CB\u5316\u3001\u5F00\u4E66\u3001\u5927\u7EB2\u548C\u7EC6\u7EB2\u9636\u6BB5\u90FD\u4E0D\u5EFA \u8FFD\u8E2A/\uFF0C
|
|
258
|
+
\u4E5F\u4E0D\u5199 \u8FFD\u8E2A/_tracking-state.json\uFF1A\u8FFD\u8E2A\u5728\u7B2C\u4E00\u7AE0\u6B63\u6587\u52A8\u7B14\u524D\uFF0C\u7531 story-long-write
|
|
259
|
+
\u5355\u7AE0\u6D41\u7A0B\u7528\u5B83\u7684 scripts/tracking_commit.py init \u521D\u59CB\u5316\uFF08\u4E8B\u52A1 JSON \u653E\u4E66\u76EE\u5F55
|
|
260
|
+
.story/work/\uFF0Ccheck \u901A\u8FC7\u540E\u5220\u6389\uFF09\uFF0C\u4E4B\u540E\u6BCF\u7AE0\u7531\u811A\u672C\u63D0\u4EA4\u3002_tracking-state.json \u4E0E
|
|
261
|
+
\u4E0A\u4E0B\u6587.md \u7B49\u6D3E\u751F Tracking \u89C6\u56FE\u53EA\u7531\u811A\u672C\u751F\u6210\uFF0C\u7EDD\u4E0D\u624B\u6539\u3002
|
|
206
262
|
\u7B2C\u4E00\u7AE0\u6B63\u6587\u843D\u76D8\u524D\u5FC5\u987B\u6709\u5BF9\u5E94\u7EC6\u7EB2\u3002\u77ED\u7BC7\u4FDD\u6301\u8F7B\u91CF\u7ED3\u6784\uFF0C\u4E0D\u5F3A\u52A0\u957F\u7BC7 Tracking\u3002
|
|
207
|
-
4. \
|
|
263
|
+
4. \u5DF2\u6709\u6B63\u6587\u5374\u6CA1\u6709 \u8FFD\u8E2A/_tracking-state.json \u65F6\uFF0C\u4E0D\u81EA\u884C\u8865\u5EFA\u8FFD\u8E2A\u6587\u4EF6\uFF1A\u5DF2\u6709\u65E7 \u8FFD\u8E2A/
|
|
264
|
+
\u7684\u662F\u65E7\u8FFD\u8E2A\u7ED3\u6784\uFF0C\u5EFA\u8BAE\u8D70 story-import \u7684\u300C\u65E7\u8FFD\u8E2A\u9879\u76EE\u8FC1\u79FB\u300D\uFF1B\u6CA1\u6709 \u8FFD\u8E2A/ \u7684\u65E2\u6709\u4E66\u7A3F
|
|
265
|
+
\u5EFA\u8BAE\u7528 story-import \u5BFC\u5165\u3002
|
|
266
|
+
5. \u9700\u8981\u67B6\u6784\u3001\u89D2\u8272\u6216\u7814\u7A76\u5DE5\u4F5C\u65F6\uFF0C\u901A\u8FC7 oh_story_role \u8C03\u7528\u5DF2\u6253\u5305 Role\uFF1B\u4E0D\u8981\u68C0\u67E5\u6216
|
|
208
267
|
\u751F\u6210 .claude\u3001.codex\u3001.opencode\u3001.agents\u3001.zcode\u3001AGENTS.md \u6216 .story-deployed\u3002
|
|
209
|
-
|
|
268
|
+
6. \u7ED9\u4F5C\u8005\u7684\u62A5\u544A\u6309\u8FD9\u4E2A\u987A\u5E8F\u5199\uFF1A\u5148\u5199\u300C\u73B0\u5728\u53EF\u4EE5\u505A\u4EC0\u4E48\u300D\uFF0C\u7528\u5199\u4E66\u7684\u8BDD\u5217\u771F\u6B63\u53EF\u7528\u7684\u4E8B
|
|
269
|
+
\uFF08\u5982\u300C\u53EF\u4EE5\u5F00\u65B0\u4E66\u3001\u7EED\u5199\uFF1A\u8BF4 /story-long-write\u300D\uFF09\uFF1B\u518D\u5199\u300C\u4F60\u8FD8\u9700\u8981\u505A\u7684\u4E8B\u300D\uFF0C\u9010\u6761
|
|
270
|
+
\u53EF\u7167\u505A\uFF08\u542B\u9700\u8981\u4F5C\u8005\u786E\u8BA4\u7684\u957F\u7BC7/\u77ED\u7BC7\u5224\u65AD\uFF09\uFF0C\u6CA1\u6709\u5C31\u5199\u300C\u65E0\u9700\u5176\u4ED6\u64CD\u4F5C\u300D\u3002\u8FD9\u4E24\u6BB5\u4E0D\u51FA\u73B0
|
|
271
|
+
\u811A\u672C\u540D\u3001\u5B57\u6BB5\u540D\u3001\u72B6\u6001\u540D\u6216\u6587\u4EF6\u8DEF\u5F84\uFF1B\u6700\u540E\u624D\u7B80\u77ED\u5217\u51FA\u521B\u5EFA\u548C\u4FDD\u7559\u4E86\u54EA\u4E9B\u6587\u4EF6\u3002
|
|
272
|
+
\u4E0D\u8981\u914D\u7F6E\u6A21\u578B\u3001\u6743\u9650\u3001Hooks \u6216 Session\u3002
|
|
210
273
|
|
|
211
274
|
\u9898\u6750\u3001\u89D2\u8272\u3001\u8282\u594F\u3001\u51B2\u7A81\u3001\u5F00\u7BC7\u548C\u5199\u4F5C\u65B9\u6CD5\u8D44\u6599\u4F4D\u4E8E references/agent-references/\uFF1B
|
|
212
275
|
\u53EA\u52A0\u8F7D\u5F53\u524D\u4EFB\u52A1\u9700\u8981\u7684\u6587\u4EF6\u3002`,
|
|
@@ -233,6 +296,12 @@ Agent\u3001\u6A21\u578B\u3001\u6743\u9650\u3001Session Log \u548C UI \u5747\u753
|
|
|
233
296
|
4. \u6309\u9898\u6750\u5206\u5E03\u3001\u65B0\u9898\u6750\u4FE1\u53F7\u3001\u7ECF\u5178\u9898\u6750\u53D8\u5316\u3001\u7BC7\u5E45\u4E0E\u66F4\u65B0\u3001\u4E66\u540D\u6A21\u5F0F\u3001\u5F00\u5934\u5356\u70B9\u548C
|
|
234
297
|
\u5DEE\u5F02\u5316\u5143\u7D20\u5206\u6790\u3002\u9700\u8981\u51B3\u7B56\u95E8\u7981\u65F6\u4F7F\u7528 references/topic-decision.md\u3002
|
|
235
298
|
5. \u8F93\u51FA\u5E02\u573A\u6982\u51B5\u3001\u9898\u6750\u70ED\u5EA6\u3001\u8BC1\u636E\u4E0E\u53EF\u4FE1\u5EA6\u3001\u98CE\u9669\u3001\u4E09\u9879\u53EF\u6267\u884C\u65B9\u5411\u548C\u4E0B\u6B21\u590D\u626B\u65F6\u95F4\u3002
|
|
299
|
+
6. \u62A5\u544A\u5199\u7ED9\u4F5C\u8005\uFF1A\u8BB2\u5E02\u573A\u7ED3\u8BBA\u548C\u80FD\u5199\u7684\u65B9\u5411\uFF1B\u811A\u672C\u540D\u3001\u547D\u4EE4\u548C\u91C7\u96C6\u72B6\u6001\u7801\u4E0D\u8FDB\u62A5\u544A\u3002
|
|
300
|
+
\u67D0\u4E2A\u699C\u6CA1\u91C7\u5230\uFF0C\u5C31\u7528\u4E00\u53E5\u8BDD\u8BF4\u660E\u300CXX \u699C\u8FD9\u6B21\u6CA1\u62FF\u5230\uFF08\u539F\u56E0\uFF09\uFF0C\u7ED3\u8BBA\u4E0D\u542B\u5B83\u300D\u3002
|
|
301
|
+
7. \u6BCF\u6B21\u626B\u699C\u65B0\u5EFA \u626B\u699C/{YYYYMMDD}/\uFF08\u540C\u65E5\u518D\u626B\u52A0 -2\uFF09\uFF0C\u6837\u672C\u8BB0\u5F55\u5B58\u5728\u8FD9\u91CC\uFF1B\u62A5\u544A\u540C\u65F6\u6309
|
|
302
|
+
references/topic-decision.md \u7684\u6A21\u677F\u5199\u8FDB\u8BE5\u76EE\u5F55\u7684 \u9009\u9898\u51B3\u7B56.md\uFF08\u5E26\u300C\u626B\u699C\u65E5\u671F\u300D\uFF09\uFF0C
|
|
303
|
+
\u4F5C\u4E3A\u300C\u626B\u699C\u7ED3\u8BBA\u300D\u4E00\u8282\uFF0C\u4F5C\u8005\u8981\u9009\u9898\u65F6\u518D\u5199\u300C\u63A8\u8350\u9009\u9898\u300D\u4E00\u8282\u3002story-long-write \u5F00\u4E66\u65F6
|
|
304
|
+
\u4ECE\u8FD9\u4EFD\u6587\u4EF6\u63A5\u4E0A\uFF0C\u6240\u4EE5\u7ED3\u8BBA\u8981\u843D\u76D8\uFF0C\u4E0D\u53EA\u7559\u5728\u5BF9\u8BDD\u91CC\u3002
|
|
236
305
|
|
|
237
306
|
\u5F53\u524D Preset \u6CA1\u6709\u7F51\u9875\u80FD\u529B\u4E14\u7528\u6237\u4E5F\u672A\u63D0\u4F9B\u6837\u672C\u65F6\uFF0C\u4F7F\u7528\u5185\u7F6E\u53C2\u8003\u5B8C\u6210\u65B9\u6CD5\u8BBA\u5206\u6790\uFF0C
|
|
238
307
|
\u5E76\u5217\u51FA\u4ECD\u9700\u6838\u9A8C\u7684\u699C\u5355\uFF1B\u4E0D\u8981\u542F\u52A8 CDP\u3001\u72EC\u7ACB\u6D4F\u89C8\u5668\u6216\u5E76\u884C\u8FD0\u884C\u65F6\u3002`,
|
|
@@ -247,7 +316,14 @@ Agent\u3001\u6A21\u578B\u3001\u6743\u9650\u3001Session Log \u548C UI \u5747\u753
|
|
|
247
316
|
3. \u8BB0\u5F55\u6765\u6E90 URL\u3001\u91C7\u96C6\u65E5\u671F\u3001\u699C\u5355\u53E3\u5F84\u3001\u6709\u6548\u6837\u672C\u6570\u3001\u7F3A\u5931\u5B57\u6BB5\u548C\u5F02\u5E38\u9879\u3002
|
|
248
317
|
4. \u5206\u6790\u60C5\u7EEA\u7C7B\u578B\u3001\u9898\u6750\u70ED\u70B9\u3001\u7BC7\u5E45\u3001\u5F00\u5934\u3001\u7ED3\u5C3E\u3001\u6807\u9898\u3001\u4EBA\u8BBE\u4E0E\u4F20\u64AD\u89E6\u53D1\u70B9\uFF1B
|
|
249
318
|
\u7ED9\u6BCF\u4E2A\u8D8B\u52BF\u6807\u6CE8\u8BC1\u636E\u5F3A\u5EA6\u3001\u9971\u548C\u98CE\u9669\u548C\u6709\u6548\u671F\u3002
|
|
250
|
-
5. \u8F93\u51FA\u5E02\u573A\u6982\u51B5\
|
|
319
|
+
5. \u8F93\u51FA\u5E02\u573A\u6982\u51B5\uFF08\u626B\u699C\u65F6\u95F4\u3001\u6838\u5FC3\u53D1\u73B0\u548C\u53EF\u4FE1\u5EA6\uFF1A\u6837\u672C\u591A\u5C11\u7BC7\u3001\u6765\u81EA\u54EA\u51E0\u4E2A\u699C\uFF0C\u5E76\u5EFA\u8BAE
|
|
320
|
+
\u54EA\u5929\u524D\u540E\u518D\u626B\u4E00\u6B21\uFF09\u3001\u60C5\u7EEA\u70ED\u5EA6\u3001\u9898\u6750\u70ED\u70B9\u3001\u5173\u952E\u6570\u636E\u3001\u98CE\u53E3\u9884\u8B66\u3001\u4E09\u9879\u53EF\u5199\u65B9\u5411\u3002
|
|
321
|
+
6. \u62A5\u544A\u5199\u7ED9\u4F5C\u8005\uFF1A\u8BB2\u5E02\u573A\u7ED3\u8BBA\u548C\u80FD\u5199\u7684\u65B9\u5411\uFF1B\u811A\u672C\u540D\u3001\u547D\u4EE4\u548C SKIP \u8FD9\u7C7B\u91C7\u96C6\u72B6\u6001\u4E0D\u8FDB\u62A5\u544A\u3002
|
|
322
|
+
\u67D0\u4E2A\u5E73\u53F0\u6CA1\u91C7\u5230\uFF0C\u5C31\u7528\u4E00\u53E5\u8BDD\u8BF4\u660E\u300CXX \u8FD9\u6B21\u6CA1\u62FF\u5230\uFF08\u539F\u56E0\uFF09\uFF0C\u7ED3\u8BBA\u4E0D\u542B\u5B83\u300D\u3002
|
|
323
|
+
7. \u6BCF\u6B21\u626B\u699C\u65B0\u5EFA \u626B\u699C/{YYYYMMDD}/\uFF08\u540C\u65E5\u518D\u626B\u52A0 -2\uFF09\uFF0C\u6837\u672C\u8BB0\u5F55\u5B58\u5728\u8FD9\u91CC\uFF1B\u62A5\u544A\u540C\u65F6\u6309
|
|
324
|
+
references/topic-match.md \u7684\u6A21\u677F\u5199\u8FDB\u8BE5\u76EE\u5F55\u7684 \u77ED\u7BC7\u626B\u699C\u7ED3\u8BBA.md\uFF0C\u4F5C\u4E3A\u300C\u626B\u699C\u7ED3\u8BBA\u300D
|
|
325
|
+
\u4E00\u8282\uFF0C\u7ED3\u5408\u9879\u76EE\u6761\u4EF6\u518D\u5199\u300C\u9009\u9898\u5339\u914D\u300D\u4E00\u8282\u3002story-short-write \u4ECE\u8FD9\u4EFD\u6587\u4EF6\u63A5\u4E0A\u9009\u9898\u3002
|
|
326
|
+
\u4F5C\u8005\u81EA\u5DF1\u7ED9\u699C\u5355\u65F6\uFF0C\u6309 references/manual-rank-input.md \u7684\u683C\u5F0F\u6574\u7406\u3002
|
|
251
327
|
|
|
252
328
|
\u5F53\u524D Preset \u6CA1\u6709\u7F51\u9875\u80FD\u529B\u4E14\u7528\u6237\u4E5F\u672A\u63D0\u4F9B\u6837\u672C\u65F6\uFF0C\u53EA\u505A\u5386\u53F2\u8D44\u6599\u5206\u6790\u5E76\u5217\u51FA\u9A8C\u8BC1\u52A8\u4F5C\uFF1B
|
|
253
329
|
\u4E0D\u8981\u542F\u52A8 CDP\u3001\u72EC\u7ACB\u6D4F\u89C8\u5668\u6216\u5E76\u884C\u8FD0\u884C\u65F6\u3002`
|
|
@@ -419,11 +495,82 @@ async function hostPython(probe = commandOutput) {
|
|
|
419
495
|
}
|
|
420
496
|
|
|
421
497
|
// src/native-hooks.ts
|
|
422
|
-
import { createUserMessage } from "@deepseek-ai/dsh-llm";
|
|
498
|
+
import { boundContextSummary, createUserMessage } from "@deepseek-ai/dsh-llm";
|
|
499
|
+
|
|
500
|
+
// src/role-provider.ts
|
|
501
|
+
import { readFile as readFile2 } from "node:fs/promises";
|
|
502
|
+
import { basename as basename2, dirname as dirname3, join as join3, resolve as resolve3 } from "node:path";
|
|
503
|
+
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
504
|
+
var OH_STORY_ROLE_NAMES = [
|
|
505
|
+
"chapter-extractor",
|
|
506
|
+
"character-designer",
|
|
507
|
+
"consistency-checker",
|
|
508
|
+
"narrative-writer",
|
|
509
|
+
"story-architect",
|
|
510
|
+
"story-explorer",
|
|
511
|
+
"story-researcher"
|
|
512
|
+
];
|
|
513
|
+
function roleBody(source) {
|
|
514
|
+
const frontmatter = /^---\r?\n[\s\S]*?\r?\n---\r?\n?/u.exec(source);
|
|
515
|
+
return source.slice(frontmatter?.[0].length ?? 0).trim();
|
|
516
|
+
}
|
|
517
|
+
function defaultBundledRoleRoot() {
|
|
518
|
+
const current = dirname3(fileURLToPath2(import.meta.url));
|
|
519
|
+
return basename2(current) === "src" ? resolve3(current, "../../knowledge/oh-story/roles") : resolve3(current, "oh-story/roles");
|
|
520
|
+
}
|
|
521
|
+
async function loadBundledRole(name2, roleRoot = defaultBundledRoleRoot(), execution = "tool-free") {
|
|
522
|
+
const body = roleBody(await readFile2(join3(resolve3(roleRoot), `${name2}.md`), "utf8"));
|
|
523
|
+
if (body.length === 0) throw new Error(`Bundled role "${name2}" is empty.`);
|
|
524
|
+
const integration = execution === "tool-free" ? [
|
|
525
|
+
"You are running inside an Oh Story review-required DSH collaboration. The caller supplies every permitted input in the prompt.",
|
|
526
|
+
"Do not read or write project files, do not call tools, and do not follow legacy .claude/.codex path or deployment instructions in the upstream role text.",
|
|
527
|
+
"Return only the output contract requested by the caller; never claim to have changed the project."
|
|
528
|
+
] : [
|
|
529
|
+
"You are running as a native oh-story-dsh specialist. The current DSH workspace and visible tool set are your complete authority boundary.",
|
|
530
|
+
"Never inspect or require legacy .claude/.opencode/.codex agent deployment files; this exact pinned Role is already active.",
|
|
531
|
+
"Bundled story-setup references are pinned plugin resources, not project files or project Skills. When the upstream Role marks one mandatory, call oh_story_bundled_reference with the exact story-setup/references/agent-references path, then use only the returned content.",
|
|
532
|
+
"If oh_story_bundled_reference or a required bundled reference is unavailable, report the missing reference to the caller. Never call the generic skill tool, fall back to a legacy platform path, or claim that an unread reference was used.",
|
|
533
|
+
"Use only the tools actually visible to you. Mutate files only when the caller explicitly requests it and your visible DSH tools permit it; otherwise return findings to the caller."
|
|
534
|
+
];
|
|
535
|
+
return [
|
|
536
|
+
`OH_STORY_DSH_ROLE:${name2}`,
|
|
537
|
+
...integration,
|
|
538
|
+
"",
|
|
539
|
+
body
|
|
540
|
+
].join("\n");
|
|
541
|
+
}
|
|
542
|
+
|
|
543
|
+
// src/role-identity.ts
|
|
544
|
+
var ROLE_LABEL_PREFIX = "oh-story:";
|
|
545
|
+
function ohStoryRoleLabel(role) {
|
|
546
|
+
return `${ROLE_LABEL_PREFIX}${role}`;
|
|
547
|
+
}
|
|
548
|
+
function roleFromLabel(label) {
|
|
549
|
+
if (typeof label !== "string" || !label.startsWith(ROLE_LABEL_PREFIX)) return void 0;
|
|
550
|
+
const name2 = label.slice(ROLE_LABEL_PREFIX.length);
|
|
551
|
+
return OH_STORY_ROLE_NAMES.find((role) => role === name2);
|
|
552
|
+
}
|
|
553
|
+
var roleSessions = /* @__PURE__ */ new WeakMap();
|
|
554
|
+
function observeOhStoryRoleDescriptor(session, event) {
|
|
555
|
+
if (event.type !== "subagent/descriptor" || roleSessions.has(session)) return;
|
|
556
|
+
const role = roleFromLabel(event.data.label);
|
|
557
|
+
if (role !== void 0) roleSessions.set(session, role);
|
|
558
|
+
}
|
|
559
|
+
function markOhStoryRoleSession(session, role) {
|
|
560
|
+
if (!roleSessions.has(session)) roleSessions.set(session, role);
|
|
561
|
+
}
|
|
562
|
+
function ohStoryRoleOfSession(session) {
|
|
563
|
+
return session === void 0 ? void 0 : roleSessions.get(session);
|
|
564
|
+
}
|
|
565
|
+
|
|
566
|
+
// src/native-hooks.ts
|
|
423
567
|
var MUTATION_TOOLS = /* @__PURE__ */ new Set(["write", "edit", "str_replace_editor"]);
|
|
568
|
+
function argumentRecord(args) {
|
|
569
|
+
return typeof args === "object" && args !== null && !Array.isArray(args) ? args : void 0;
|
|
570
|
+
}
|
|
424
571
|
function mutationPath(name2, args) {
|
|
425
|
-
|
|
426
|
-
|
|
572
|
+
const record2 = argumentRecord(args);
|
|
573
|
+
if (!MUTATION_TOOLS.has(name2) || record2 === void 0) return void 0;
|
|
427
574
|
if (name2 === "str_replace_editor") {
|
|
428
575
|
if (!(/* @__PURE__ */ new Set(["create", "str_replace", "insert"])).has(String(record2.command))) return void 0;
|
|
429
576
|
return typeof record2.path === "string" && record2.path.trim() !== "" ? record2.path : void 0;
|
|
@@ -441,6 +588,19 @@ function normalizedRelativePath(path) {
|
|
|
441
588
|
}
|
|
442
589
|
return segments.join("/");
|
|
443
590
|
}
|
|
591
|
+
function proseLocation(path) {
|
|
592
|
+
const segments = path.split("/");
|
|
593
|
+
if (segments.length < 2) return void 0;
|
|
594
|
+
const index = segments.lastIndexOf("\u6B63\u6587", segments.length - 2);
|
|
595
|
+
if (index < 0) return void 0;
|
|
596
|
+
return { book: segments.slice(0, index).join("/"), name: segments.at(-1) ?? "" };
|
|
597
|
+
}
|
|
598
|
+
function inBook(book, path) {
|
|
599
|
+
return book === "" ? path : `${book}/${path}`;
|
|
600
|
+
}
|
|
601
|
+
function lastSegment(path) {
|
|
602
|
+
return path.replaceAll("\\", "/").split("/").filter((part) => part !== "").at(-1) ?? "";
|
|
603
|
+
}
|
|
444
604
|
function detectStoryMutation(name2, args, cwd) {
|
|
445
605
|
const rawPath = mutationPath(name2, args);
|
|
446
606
|
if (cwd === void 0 || rawPath === void 0) return void 0;
|
|
@@ -451,8 +611,9 @@ function detectStoryMutation(name2, args, cwd) {
|
|
|
451
611
|
if (absolute && !insideRoot) return void 0;
|
|
452
612
|
const normalized = normalizedRelativePath(absolute ? candidate.slice(root.length + 1) : candidate);
|
|
453
613
|
if (normalized === void 0) return void 0;
|
|
454
|
-
|
|
455
|
-
|
|
614
|
+
const location = proseLocation(normalized);
|
|
615
|
+
if (location === void 0) return void 0;
|
|
616
|
+
const chapterText = /^第0*(\d+)章/u.exec(location.name)?.[1];
|
|
456
617
|
return { root, path: normalized, ...chapterText === void 0 ? {} : { chapter: Number(chapterText) } };
|
|
457
618
|
}
|
|
458
619
|
async function storyMutation(exec, fs) {
|
|
@@ -476,20 +637,54 @@ async function target(fs, root, path, signal) {
|
|
|
476
637
|
async function exists(fs, root, path, signal) {
|
|
477
638
|
return target(fs, root, path, signal).then((value) => fs.stat(value, signal)).then((info) => info !== void 0, () => false);
|
|
478
639
|
}
|
|
479
|
-
async function
|
|
480
|
-
|
|
481
|
-
|
|
640
|
+
async function isLongFormBook(fs, root, book, signal) {
|
|
641
|
+
return await exists(fs, root, inBook(book, "\u5927\u7EB2"), signal) || await exists(fs, root, inBook(book, "\u8FFD\u8E2A"), signal);
|
|
642
|
+
}
|
|
643
|
+
var OUTLINE_MIN_CHARS = 30;
|
|
644
|
+
var OUTLINE_READ_LIMIT = 64 * 1024;
|
|
645
|
+
async function outlineIsEmpty(fs, outline, signal) {
|
|
646
|
+
if (fs.readBytes === void 0) return false;
|
|
647
|
+
let text2;
|
|
648
|
+
try {
|
|
649
|
+
text2 = new TextDecoder("utf-8", { fatal: true, ignoreBOM: true }).decode(await fs.readBytes(outline, signal, OUTLINE_READ_LIMIT));
|
|
650
|
+
} catch {
|
|
651
|
+
return false;
|
|
652
|
+
}
|
|
653
|
+
if (text2.startsWith("\uFEFF")) text2 = text2.slice(1);
|
|
654
|
+
const body = text2.split("\n").map((line) => line.replace(/^[ \t]*#+/u, "")).join("");
|
|
655
|
+
return Array.from(body.replace(/[ \t\r\n\f\v\u3000]/gu, "")).length < OUTLINE_MIN_CHARS;
|
|
656
|
+
}
|
|
657
|
+
async function chapterOutlines(fs, root, book, chapter, signal) {
|
|
658
|
+
const entries = await target(fs, root, inBook(book, "\u5927\u7EB2"), signal).then((directory) => fs.listDir(directory, signal)).catch(() => []);
|
|
659
|
+
return entries.filter((entry) => entry.type === "file" && Number(/^细纲_第0*(\d+)章.*\.md$/u.exec(entry.name)?.[1]) === chapter).sort((left, right) => left.name < right.name ? -1 : left.name > right.name ? 1 : 0);
|
|
660
|
+
}
|
|
661
|
+
var TRACKING_STATE = "\u8FFD\u8E2A/_tracking-state.json";
|
|
662
|
+
var IMPORT_MARKER = ".story/work/\u5BFC\u5165\u4E2D.md";
|
|
663
|
+
async function hasTrackingState(fs, root, book, signal) {
|
|
664
|
+
return exists(fs, root, inBook(book, TRACKING_STATE), signal);
|
|
665
|
+
}
|
|
666
|
+
async function hasImportSignal(fs, root, book, signal) {
|
|
667
|
+
if (await exists(fs, root, inBook(book, IMPORT_MARKER), signal)) return true;
|
|
668
|
+
const bookName = book === "" ? lastSegment(root) : lastSegment(book);
|
|
669
|
+
return bookName !== "" && await exists(fs, root, `\u62C6\u6587\u5E93/${bookName}`, signal);
|
|
482
670
|
}
|
|
483
671
|
async function validateStoryMutation(fs, mutation, signal) {
|
|
484
|
-
const
|
|
485
|
-
if (
|
|
486
|
-
|
|
672
|
+
const location = proseLocation(mutation.path);
|
|
673
|
+
if (mutation.chapter === void 0 || location === void 0) return void 0;
|
|
674
|
+
const { book } = location;
|
|
675
|
+
if (!await isLongFormBook(fs, mutation.root, book, signal)) return void 0;
|
|
676
|
+
if (await exists(fs, mutation.root, mutation.path, signal)) return void 0;
|
|
677
|
+
if (!await hasTrackingState(fs, mutation.root, book, signal) && await hasImportSignal(fs, mutation.root, book, signal)) {
|
|
487
678
|
return void 0;
|
|
488
679
|
}
|
|
489
|
-
|
|
490
|
-
|
|
680
|
+
const outlines = await chapterOutlines(fs, mutation.root, book, mutation.chapter, signal);
|
|
681
|
+
const [first] = outlines;
|
|
682
|
+
if (first !== void 0) {
|
|
683
|
+
for (const outline of outlines) if (!await outlineIsEmpty(fs, outline.target, signal)) return void 0;
|
|
684
|
+
return `Oh Story \u963B\u6B62\u5199\u5165\u7B2C ${String(mutation.chapter)} \u7AE0\uFF1A\u7EC6\u7EB2 ${inBook(book, "\u5927\u7EB2")}/${first.name} \u662F\u7A7A\u7684\uFF08\u4E0D\u8BA1 # \u53F7\u548C\u7A7A\u767D\u4E0D\u5230 ${String(OUTLINE_MIN_CHARS)} \u5B57\uFF09\u3002\u5148\u6309 story-long-write \u5355\u7AE0\u6D41\u7A0B\u628A\u7EC6\u7EB2\u5199\u5B8C\u6574\uFF08\u8FD9\u7AE0\u53D1\u751F\u4EC0\u4E48\u3001\u4E3B\u89D2\u505A\u4EC0\u4E48\u9009\u62E9\uFF09\uFF0C\u518D\u5199\u6B63\u6587\u3002`;
|
|
491
685
|
}
|
|
492
|
-
|
|
686
|
+
const padded = String(mutation.chapter).padStart(3, "0");
|
|
687
|
+
return `Oh Story \u963B\u6B62\u5199\u5165\u7B2C ${String(mutation.chapter)} \u7AE0\uFF1A\u672A\u627E\u5230\u5BF9\u5E94\u7684 ${inBook(book, "\u5927\u7EB2")}/\u7EC6\u7EB2_\u7B2C${padded}\u7AE0*.md\u3002\u5148\u6309 story-long-write \u5355\u7AE0\u6D41\u7A0B\u8865\u5EFA\u7EC6\u7EB2\u518D\u5199\u6B63\u6587\u3002`;
|
|
493
688
|
}
|
|
494
689
|
async function decideStoryMutation(exec, next) {
|
|
495
690
|
const fs = exec.agent?.ctx.get("fs");
|
|
@@ -500,20 +695,90 @@ async function decideStoryMutation(exec, next) {
|
|
|
500
695
|
if (reason !== void 0) return { kind: "deny", reason };
|
|
501
696
|
return next();
|
|
502
697
|
}
|
|
698
|
+
var ANALYSIS_INPUT = /^输入-(RAW|REUSE)-(\d+)-(\d+)\.md$/u;
|
|
699
|
+
var ANALYSIS_INPUT_RULE = "\u53EA\u5141\u8BB8\u5199\u8C03\u7528\u65B9\u7ED9\u7684 {\u62C6\u6587\u76EE\u5F55}/_analysis_cache/\u8F93\u5165-{\u6279\u6B21ID}.md\uFF08\u6279\u6B21 ID \u5982 RAW-4-6\uFF09\uFF0C\u4E0D\u5199\u5176\u4ED6\u6587\u4EF6\u3002";
|
|
700
|
+
function isFileMutationCall(name2, args) {
|
|
701
|
+
if (name2 === "write" || name2 === "edit") return true;
|
|
702
|
+
return name2 === "str_replace_editor" && argumentRecord(args)?.command !== "view";
|
|
703
|
+
}
|
|
704
|
+
function displayParent(path) {
|
|
705
|
+
const index = Math.max(path.lastIndexOf("/"), path.lastIndexOf("\\"));
|
|
706
|
+
return index <= 0 ? path.slice(0, index + 1) : path.slice(0, index);
|
|
707
|
+
}
|
|
708
|
+
function displayName(path) {
|
|
709
|
+
return path.slice(Math.max(path.lastIndexOf("/"), path.lastIndexOf("\\")) + 1);
|
|
710
|
+
}
|
|
711
|
+
async function isAnalysisDirectory(fs, directory, signal) {
|
|
712
|
+
return await exists(fs, directory, "chapter_index.csv", signal) || await exists(fs, directory, "_progress.md", signal);
|
|
713
|
+
}
|
|
714
|
+
async function validateAnalysisInputWrite(fs, cwd, path, signal) {
|
|
715
|
+
const deny = (shown, reasons2) => `Oh Story \u963B\u6B62 chapter-extractor \u5199\u5165 ${shown}\uFF1A${reasons2.join("\uFF1B")}\u3002${ANALYSIS_INPUT_RULE}`;
|
|
716
|
+
if (path === void 0) return deny("\uFF08\u672A\u7ED9\u51FA\u8DEF\u5F84\uFF09", ["\u5199\u5165\u6CA1\u6709\u7ED9\u51FA\u6587\u4EF6\u8DEF\u5F84"]);
|
|
717
|
+
let rootTarget;
|
|
718
|
+
let fileTarget;
|
|
719
|
+
try {
|
|
720
|
+
[rootTarget, fileTarget] = await Promise.all([
|
|
721
|
+
fs.resolve(cwd, signal === void 0 ? {} : { signal }),
|
|
722
|
+
fs.resolve(path, { cwd, ...signal === void 0 ? {} : { signal } })
|
|
723
|
+
]);
|
|
724
|
+
} catch {
|
|
725
|
+
return deny(path, ["\u8DEF\u5F84\u65E0\u6CD5\u89E3\u6790"]);
|
|
726
|
+
}
|
|
727
|
+
const reasons = [];
|
|
728
|
+
const match = ANALYSIS_INPUT.exec(displayName(fileTarget.displayPath));
|
|
729
|
+
if (match === null) reasons.push("\u6587\u4EF6\u540D\u5FC5\u987B\u662F \u8F93\u5165-{RAW|REUSE}-{\u8D77\u7AE0}-{\u6B62\u7AE0}.md");
|
|
730
|
+
else if (Number(match[2]) < 1 || Number(match[3]) < Number(match[2])) reasons.push("\u6279\u6B21\u7AE0\u53F7\u8303\u56F4\u65E0\u6548");
|
|
731
|
+
const cacheDirectory = displayParent(fileTarget.displayPath);
|
|
732
|
+
if (displayName(cacheDirectory) !== "_analysis_cache") reasons.push("\u53EA\u80FD\u5199\u5728\u62C6\u6587\u76EE\u5F55\u7684 _analysis_cache/ \u4E0B");
|
|
733
|
+
else if (!await isAnalysisDirectory(fs, displayParent(cacheDirectory), signal)) {
|
|
734
|
+
reasons.push("\u4E0A\u7EA7\u76EE\u5F55\u4E0D\u662F\u62C6\u6587\u76EE\u5F55\uFF08\u7F3A chapter_index.csv \u4E0E _progress.md\uFF09");
|
|
735
|
+
}
|
|
736
|
+
if (!fs.contains(rootTarget, fileTarget)) reasons.push("\u8DEF\u5F84\u5728\u9879\u76EE\u76EE\u5F55\u4E4B\u5916");
|
|
737
|
+
return reasons.length === 0 ? void 0 : deny(path, reasons);
|
|
738
|
+
}
|
|
739
|
+
async function decideChapterExtractorWrite(exec, next) {
|
|
740
|
+
if (ohStoryRoleOfSession(exec.agent?.session) !== "chapter-extractor" || !isFileMutationCall(exec.name, exec.arguments)) {
|
|
741
|
+
return next();
|
|
742
|
+
}
|
|
743
|
+
const fs = exec.agent?.ctx.get("fs");
|
|
744
|
+
const cwd = exec.agent?.session.header.cwd;
|
|
745
|
+
const reason = fs === void 0 || cwd === void 0 ? `Oh Story \u963B\u6B62 chapter-extractor \u5199\u5165\uFF1A\u65E0\u6CD5\u786E\u8BA4\u9879\u76EE\u76EE\u5F55\u3002${ANALYSIS_INPUT_RULE}` : await validateAnalysisInputWrite(fs, cwd, mutationPath(exec.name, exec.arguments), exec.signal);
|
|
746
|
+
return reason === void 0 ? next() : { kind: "deny", reason };
|
|
747
|
+
}
|
|
748
|
+
function postWriteReminderText(path, options = {}) {
|
|
749
|
+
return [
|
|
750
|
+
`<oh-story-post-write>\u6B63\u6587 ${path} \u5DF2\u53D8\u66F4\u3002`,
|
|
751
|
+
"\u6BCF\u6B21\u5199\u5165\u6B63\u6587\u90FD\u4F1A\u51FA\u73B0\u8FD9\u6761\u63D0\u9192\uFF0C\u4E00\u7AE0\u5199\u5230\u4E00\u534A\u65F6\u4E5F\u4F1A\uFF1B\u5B83\u4E0D\u8868\u793A\u672C\u7AE0\u5DF2\u7ECF\u5B8C\u6210\uFF0C\u4E5F\u4E0D\u662F\u4F5C\u8005\u7684\u65B0\u5199\u4F5C\u8981\u6C42\uFF0C\u7EE7\u7EED\u5F53\u524D\u6B65\u9AA4\u5373\u53EF\u3002",
|
|
752
|
+
...options.trackingUninitialized === true ? [
|
|
753
|
+
"\u672C\u4E66\u8FD8\u6CA1\u6709 \u8FFD\u8E2A/_tracking-state.json\u3002\u65B0\u4E66\u5199\u7B2C\u4E00\u7AE0\u65F6\uFF0Cdraft \u4E4B\u524D\u5148\u6309 story-long-write workflow-chapter \u5F00\u5934\u7684\u521D\u59CB\u5316\u6B65\u9AA4\u5B8C\u6574\u8BFB\u53D6 references/tracking-initialization.md\uFF0C\u6784\u9020 last_chapter=0 \u7684\u521D\u59CB\u5316\u4E8B\u52A1\u5B58\u4E66\u76EE\u5F55 .story/work/init.json\uFF0C\u8FD0\u884C scripts/tracking_commit.py init\uFF0C\u518D\u8FD0\u884C tracking_commit.py check\uFF0C\u901A\u8FC7\u540E\u5220\u6389 init.json\uFF1B",
|
|
754
|
+
"\u4E66\u91CC\u5728\u672C\u7AE0\u4E4B\u524D\u5DF2\u6709\u6B63\u6587\u65F6\u4E0D\u8981\u521D\u59CB\u5316\uFF0C\u505C\u4E0B\u6765\u6539\u8D70 story-import \u7684\u300C\u65E7\u8FFD\u8E2A\u9879\u76EE\u8FC1\u79FB\u300D\u3002"
|
|
755
|
+
] : [],
|
|
756
|
+
"\u7B49\u672C\u7AE0\u5199\u5B8C\u6536\u5C3E\u65F6\u518D\u63D0\u4EA4\u8FFD\u8E2A\uFF1A\u65B0\u7AE0\u5148\u7528 story-long-write \u7684 scripts/tracking_commit.py draft \u751F\u6210\u672C\u7AE0\u8349\u7A3F\uFF0C\u586B\u597D\u540E\u6267\u884C scripts/storyctl.py chapter commit\uFF08\u4F5C\u8005\u63A5\u53D7\u5F53\u524D\u957F\u5EA6\u65F6\u7528 chapter accept-current-length\uFF09\uFF1B",
|
|
757
|
+
"\u4FEE\u6539\u5DF2\u63D0\u4EA4\u7684\u7AE0\u8282\u6309 workflow-revision \u63D0\u4EA4\u4E00\u6B21 mode=revision \u4E8B\u52A1\uFF1B\u5BFC\u5165\u65E2\u6709\u6B63\u6587\u65F6\u7531 story-import \u5728\u8FC1\u79FB\u540E\u7528 tracking_commit.py init \u7EDF\u4E00\u521D\u59CB\u5316\u3002",
|
|
758
|
+
"\u8FFD\u8E2A/_tracking-state.json \u4EE5\u53CA \u4E0A\u4E0B\u6587.md\u3001\u89D2\u8272\u72B6\u6001/\u3001\u4F0F\u7B14.md\u3001\u65F6\u95F4\u7EBF/\u3001\u9010\u7AE0\u8BB0\u5F55/ \u7B49\u6D3E\u751F Tracking \u89C6\u56FE\u53EA\u7531\u8FD9\u4E9B\u811A\u672C\u5199\u5165\uFF0C\u7EDD\u4E0D\u624B\u6539\u3002</oh-story-post-write>"
|
|
759
|
+
].join("");
|
|
760
|
+
}
|
|
503
761
|
function registerOhStoryHooks(context) {
|
|
762
|
+
context.on("session/event", (session, event) => {
|
|
763
|
+
observeOhStoryRoleDescriptor(session, event);
|
|
764
|
+
});
|
|
765
|
+
context.on("tools/pre-execute", decideChapterExtractorWrite);
|
|
504
766
|
context.on("tools/pre-execute", decideStoryMutation);
|
|
505
767
|
context.on("tools/post-execute", async (exec, result, next) => {
|
|
506
768
|
const downstream = await next();
|
|
507
769
|
if (result.isError || downstream.kind !== "accept") return downstream;
|
|
770
|
+
if (ohStoryRoleOfSession(exec.agent?.session) !== void 0) return downstream;
|
|
508
771
|
const fs = exec.agent?.ctx.get("fs");
|
|
509
772
|
const mutation = fs === void 0 ? void 0 : await storyMutation(exec, fs);
|
|
510
|
-
|
|
773
|
+
const location = mutation === void 0 ? void 0 : proseLocation(mutation.path);
|
|
774
|
+
if (fs === void 0 || mutation === void 0 || location === void 0) return downstream;
|
|
775
|
+
const { root } = mutation;
|
|
776
|
+
const { book } = location;
|
|
777
|
+
if (!await isLongFormBook(fs, root, book, exec.signal)) return downstream;
|
|
778
|
+
const trackingUninitialized = !await hasTrackingState(fs, root, book, exec.signal) && !await hasImportSignal(fs, root, book, exec.signal);
|
|
511
779
|
const reminder = createUserMessage({
|
|
512
|
-
source: { kind: "
|
|
513
|
-
content: [{
|
|
514
|
-
type: "text",
|
|
515
|
-
text: `<oh-story-post-write>\u6B63\u6587 ${mutation.path} \u5DF2\u53D8\u66F4\u3002\u7EE7\u7EED\u5F53\u524D\u6B65\u9AA4\u524D\u6838\u5BF9\u5E76\u66F4\u65B0 _tracking-state.json \u53CA\u5BF9\u5E94\u6D3E\u751F Tracking \u89C6\u56FE\uFF1B\u4E0D\u8981\u628A\u8FD9\u6761\u63D0\u9192\u5F53\u4F5C\u7528\u6237\u7684\u65B0\u5199\u4F5C\u8981\u6C42\u3002</oh-story-post-write>`
|
|
516
|
-
}]
|
|
780
|
+
source: { kind: "oh-story-post-write", form: "notice", summary: boundContextSummary(`\u6B63\u6587 ${mutation.path} \u5DF2\u53D8\u66F4`) },
|
|
781
|
+
content: [{ type: "text", text: postWriteReminderText(mutation.path, { trackingUninitialized }) }]
|
|
517
782
|
});
|
|
518
783
|
return {
|
|
519
784
|
...downstream,
|
|
@@ -526,22 +791,22 @@ function registerOhStoryHooks(context) {
|
|
|
526
791
|
import { defineTool as defineTool2 } from "@deepseek-ai/dsh-tools";
|
|
527
792
|
|
|
528
793
|
// src/reference-tool.ts
|
|
529
|
-
import { readdir as readdir2, readFile as
|
|
530
|
-
import { isAbsolute as isAbsolute2, join as
|
|
794
|
+
import { readdir as readdir2, readFile as readFile3, realpath } from "node:fs/promises";
|
|
795
|
+
import { isAbsolute as isAbsolute2, join as join4, relative as relative2, resolve as resolve4 } from "node:path";
|
|
531
796
|
import { defineTool } from "@deepseek-ai/dsh-tools";
|
|
532
797
|
var OH_STORY_REFERENCE_TOOL_NAME = "oh_story_bundled_reference";
|
|
533
798
|
async function collectMarkdown(root, directory = root) {
|
|
534
799
|
const entries = await readdir2(directory, { withFileTypes: true });
|
|
535
800
|
const nested = await Promise.all(entries.map(async (entry) => {
|
|
536
|
-
const path =
|
|
801
|
+
const path = join4(directory, entry.name);
|
|
537
802
|
if (entry.isDirectory()) return collectMarkdown(root, path);
|
|
538
803
|
return entry.isFile() && entry.name.endsWith(".md") ? [path] : [];
|
|
539
804
|
}));
|
|
540
805
|
return nested.flat();
|
|
541
806
|
}
|
|
542
807
|
async function bundledReferences(storySetupRoot) {
|
|
543
|
-
const root = await realpath(
|
|
544
|
-
const referenceRoot = await realpath(
|
|
808
|
+
const root = await realpath(resolve4(storySetupRoot));
|
|
809
|
+
const referenceRoot = await realpath(join4(root, "references", "agent-references"));
|
|
545
810
|
const referenceDirectory = relative2(root, referenceRoot);
|
|
546
811
|
if (referenceDirectory === "" || referenceDirectory.startsWith("..") || isAbsolute2(referenceDirectory)) {
|
|
547
812
|
throw new Error("Bundled Oh Story reference directory escaped its package root.");
|
|
@@ -559,7 +824,7 @@ async function bundledReferences(storySetupRoot) {
|
|
|
559
824
|
}));
|
|
560
825
|
return values.sort((left, right) => left.name.localeCompare(right.name));
|
|
561
826
|
}
|
|
562
|
-
async function createOhStoryReferenceTool(storySetupRoot =
|
|
827
|
+
async function createOhStoryReferenceTool(storySetupRoot = join4(defaultBundledSkillRoot(), "story-setup")) {
|
|
563
828
|
const references = await bundledReferences(storySetupRoot);
|
|
564
829
|
if (references.length === 0) throw new Error("No bundled Oh Story references were found.");
|
|
565
830
|
const paths = references.map((reference) => reference.name);
|
|
@@ -595,7 +860,7 @@ ${value.content}`
|
|
|
595
860
|
async execute(args) {
|
|
596
861
|
const path = byName.get(args.reference);
|
|
597
862
|
if (path === void 0) throw new Error(`Oh Story reference is not bundled: ${args.reference}`);
|
|
598
|
-
return { reference: args.reference, content: await
|
|
863
|
+
return { reference: args.reference, content: await readFile3(path, "utf8") };
|
|
599
864
|
}
|
|
600
865
|
});
|
|
601
866
|
}
|
|
@@ -603,58 +868,18 @@ function bundledReferenceGuard(definition, tools) {
|
|
|
603
868
|
return (execution) => execution.name === OH_STORY_REFERENCE_TOOL_NAME && tools.get(OH_STORY_REFERENCE_TOOL_NAME, execution.agent) !== definition ? "The pinned Oh Story reference tool was shadowed in this Agent scope." : void 0;
|
|
604
869
|
}
|
|
605
870
|
|
|
606
|
-
// src/role-provider.ts
|
|
607
|
-
import { readFile as readFile3 } from "node:fs/promises";
|
|
608
|
-
import { basename as basename2, dirname as dirname3, join as join4, resolve as resolve4 } from "node:path";
|
|
609
|
-
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
610
|
-
var OH_STORY_ROLE_NAMES = [
|
|
611
|
-
"chapter-extractor",
|
|
612
|
-
"character-designer",
|
|
613
|
-
"consistency-checker",
|
|
614
|
-
"narrative-writer",
|
|
615
|
-
"story-architect",
|
|
616
|
-
"story-explorer",
|
|
617
|
-
"story-researcher"
|
|
618
|
-
];
|
|
619
|
-
function roleBody(source) {
|
|
620
|
-
const frontmatter = /^---\r?\n[\s\S]*?\r?\n---\r?\n?/u.exec(source);
|
|
621
|
-
return source.slice(frontmatter?.[0].length ?? 0).trim();
|
|
622
|
-
}
|
|
623
|
-
function defaultBundledRoleRoot() {
|
|
624
|
-
const current = dirname3(fileURLToPath2(import.meta.url));
|
|
625
|
-
return basename2(current) === "src" ? resolve4(current, "../../knowledge/oh-story/roles") : resolve4(current, "oh-story/roles");
|
|
626
|
-
}
|
|
627
|
-
async function loadBundledRole(name2, roleRoot = defaultBundledRoleRoot(), execution = "tool-free") {
|
|
628
|
-
const body = roleBody(await readFile3(join4(resolve4(roleRoot), `${name2}.md`), "utf8"));
|
|
629
|
-
if (body.length === 0) throw new Error(`Bundled role "${name2}" is empty.`);
|
|
630
|
-
const integration = execution === "tool-free" ? [
|
|
631
|
-
"You are running inside an Oh Story review-required DSH collaboration. The caller supplies every permitted input in the prompt.",
|
|
632
|
-
"Do not read or write project files, do not call tools, and do not follow legacy .claude/.codex path or deployment instructions in the upstream role text.",
|
|
633
|
-
"Return only the output contract requested by the caller; never claim to have changed the project."
|
|
634
|
-
] : [
|
|
635
|
-
"You are running as a native oh-story-dsh specialist. The current DSH workspace and visible tool set are your complete authority boundary.",
|
|
636
|
-
"Never inspect or require legacy .claude/.opencode/.codex agent deployment files; this exact pinned Role is already active.",
|
|
637
|
-
"Bundled story-setup references are pinned plugin resources, not project files or project Skills. When the upstream Role marks one mandatory, call oh_story_bundled_reference with the exact story-setup/references/agent-references path, then use only the returned content.",
|
|
638
|
-
"If oh_story_bundled_reference or a required bundled reference is unavailable, report the missing reference to the caller. Never call the generic skill tool, fall back to a legacy platform path, or claim that an unread reference was used.",
|
|
639
|
-
"Use only the tools actually visible to you. Mutate files only when the caller explicitly requests it and your visible DSH tools permit it; otherwise return findings to the caller."
|
|
640
|
-
];
|
|
641
|
-
return [
|
|
642
|
-
`OH_STORY_DSH_ROLE:${name2}`,
|
|
643
|
-
...integration,
|
|
644
|
-
"",
|
|
645
|
-
body
|
|
646
|
-
].join("\n");
|
|
647
|
-
}
|
|
648
|
-
|
|
649
871
|
// src/role-tool.ts
|
|
650
872
|
var OH_STORY_ROLE_TOOL_NAME = "oh_story_role";
|
|
651
873
|
var roleTools = {
|
|
652
|
-
|
|
874
|
+
// Oh Story 0.8.0 lets the extractor write its own batch input file (never
|
|
875
|
+
// bash). native-hooks fences write/edit to {拆文目录}/_analysis_cache/输入-*.md.
|
|
876
|
+
"chapter-extractor": ["read", "glob", "grep", "write", "edit"],
|
|
653
877
|
"character-designer": [OH_STORY_REFERENCE_TOOL_NAME, "read", "glob", "grep", "write", "edit"],
|
|
654
878
|
"consistency-checker": [OH_STORY_REFERENCE_TOOL_NAME, "read", "glob", "grep"],
|
|
655
879
|
"narrative-writer": [OH_STORY_REFERENCE_TOOL_NAME, "read", "glob", "grep", "write", "edit", "bash"],
|
|
656
880
|
"story-architect": [OH_STORY_REFERENCE_TOOL_NAME, "read", "glob", "grep", "write", "edit"],
|
|
657
|
-
|
|
881
|
+
// Oh Story 0.8.2 moved benchmark_style_load's procedure into agent-references/benchmark-style-load.md.
|
|
882
|
+
"story-explorer": [OH_STORY_REFERENCE_TOOL_NAME, "read", "glob", "grep"],
|
|
658
883
|
"story-researcher": ["read", "glob", "grep", "bash", "write", "web_search", "web_fetch"]
|
|
659
884
|
};
|
|
660
885
|
function roleToolFilter(role) {
|
|
@@ -705,7 +930,9 @@ async function createOhStoryRoleTool(subagents) {
|
|
|
705
930
|
const runtime = subagents ?? exec.agent.ctx.get("subagents");
|
|
706
931
|
if (runtime === void 0) throw new Error("oh_story_role requires the DSH subagent runtime.");
|
|
707
932
|
const run = await runtime.start("spawn", {
|
|
708
|
-
label
|
|
933
|
+
// DSH persists this label in the child's subagent/descriptor; the
|
|
934
|
+
// native hooks read the Role back from it before the child's first tool call.
|
|
935
|
+
label: ohStoryRoleLabel(args.role),
|
|
709
936
|
prompt: [{ type: "text", text: args.prompt }],
|
|
710
937
|
parent: exec.agent,
|
|
711
938
|
persona,
|
|
@@ -713,6 +940,7 @@ async function createOhStoryRoleTool(subagents) {
|
|
|
713
940
|
maxDepth: 1,
|
|
714
941
|
signal: exec.signal
|
|
715
942
|
});
|
|
943
|
+
if (run.localAgent !== void 0) markOhStoryRoleSession(run.localAgent.session, args.role);
|
|
716
944
|
try {
|
|
717
945
|
const result = await run.result;
|
|
718
946
|
if (result.stopReason !== "completed") {
|
|
@@ -910,6 +1138,9 @@ var VISIBLE_TEXT_FILES = /* @__PURE__ */ new Set([
|
|
|
910
1138
|
"final_qc.json",
|
|
911
1139
|
"final_qc.md",
|
|
912
1140
|
"delivery_qc.json",
|
|
1141
|
+
"cut_delivery_qc.json",
|
|
1142
|
+
"recap_project.json",
|
|
1143
|
+
"resource_lock.json",
|
|
913
1144
|
"subtitles.srt",
|
|
914
1145
|
"subtitles.ass"
|
|
915
1146
|
]);
|
|
@@ -929,6 +1160,9 @@ var ARTIFACT_META = {
|
|
|
929
1160
|
"final_qc.json": { label: "\u6700\u7EC8\u8D28\u68C0", kind: "quality" },
|
|
930
1161
|
"final_qc.md": { label: "\u6700\u7EC8\u8D28\u68C0\u62A5\u544A", kind: "quality" },
|
|
931
1162
|
"delivery_qc.json": { label: "\u4EA4\u4ED8\u8D28\u68C0", kind: "quality" },
|
|
1163
|
+
"cut_delivery_qc.json": { label: "\u526A\u540E\u7247\u8D28\u68C0", kind: "quality" },
|
|
1164
|
+
"recap_project.json": { label: "\u9879\u76EE\u7ED1\u5B9A", kind: "manifest" },
|
|
1165
|
+
"resource_lock.json": { label: "\u8D44\u6E90\u9501\u5B9A", kind: "manifest" },
|
|
932
1166
|
"subtitles.srt": { label: "SRT \u5B57\u5E55", kind: "subtitle" },
|
|
933
1167
|
"subtitles.ass": { label: "ASS \u5B57\u5E55", kind: "subtitle" }
|
|
934
1168
|
};
|
|
@@ -986,6 +1220,7 @@ function summarizeVideoProject(root, files, metadata2 = {}) {
|
|
|
986
1220
|
].filter((value) => value !== void 0);
|
|
987
1221
|
const names = new Set(projectFiles.map((file) => file.path.split("/").at(-1)));
|
|
988
1222
|
const cutMode = settings?.edit_mode === "cut" || names.has("clip_plan.json") || edited !== void 0;
|
|
1223
|
+
const narrated = (text(record(manifest?.audio)?.mode) ?? "narration") === "narration";
|
|
989
1224
|
let state = "not-started";
|
|
990
1225
|
let stage = "source";
|
|
991
1226
|
let stageLabel = source === void 0 ? "\u7B49\u5F85\u5BFC\u5165\u89C6\u9891" : "\u53EF\u4EE5\u5F00\u59CB";
|
|
@@ -1003,14 +1238,24 @@ function summarizeVideoProject(root, files, metadata2 = {}) {
|
|
|
1003
1238
|
stage = "voiceover";
|
|
1004
1239
|
stageLabel = "\u914D\u97F3\u4E0E\u5408\u6210";
|
|
1005
1240
|
} else if (cutMode && edited !== void 0) {
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1241
|
+
if (narrated) {
|
|
1242
|
+
state = "waiting";
|
|
1243
|
+
stage = "narration";
|
|
1244
|
+
stageLabel = "\u7B49\u5F85\u89E3\u8BF4\u8BCD";
|
|
1245
|
+
nextArtifact = "narration.json";
|
|
1246
|
+
} else {
|
|
1247
|
+
state = "working";
|
|
1248
|
+
stage = "assemble";
|
|
1249
|
+
stageLabel = "\u6B63\u5728\u5408\u6210";
|
|
1250
|
+
}
|
|
1010
1251
|
} else if (cutMode && names.has("clip_plan.json")) {
|
|
1011
1252
|
state = "working";
|
|
1012
1253
|
stage = "cut";
|
|
1013
1254
|
stageLabel = "\u6B63\u5728\u526A\u8F91";
|
|
1255
|
+
} else if (manifest !== void 0 && !cutMode && !narrated) {
|
|
1256
|
+
state = "working";
|
|
1257
|
+
stage = "assemble";
|
|
1258
|
+
stageLabel = "\u6B63\u5728\u5408\u6210";
|
|
1014
1259
|
} else if (manifest !== void 0) {
|
|
1015
1260
|
state = "waiting";
|
|
1016
1261
|
stage = cutMode ? "clip-plan" : "narration";
|
|
@@ -1165,7 +1410,10 @@ async function videoPreflight() {
|
|
|
1165
1410
|
// Upstream falls back to the shared MIMO_API_KEY only when a per-service key is unset.
|
|
1166
1411
|
mimo: configured("MIMO_API_KEY", "MIMO_VIDEO_API_KEY", "MIMO_TTS_API_KEY", "MIMO_ASR_API_KEY"),
|
|
1167
1412
|
fish: configured("FISH_API_KEY"),
|
|
1168
|
-
|
|
1413
|
+
// index-tts fails before any request unless both are set (video-voiceover/references/index-tts.md).
|
|
1414
|
+
indexTts: configured("INDEX_TTS_ENDPOINT") && configured("INDEX_TTS_VOICE"),
|
|
1415
|
+
// Upstream accepts auto | mimo-tts | fish-audio | index-tts and defaults to auto (voiceover.py).
|
|
1416
|
+
ttsProvider: (process.env.TTS_PROVIDER ?? "").trim().toLowerCase() || "auto"
|
|
1169
1417
|
}
|
|
1170
1418
|
};
|
|
1171
1419
|
videoPreflightCache = { expires: Date.now() + 3e4, value };
|