@lemoncat7/dsh-partner 2.5.0 → 2.7.0
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 +4 -0
- package/docs/THIRD_PARTY_LICENSES.md +13 -0
- package/docs/attachment-storage.md +18 -0
- package/docs/director-skills.md +24 -0
- package/docs/long-task-continuation.md +1 -1
- package/docs/releases/2.6.0.md +11 -0
- package/docs/releases/2.7.0.md +21 -0
- package/lib/agent-runtime.d.ts +3 -1
- package/lib/agent-runtime.d.ts.map +1 -1
- package/lib/agent-runtime.js +35 -11
- package/lib/agent-runtime.js.map +1 -1
- package/lib/api/features/attachments-api.d.ts.map +1 -1
- package/lib/api/features/attachments-api.js +31 -1
- package/lib/api/features/attachments-api.js.map +1 -1
- package/lib/api.d.ts +1 -1
- package/lib/api.d.ts.map +1 -1
- package/lib/api.js +1 -1
- package/lib/api.js.map +1 -1
- package/lib/attachments/grouped-storage.d.ts +5 -0
- package/lib/attachments/grouped-storage.d.ts.map +1 -0
- package/lib/attachments/grouped-storage.js +47 -0
- package/lib/attachments/grouped-storage.js.map +1 -0
- package/lib/attachments/service.d.ts +17 -0
- package/lib/attachments/service.d.ts.map +1 -1
- package/lib/attachments/service.js +100 -8
- package/lib/attachments/service.js.map +1 -1
- package/lib/attachments/shared-storage.d.ts +7 -0
- package/lib/attachments/shared-storage.d.ts.map +1 -0
- package/lib/attachments/shared-storage.js +44 -0
- package/lib/attachments/shared-storage.js.map +1 -0
- package/lib/attachments/storage-admin.d.ts +6 -0
- package/lib/attachments/storage-admin.d.ts.map +1 -0
- package/lib/attachments/storage-admin.js +43 -0
- package/lib/attachments/storage-admin.js.map +1 -0
- package/lib/attachments/storage-types.d.ts +33 -0
- package/lib/attachments/storage-types.d.ts.map +1 -0
- package/lib/attachments/storage-types.js +2 -0
- package/lib/attachments/storage-types.js.map +1 -0
- package/lib/attachments/tool.d.ts.map +1 -1
- package/lib/attachments/tool.js +16 -5
- package/lib/attachments/tool.js.map +1 -1
- package/lib/channels/delivery-policy.d.ts.map +1 -1
- package/lib/channels/delivery-policy.js +6 -4
- package/lib/channels/delivery-policy.js.map +1 -1
- package/lib/channels/direct/message-format.js +418 -281
- package/lib/channels/direct/message-format.js.map +4 -4
- package/lib/channels/manager.d.ts +6 -3
- package/lib/channels/manager.d.ts.map +1 -1
- package/lib/channels/manager.js +64 -44
- package/lib/channels/manager.js.map +1 -1
- package/lib/channels/weixin/api.d.ts.map +1 -1
- package/lib/channels/weixin/api.js +7 -2
- package/lib/channels/weixin/api.js.map +1 -1
- package/lib/channels/weixin/errors.d.ts +14 -0
- package/lib/channels/weixin/errors.d.ts.map +1 -0
- package/lib/channels/weixin/errors.js +29 -0
- package/lib/channels/weixin/errors.js.map +1 -0
- package/lib/channels/weixin/poll.d.ts +14 -0
- package/lib/channels/weixin/poll.d.ts.map +1 -0
- package/lib/channels/weixin/poll.js +50 -0
- package/lib/channels/weixin/poll.js.map +1 -0
- package/lib/client-controller.d.ts.map +1 -1
- package/lib/client-controller.js +3 -3
- package/lib/client-controller.js.map +1 -1
- package/lib/client.d.ts.map +1 -1
- package/lib/client.js +996 -645
- package/lib/client.js.map +4 -4
- package/lib/collaboration/composition.d.ts.map +1 -1
- package/lib/collaboration/composition.js +16 -6
- package/lib/collaboration/composition.js.map +1 -1
- package/lib/collaboration/domain.d.ts +6 -0
- package/lib/collaboration/domain.d.ts.map +1 -1
- package/lib/collaboration/domain.js.map +1 -1
- package/lib/collaboration/service.d.ts.map +1 -1
- package/lib/collaboration/service.js +33 -3
- package/lib/collaboration/service.js.map +1 -1
- package/lib/concern-notification.d.ts.map +1 -1
- package/lib/concern-notification.js +2 -1
- package/lib/concern-notification.js.map +1 -1
- package/lib/concern-tool.js +1 -1
- package/lib/concern-tool.js.map +1 -1
- package/lib/execution/reply-progress.d.ts.map +1 -1
- package/lib/execution/reply-progress.js +4 -2
- package/lib/execution/reply-progress.js.map +1 -1
- package/lib/execution/service.d.ts +1 -1
- package/lib/execution/service.d.ts.map +1 -1
- package/lib/execution/service.js +4 -7
- package/lib/execution/service.js.map +1 -1
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +3 -1
- package/lib/index.js.map +1 -1
- package/lib/memory-reflection.js +2 -2
- package/lib/memory-reflection.js.map +1 -1
- package/lib/message-source.d.ts +25 -0
- package/lib/message-source.d.ts.map +1 -0
- package/lib/message-source.js +8 -0
- package/lib/message-source.js.map +1 -0
- package/lib/observation-loop.js +4 -4
- package/lib/observation-loop.js.map +1 -1
- package/lib/pendant/reader.js +1 -1
- package/lib/pendant/reader.js.map +1 -1
- package/lib/pendant/settings-panel.js +1 -1
- package/lib/pendant/settings-panel.js.map +1 -1
- package/lib/persona/service.js +1 -1
- package/lib/persona/service.js.map +1 -1
- package/lib/requirements/attachments.d.ts +7 -0
- package/lib/requirements/attachments.d.ts.map +1 -0
- package/lib/requirements/attachments.js +26 -0
- package/lib/requirements/attachments.js.map +1 -0
- package/lib/requirements/domain.d.ts +1 -1
- package/lib/requirements/domain.d.ts.map +1 -1
- package/lib/requirements/service.d.ts.map +1 -1
- package/lib/requirements/service.js +4 -1
- package/lib/requirements/service.js.map +1 -1
- package/lib/scheduler/channel-origin.d.ts +7 -0
- package/lib/scheduler/channel-origin.d.ts.map +1 -0
- package/lib/scheduler/channel-origin.js +27 -0
- package/lib/scheduler/channel-origin.js.map +1 -0
- package/lib/scheduler/continuations.d.ts +2 -2
- package/lib/scheduler/continuations.d.ts.map +1 -1
- package/lib/scheduler/continuations.js +28 -8
- package/lib/scheduler/continuations.js.map +1 -1
- package/lib/scheduler/domain.d.ts +13 -0
- package/lib/scheduler/domain.d.ts.map +1 -1
- package/lib/scheduler/final-reply.d.ts +13 -0
- package/lib/scheduler/final-reply.d.ts.map +1 -0
- package/lib/scheduler/final-reply.js +21 -0
- package/lib/scheduler/final-reply.js.map +1 -0
- package/lib/skills/builtin-resources.d.ts +6 -0
- package/lib/skills/builtin-resources.d.ts.map +1 -0
- package/lib/skills/builtin-resources.js +47 -0
- package/lib/skills/builtin-resources.js.map +1 -0
- package/lib/skills/builtin.d.ts +2 -5
- package/lib/skills/builtin.d.ts.map +1 -1
- package/lib/skills/builtin.js +6 -0
- package/lib/skills/builtin.js.map +1 -1
- package/lib/skills/director-builtins.d.ts +8 -0
- package/lib/skills/director-builtins.d.ts.map +1 -0
- package/lib/skills/director-builtins.js +65 -0
- package/lib/skills/director-builtins.js.map +1 -0
- package/lib/skills/drama-builtin.d.ts +3 -0
- package/lib/skills/drama-builtin.d.ts.map +1 -0
- package/lib/skills/drama-builtin.js +49 -0
- package/lib/skills/drama-builtin.js.map +1 -0
- package/lib/skills/long-task-continuation.d.ts +2 -2
- package/lib/skills/long-task-continuation.d.ts.map +1 -1
- package/lib/skills/long-task-continuation.js +2 -2
- package/lib/skills/service.d.ts.map +1 -1
- package/lib/skills/service.js +8 -3
- package/lib/skills/service.js.map +1 -1
- package/lib/skills/viora-canvas-builtin.d.ts +3 -0
- package/lib/skills/viora-canvas-builtin.d.ts.map +1 -0
- package/lib/skills/viora-canvas-builtin.js +19 -0
- package/lib/skills/viora-canvas-builtin.js.map +1 -0
- package/lib/storage/migrate-layout.d.ts.map +1 -1
- package/lib/storage/migrate-layout.js +13 -4
- package/lib/storage/migrate-layout.js.map +1 -1
- package/lib/tasks/context.js +1 -0
- package/lib/tasks/context.js.map +1 -1
- package/lib/tasks/continuation.d.ts.map +1 -1
- package/lib/tasks/continuation.js +3 -0
- package/lib/tasks/continuation.js.map +1 -1
- package/lib/tasks/domain.d.ts +2 -0
- package/lib/tasks/domain.d.ts.map +1 -1
- package/lib/tasks/service.d.ts +2 -1
- package/lib/tasks/service.d.ts.map +1 -1
- package/lib/tasks/service.js +15 -1
- package/lib/tasks/service.js.map +1 -1
- package/lib/ui/attachment-storage.d.ts +2 -0
- package/lib/ui/attachment-storage.d.ts.map +1 -0
- package/lib/ui/attachment-storage.js +59 -0
- package/lib/ui/attachment-storage.js.map +1 -0
- package/lib/ui/capability-editor.js +1 -1
- package/lib/ui/capability-editor.js.map +1 -1
- package/lib/ui/companion-access-panel.js +1 -1
- package/lib/ui/companion-access-panel.js.map +1 -1
- package/lib/ui/companion-create.js +1 -1
- package/lib/ui/companion-create.js.map +1 -1
- package/lib/ui/companion-picker.js +1 -1
- package/lib/ui/companion-picker.js.map +1 -1
- package/lib/ui/identity-editor.js +1 -1
- package/lib/ui/identity-editor.js.map +1 -1
- package/lib/ui/mcp-capabilities.js +1 -1
- package/lib/ui/mcp-capabilities.js.map +1 -1
- package/lib/ui/mcp-panel.js +1 -1
- package/lib/ui/mcp-panel.js.map +1 -1
- package/lib/ui/memory/concern-board.js +2 -2
- package/lib/ui/memory/concern-board.js.map +1 -1
- package/lib/ui/memory/concern-deletion.d.ts +1 -1
- package/lib/ui/memory/concern-deletion.d.ts.map +1 -1
- package/lib/ui/memory/concern-deletion.js +9 -4
- package/lib/ui/memory/concern-deletion.js.map +1 -1
- package/lib/ui/memory/concern-panel.js +1 -1
- package/lib/ui/memory/concern-panel.js.map +1 -1
- package/lib/ui/memory/memory-library.js +1 -1
- package/lib/ui/memory/memory-library.js.map +1 -1
- package/lib/ui/memory/memory-panel.js +1 -1
- package/lib/ui/memory/memory-panel.js.map +1 -1
- package/lib/ui/partner-components.js +1 -1
- package/lib/ui/partner-components.js.map +1 -1
- package/lib/ui/requirement-board.js +1 -1
- package/lib/ui/requirement-board.js.map +1 -1
- package/lib/ui/requirement-dialog.js +1 -1
- package/lib/ui/requirement-dialog.js.map +1 -1
- package/lib/ui/requirement-tasks-panel.js +1 -1
- package/lib/ui/requirement-tasks-panel.js.map +1 -1
- package/lib/ui/schedule-panel.js +1 -1
- package/lib/ui/schedule-panel.js.map +1 -1
- package/lib/ui/skills-panel.js +1 -1
- package/lib/ui/skills-panel.js.map +1 -1
- package/lib/ui/storage-settings.d.ts.map +1 -1
- package/lib/ui/storage-settings.js +2 -1
- package/lib/ui/storage-settings.js.map +1 -1
- package/lib/ui/task-board-stage.js +1 -1
- package/lib/ui/task-board-stage.js.map +1 -1
- package/lib/ui/workspace-components.js +1 -1
- package/lib/ui/workspace-components.js.map +1 -1
- package/lib/ui/workspace-navigation.d.ts +16 -16
- package/lib/ui/workspace-navigation.js +1 -1
- package/lib/ui/workspace-navigation.js.map +1 -1
- package/package.json +53 -41
- package/resources/skills/cinematic-director/manifest.json +205 -0
- package/resources/skills/cinematic-director/upstream/CHANGELOG.md +213 -0
- package/resources/skills/cinematic-director/upstream/CONTRIBUTING.md +316 -0
- package/resources/skills/cinematic-director/upstream/LICENSE +21 -0
- package/resources/skills/cinematic-director/upstream/README.md +507 -0
- package/resources/skills/cinematic-director/upstream/SKILL.md +420 -0
- package/resources/skills/cinematic-director/upstream/assets/beat-sheet-template.md +97 -0
- package/resources/skills/cinematic-director/upstream/assets/director-book-template.md +254 -0
- package/resources/skills/cinematic-director/upstream/assets/edit-timeline-template.md +147 -0
- package/resources/skills/cinematic-director/upstream/assets/keyframe-prompt-template.md +334 -0
- package/resources/skills/cinematic-director/upstream/assets/qc-checklist.md +153 -0
- package/resources/skills/cinematic-director/upstream/assets/shot-plan-template.md +95 -0
- package/resources/skills/cinematic-director/upstream/assets/sound-plan-template.md +181 -0
- package/resources/skills/cinematic-director/upstream/assets/video-prompt-template.md +305 -0
- package/resources/skills/cinematic-director/upstream/evals/run.md +69 -0
- package/resources/skills/cinematic-director/upstream/references/ai-video-tool-adapters.md +527 -0
- package/resources/skills/cinematic-director/upstream/references/blocking-and-staging.md +424 -0
- package/resources/skills/cinematic-director/upstream/references/cinematic-language.md +595 -0
- package/resources/skills/cinematic-director/upstream/references/continuity-bible.md +410 -0
- package/resources/skills/cinematic-director/upstream/references/director_styles/01_spielberg.md +192 -0
- package/resources/skills/cinematic-director/upstream/references/director_styles/02_hitchcock.md +193 -0
- package/resources/skills/cinematic-director/upstream/references/director_styles/03_kubrick.md +196 -0
- package/resources/skills/cinematic-director/upstream/references/director_styles/04_kurosawa.md +196 -0
- package/resources/skills/cinematic-director/upstream/references/director_styles/05_scorsese.md +195 -0
- package/resources/skills/cinematic-director/upstream/references/director_styles/06_fellini.md +197 -0
- package/resources/skills/cinematic-director/upstream/references/director_styles/07_bergman.md +197 -0
- package/resources/skills/cinematic-director/upstream/references/director_styles/08_tarkovsky.md +184 -0
- package/resources/skills/cinematic-director/upstream/references/director_styles/09_wong_kar_wai.md +189 -0
- package/resources/skills/cinematic-director/upstream/references/director_styles/10_nolan.md +185 -0
- package/resources/skills/cinematic-director/upstream/references/director_styles/11_villeneuve.md +188 -0
- package/resources/skills/cinematic-director/upstream/references/director_styles/12_fincher.md +185 -0
- package/resources/skills/cinematic-director/upstream/references/director_styles/13_refn.md +186 -0
- package/resources/skills/cinematic-director/upstream/references/director_styles/14_bi_gan.md +188 -0
- package/resources/skills/cinematic-director/upstream/references/director_styles/15_zhang_yimou.md +192 -0
- package/resources/skills/cinematic-director/upstream/references/director_styles/16_hou_hsiao_hsien.md +192 -0
- package/resources/skills/cinematic-director/upstream/references/director_styles/17_park_chan_wook.md +192 -0
- package/resources/skills/cinematic-director/upstream/references/director_styles/18_malick.md +191 -0
- package/resources/skills/cinematic-director/upstream/references/director_styles/19_michael_mann.md +192 -0
- package/resources/skills/cinematic-director/upstream/references/director_styles/20_coen_brothers.md +194 -0
- package/resources/skills/cinematic-director/upstream/references/director_styles/README.md +89 -0
- package/resources/skills/cinematic-director/upstream/references/director_styles/example_comparisons.md +140 -0
- package/resources/skills/cinematic-director/upstream/references/editing-and-assembly.md +263 -0
- package/resources/skills/cinematic-director/upstream/references/failure-modes.md +594 -0
- package/resources/skills/cinematic-director/upstream/references/genre-playbooks.md +407 -0
- package/resources/skills/cinematic-director/upstream/references/image-model-adapters.md +290 -0
- package/resources/skills/cinematic-director/upstream/references/lighting-and-color.md +349 -0
- package/resources/skills/cinematic-director/upstream/references/product-and-macro.md +207 -0
- package/resources/skills/cinematic-director/upstream/references/production-workflow.md +238 -0
- package/resources/skills/cinematic-director/upstream/references/prompt-lexicon.md +602 -0
- package/resources/skills/cinematic-director/upstream/references/sound-and-dialogue.md +364 -0
- package/resources/skills/director-skills/manifest.json +541 -0
- package/resources/skills/director-skills/upstream/CHANGELOG.md +32 -0
- package/resources/skills/director-skills/upstream/LICENSE +21 -0
- package/resources/skills/director-skills/upstream/MANIFEST.md +366 -0
- package/resources/skills/director-skills/upstream/README.md +251 -0
- package/resources/skills/director-skills/upstream/RESEARCH_PROVENANCE.md +37 -0
- package/resources/skills/director-skills/upstream/SKILL.md +114 -0
- package/resources/skills/director-skills/upstream/skills/character-location-prop-bible/SKILL.md +81 -0
- package/resources/skills/director-skills/upstream/skills/character-location-prop-bible/checklists/continuity_checklist.md +8 -0
- package/resources/skills/director-skills/upstream/skills/character-location-prop-bible/examples/character_continuity_update.md +9 -0
- package/resources/skills/director-skills/upstream/skills/character-location-prop-bible/examples/location_continuity_update.md +9 -0
- package/resources/skills/director-skills/upstream/skills/character-location-prop-bible/references/continuity_system.md +21 -0
- package/resources/skills/director-skills/upstream/skills/character-location-prop-bible/references/golden_image_workflow.md +29 -0
- package/resources/skills/director-skills/upstream/skills/character-location-prop-bible/references/identity_anchors.md +14 -0
- package/resources/skills/director-skills/upstream/skills/character-location-prop-bible/references/visual_bible_system.md +15 -0
- package/resources/skills/director-skills/upstream/skills/character-location-prop-bible/templates/character_profile.md +15 -0
- package/resources/skills/director-skills/upstream/skills/character-location-prop-bible/templates/continuity_checklist.md +11 -0
- package/resources/skills/director-skills/upstream/skills/character-location-prop-bible/templates/costume_profile.md +12 -0
- package/resources/skills/director-skills/upstream/skills/character-location-prop-bible/templates/location_profile.md +14 -0
- package/resources/skills/director-skills/upstream/skills/character-location-prop-bible/templates/prop_profile.md +13 -0
- package/resources/skills/director-skills/upstream/skills/character-location-prop-bible/templates/visual_style_bible.md +15 -0
- package/resources/skills/director-skills/upstream/skills/character-location-prop-bible/tests/continuity_tests.md +6 -0
- package/resources/skills/director-skills/upstream/skills/cinematic-image-prompting/SKILL.md +80 -0
- package/resources/skills/director-skills/upstream/skills/cinematic-image-prompting/checklists/image_prompt_quality_checklist.md +10 -0
- package/resources/skills/director-skills/upstream/skills/cinematic-image-prompting/examples/shot_list_to_image_prompts.md +4 -0
- package/resources/skills/director-skills/upstream/skills/cinematic-image-prompting/references/image_prompt_components.md +22 -0
- package/resources/skills/director-skills/upstream/skills/cinematic-image-prompting/references/lighting_and_photorealism.md +19 -0
- package/resources/skills/director-skills/upstream/skills/cinematic-image-prompting/references/negative_prompt_patterns.md +18 -0
- package/resources/skills/director-skills/upstream/skills/cinematic-image-prompting/references/prompt_anatomy.md +18 -0
- package/resources/skills/director-skills/upstream/skills/cinematic-image-prompting/templates/character_reference_sheet_prompt.md +5 -0
- package/resources/skills/director-skills/upstream/skills/cinematic-image-prompting/templates/cinematic_still_prompt.md +3 -0
- package/resources/skills/director-skills/upstream/skills/cinematic-image-prompting/templates/keyframe_prompt.md +6 -0
- package/resources/skills/director-skills/upstream/skills/cinematic-image-prompting/templates/location_reference_prompt.md +3 -0
- package/resources/skills/director-skills/upstream/skills/cinematic-image-prompting/templates/prop_prompt.md +3 -0
- package/resources/skills/director-skills/upstream/skills/cinematic-image-prompting/tests/image_prompt_completeness_tests.md +5 -0
- package/resources/skills/director-skills/upstream/skills/cinematic-video-prompting/SKILL.md +84 -0
- package/resources/skills/director-skills/upstream/skills/cinematic-video-prompting/checklists/video_prompt_quality_checklist.md +9 -0
- package/resources/skills/director-skills/upstream/skills/cinematic-video-prompting/examples/image_prompt_to_video_prompt.md +3 -0
- package/resources/skills/director-skills/upstream/skills/cinematic-video-prompting/references/ai_film_production_pipeline.md +21 -0
- package/resources/skills/director-skills/upstream/skills/cinematic-video-prompting/references/audio_motion_timing.md +16 -0
- package/resources/skills/director-skills/upstream/skills/cinematic-video-prompting/references/camera_lens_movement.md +26 -0
- package/resources/skills/director-skills/upstream/skills/cinematic-video-prompting/references/negative_prompt_patterns.md +18 -0
- package/resources/skills/director-skills/upstream/skills/cinematic-video-prompting/references/prompt_anatomy.md +18 -0
- package/resources/skills/director-skills/upstream/skills/cinematic-video-prompting/references/video_prompt_components.md +25 -0
- package/resources/skills/director-skills/upstream/skills/cinematic-video-prompting/templates/image_to_video_prompt.md +5 -0
- package/resources/skills/director-skills/upstream/skills/cinematic-video-prompting/templates/text_to_video_prompt.md +5 -0
- package/resources/skills/director-skills/upstream/skills/cinematic-video-prompting/templates/video_beat_prompt.md +9 -0
- package/resources/skills/director-skills/upstream/skills/cinematic-video-prompting/tests/video_prompt_completeness_tests.md +5 -0
- package/resources/skills/director-skills/upstream/skills/model-adaptation/SKILL.md +82 -0
- package/resources/skills/director-skills/upstream/skills/model-adaptation/checklists/model_export_checklist.md +9 -0
- package/resources/skills/director-skills/upstream/skills/model-adaptation/examples/failed_model_transfer_diagnosis.md +5 -0
- package/resources/skills/director-skills/upstream/skills/model-adaptation/examples/image_prompt_translation.md +10 -0
- package/resources/skills/director-skills/upstream/skills/model-adaptation/examples/same_scene_across_models.md +9 -0
- package/resources/skills/director-skills/upstream/skills/model-adaptation/examples/universal_prompt_to_model_specific_exports.md +14 -0
- package/resources/skills/director-skills/upstream/skills/model-adaptation/examples/video_prompt_translation.md +9 -0
- package/resources/skills/director-skills/upstream/skills/model-adaptation/references/failure_modes_by_model.md +13 -0
- package/resources/skills/director-skills/upstream/skills/model-adaptation/references/image_model_profiles.md +226 -0
- package/resources/skills/director-skills/upstream/skills/model-adaptation/references/model_capability_matrix.md +24 -0
- package/resources/skills/director-skills/upstream/skills/model-adaptation/references/model_update_protocol.md +10 -0
- package/resources/skills/director-skills/upstream/skills/model-adaptation/references/parameter_compatibility.md +20 -0
- package/resources/skills/director-skills/upstream/skills/model-adaptation/references/prompt_translation_rules.md +18 -0
- package/resources/skills/director-skills/upstream/skills/model-adaptation/references/video_model_profiles.md +251 -0
- package/resources/skills/director-skills/upstream/skills/model-adaptation/templates/model_comparison_table.md +4 -0
- package/resources/skills/director-skills/upstream/skills/model-adaptation/templates/model_specific_prompt_export.md +21 -0
- package/resources/skills/director-skills/upstream/skills/model-adaptation/templates/multi_model_export_package.md +18 -0
- package/resources/skills/director-skills/upstream/skills/model-adaptation/templates/prompt_translation_report.md +13 -0
- package/resources/skills/director-skills/upstream/skills/model-adaptation/templates/universal_prompt_brief.md +25 -0
- package/resources/skills/director-skills/upstream/skills/model-adaptation/tests/model_routing_tests.md +8 -0
- package/resources/skills/director-skills/upstream/skills/model-adaptation/tests/prompt_translation_tests.md +7 -0
- package/resources/skills/director-skills/upstream/skills/model-adaptation/tests/research_provenance_tests.md +6 -0
- package/resources/skills/director-skills/upstream/skills/model-adaptation/tests/unknown_capability_tests.md +7 -0
- package/resources/skills/director-skills/upstream/skills/prompt-iteration-and-diagnostics/SKILL.md +82 -0
- package/resources/skills/director-skills/upstream/skills/prompt-iteration-and-diagnostics/checklists/diagnostic_checklist.md +8 -0
- package/resources/skills/director-skills/upstream/skills/prompt-iteration-and-diagnostics/checklists/release_quality_checklist.md +9 -0
- package/resources/skills/director-skills/upstream/skills/prompt-iteration-and-diagnostics/examples/failed_output_to_revised_prompt.md +10 -0
- package/resources/skills/director-skills/upstream/skills/prompt-iteration-and-diagnostics/examples/final_prompt_package_export.md +10 -0
- package/resources/skills/director-skills/upstream/skills/prompt-iteration-and-diagnostics/references/failure_modes.md +13 -0
- package/resources/skills/director-skills/upstream/skills/prompt-iteration-and-diagnostics/references/iteration_diagnostics.md +17 -0
- package/resources/skills/director-skills/upstream/skills/prompt-iteration-and-diagnostics/references/revision_loops.md +17 -0
- package/resources/skills/director-skills/upstream/skills/prompt-iteration-and-diagnostics/references/story_voice_release_qc.md +30 -0
- package/resources/skills/director-skills/upstream/skills/prompt-iteration-and-diagnostics/templates/failed_output_intake.md +13 -0
- package/resources/skills/director-skills/upstream/skills/prompt-iteration-and-diagnostics/templates/final_production_package.md +11 -0
- package/resources/skills/director-skills/upstream/skills/prompt-iteration-and-diagnostics/templates/prompt_revision_report.md +17 -0
- package/resources/skills/director-skills/upstream/skills/prompt-iteration-and-diagnostics/tests/prompt_quality_checklist_tests.md +6 -0
- package/resources/skills/director-skills/upstream/skills/screenplay-and-scene-writing/SKILL.md +81 -0
- package/resources/skills/director-skills/upstream/skills/screenplay-and-scene-writing/checklists/scene_quality_checklist.md +8 -0
- package/resources/skills/director-skills/upstream/skills/screenplay-and-scene-writing/examples/scene_to_screenplay_excerpt.md +18 -0
- package/resources/skills/director-skills/upstream/skills/screenplay-and-scene-writing/references/dialogue_and_subtext.md +15 -0
- package/resources/skills/director-skills/upstream/skills/screenplay-and-scene-writing/references/fountain_workflow.md +29 -0
- package/resources/skills/director-skills/upstream/skills/screenplay-and-scene-writing/references/scene_construction.md +20 -0
- package/resources/skills/director-skills/upstream/skills/screenplay-and-scene-writing/references/screenplay_format.md +18 -0
- package/resources/skills/director-skills/upstream/skills/screenplay-and-scene-writing/templates/beat_sheet.md +6 -0
- package/resources/skills/director-skills/upstream/skills/screenplay-and-scene-writing/templates/dialogue_pass.md +9 -0
- package/resources/skills/director-skills/upstream/skills/screenplay-and-scene-writing/templates/fountain_scene.md +25 -0
- package/resources/skills/director-skills/upstream/skills/screenplay-and-scene-writing/templates/screenplay_scene.md +19 -0
- package/resources/skills/director-skills/upstream/skills/screenplay-and-scene-writing/tests/screenplay_scene_tests.md +6 -0
- package/resources/skills/director-skills/upstream/skills/short-film-development/SKILL.md +83 -0
- package/resources/skills/director-skills/upstream/skills/short-film-development/checklists/concept_quality_checklist.md +8 -0
- package/resources/skills/director-skills/upstream/skills/short-film-development/examples/idea_to_logline.md +13 -0
- package/resources/skills/director-skills/upstream/skills/short-film-development/examples/logline_to_outline.md +10 -0
- package/resources/skills/director-skills/upstream/skills/short-film-development/references/ai_storytelling_workflow.md +46 -0
- package/resources/skills/director-skills/upstream/skills/short-film-development/references/continuity_handoff.md +8 -0
- package/resources/skills/director-skills/upstream/skills/short-film-development/references/screenplay_structure.md +19 -0
- package/resources/skills/director-skills/upstream/skills/short-film-development/references/story_development_workflow.md +23 -0
- package/resources/skills/director-skills/upstream/skills/short-film-development/templates/beat_sheet.md +7 -0
- package/resources/skills/director-skills/upstream/skills/short-film-development/templates/idea_intake.md +16 -0
- package/resources/skills/director-skills/upstream/skills/short-film-development/templates/logline.md +10 -0
- package/resources/skills/director-skills/upstream/skills/short-film-development/templates/short_film_treatment.md +23 -0
- package/resources/skills/director-skills/upstream/skills/short-film-development/templates/short_story_plan.md +22 -0
- package/resources/skills/director-skills/upstream/skills/short-film-development/templates/story_premise.md +19 -0
- package/resources/skills/director-skills/upstream/skills/short-film-development/templates/story_revision_audit.md +22 -0
- package/resources/skills/director-skills/upstream/skills/short-film-development/tests/output_format_tests.md +3 -0
- package/resources/skills/director-skills/upstream/skills/short-film-development/tests/routing_tests.md +7 -0
- package/resources/skills/director-skills/upstream/skills/shotlist-and-visual-breakdown/SKILL.md +77 -0
- package/resources/skills/director-skills/upstream/skills/shotlist-and-visual-breakdown/checklists/shotlist_quality_checklist.md +8 -0
- package/resources/skills/director-skills/upstream/skills/shotlist-and-visual-breakdown/examples/screenplay_scene_to_shot_list.md +8 -0
- package/resources/skills/director-skills/upstream/skills/shotlist-and-visual-breakdown/references/camera_plan.md +11 -0
- package/resources/skills/director-skills/upstream/skills/shotlist-and-visual-breakdown/references/production_breakdown.md +11 -0
- package/resources/skills/director-skills/upstream/skills/shotlist-and-visual-breakdown/references/shotlist_schema.md +21 -0
- package/resources/skills/director-skills/upstream/skills/shotlist-and-visual-breakdown/templates/asset_list.md +7 -0
- package/resources/skills/director-skills/upstream/skills/shotlist-and-visual-breakdown/templates/camera_plan.md +10 -0
- package/resources/skills/director-skills/upstream/skills/shotlist-and-visual-breakdown/templates/scene_breakdown.md +16 -0
- package/resources/skills/director-skills/upstream/skills/shotlist-and-visual-breakdown/templates/shot_list.md +5 -0
- package/resources/skills/director-skills/upstream/skills/shotlist-and-visual-breakdown/tests/screenplay_to_shotlist_tests.md +5 -0
- package/resources/skills/director-skills/upstream/skills/style-cinematography-director/SKILL.md +77 -0
- package/resources/skills/director-skills/upstream/skills/style-cinematography-director/checklists/style_quality_checklist.md +8 -0
- package/resources/skills/director-skills/upstream/skills/style-cinematography-director/examples/genre_to_visual_direction.md +15 -0
- package/resources/skills/director-skills/upstream/skills/style-cinematography-director/references/camera_lens_movement.md +26 -0
- package/resources/skills/director-skills/upstream/skills/style-cinematography-director/references/cinematic_language.md +32 -0
- package/resources/skills/director-skills/upstream/skills/style-cinematography-director/references/genre_style_tone.md +17 -0
- package/resources/skills/director-skills/upstream/skills/style-cinematography-director/references/lighting_and_photorealism.md +19 -0
- package/resources/skills/director-skills/upstream/skills/style-cinematography-director/templates/visual_style_bible.md +33 -0
- package/resources/skills/director-skills/upstream/skills/style-cinematography-director/tests/style_translation_tests.md +5 -0
- package/resources/skills/director-skills/upstream/tests/master_router_tests.md +80 -0
- package/resources/skills/drama-production/manifest.json +933 -0
- package/resources/skills/drama-production/upstream/LICENSE +21 -0
- package/resources/skills/drama-production/upstream/skills/short-drama/SKILL.md +153 -0
- package/resources/skills/drama-production/upstream/skills/short-drama/agents/openai.yaml +4 -0
- package/resources/skills/drama-production/upstream/skills/short-drama/assets/creator-decision.example.jsonl +4 -0
- package/resources/skills/drama-production/upstream/skills/short-drama/assets/dashboard/app.js +1263 -0
- package/resources/skills/drama-production/upstream/skills/short-drama/assets/dashboard/index.html +114 -0
- package/resources/skills/drama-production/upstream/skills/short-drama/assets/dashboard/styles.css +297 -0
- package/resources/skills/drama-production/upstream/skills/short-drama/assets/production-observation.example.jsonl +2 -0
- package/resources/skills/drama-production/upstream/skills/short-drama/assets/project-template/short-drama.json +36 -0
- package/resources/skills/drama-production/upstream/skills/short-drama/assets/reference-observation.example.jsonl +2 -0
- package/resources/skills/drama-production/upstream/skills/short-drama/references/audience-reveal.md +21 -0
- package/resources/skills/drama-production/upstream/skills/short-drama/references/contract-and-ownership.md +45 -0
- package/resources/skills/drama-production/upstream/skills/short-drama/references/creator-documents.md +230 -0
- package/resources/skills/drama-production/upstream/skills/short-drama/references/creator-workflow.md +98 -0
- package/resources/skills/drama-production/upstream/skills/short-drama/references/form-cards/Q/347/211/210/350/241/250/350/276/276.md +73 -0
- package/resources/skills/drama-production/upstream/skills/short-drama/references/form-cards//344/272/214/347/273/264/345/212/250/346/200/201/346/274/253.md +74 -0
- package/resources/skills/drama-production/upstream/skills/short-drama/references/form-cards//345/233/275/346/274/253/344/272/214/346/254/241/345/205/203.md +79 -0
- package/resources/skills/drama-production/upstream/skills/short-drama/references/form-cards//345/256/236/346/213/215.md +75 -0
- package/resources/skills/drama-production/upstream/skills/short-drama/references/form-cards//346/260/264/345/242/250/347/254/224/350/247/246.md +85 -0
- package/resources/skills/drama-production/upstream/skills/short-drama/references/form-cards//351/243/216/346/240/274/345/214/226/344/270/211/347/273/264.md +72 -0
- package/resources/skills/drama-production/upstream/skills/short-drama/references/knowhow-index.md +85 -0
- package/resources/skills/drama-production/upstream/skills/short-drama/references/look-development.md +51 -0
- package/resources/skills/drama-production/upstream/skills/short-drama/references/pickup-and-alternate.md +24 -0
- package/resources/skills/drama-production/upstream/skills/short-drama/references/production-form-profiles.md +126 -0
- package/resources/skills/drama-production/upstream/skills/short-drama/references/reference-roles.md +53 -0
- package/resources/skills/drama-production/upstream/skills/short-drama/references/runtime-preflight.md +24 -0
- package/resources/skills/drama-production/upstream/skills/short-drama/scripts/creator_markdown_check.py +1413 -0
- package/resources/skills/drama-production/upstream/skills/short-drama/scripts/dashboard_server.py +1798 -0
- package/resources/skills/drama-production/upstream/skills/short-drama/scripts/project_tool.py +2454 -0
- package/resources/skills/drama-production/upstream/skills/short-drama/scripts/selftest.py +287 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-assets/SKILL.md +76 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-assets/agents/openai.yaml +4 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-assets/assets/character-look.example.jsonl +3 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-assets/assets/continuity.example.jsonl +4 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-assets/assets/decisions.example.jsonl +5 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-assets/assets/location-view.example.jsonl +3 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-assets/assets/occurrences.example.jsonl +5 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-assets/assets/prop-state.example.jsonl +3 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-assets/examples/minimal/characters.jsonl +2 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-assets/examples/minimal/looks.jsonl +2 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-assets/references/asset-review-checklist.md +82 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-assets/references/character-and-look.md +190 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-assets/references/continuity-delta.md +120 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-assets/references/continuity-lock.md +122 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-assets/references/identity-vs-variant.md +140 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-assets/references/location-and-view.md +84 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-assets/references/occurrence-extraction.md +108 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-assets/references/prop-and-state.md +126 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-assets/references/stage-contract.md +43 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-assets/references/voice-direction.md +179 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-assets/scripts/asset_check.py +267 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-assets/scripts/selftest.py +89 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-develop/SKILL.md +157 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-develop/agents/openai.yaml +4 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-develop/assets/adaptation-map.example.jsonl +1 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-develop/assets/creative-brief.md +120 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-develop/assets/episode-map.jsonl +1 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-develop/assets/story-engine.md +181 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-develop/references/adaptation-craft.md +219 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-develop/references/creative-reference-intake.md +57 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-develop/references/director-brief-craft.md +113 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-develop/references/episode-design.md +509 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-develop/references/genre-and-hook-playbook.md +240 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-develop/references/genre-cards//344/272/262/345/255/220/351/232/220/347/247/230.md +112 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-develop/references/genre-cards//344/273/231/344/276/240/344/277/256/347/234/237.md +51 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-develop/references/genre-cards//345/212/250/344/275/234/344/273/273/345/212/241.md +51 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-develop/references/genre-cards//345/217/244/350/243/205/346/235/203/350/260/213.md +51 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-develop/references/genre-cards//345/244/215/344/273/207/346/211/223/350/204/270.md +51 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-develop/references/genre-cards//345/256/266/345/272/255/345/205/263/347/263/273.md +51 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-develop/references/genre-cards//346/202/254/347/226/221/350/247/204/345/210/231.md +51 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-develop/references/genre-cards//347/224/237/346/264/273/346/265/201.md +51 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-develop/references/genre-cards//347/240/264/351/225/234/351/207/215/345/234/206.md +109 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-develop/references/genre-cards//350/201/214/345/234/272/345/226/234/345/211/247.md +51 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-develop/references/genre-cards//350/261/252/351/227/250/345/251/232/346/201/213.md +51 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-develop/references/genre-cards//350/272/253/344/273/275/351/224/231/344/275/215.md +51 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-develop/references/genre-cards.md +92 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-develop/references/mechanism-loop.md +282 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-develop/references/multi-episode-intake.md +128 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-develop/references/premise-devices.md +211 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-develop/references/reveal-reversal-payoff.md +99 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-develop/references/serial-character-and-memory.md +293 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-develop/references/stage-contract.md +88 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-develop/references/story-craft.md +359 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-develop/scripts/episode_intake.py +699 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-develop/scripts/selftest.py +47 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-edit/SKILL.md +146 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-edit/agents/openai.yaml +4 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-edit/assets/remotion/README.md +60 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-edit/assets/remotion/package.json +15 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-edit/assets/remotion/remotion.config.ts +6 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-edit/assets/remotion/src/Root.tsx +26 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-edit/assets/remotion/src/Subtitles.tsx +88 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-edit/assets/remotion/src/font.ts +46 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-edit/assets/remotion/src/index.ts +4 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-edit/assets/remotion/src/schema.ts +32 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-edit/assets/remotion/tsconfig.json +13 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-edit/assets//345/211/252/350/276/221/345/215/225.md +43 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-edit/references/cut-craft.md +38 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-edit/references/delivery-verify.md +29 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-edit/references/generated-footage.md +54 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-edit/references/sound-and-subtitles.md +60 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-edit/references/stage-contract.md +51 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-edit/scripts/edit_tool.py +1156 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-edit/scripts/selftest.py +520 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-image-prompts/SKILL.md +73 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-image-prompts/agents/openai.yaml +4 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-image-prompts/assets/image-prompt-spec.jsonl.md +187 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-image-prompts/assets/image-prompts.md +42 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-image-prompts/assets/lookdev-frame-spec.jsonl.md +128 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-image-prompts/assets/lookdev-prompts.md +34 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-image-prompts/examples/minimal-image-prompt-specs.jsonl +2 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-image-prompts/references/character-and-look.md +153 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-image-prompts/references/common-recipe.md +241 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-image-prompts/references/edit-and-revision.md +110 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-image-prompts/references/location-plate.md +151 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-image-prompts/references/look-and-state-variant.md +97 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-image-prompts/references/lookdev-frame.md +34 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-image-prompts/references/production-sheet-recipes.md +177 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-image-prompts/references/prop-plate.md +137 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-image-prompts/references/review-and-fixtures.md +92 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-image-prompts/references/stage-contract.md +32 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-image-prompts/scripts/image_prompt_check.py +443 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-image-prompts/scripts/selftest.py +95 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-novel-analyze/SKILL.md +245 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-novel-analyze/agents/openai.yaml +4 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-novel-analyze/assets/episode-candidate.example.jsonl +3 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-novel-analyze/references/adaptation-triage.md +116 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-novel-analyze/references/adaptation-value.md +124 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-novel-analyze/references/aggregation-and-entities.md +155 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-novel-analyze/references/chapter-extraction.md +144 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-novel-analyze/references/stage-contract.md +67 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-novel-analyze/scripts/novel_index.py +651 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-novel-analyze/scripts/selftest.py +51 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-produce/SKILL.md +183 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-produce/agents/openai.yaml +4 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-produce/references/adapter-contract.md +219 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-produce/references/providers/gpt-image-2.md +24 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-produce/references/providers/minimax-h3-video.md +86 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-produce/references/providers/minimax-music.md +25 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-produce/references/providers/minimax-speech.md +41 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-produce/references/providers/seedance.md +64 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-produce/scripts/fixture_adapter.py +77 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-produce/scripts/production_tool.py +2205 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-produce/scripts/provider_adapters.py +1747 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-produce/scripts/selftest.py +135 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-review/SKILL.md +118 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-review/agents/openai.yaml +4 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-review/assets/finding-template.jsonl +2 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-review/assets/supersession-decision.example.json +42 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-review/assets/verdict-template.json +32 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-review/examples/minimal-findings.jsonl +2 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-review/examples/minimal-verdict.json +34 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-review/references/anti-template-repair.md +109 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-review/references/production-quality-gates.md +276 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-review/references/project-calibration.md +83 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-review/references/review-method.md +81 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-review/references/rubric-assets-prompts.md +111 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-review/references/rubric-source-analysis.md +108 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-review/references/rubric-story-script.md +264 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-review/references/rubric-visual-motion.md +184 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-review/references/stage-contract.md +28 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-review/scripts/review_check.py +325 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-review/scripts/selftest.py +87 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-storyboard/SKILL.md +175 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-storyboard/agents/openai.yaml +4 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-storyboard/assets/coverage-audition.example.jsonl +2 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-storyboard/assets/coverage-template.json +49 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-storyboard/assets/keyframe-prompts.md +36 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-storyboard/assets/keyframe-template.jsonl +2 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-storyboard/assets/revision-lineage.fragment.json +12 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-storyboard/assets/scene-visual-plan.example.jsonl +2 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-storyboard/assets/shot-template.jsonl +2 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-storyboard/references/blocking-playbooks.md +216 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-storyboard/references/comic-keyframe-lexicon.md +156 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-storyboard/references/coverage-audition.md +34 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-storyboard/references/keyframe-craft.md +174 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-storyboard/references/lighting-craft.md +39 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-storyboard/references/production-shot-grammar.md +279 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-storyboard/references/review-and-fixtures.md +36 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-storyboard/references/scene-visual-plan.md +30 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-storyboard/references/screenplay-to-keyframe-example.md +155 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-storyboard/references/shot-craft.md +266 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-storyboard/references/shot-revision-identity.md +25 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-storyboard/references/stage-contract.md +57 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-storyboard/scripts/selftest.py +191 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-storyboard/scripts/storyboard_check.py +824 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-video-prompts/SKILL.md +154 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-video-prompts/agents/openai.yaml +4 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-video-prompts/assets/coverage-scope.fragment.json +21 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-video-prompts/assets/delivery-container.jsonl.md +101 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-video-prompts/assets/motion-spec.jsonl.md +217 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-video-prompts/assets/motion-terminal.example.jsonl +2 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-video-prompts/assets/music-spec.jsonl.md +31 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-video-prompts/assets/performance.fragment.json +38 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-video-prompts/assets/video-prompts.md +67 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-video-prompts/examples/minimal-music-specs.jsonl +2 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-video-prompts/references/camera-audio-continuity.md +259 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-video-prompts/references/delivery-profile.md +273 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-video-prompts/references/generability.md +93 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-video-prompts/references/minimax-h3.md +253 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-video-prompts/references/motion-recipe.md +315 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-video-prompts/references/performance-action-timing.md +209 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-video-prompts/references/production-prompt-grammar.md +304 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-video-prompts/references/review-and-fixtures.md +139 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-video-prompts/references/seedance-2.0.md +50 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-video-prompts/references/seedance-2.5.md +122 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-video-prompts/references/stage-contract.md +60 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-video-prompts/references/target-model-profile.md +116 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-video-prompts/scripts/container_check.py +329 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-video-prompts/scripts/motion_timing_check.py +450 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-video-prompts/scripts/music_spec_check.py +327 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-video-prompts/scripts/selftest.py +82 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-write/SKILL.md +99 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-write/agents/openai.yaml +4 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-write/assets/beats.jsonl +2 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-write/assets/episode-card-standalone.json +120 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-write/assets/episode-card.json +55 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-write/assets/screenplay.md +36 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-write/assets/voice-record-sheet.jsonl.md +89 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-write/references/dialogue-craft.md +526 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-write/references/production-format-dialect.md +273 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-write/references/scene-handoff-capsule.md +25 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-write/references/scene-sound-dramaturgy.md +43 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-write/references/screenplay-format.md +266 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-write/references/script-craft.md +745 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-write/references/stage-contract.md +36 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-write/references/substitutable-realization.md +107 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-write/scripts/duration_estimate.py +309 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-write/scripts/screenplay_index.py +1091 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-write/scripts/selftest.py +229 -0
- package/resources/skills/drama-production/upstream/skills/short-drama-write/scripts/voice_sheet_check.py +416 -0
- package/resources/skills/viora-canvas-production/manifest.json +23 -0
- package/resources/skills/viora-canvas-production/references/canvas-contract.md +50 -0
- package/resources/skills/viora-canvas-production/references/creative-production.md +50 -0
- package/resources/skills/viora-canvas-production/references/generation-delivery.md +36 -0
- package/resources/skills/viora-canvas-production/references/production-ledger.md +25 -0
|
@@ -0,0 +1,824 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""Check the storyboard invariants that are pure bookkeeping.
|
|
3
|
+
|
|
4
|
+
`SHT-16` is arithmetic over shot durations, `SHT-17` is a structural claim about
|
|
5
|
+
which boundary a keyframe freezes, and a boundary entry that only points back at
|
|
6
|
+
an earlier shot states no fact at all. None of these needs a reading of the
|
|
7
|
+
drama, so leaving them to a reviewer spends judgment on work a script does
|
|
8
|
+
exactly. Everything requiring judgment stays in the reference documents.
|
|
9
|
+
|
|
10
|
+
The script reads accepted creator files and writes nothing.
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
from __future__ import annotations
|
|
14
|
+
|
|
15
|
+
import argparse
|
|
16
|
+
import json
|
|
17
|
+
import re
|
|
18
|
+
import sys
|
|
19
|
+
from pathlib import Path
|
|
20
|
+
from typing import Any, NamedTuple
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
# Creators run these scripts on whatever interpreter their machine provides, so
|
|
24
|
+
# an unsupported version must say so instead of failing inside an import.
|
|
25
|
+
MINIMUM_PYTHON = (3, 9)
|
|
26
|
+
if sys.version_info < MINIMUM_PYTHON:
|
|
27
|
+
raise SystemExit(
|
|
28
|
+
"short-drama needs Python {}.{} or newer; this interpreter is {}.{}".format(
|
|
29
|
+
*MINIMUM_PYTHON, sys.version_info.major, sys.version_info.minor
|
|
30
|
+
)
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
# ---------------------------------------------------------------------------
|
|
34
|
+
# REFERENCE RESOLVER -- reference implementation.
|
|
35
|
+
#
|
|
36
|
+
# Each skill checker carries its own copy of this block. The suite has no shared
|
|
37
|
+
# library on purpose: a skill must stay runnable after copying only its own
|
|
38
|
+
# directory, so duplicating these few lines across skills is the correct shape.
|
|
39
|
+
# Copy the block verbatim; do not import it.
|
|
40
|
+
# ---------------------------------------------------------------------------
|
|
41
|
+
|
|
42
|
+
SOURCES_RECORD_TYPE = "sources"
|
|
43
|
+
SOURCES_SCHEMA_VERSION = "1.0.0"
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
class ResolvedRef(NamedTuple):
|
|
47
|
+
"""An upstream reference with its snapshot resolved, whichever form it used."""
|
|
48
|
+
|
|
49
|
+
owner: str
|
|
50
|
+
artifact: str
|
|
51
|
+
record_id: str | None
|
|
52
|
+
field: str | None
|
|
53
|
+
authority: str | None
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
class RefFinding(NamedTuple):
|
|
57
|
+
"""A structural defect in a reference object."""
|
|
58
|
+
|
|
59
|
+
code: str
|
|
60
|
+
location: str
|
|
61
|
+
detail: str
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def load_sources(document: Any) -> dict[str, dict[str, Any]]:
|
|
65
|
+
"""Return the ``sources`` declaration of a parsed file, or ``{}`` if absent.
|
|
66
|
+
|
|
67
|
+
Accepts a parsed ``.json`` document (a dict) or the parsed record list of a
|
|
68
|
+
``.jsonl`` file, whose declaration lives on the first record.
|
|
69
|
+
"""
|
|
70
|
+
if isinstance(document, list):
|
|
71
|
+
document = document[0] if document else None
|
|
72
|
+
if not isinstance(document, dict):
|
|
73
|
+
return {}
|
|
74
|
+
declared = document.get("sources")
|
|
75
|
+
if not isinstance(declared, dict):
|
|
76
|
+
return {}
|
|
77
|
+
return {key: value for key, value in declared.items() if isinstance(value, dict)}
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
def resolve_ref(
|
|
81
|
+
ref: Any, sources: dict[str, dict[str, Any]], location: str
|
|
82
|
+
) -> tuple[ResolvedRef | None, RefFinding | None]:
|
|
83
|
+
"""Resolve a reference object written in either the compact or expanded form."""
|
|
84
|
+
if not isinstance(ref, dict):
|
|
85
|
+
return None, RefFinding("REF_IS_NOT_AN_OBJECT", location, f"got {type(ref).__name__}")
|
|
86
|
+
src = ref.get("src")
|
|
87
|
+
if isinstance(src, str):
|
|
88
|
+
entry = sources.get(src)
|
|
89
|
+
if entry is None:
|
|
90
|
+
return None, RefFinding(
|
|
91
|
+
"REF_SRC_IS_NOT_DECLARED", location, f"src {src!r} has no sources entry"
|
|
92
|
+
)
|
|
93
|
+
owner, artifact = entry.get("owner"), entry.get("artifact")
|
|
94
|
+
if not (isinstance(owner, str) and isinstance(artifact, str)):
|
|
95
|
+
return None, RefFinding(
|
|
96
|
+
"SOURCE_ENTRY_IS_INCOMPLETE", location, f"sources[{src!r}] needs owner/artifact"
|
|
97
|
+
)
|
|
98
|
+
elif all(isinstance(ref.get(key), str) for key in ("owner", "artifact")):
|
|
99
|
+
owner, artifact = ref["owner"], ref["artifact"]
|
|
100
|
+
else:
|
|
101
|
+
return None, RefFinding(
|
|
102
|
+
"REF_HAS_NO_UPSTREAM_BINDING", location, "needs src, or owner+artifact"
|
|
103
|
+
)
|
|
104
|
+
optional = {
|
|
105
|
+
key: ref[key] for key in ("record_id", "field", "authority") if isinstance(ref.get(key), str)
|
|
106
|
+
}
|
|
107
|
+
return (
|
|
108
|
+
ResolvedRef(
|
|
109
|
+
owner,
|
|
110
|
+
artifact,
|
|
111
|
+
optional.get("record_id"),
|
|
112
|
+
optional.get("field"),
|
|
113
|
+
optional.get("authority"),
|
|
114
|
+
),
|
|
115
|
+
None,
|
|
116
|
+
)
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
# ---------------------------------------------------------------------------
|
|
120
|
+
# END REFERENCE RESOLVER
|
|
121
|
+
# ---------------------------------------------------------------------------
|
|
122
|
+
|
|
123
|
+
SCHEMA_VERSION = "1.0.0"
|
|
124
|
+
BOUNDARY_FIELD = {"start": "/start_boundary", "end": "/end_boundary"}
|
|
125
|
+
PLACEHOLDER = re.compile(r"^<.*>$")
|
|
126
|
+
|
|
127
|
+
# A boundary entry is read on its own by whoever owns the next stage, so an
|
|
128
|
+
# entry whose whole content points back at another shot leaves that field empty
|
|
129
|
+
# in practice. Only a wholly referential entry is a defect: "站在柜台东侧(与上一
|
|
130
|
+
# 镜相同)" still says where the character is.
|
|
131
|
+
BACK_REFERENCE = re.compile(
|
|
132
|
+
r"^(同上一?镜?|同前一?镜?|同上镜|与上一?镜相同|照旧"
|
|
133
|
+
r"|(位置|朝向|目光|手部|状态|持物)?(保持)?不变|无变化"
|
|
134
|
+
r"|same as (above|before|previous( shot)?)|unchanged|no change)$",
|
|
135
|
+
re.IGNORECASE,
|
|
136
|
+
)
|
|
137
|
+
BACK_REFERENCE_TRIM = " \t 。,、;:()()【】〔〕「」『』\"'·-—~…!!??"
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
class CheckError(ValueError):
|
|
141
|
+
"""The inputs cannot be checked at all, as opposed to failing a check."""
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
def _load_json(path: Path) -> Any:
|
|
145
|
+
try:
|
|
146
|
+
return json.loads(path.read_text(encoding="utf-8"))
|
|
147
|
+
except (OSError, UnicodeError, json.JSONDecodeError) as error:
|
|
148
|
+
raise CheckError(f"unreadable JSON: {path}") from error
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
def _load_jsonl(path: Path) -> tuple[dict[str, dict[str, Any]], list[dict[str, Any]]]:
|
|
152
|
+
"""Return the file's ``sources`` declaration and its data records.
|
|
153
|
+
|
|
154
|
+
A leading ``{"record_type": "sources"}`` header declares the upstream
|
|
155
|
+
snapshots of the whole file; it is a declaration, not a data record, so it
|
|
156
|
+
is kept out of the returned list.
|
|
157
|
+
"""
|
|
158
|
+
|
|
159
|
+
records: list[dict[str, Any]] = []
|
|
160
|
+
try:
|
|
161
|
+
text = path.read_text(encoding="utf-8")
|
|
162
|
+
except (OSError, UnicodeError) as error:
|
|
163
|
+
raise CheckError(f"unreadable JSONL: {path}") from error
|
|
164
|
+
for number, line in enumerate(text.splitlines(), start=1):
|
|
165
|
+
if not line.strip():
|
|
166
|
+
continue
|
|
167
|
+
try:
|
|
168
|
+
record = json.loads(line)
|
|
169
|
+
except json.JSONDecodeError as error:
|
|
170
|
+
raise CheckError(f"invalid JSONL at {path.name}:{number}") from error
|
|
171
|
+
if not isinstance(record, dict):
|
|
172
|
+
raise CheckError(f"JSONL needs one object per line: {path.name}:{number}")
|
|
173
|
+
records.append(record)
|
|
174
|
+
sources = load_sources(records)
|
|
175
|
+
if records and records[0].get("record_type") == SOURCES_RECORD_TYPE:
|
|
176
|
+
records = records[1:]
|
|
177
|
+
return sources, records
|
|
178
|
+
|
|
179
|
+
|
|
180
|
+
def _is_template(value: Any) -> bool:
|
|
181
|
+
"""Template files ship placeholder strings; they are not project data."""
|
|
182
|
+
|
|
183
|
+
return isinstance(value, str) and bool(PLACEHOLDER.match(value.strip()))
|
|
184
|
+
|
|
185
|
+
|
|
186
|
+
def _finding(code: str, message: str, **detail: Any) -> dict[str, Any]:
|
|
187
|
+
return {"code": code, "message": message, **detail}
|
|
188
|
+
|
|
189
|
+
|
|
190
|
+
def _duration_of(shot: dict[str, Any]) -> float | None:
|
|
191
|
+
value = shot.get("duration_seconds")
|
|
192
|
+
if isinstance(value, bool) or not isinstance(value, (int, float)):
|
|
193
|
+
return None
|
|
194
|
+
return float(value)
|
|
195
|
+
|
|
196
|
+
|
|
197
|
+
def _ref_finding(finding: RefFinding, **detail: Any) -> dict[str, Any]:
|
|
198
|
+
return _finding(finding.code, finding.detail, location=finding.location, **detail)
|
|
199
|
+
|
|
200
|
+
|
|
201
|
+
def _covered_shot_ids(coverage: dict[str, Any]) -> tuple[list[str], list[dict[str, Any]]]:
|
|
202
|
+
"""Return the shot IDs the coverage claims, and any unusable reference."""
|
|
203
|
+
|
|
204
|
+
ids: list[str] = []
|
|
205
|
+
findings: list[dict[str, Any]] = []
|
|
206
|
+
sources = load_sources(coverage)
|
|
207
|
+
dispositions = coverage.get("dispositions")
|
|
208
|
+
if not isinstance(dispositions, list):
|
|
209
|
+
return ids, findings
|
|
210
|
+
for index, disposition in enumerate(dispositions):
|
|
211
|
+
if not isinstance(disposition, dict):
|
|
212
|
+
continue
|
|
213
|
+
refs = disposition.get("shot_refs")
|
|
214
|
+
if not isinstance(refs, list):
|
|
215
|
+
continue
|
|
216
|
+
for position, ref in enumerate(refs):
|
|
217
|
+
resolved, finding = resolve_ref(
|
|
218
|
+
ref, sources, f"/dispositions/{index}/shot_refs/{position}"
|
|
219
|
+
)
|
|
220
|
+
if finding is not None:
|
|
221
|
+
findings.append(_ref_finding(finding))
|
|
222
|
+
continue
|
|
223
|
+
if resolved is not None and resolved.record_id is not None:
|
|
224
|
+
ids.append(resolved.record_id)
|
|
225
|
+
return ids, findings
|
|
226
|
+
|
|
227
|
+
|
|
228
|
+
def check_episode_duration(
|
|
229
|
+
coverage: dict[str, Any],
|
|
230
|
+
shots: list[dict[str, Any]],
|
|
231
|
+
target_seconds: float | None,
|
|
232
|
+
) -> list[dict[str, Any]]:
|
|
233
|
+
"""SHT-16: the total is arithmetic, and no shot may leave it silently."""
|
|
234
|
+
|
|
235
|
+
covered_ids, findings = _covered_shot_ids(coverage)
|
|
236
|
+
duration = coverage.get("episode_duration")
|
|
237
|
+
if not isinstance(duration, dict):
|
|
238
|
+
findings.append(_finding("SHT16_RECORD_MISSING", "coverage carries no episode_duration"))
|
|
239
|
+
return findings
|
|
240
|
+
|
|
241
|
+
by_id = {
|
|
242
|
+
shot["shot_id"]: shot
|
|
243
|
+
for shot in shots
|
|
244
|
+
if isinstance(shot.get("shot_id"), str)
|
|
245
|
+
}
|
|
246
|
+
counted = duration.get("counted_shot_ids")
|
|
247
|
+
unresolved = duration.get("unresolved_durations")
|
|
248
|
+
if not isinstance(counted, list) or not isinstance(unresolved, list):
|
|
249
|
+
findings.append(
|
|
250
|
+
_finding(
|
|
251
|
+
"SHT16_RECORD_INCOMPLETE",
|
|
252
|
+
"episode_duration needs counted_shot_ids and unresolved_durations",
|
|
253
|
+
)
|
|
254
|
+
)
|
|
255
|
+
return findings
|
|
256
|
+
counted_ids = [value for value in counted if isinstance(value, str)]
|
|
257
|
+
unresolved_ids = [value for value in unresolved if isinstance(value, str)]
|
|
258
|
+
|
|
259
|
+
overlap = sorted(set(counted_ids) & set(unresolved_ids))
|
|
260
|
+
if overlap:
|
|
261
|
+
findings.append(
|
|
262
|
+
_finding(
|
|
263
|
+
"SHT16_SHOT_COUNTED_AND_UNRESOLVED",
|
|
264
|
+
"a shot cannot be both counted and unresolved",
|
|
265
|
+
shot_ids=overlap,
|
|
266
|
+
)
|
|
267
|
+
)
|
|
268
|
+
|
|
269
|
+
# A shot listed twice is summed twice, and set arithmetic above never sees
|
|
270
|
+
# it. One copy-paste inflates the episode by a whole shot, and the checker
|
|
271
|
+
# then confirms the inflated figure in the coverage file as correct.
|
|
272
|
+
duplicates = sorted(
|
|
273
|
+
{shot_id for shot_id in counted_ids + unresolved_ids
|
|
274
|
+
if (counted_ids + unresolved_ids).count(shot_id) > 1}
|
|
275
|
+
)
|
|
276
|
+
if duplicates:
|
|
277
|
+
findings.append(
|
|
278
|
+
_finding(
|
|
279
|
+
"SHT16_SHOT_LISTED_TWICE",
|
|
280
|
+
"episode_duration names the same shot more than once",
|
|
281
|
+
shot_ids=duplicates,
|
|
282
|
+
)
|
|
283
|
+
)
|
|
284
|
+
|
|
285
|
+
accounted = set(counted_ids) | set(unresolved_ids)
|
|
286
|
+
missing = sorted(set(covered_ids) - accounted)
|
|
287
|
+
if missing:
|
|
288
|
+
findings.append(
|
|
289
|
+
_finding(
|
|
290
|
+
"SHT16_SHOT_LEFT_THE_TOTAL",
|
|
291
|
+
"coverage lists shots that neither contribute nor are suspended",
|
|
292
|
+
shot_ids=missing,
|
|
293
|
+
)
|
|
294
|
+
)
|
|
295
|
+
# `covered_ids` comes from the coverage document itself, so the check above
|
|
296
|
+
# only asks whether coverage agrees with coverage. The episode's real shot
|
|
297
|
+
# list is `shots.jsonl`; a shot dropped from both the dispositions and the
|
|
298
|
+
# total is invisible to every check that reads only the one file.
|
|
299
|
+
unaccounted = sorted(set(by_id) - accounted)
|
|
300
|
+
if unaccounted:
|
|
301
|
+
findings.append(
|
|
302
|
+
_finding(
|
|
303
|
+
"SHT16_EPISODE_SHOT_LEFT_THE_TOTAL",
|
|
304
|
+
"the shot file carries shots that episode_duration neither "
|
|
305
|
+
"counts nor suspends",
|
|
306
|
+
shot_ids=unaccounted,
|
|
307
|
+
)
|
|
308
|
+
)
|
|
309
|
+
unknown = sorted(accounted - set(by_id))
|
|
310
|
+
if unknown:
|
|
311
|
+
findings.append(
|
|
312
|
+
_finding(
|
|
313
|
+
"SHT16_SHOT_UNRESOLVABLE",
|
|
314
|
+
"episode_duration names shots that are not in the shot file",
|
|
315
|
+
shot_ids=unknown,
|
|
316
|
+
)
|
|
317
|
+
)
|
|
318
|
+
|
|
319
|
+
total = 0.0
|
|
320
|
+
for shot_id in sorted(set(counted_ids)):
|
|
321
|
+
shot = by_id.get(shot_id)
|
|
322
|
+
if shot is None:
|
|
323
|
+
continue
|
|
324
|
+
seconds = _duration_of(shot)
|
|
325
|
+
if seconds is None:
|
|
326
|
+
findings.append(
|
|
327
|
+
_finding(
|
|
328
|
+
"SHT16_COUNTED_SHOT_HAS_NO_DURATION",
|
|
329
|
+
"a counted shot carries no numeric duration_seconds",
|
|
330
|
+
shot_id=shot_id,
|
|
331
|
+
)
|
|
332
|
+
)
|
|
333
|
+
continue
|
|
334
|
+
total += seconds
|
|
335
|
+
for shot_id in unresolved_ids:
|
|
336
|
+
shot = by_id.get(shot_id)
|
|
337
|
+
if shot is not None and _duration_of(shot) is not None:
|
|
338
|
+
findings.append(
|
|
339
|
+
_finding(
|
|
340
|
+
"SHT16_SUSPENDED_SHOT_HAS_A_DURATION",
|
|
341
|
+
"a shot listed as unresolved already carries a duration",
|
|
342
|
+
shot_id=shot_id,
|
|
343
|
+
)
|
|
344
|
+
)
|
|
345
|
+
|
|
346
|
+
stated = duration.get("shot_seconds_total")
|
|
347
|
+
if isinstance(stated, bool) or not isinstance(stated, (int, float)):
|
|
348
|
+
findings.append(
|
|
349
|
+
_finding("SHT16_TOTAL_MISSING", "shot_seconds_total is not a number")
|
|
350
|
+
)
|
|
351
|
+
elif abs(float(stated) - total) > 1e-6:
|
|
352
|
+
findings.append(
|
|
353
|
+
_finding(
|
|
354
|
+
"SHT16_TOTAL_IS_NOT_THE_SUM",
|
|
355
|
+
"shot_seconds_total does not equal the sum of the counted shots",
|
|
356
|
+
stated=float(stated),
|
|
357
|
+
computed=round(total, 6),
|
|
358
|
+
)
|
|
359
|
+
)
|
|
360
|
+
|
|
361
|
+
if target_seconds is None:
|
|
362
|
+
if duration.get("disposition") not in (None, "no_target_declared"):
|
|
363
|
+
findings.append(
|
|
364
|
+
_finding(
|
|
365
|
+
"SHT16_DISPOSITION_CLAIMS_A_TARGET",
|
|
366
|
+
"no target is declared, so the disposition cannot judge one; "
|
|
367
|
+
"leave it unset or use no_target_declared",
|
|
368
|
+
)
|
|
369
|
+
)
|
|
370
|
+
return findings
|
|
371
|
+
|
|
372
|
+
delta = duration.get("delta_seconds")
|
|
373
|
+
expected = total - target_seconds
|
|
374
|
+
if isinstance(delta, bool) or not isinstance(delta, (int, float)):
|
|
375
|
+
findings.append(
|
|
376
|
+
_finding("SHT16_DELTA_MISSING", "a declared target needs a signed delta")
|
|
377
|
+
)
|
|
378
|
+
elif abs(float(delta) - expected) > 1e-6:
|
|
379
|
+
findings.append(
|
|
380
|
+
_finding(
|
|
381
|
+
"SHT16_DELTA_IS_WRONG",
|
|
382
|
+
"delta_seconds does not equal total minus target",
|
|
383
|
+
stated=float(delta),
|
|
384
|
+
computed=round(expected, 6),
|
|
385
|
+
)
|
|
386
|
+
)
|
|
387
|
+
allowed = ("within_creator_tolerance", "creator_accepted_overrun", "to_revise")
|
|
388
|
+
if duration.get("disposition") not in set(allowed):
|
|
389
|
+
findings.append(
|
|
390
|
+
_finding(
|
|
391
|
+
"SHT16_DISPOSITION_MISSING",
|
|
392
|
+
"a declared target needs a disposition for its delta; "
|
|
393
|
+
f"use one of {', '.join(allowed)}",
|
|
394
|
+
stated=duration.get("disposition"),
|
|
395
|
+
)
|
|
396
|
+
)
|
|
397
|
+
return findings
|
|
398
|
+
|
|
399
|
+
|
|
400
|
+
def check_keyframe_boundaries(
|
|
401
|
+
keyframes: list[dict[str, Any]],
|
|
402
|
+
shots: list[dict[str, Any]],
|
|
403
|
+
sources: dict[str, dict[str, Any]] | None = None,
|
|
404
|
+
) -> list[dict[str, Any]]:
|
|
405
|
+
"""SHT-17: say which boundary is frozen, and bind that shot's field."""
|
|
406
|
+
|
|
407
|
+
declared = sources or {}
|
|
408
|
+
findings: list[dict[str, Any]] = []
|
|
409
|
+
shot_ids = {
|
|
410
|
+
shot["shot_id"] for shot in shots if isinstance(shot.get("shot_id"), str)
|
|
411
|
+
}
|
|
412
|
+
seen: dict[tuple[str, str], str] = {}
|
|
413
|
+
for keyframe in keyframes:
|
|
414
|
+
keyframe_id = keyframe.get("keyframe_id")
|
|
415
|
+
if not isinstance(keyframe_id, str):
|
|
416
|
+
findings.append(
|
|
417
|
+
_finding("SHT17_KEYFRAME_HAS_NO_ID", "a keyframe record has no id")
|
|
418
|
+
)
|
|
419
|
+
continue
|
|
420
|
+
role = keyframe.get("boundary_role")
|
|
421
|
+
if role not in BOUNDARY_FIELD:
|
|
422
|
+
findings.append(
|
|
423
|
+
_finding(
|
|
424
|
+
"SHT17_BOUNDARY_ROLE_MISSING",
|
|
425
|
+
"boundary_role must be start or end",
|
|
426
|
+
keyframe_id=keyframe_id,
|
|
427
|
+
)
|
|
428
|
+
)
|
|
429
|
+
continue
|
|
430
|
+
ref = keyframe.get("boundary_ref")
|
|
431
|
+
if not isinstance(ref, dict):
|
|
432
|
+
findings.append(
|
|
433
|
+
_finding(
|
|
434
|
+
"SHT17_BOUNDARY_REF_MISSING",
|
|
435
|
+
"a keyframe must bind the boundary it projects",
|
|
436
|
+
keyframe_id=keyframe_id,
|
|
437
|
+
)
|
|
438
|
+
)
|
|
439
|
+
continue
|
|
440
|
+
resolved, ref_finding = resolve_ref(ref, declared, f"{keyframe_id}/boundary_ref")
|
|
441
|
+
if ref_finding is not None or resolved is None:
|
|
442
|
+
if ref_finding is not None:
|
|
443
|
+
findings.append(_ref_finding(ref_finding, keyframe_id=keyframe_id))
|
|
444
|
+
continue
|
|
445
|
+
if resolved.field != BOUNDARY_FIELD[role]:
|
|
446
|
+
findings.append(
|
|
447
|
+
_finding(
|
|
448
|
+
"SHT17_BOUNDARY_REF_DISAGREES_WITH_ROLE",
|
|
449
|
+
"boundary_ref.field does not match the declared role",
|
|
450
|
+
keyframe_id=keyframe_id,
|
|
451
|
+
role=role,
|
|
452
|
+
field=resolved.field,
|
|
453
|
+
)
|
|
454
|
+
)
|
|
455
|
+
shot_id = resolved.record_id
|
|
456
|
+
if shot_id is None or shot_id not in shot_ids:
|
|
457
|
+
findings.append(
|
|
458
|
+
_finding(
|
|
459
|
+
"SHT17_BOUNDARY_REF_UNRESOLVABLE",
|
|
460
|
+
"boundary_ref does not resolve to a shot in the shot file",
|
|
461
|
+
keyframe_id=keyframe_id,
|
|
462
|
+
record_id=shot_id,
|
|
463
|
+
)
|
|
464
|
+
)
|
|
465
|
+
continue
|
|
466
|
+
previous = seen.get((shot_id, role))
|
|
467
|
+
if previous is not None:
|
|
468
|
+
findings.append(
|
|
469
|
+
_finding(
|
|
470
|
+
"SHT17_DUPLICATE_BOUNDARY_KEYFRAME",
|
|
471
|
+
"one shot boundary cannot have two keyframes",
|
|
472
|
+
shot_id=shot_id,
|
|
473
|
+
role=role,
|
|
474
|
+
keyframe_ids=[previous, keyframe_id],
|
|
475
|
+
)
|
|
476
|
+
)
|
|
477
|
+
continue
|
|
478
|
+
seen[(shot_id, role)] = keyframe_id
|
|
479
|
+
return findings
|
|
480
|
+
|
|
481
|
+
|
|
482
|
+
def check_boundary_entries(shots: list[dict[str, Any]]) -> list[dict[str, Any]]:
|
|
483
|
+
"""SHT-05: every boundary entry states a fact readable without the last shot."""
|
|
484
|
+
|
|
485
|
+
findings: list[dict[str, Any]] = []
|
|
486
|
+
for shot in shots:
|
|
487
|
+
shot_id = shot.get("shot_id")
|
|
488
|
+
for boundary in ("start_boundary", "end_boundary"):
|
|
489
|
+
fields = shot.get(boundary)
|
|
490
|
+
if isinstance(fields, str):
|
|
491
|
+
# A boundary written as one string carries the same defect. The
|
|
492
|
+
# empty key keeps the reported pointer at /<boundary>/0.
|
|
493
|
+
fields = {"": [fields]}
|
|
494
|
+
if not isinstance(fields, dict):
|
|
495
|
+
continue
|
|
496
|
+
for name, entries in sorted(fields.items()):
|
|
497
|
+
if isinstance(entries, str):
|
|
498
|
+
entries = [entries]
|
|
499
|
+
if not isinstance(entries, list):
|
|
500
|
+
continue
|
|
501
|
+
for index, entry in enumerate(entries):
|
|
502
|
+
if not isinstance(entry, str) or _is_template(entry):
|
|
503
|
+
continue
|
|
504
|
+
if BACK_REFERENCE.match(entry.strip(BACK_REFERENCE_TRIM)):
|
|
505
|
+
findings.append(
|
|
506
|
+
_finding(
|
|
507
|
+
"SHT05_BOUNDARY_ENTRY_IS_A_BACK_REFERENCE",
|
|
508
|
+
"a boundary entry points back instead of stating the fact",
|
|
509
|
+
shot_id=shot_id,
|
|
510
|
+
location=f"/{boundary}/{name}/{index}" if name else f"/{boundary}/{index}",
|
|
511
|
+
entry=entry,
|
|
512
|
+
)
|
|
513
|
+
)
|
|
514
|
+
return findings
|
|
515
|
+
|
|
516
|
+
|
|
517
|
+
def _declared_target(project: Path | None) -> float | None:
|
|
518
|
+
if project is None:
|
|
519
|
+
return None
|
|
520
|
+
document = _load_json(project)
|
|
521
|
+
if not isinstance(document, dict):
|
|
522
|
+
raise CheckError("project file must be a JSON object")
|
|
523
|
+
value = document.get("format", {}).get("target_seconds_per_episode")
|
|
524
|
+
if value is None or _is_template(value):
|
|
525
|
+
return None
|
|
526
|
+
if isinstance(value, bool) or not isinstance(value, (int, float)):
|
|
527
|
+
raise CheckError("target_seconds_per_episode must be a number or null")
|
|
528
|
+
return float(value)
|
|
529
|
+
|
|
530
|
+
|
|
531
|
+
# A screenplay block that no shot claims is a block nobody will film. A block
|
|
532
|
+
# two shots claim is a block the edit will show twice. Shots bind to the
|
|
533
|
+
# screenplay through the index -- stable block IDs -- not through the prose,
|
|
534
|
+
# because the prose is edited constantly and the IDs survive that.
|
|
535
|
+
def screenplay_block_ids(index_path: Path) -> tuple[list[str], int]:
|
|
536
|
+
"""The indexed blocks, and how much of the screenplay stayed unclassified.
|
|
537
|
+
|
|
538
|
+
A line the index could not classify is not a block, so it is invisible to
|
|
539
|
+
every check below: no shot can claim it, and nothing reports that it is
|
|
540
|
+
missing. Coverage measured against a partial index is not coverage of the
|
|
541
|
+
screenplay, so the count comes back with the IDs.
|
|
542
|
+
"""
|
|
543
|
+
|
|
544
|
+
_sources, records = _load_jsonl(index_path)
|
|
545
|
+
blocks = [
|
|
546
|
+
str(record["block_id"])
|
|
547
|
+
for record in records
|
|
548
|
+
if record.get("record_type") == "block" and isinstance(record.get("block_id"), str)
|
|
549
|
+
]
|
|
550
|
+
issues = sum(
|
|
551
|
+
1 for record in records if record.get("record_type") == "source_issue"
|
|
552
|
+
)
|
|
553
|
+
return blocks, issues
|
|
554
|
+
|
|
555
|
+
|
|
556
|
+
# SKILL.md gives four dispositions, and three of them are not "one shot claims
|
|
557
|
+
# this block": material can be intentionally repeated, omitted for a reason, or
|
|
558
|
+
# present only so the reader understands the scene. A claim check that knows
|
|
559
|
+
# nothing about them can only ever demand exactly one shot per block, which is
|
|
560
|
+
# why marking a block `nonvisual_context` as the workflow instructs used to fail.
|
|
561
|
+
DISPOSITIONS = {
|
|
562
|
+
"covered",
|
|
563
|
+
"intentional_repeat",
|
|
564
|
+
"omitted_with_reason",
|
|
565
|
+
"nonvisual_context",
|
|
566
|
+
}
|
|
567
|
+
# Two of them are a decision, not an observation, so they have to carry the
|
|
568
|
+
# reason the decision was made.
|
|
569
|
+
DISPOSITIONS_NEEDING_A_REASON = {"intentional_repeat", "omitted_with_reason"}
|
|
570
|
+
# Only these expect shots. The other two are records of material that is
|
|
571
|
+
# deliberately not on screen.
|
|
572
|
+
DISPOSITIONS_EXPECTING_SHOTS = {"covered", "intentional_repeat"}
|
|
573
|
+
|
|
574
|
+
|
|
575
|
+
def block_dispositions(
|
|
576
|
+
coverage: dict[str, Any], wanted: set[str]
|
|
577
|
+
) -> tuple[dict[str, str], list[dict[str, Any]]]:
|
|
578
|
+
"""Read the disposition table, and check it against the screenplay index.
|
|
579
|
+
|
|
580
|
+
Nothing validated this table before: rows could be dropped, given a status
|
|
581
|
+
no rule defines, or point at blocks that do not exist, and the file still
|
|
582
|
+
passed. Coverage and `shots.jsonl` were two independent claims about the
|
|
583
|
+
same fact with no reconciliation between them.
|
|
584
|
+
"""
|
|
585
|
+
|
|
586
|
+
findings: list[dict[str, Any]] = []
|
|
587
|
+
rows = coverage.get("dispositions")
|
|
588
|
+
if not isinstance(rows, list):
|
|
589
|
+
return {}, [
|
|
590
|
+
_finding("SHT01_DISPOSITIONS_MISSING", "coverage carries no dispositions")
|
|
591
|
+
]
|
|
592
|
+
|
|
593
|
+
status_of: dict[str, str] = {}
|
|
594
|
+
for index, row in enumerate(rows):
|
|
595
|
+
if not isinstance(row, dict):
|
|
596
|
+
findings.append(
|
|
597
|
+
_finding(
|
|
598
|
+
"SHT01_DISPOSITION_MALFORMED",
|
|
599
|
+
"a disposition row is not an object",
|
|
600
|
+
position=index,
|
|
601
|
+
)
|
|
602
|
+
)
|
|
603
|
+
continue
|
|
604
|
+
block_id = row.get("block_id")
|
|
605
|
+
status = row.get("status")
|
|
606
|
+
if not isinstance(block_id, str) or not block_id:
|
|
607
|
+
findings.append(
|
|
608
|
+
_finding(
|
|
609
|
+
"SHT01_DISPOSITION_MALFORMED",
|
|
610
|
+
"a disposition row names no block",
|
|
611
|
+
position=index,
|
|
612
|
+
)
|
|
613
|
+
)
|
|
614
|
+
continue
|
|
615
|
+
if status not in DISPOSITIONS:
|
|
616
|
+
findings.append(
|
|
617
|
+
_finding(
|
|
618
|
+
"SHT01_DISPOSITION_UNKNOWN",
|
|
619
|
+
"a disposition must be one of the four the workflow defines",
|
|
620
|
+
block_id=block_id,
|
|
621
|
+
status=status,
|
|
622
|
+
)
|
|
623
|
+
)
|
|
624
|
+
continue
|
|
625
|
+
if block_id in status_of:
|
|
626
|
+
findings.append(
|
|
627
|
+
_finding(
|
|
628
|
+
"SHT01_DISPOSITION_REPEATED",
|
|
629
|
+
"a block carries more than one disposition",
|
|
630
|
+
block_id=block_id,
|
|
631
|
+
)
|
|
632
|
+
)
|
|
633
|
+
continue
|
|
634
|
+
if block_id not in wanted:
|
|
635
|
+
findings.append(
|
|
636
|
+
_finding(
|
|
637
|
+
"SHT01_DISPOSITION_NOT_IN_SCREENPLAY",
|
|
638
|
+
"a disposition names a block that is not in the screenplay index",
|
|
639
|
+
block_id=block_id,
|
|
640
|
+
)
|
|
641
|
+
)
|
|
642
|
+
continue
|
|
643
|
+
if status in DISPOSITIONS_NEEDING_A_REASON and not str(
|
|
644
|
+
row.get("reason") or ""
|
|
645
|
+
).strip():
|
|
646
|
+
findings.append(
|
|
647
|
+
_finding(
|
|
648
|
+
"SHT01_DISPOSITION_HAS_NO_REASON",
|
|
649
|
+
"repeating or omitting material is a decision and must say why",
|
|
650
|
+
block_id=block_id,
|
|
651
|
+
status=status,
|
|
652
|
+
)
|
|
653
|
+
)
|
|
654
|
+
status_of[block_id] = status
|
|
655
|
+
|
|
656
|
+
undecided = sorted(wanted - set(status_of))
|
|
657
|
+
if undecided:
|
|
658
|
+
findings.append(
|
|
659
|
+
_finding(
|
|
660
|
+
"SHT01_BLOCK_HAS_NO_DISPOSITION",
|
|
661
|
+
"every production-relevant block must carry a disposition",
|
|
662
|
+
block_ids=undecided,
|
|
663
|
+
)
|
|
664
|
+
)
|
|
665
|
+
return status_of, findings
|
|
666
|
+
|
|
667
|
+
|
|
668
|
+
def check_screenplay_coverage(
|
|
669
|
+
shots: list[dict[str, Any]],
|
|
670
|
+
shot_sources: dict[str, Any],
|
|
671
|
+
index_path: Path | None,
|
|
672
|
+
coverage: dict[str, Any] | None = None,
|
|
673
|
+
) -> list[dict[str, Any]]:
|
|
674
|
+
if index_path is None:
|
|
675
|
+
return []
|
|
676
|
+
try:
|
|
677
|
+
wanted, unclassified = screenplay_block_ids(index_path)
|
|
678
|
+
except OSError as error:
|
|
679
|
+
raise CheckError(f"screenplay index cannot be read: {error}") from error
|
|
680
|
+
|
|
681
|
+
status_of: dict[str, str] = {}
|
|
682
|
+
disposition_findings: list[dict[str, Any]] = []
|
|
683
|
+
if unclassified:
|
|
684
|
+
disposition_findings.append(
|
|
685
|
+
_finding(
|
|
686
|
+
"SHT01_SCREENPLAY_IS_NOT_FULLY_INDEXED",
|
|
687
|
+
"the screenplay index left lines unclassified, so this coverage "
|
|
688
|
+
"check cannot see all of the screenplay",
|
|
689
|
+
source_issue_count=unclassified,
|
|
690
|
+
)
|
|
691
|
+
)
|
|
692
|
+
if coverage is not None:
|
|
693
|
+
status_of, disposition_findings2 = block_dispositions(coverage, set(wanted))
|
|
694
|
+
disposition_findings.extend(disposition_findings2)
|
|
695
|
+
|
|
696
|
+
claims: dict[str, list[str]] = {block_id: [] for block_id in wanted}
|
|
697
|
+
unknown: list[dict[str, Any]] = []
|
|
698
|
+
for shot in shots:
|
|
699
|
+
shot_id = shot.get("shot_id")
|
|
700
|
+
for reference in shot.get("source_refs") or []:
|
|
701
|
+
resolved, _defect = resolve_ref(reference, shot_sources, "source_refs")
|
|
702
|
+
if resolved is None or resolved.record_id is None:
|
|
703
|
+
continue
|
|
704
|
+
record_id = str(resolved.record_id)
|
|
705
|
+
if record_id in claims:
|
|
706
|
+
claims[record_id].append(shot_id)
|
|
707
|
+
elif resolved.artifact.endswith("screenplay-index.jsonl"):
|
|
708
|
+
unknown.append({"shot_id": shot_id, "block_id": record_id})
|
|
709
|
+
|
|
710
|
+
findings = list(disposition_findings)
|
|
711
|
+
for block_id, owners in claims.items():
|
|
712
|
+
# With no coverage file to read, every block is treated as `covered`:
|
|
713
|
+
# that is the old behaviour, and the only safe assumption when the
|
|
714
|
+
# creator has not said otherwise.
|
|
715
|
+
status = status_of.get(block_id, "covered") if coverage is not None else "covered"
|
|
716
|
+
if not owners:
|
|
717
|
+
if status in DISPOSITIONS_EXPECTING_SHOTS:
|
|
718
|
+
findings.append(
|
|
719
|
+
_finding(
|
|
720
|
+
"SHT01_BLOCK_UNCLAIMED",
|
|
721
|
+
"no shot claims this screenplay block",
|
|
722
|
+
block_id=block_id,
|
|
723
|
+
status=status,
|
|
724
|
+
)
|
|
725
|
+
)
|
|
726
|
+
elif status not in DISPOSITIONS_EXPECTING_SHOTS:
|
|
727
|
+
findings.append(
|
|
728
|
+
_finding(
|
|
729
|
+
"SHT01_BLOCK_IS_ON_SCREEN_ANYWAY",
|
|
730
|
+
"a block recorded as not filmed is claimed by a shot",
|
|
731
|
+
block_id=block_id,
|
|
732
|
+
status=status,
|
|
733
|
+
shot_ids=owners,
|
|
734
|
+
)
|
|
735
|
+
)
|
|
736
|
+
elif len(owners) > 1 and status != "intentional_repeat":
|
|
737
|
+
findings.append(
|
|
738
|
+
_finding(
|
|
739
|
+
"SHT01_BLOCK_CLAIMED_TWICE",
|
|
740
|
+
"more than one shot claims the same screenplay block",
|
|
741
|
+
block_id=block_id,
|
|
742
|
+
shot_ids=owners,
|
|
743
|
+
)
|
|
744
|
+
)
|
|
745
|
+
for stray in unknown:
|
|
746
|
+
findings.append(
|
|
747
|
+
_finding(
|
|
748
|
+
"SHT01_BLOCK_NOT_IN_SCREENPLAY",
|
|
749
|
+
"a shot claims a block that is not in the screenplay index",
|
|
750
|
+
**stray,
|
|
751
|
+
)
|
|
752
|
+
)
|
|
753
|
+
return findings
|
|
754
|
+
|
|
755
|
+
|
|
756
|
+
def check(
|
|
757
|
+
coverage_path: Path,
|
|
758
|
+
shots_path: Path,
|
|
759
|
+
keyframes_path: Path | None,
|
|
760
|
+
project_path: Path | None,
|
|
761
|
+
screenplay_index_path: Path | None = None,
|
|
762
|
+
) -> dict[str, Any]:
|
|
763
|
+
coverage = _load_json(coverage_path)
|
|
764
|
+
if not isinstance(coverage, dict):
|
|
765
|
+
raise CheckError("coverage must be a JSON object")
|
|
766
|
+
shot_sources, shots = _load_jsonl(shots_path)
|
|
767
|
+
findings = check_episode_duration(coverage, shots, _declared_target(project_path))
|
|
768
|
+
findings.extend(check_boundary_entries(shots))
|
|
769
|
+
findings.extend(
|
|
770
|
+
check_screenplay_coverage(
|
|
771
|
+
shots, shot_sources, screenplay_index_path, coverage
|
|
772
|
+
)
|
|
773
|
+
)
|
|
774
|
+
keyframes: list[dict[str, Any]] | None = None
|
|
775
|
+
if keyframes_path is not None:
|
|
776
|
+
keyframe_sources, keyframes = _load_jsonl(keyframes_path)
|
|
777
|
+
findings.extend(check_keyframe_boundaries(keyframes, shots, keyframe_sources))
|
|
778
|
+
return {
|
|
779
|
+
"schema_version": SCHEMA_VERSION,
|
|
780
|
+
"episode_id": coverage.get("episode_id"),
|
|
781
|
+
"checked": {
|
|
782
|
+
"shots": len(shots),
|
|
783
|
+
"keyframes": None if keyframes is None else len(keyframes),
|
|
784
|
+
},
|
|
785
|
+
"findings": findings,
|
|
786
|
+
"status": "pass" if not findings else "fail",
|
|
787
|
+
}
|
|
788
|
+
|
|
789
|
+
|
|
790
|
+
def build_parser() -> argparse.ArgumentParser:
|
|
791
|
+
parser = argparse.ArgumentParser(
|
|
792
|
+
description="Check storyboard duration arithmetic and keyframe boundary roles."
|
|
793
|
+
)
|
|
794
|
+
parser.add_argument("coverage", type=Path, help="the episode coverage JSON")
|
|
795
|
+
parser.add_argument("--shots", type=Path, required=True)
|
|
796
|
+
parser.add_argument("--keyframes", type=Path)
|
|
797
|
+
parser.add_argument(
|
|
798
|
+
"--screenplay-index",
|
|
799
|
+
type=Path,
|
|
800
|
+
help="screenplay-index.jsonl, so every block is claimed by exactly one shot",
|
|
801
|
+
)
|
|
802
|
+
parser.add_argument(
|
|
803
|
+
"--project",
|
|
804
|
+
type=Path,
|
|
805
|
+
help="short-drama.json, so a declared per-episode target is compared",
|
|
806
|
+
)
|
|
807
|
+
return parser
|
|
808
|
+
|
|
809
|
+
|
|
810
|
+
def main(argv: list[str] | None = None) -> int:
|
|
811
|
+
args = build_parser().parse_args(argv)
|
|
812
|
+
try:
|
|
813
|
+
result = check(
|
|
814
|
+
args.coverage, args.shots, args.keyframes, args.project, args.screenplay_index
|
|
815
|
+
)
|
|
816
|
+
except CheckError as error:
|
|
817
|
+
print(f"{type(error).__name__}: {error}", file=sys.stderr)
|
|
818
|
+
return 2
|
|
819
|
+
print(json.dumps(result, ensure_ascii=True, sort_keys=True))
|
|
820
|
+
return 0 if result["status"] == "pass" else 1
|
|
821
|
+
|
|
822
|
+
|
|
823
|
+
if __name__ == "__main__":
|
|
824
|
+
raise SystemExit(main())
|