@lingjingai/scriptctl 0.35.0 → 0.36.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 +21 -5
- package/changes/0.36.0.md +22 -0
- package/dist/bin.js +0 -0
- package/dist/cli.d.ts +2 -1
- package/dist/cli.js +52 -128
- package/dist/cli.js.map +1 -1
- package/dist/common.d.ts +0 -16
- package/dist/common.js +2 -342
- package/dist/common.js.map +1 -1
- package/dist/domain/ingest/apply-plan.d.ts +23 -0
- package/dist/domain/ingest/apply-plan.js +210 -0
- package/dist/domain/ingest/apply-plan.js.map +1 -0
- package/dist/domain/ingest/assembler.d.ts +57 -0
- package/dist/domain/ingest/assembler.js +181 -0
- package/dist/domain/ingest/assembler.js.map +1 -0
- package/dist/domain/ingest/chunker.d.ts +9 -0
- package/dist/domain/ingest/chunker.js +38 -0
- package/dist/domain/ingest/chunker.js.map +1 -0
- package/dist/domain/ingest/evidence.d.ts +5 -0
- package/dist/domain/ingest/evidence.js +66 -0
- package/dist/domain/ingest/evidence.js.map +1 -0
- package/dist/domain/ingest/govern.d.ts +3 -0
- package/dist/domain/ingest/govern.js +127 -0
- package/dist/domain/ingest/govern.js.map +1 -0
- package/dist/domain/ingest/jsonl-parser.d.ts +6 -0
- package/dist/domain/ingest/jsonl-parser.js +187 -0
- package/dist/domain/ingest/jsonl-parser.js.map +1 -0
- package/dist/domain/ingest/markdown-parser.d.ts +6 -0
- package/dist/domain/ingest/markdown-parser.js +186 -0
- package/dist/domain/ingest/markdown-parser.js.map +1 -0
- package/dist/domain/ingest/records.d.ts +71 -0
- package/dist/domain/ingest/records.js +9 -0
- package/dist/domain/ingest/records.js.map +1 -0
- package/dist/domain/ingest/renumber.d.ts +14 -0
- package/dist/domain/ingest/renumber.js +130 -0
- package/dist/domain/ingest/renumber.js.map +1 -0
- package/dist/domain/ingest/script-v3.d.ts +94 -0
- package/dist/domain/ingest/script-v3.js +7 -0
- package/dist/domain/ingest/script-v3.js.map +1 -0
- package/dist/domain/ingest/state-reconcile.d.ts +11 -0
- package/dist/domain/ingest/state-reconcile.js +90 -0
- package/dist/domain/ingest/state-reconcile.js.map +1 -0
- package/dist/domain/ingest/validation.d.ts +11 -0
- package/dist/domain/ingest/validation.js +168 -0
- package/dist/domain/ingest/validation.js.map +1 -0
- package/dist/domain/ingest/video-aggregate.d.ts +23 -0
- package/dist/domain/ingest/video-aggregate.js +89 -0
- package/dist/domain/ingest/video-aggregate.js.map +1 -0
- package/dist/domain/ingest/video-apply.d.ts +37 -0
- package/dist/domain/ingest/video-apply.js +236 -0
- package/dist/domain/ingest/video-apply.js.map +1 -0
- package/dist/domain/ingest/video-md-parser.d.ts +2 -0
- package/dist/domain/ingest/video-md-parser.js +233 -0
- package/dist/domain/ingest/video-md-parser.js.map +1 -0
- package/dist/domain/ingest/video-records.d.ts +56 -0
- package/dist/domain/ingest/video-records.js +9 -0
- package/dist/domain/ingest/video-records.js.map +1 -0
- package/dist/domain/loom/index.d.ts +2 -1
- package/dist/domain/loom/index.js +12 -10
- package/dist/domain/loom/index.js.map +1 -1
- package/dist/domain/loom/types.d.ts +3 -2
- package/dist/domain/script/lookups.d.ts +3 -2
- package/dist/domain/script/lookups.js +25 -8
- package/dist/domain/script/lookups.js.map +1 -1
- package/dist/domain/script/patch/apply.js +2 -2
- package/dist/domain/script/patch/apply.js.map +1 -1
- package/dist/domain/script/patch/helpers.d.ts +3 -7
- package/dist/domain/script/patch/helpers.js +23 -96
- package/dist/domain/script/patch/helpers.js.map +1 -1
- package/dist/domain/script/patch/ops-action.d.ts +0 -2
- package/dist/domain/script/patch/ops-action.js +34 -100
- package/dist/domain/script/patch/ops-action.js.map +1 -1
- package/dist/domain/script/patch/ops-asset.d.ts +1 -0
- package/dist/domain/script/patch/ops-asset.js +102 -155
- package/dist/domain/script/patch/ops-asset.js.map +1 -1
- package/dist/domain/script/patch/ops-dialogue.d.ts +1 -4
- package/dist/domain/script/patch/ops-dialogue.js +43 -220
- package/dist/domain/script/patch/ops-dialogue.js.map +1 -1
- package/dist/domain/script/patch/ops-extend.js +8 -2
- package/dist/domain/script/patch/ops-extend.js.map +1 -1
- package/dist/domain/script/patch/ops-meta.js.map +1 -1
- package/dist/domain/script/patch/ops-scene.js +26 -39
- package/dist/domain/script/patch/ops-scene.js.map +1 -1
- package/dist/domain/script/patch/ops-state.d.ts +3 -3
- package/dist/domain/script/patch/ops-state.js +33 -49
- package/dist/domain/script/patch/ops-state.js.map +1 -1
- package/dist/domain/script/patch/registry.js +9 -13
- package/dist/domain/script/patch/registry.js.map +1 -1
- package/dist/domain/script/refs.js +23 -111
- package/dist/domain/script/refs.js.map +1 -1
- package/dist/domain/script/scene-refs.d.ts +3 -0
- package/dist/domain/script/scene-refs.js +35 -0
- package/dist/domain/script/scene-refs.js.map +1 -0
- package/dist/domain/script/schema.js +17 -21
- package/dist/domain/script/schema.js.map +1 -1
- package/dist/domain/script/text-util.d.ts +7 -0
- package/dist/domain/script/text-util.js +91 -0
- package/dist/domain/script/text-util.js.map +1 -0
- package/dist/help-text.js +117 -410
- package/dist/help-text.js.map +1 -1
- package/dist/infra/converters.js +1 -1
- package/dist/infra/converters.js.map +1 -1
- package/dist/infra/episode-title.d.ts +4 -0
- package/dist/infra/episode-title.js +129 -0
- package/dist/infra/episode-title.js.map +1 -0
- package/dist/infra/ingest/review-renderer.d.ts +1 -0
- package/dist/infra/ingest/review-renderer.js +431 -0
- package/dist/infra/ingest/review-renderer.js.map +1 -0
- package/dist/infra/ingest/source-resolver.d.ts +21 -0
- package/dist/infra/ingest/source-resolver.js +51 -0
- package/dist/infra/ingest/source-resolver.js.map +1 -0
- package/dist/infra/ingest/text-reader.d.ts +3 -0
- package/dist/infra/ingest/text-reader.js +27 -0
- package/dist/infra/ingest/text-reader.js.map +1 -0
- package/dist/infra/ingest/video-discovery.d.ts +8 -0
- package/dist/infra/ingest/video-discovery.js +60 -0
- package/dist/infra/ingest/video-discovery.js.map +1 -0
- package/dist/infra/ingest/workspace-store.d.ts +18 -0
- package/dist/infra/ingest/workspace-store.js +70 -0
- package/dist/infra/ingest/workspace-store.js.map +1 -0
- package/dist/infra/llm/anthropic-model.d.ts +11 -0
- package/dist/infra/llm/anthropic-model.js +109 -0
- package/dist/infra/llm/anthropic-model.js.map +1 -0
- package/dist/infra/llm/gemini-upload.d.ts +9 -0
- package/dist/infra/llm/gemini-upload.js +94 -0
- package/dist/infra/llm/gemini-upload.js.map +1 -0
- package/dist/infra/llm/gemini-video-model.d.ts +47 -0
- package/dist/infra/llm/gemini-video-model.js +167 -0
- package/dist/infra/llm/gemini-video-model.js.map +1 -0
- package/dist/infra/llm/openai-compatible-model.d.ts +13 -0
- package/dist/infra/llm/openai-compatible-model.js +143 -0
- package/dist/infra/llm/openai-compatible-model.js.map +1 -0
- package/dist/infra/llm/proxy.d.ts +1 -0
- package/dist/infra/llm/proxy.js +30 -0
- package/dist/infra/llm/proxy.js.map +1 -0
- package/dist/infra/llm/retry.d.ts +5 -0
- package/dist/infra/llm/retry.js +20 -0
- package/dist/infra/llm/retry.js.map +1 -0
- package/dist/llm/composition.d.ts +5 -0
- package/dist/llm/composition.js +5 -0
- package/dist/llm/composition.js.map +1 -0
- package/dist/llm/config.d.ts +26 -0
- package/dist/llm/config.js +201 -0
- package/dist/llm/config.js.map +1 -0
- package/dist/llm/registry.d.ts +44 -0
- package/dist/llm/registry.js +48 -0
- package/dist/llm/registry.js.map +1 -0
- package/dist/llm/router.d.ts +23 -0
- package/dist/llm/router.js +0 -0
- package/dist/llm/router.js.map +1 -0
- package/dist/llm/tasks/ingest/asset-curate.d.ts +13 -0
- package/dist/llm/tasks/ingest/asset-curate.js +45 -0
- package/dist/llm/tasks/ingest/asset-curate.js.map +1 -0
- package/dist/llm/tasks/ingest/asset-extract.d.ts +12 -0
- package/dist/llm/tasks/ingest/asset-extract.js +51 -0
- package/dist/llm/tasks/ingest/asset-extract.js.map +1 -0
- package/dist/llm/tasks/ingest/asset-govern.d.ts +22 -0
- package/dist/llm/tasks/ingest/asset-govern.js +143 -0
- package/dist/llm/tasks/ingest/asset-govern.js.map +1 -0
- package/dist/llm/tasks/ingest/mention-resolve.d.ts +9 -0
- package/dist/llm/tasks/ingest/mention-resolve.js +39 -0
- package/dist/llm/tasks/ingest/mention-resolve.js.map +1 -0
- package/dist/llm/tasks/ingest/plot-speaker.d.ts +11 -0
- package/dist/llm/tasks/ingest/plot-speaker.js +72 -0
- package/dist/llm/tasks/ingest/plot-speaker.js.map +1 -0
- package/dist/llm/tasks/ingest/roster-merge.d.ts +46 -0
- package/dist/llm/tasks/ingest/roster-merge.js +235 -0
- package/dist/llm/tasks/ingest/roster-merge.js.map +1 -0
- package/dist/llm/tasks/ingest/state-merge.d.ts +10 -0
- package/dist/llm/tasks/ingest/state-merge.js +84 -0
- package/dist/llm/tasks/ingest/state-merge.js.map +1 -0
- package/dist/llm/tasks/ingest/state-reconcile.d.ts +8 -0
- package/dist/llm/tasks/ingest/state-reconcile.js +44 -0
- package/dist/llm/tasks/ingest/state-reconcile.js.map +1 -0
- package/dist/llm/tasks/ingest/text-normalize.d.ts +10 -0
- package/dist/llm/tasks/ingest/text-normalize.js +89 -0
- package/dist/llm/tasks/ingest/text-normalize.js.map +1 -0
- package/dist/llm/tasks/ingest/video-correct.d.ts +30 -0
- package/dist/llm/tasks/ingest/video-correct.js +144 -0
- package/dist/llm/tasks/ingest/video-correct.js.map +1 -0
- package/dist/llm/tasks/ingest/video-transcribe.d.ts +4 -0
- package/dist/llm/tasks/ingest/video-transcribe.js +105 -0
- package/dist/llm/tasks/ingest/video-transcribe.js.map +1 -0
- package/dist/llm/tasks/schemas.d.ts +5 -0
- package/dist/llm/tasks/schemas.js +107 -0
- package/dist/llm/tasks/schemas.js.map +1 -0
- package/dist/llm/types.d.ts +97 -0
- package/dist/llm/types.js +13 -0
- package/dist/llm/types.js.map +1 -0
- package/dist/usecases/doctor.d.ts +1 -1
- package/dist/usecases/doctor.js +36 -9
- package/dist/usecases/doctor.js.map +1 -1
- package/dist/usecases/ingest/command.d.ts +5 -0
- package/dist/usecases/ingest/command.js +57 -0
- package/dist/usecases/ingest/command.js.map +1 -0
- package/dist/usecases/ingest/fanout.d.ts +10 -0
- package/dist/usecases/ingest/fanout.js +23 -0
- package/dist/usecases/ingest/fanout.js.map +1 -0
- package/dist/usecases/ingest/pass4-mention-resolve.d.ts +11 -0
- package/dist/usecases/ingest/pass4-mention-resolve.js +52 -0
- package/dist/usecases/ingest/pass4-mention-resolve.js.map +1 -0
- package/dist/usecases/ingest/pass5-extract.d.ts +7 -0
- package/dist/usecases/ingest/pass5-extract.js +50 -0
- package/dist/usecases/ingest/pass5-extract.js.map +1 -0
- package/dist/usecases/ingest/pass5-govern.d.ts +13 -0
- package/dist/usecases/ingest/pass5-govern.js +155 -0
- package/dist/usecases/ingest/pass5-govern.js.map +1 -0
- package/dist/usecases/ingest/pipeline.d.ts +28 -0
- package/dist/usecases/ingest/pipeline.js +144 -0
- package/dist/usecases/ingest/pipeline.js.map +1 -0
- package/dist/usecases/ingest/publish-command.d.ts +4 -0
- package/dist/usecases/ingest/publish-command.js +77 -0
- package/dist/usecases/ingest/publish-command.js.map +1 -0
- package/dist/usecases/ingest/status.d.ts +39 -0
- package/dist/usecases/ingest/status.js +155 -0
- package/dist/usecases/ingest/status.js.map +1 -0
- package/dist/usecases/ingest/video-pass3.d.ts +26 -0
- package/dist/usecases/ingest/video-pass3.js +0 -0
- package/dist/usecases/ingest/video-pass3.js.map +1 -0
- package/dist/usecases/ingest/video-pipeline.d.ts +32 -0
- package/dist/usecases/ingest/video-pipeline.js +202 -0
- package/dist/usecases/ingest/video-pipeline.js.map +1 -0
- package/dist/usecases/ingest/view-command.d.ts +4 -0
- package/dist/usecases/ingest/view-command.js +51 -0
- package/dist/usecases/ingest/view-command.js.map +1 -0
- package/dist/usecases/script/actions.js +2 -2
- package/dist/usecases/script/actions.js.map +1 -1
- package/dist/usecases/script/actor.js.map +1 -1
- package/dist/usecases/script/actors.js.map +1 -1
- package/dist/usecases/script/add-actor.js.map +1 -1
- package/dist/usecases/script/add-episode.js.map +1 -1
- package/dist/usecases/script/add-location.js.map +1 -1
- package/dist/usecases/script/add-prop.js.map +1 -1
- package/dist/usecases/script/alias.js.map +1 -1
- package/dist/usecases/script/assets.js.map +1 -1
- package/dist/usecases/script/context.js.map +1 -1
- package/dist/usecases/script/create.js +3 -6
- package/dist/usecases/script/create.js.map +1 -1
- package/dist/usecases/script/delete.js.map +1 -1
- package/dist/usecases/script/describe.js.map +1 -1
- package/dist/usecases/script/dialogue.js +6 -13
- package/dist/usecases/script/dialogue.js.map +1 -1
- package/dist/usecases/script/do.js +1 -1
- package/dist/usecases/script/do.js.map +1 -1
- package/dist/usecases/script/episodes.js.map +1 -1
- package/dist/usecases/script/{add-speaker.d.ts → importance.d.ts} +1 -1
- package/dist/usecases/script/importance.js +17 -0
- package/dist/usecases/script/importance.js.map +1 -0
- package/dist/usecases/script/insert.js.map +1 -1
- package/dist/usecases/script/issues.js.map +1 -1
- package/dist/usecases/script/lib.d.ts +8 -6
- package/dist/usecases/script/lib.js +81 -97
- package/dist/usecases/script/lib.js.map +1 -1
- package/dist/usecases/script/locations.js.map +1 -1
- package/dist/usecases/script/merge.js.map +1 -1
- package/dist/usecases/script/move.js.map +1 -1
- package/dist/usecases/script/props.js.map +1 -1
- package/dist/usecases/script/refs.js.map +1 -1
- package/dist/usecases/script/rename.js.map +1 -1
- package/dist/usecases/script/replace.js.map +1 -1
- package/dist/usecases/script/role.js.map +1 -1
- package/dist/usecases/script/scenes.js +8 -15
- package/dist/usecases/script/scenes.js.map +1 -1
- package/dist/usecases/script/script-patch.js +1 -1
- package/dist/usecases/script/script-patch.js.map +1 -1
- package/dist/usecases/script/script-validate.js +1 -1
- package/dist/usecases/script/script-validate.js.map +1 -1
- package/dist/usecases/script/session.d.ts +4 -4
- package/dist/usecases/script/session.js +57 -78
- package/dist/usecases/script/session.js.map +1 -1
- package/dist/usecases/script/split.js.map +1 -1
- package/dist/usecases/script/state-add.js.map +1 -1
- package/dist/usecases/script/state-delete.js.map +1 -1
- package/dist/usecases/script/state-rename.js.map +1 -1
- package/dist/usecases/script/summary.js.map +1 -1
- package/dist/usecases/script/synopsis-generate.d.ts +4 -5
- package/dist/usecases/script/synopsis-generate.js +30 -46
- package/dist/usecases/script/synopsis-generate.js.map +1 -1
- package/dist/usecases/script/transition.js.map +1 -1
- package/dist/usecases/script/type.js.map +1 -1
- package/dist/usecases/script/worldview.js.map +1 -1
- package/package.json +22 -17
- package/skills/scriptctl/SKILL.md +140 -120
- package/skills/scriptctl/references/atomic-write-workflow.md +12 -9
- package/skills/scriptctl/references/ingest-workflow.md +85 -0
- package/skills/scriptctl/references/state-reference-repair.md +26 -39
- package/dist/domain/direct/runner.d.ts +0 -25
- package/dist/domain/direct/runner.js +0 -88
- package/dist/domain/direct/runner.js.map +0 -1
- package/dist/domain/direct/stage.d.ts +0 -108
- package/dist/domain/direct/stage.js +0 -134
- package/dist/domain/direct/stage.js.map +0 -1
- package/dist/domain/direct/stages/asset-curation.d.ts +0 -2
- package/dist/domain/direct/stages/asset-curation.js +0 -10
- package/dist/domain/direct/stages/asset-curation.js.map +0 -1
- package/dist/domain/direct/stages/batch-extract.d.ts +0 -2
- package/dist/domain/direct/stages/batch-extract.js +0 -12
- package/dist/domain/direct/stages/batch-extract.js.map +0 -1
- package/dist/domain/direct/stages/batch-plan.d.ts +0 -2
- package/dist/domain/direct/stages/batch-plan.js +0 -9
- package/dist/domain/direct/stages/batch-plan.js.map +0 -1
- package/dist/domain/direct/stages/episode-merge.d.ts +0 -2
- package/dist/domain/direct/stages/episode-merge.js +0 -11
- package/dist/domain/direct/stages/episode-merge.js.map +0 -1
- package/dist/domain/direct/stages/episode-plan.d.ts +0 -2
- package/dist/domain/direct/stages/episode-plan.js +0 -9
- package/dist/domain/direct/stages/episode-plan.js.map +0 -1
- package/dist/domain/direct/stages/episode-synopsis.d.ts +0 -2
- package/dist/domain/direct/stages/episode-synopsis.js +0 -12
- package/dist/domain/direct/stages/episode-synopsis.js.map +0 -1
- package/dist/domain/direct/stages/episode-titles.d.ts +0 -2
- package/dist/domain/direct/stages/episode-titles.js +0 -12
- package/dist/domain/direct/stages/episode-titles.js.map +0 -1
- package/dist/domain/direct/stages/index.d.ts +0 -19
- package/dist/domain/direct/stages/index.js +0 -41
- package/dist/domain/direct/stages/index.js.map +0 -1
- package/dist/domain/direct/stages/metadata.d.ts +0 -2
- package/dist/domain/direct/stages/metadata.js +0 -11
- package/dist/domain/direct/stages/metadata.js.map +0 -1
- package/dist/domain/direct/stages/script-merge.d.ts +0 -2
- package/dist/domain/direct/stages/script-merge.js +0 -15
- package/dist/domain/direct/stages/script-merge.js.map +0 -1
- package/dist/domain/direct/stages/script-synopsis.d.ts +0 -2
- package/dist/domain/direct/stages/script-synopsis.js +0 -12
- package/dist/domain/direct/stages/script-synopsis.js.map +0 -1
- package/dist/domain/direct/stages/source-prepare.d.ts +0 -2
- package/dist/domain/direct/stages/source-prepare.js +0 -9
- package/dist/domain/direct/stages/source-prepare.js.map +0 -1
- package/dist/domain/direct/stages/state-binding.d.ts +0 -2
- package/dist/domain/direct/stages/state-binding.js +0 -9
- package/dist/domain/direct/stages/state-binding.js.map +0 -1
- package/dist/domain/direct/stages/state-curation.d.ts +0 -2
- package/dist/domain/direct/stages/state-curation.js +0 -10
- package/dist/domain/direct/stages/state-curation.js.map +0 -1
- package/dist/domain/direct/stages/validate.d.ts +0 -2
- package/dist/domain/direct/stages/validate.js +0 -10
- package/dist/domain/direct/stages/validate.js.map +0 -1
- package/dist/domain/direct-core.d.ts +0 -313
- package/dist/domain/direct-core.js +0 -8514
- package/dist/domain/direct-core.js.map +0 -1
- package/dist/domain/script/validate.d.ts +0 -22
- package/dist/domain/script/validate.js +0 -997
- package/dist/domain/script/validate.js.map +0 -1
- package/dist/infra/providers.d.ts +0 -97
- package/dist/infra/providers.js +0 -1396
- package/dist/infra/providers.js.map +0 -1
- package/dist/usecases/direct.d.ts +0 -27
- package/dist/usecases/direct.js +0 -4172
- package/dist/usecases/direct.js.map +0 -1
- package/dist/usecases/parse.d.ts +0 -15
- package/dist/usecases/parse.js +0 -429
- package/dist/usecases/parse.js.map +0 -1
- package/dist/usecases/script/add-speaker.js +0 -22
- package/dist/usecases/script/add-speaker.js.map +0 -1
- package/dist/usecases/script/export.d.ts +0 -3
- package/dist/usecases/script/export.js +0 -111
- package/dist/usecases/script/export.js.map +0 -1
- package/dist/usecases/script/overlap.d.ts +0 -3
- package/dist/usecases/script/overlap.js +0 -21
- package/dist/usecases/script/overlap.js.map +0 -1
- package/dist/usecases/script/speakers.d.ts +0 -3
- package/dist/usecases/script/speakers.js +0 -28
- package/dist/usecases/script/speakers.js.map +0 -1
- package/dist/usecases/script/state-change.d.ts +0 -3
- package/dist/usecases/script/state-change.js +0 -24
- package/dist/usecases/script/state-change.js.map +0 -1
- package/skills/scriptctl/references/direct-workflow.md +0 -72
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
// Strict JSONL → typed record parser (§7). Rejects unknown fields, malformed
|
|
2
|
+
// records, missing/invalid source spans, and inline-tag syntax errors. Never
|
|
3
|
+
// repairs or downgrades: a bad line fails the batch (§12.3).
|
|
4
|
+
import { NON_ACTOR_SPEAKER_KINDS, RECORD_KINDS, } from "./records.js";
|
|
5
|
+
export class JsonlParseError extends Error {
|
|
6
|
+
line;
|
|
7
|
+
constructor(message, line) {
|
|
8
|
+
super(`line ${line}: ${message}`);
|
|
9
|
+
this.line = line;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
function isObj(v) {
|
|
13
|
+
return typeof v === "object" && v !== null && !Array.isArray(v);
|
|
14
|
+
}
|
|
15
|
+
function requireKeys(obj, allowed, line) {
|
|
16
|
+
for (const key of Object.keys(obj)) {
|
|
17
|
+
if (!allowed.includes(key))
|
|
18
|
+
throw new JsonlParseError(`unknown field '${key}'`, line);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
function parseSource(v, line) {
|
|
22
|
+
if (!isObj(v))
|
|
23
|
+
throw new JsonlParseError("missing source", line);
|
|
24
|
+
requireKeys(v, ["chunk", "line_start", "line_end"], line);
|
|
25
|
+
const { chunk, line_start, line_end } = v;
|
|
26
|
+
if (![chunk, line_start, line_end].every((n) => typeof n === "number" && Number.isInteger(n) && n >= 0)) {
|
|
27
|
+
throw new JsonlParseError("source needs integer chunk/line_start/line_end", line);
|
|
28
|
+
}
|
|
29
|
+
if (line_start >= line_end)
|
|
30
|
+
throw new JsonlParseError("source line_start must be < line_end", line);
|
|
31
|
+
return { chunk: chunk, line_start: line_start, line_end: line_end };
|
|
32
|
+
}
|
|
33
|
+
function str(obj, key, line) {
|
|
34
|
+
const v = obj[key];
|
|
35
|
+
if (typeof v !== "string" || v === "")
|
|
36
|
+
throw new JsonlParseError(`'${key}' must be a non-empty string`, line);
|
|
37
|
+
return v;
|
|
38
|
+
}
|
|
39
|
+
function optStr(obj, key, line) {
|
|
40
|
+
if (!(key in obj) || obj[key] === undefined)
|
|
41
|
+
return undefined;
|
|
42
|
+
const v = obj[key];
|
|
43
|
+
if (typeof v !== "string" || v === "")
|
|
44
|
+
throw new JsonlParseError(`'${key}' must be a non-empty string`, line);
|
|
45
|
+
return v;
|
|
46
|
+
}
|
|
47
|
+
function parseEntityRefs(v, key, line) {
|
|
48
|
+
if (!Array.isArray(v))
|
|
49
|
+
throw new JsonlParseError(`'${key}' must be an array`, line);
|
|
50
|
+
return v.map((item) => {
|
|
51
|
+
if (!isObj(item))
|
|
52
|
+
throw new JsonlParseError(`'${key}' entries must be objects`, line);
|
|
53
|
+
requireKeys(item, ["name", "state"], line);
|
|
54
|
+
const ref = { name: str(item, "name", line) };
|
|
55
|
+
const state = optStr(item, "state", line);
|
|
56
|
+
if (state !== undefined)
|
|
57
|
+
ref.state = state;
|
|
58
|
+
return ref;
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
function parseSpeaker(v, line) {
|
|
62
|
+
if (!isObj(v))
|
|
63
|
+
throw new JsonlParseError("dialogue/inner_thought needs a speaker", line);
|
|
64
|
+
if ("kind" in v) {
|
|
65
|
+
requireKeys(v, ["kind", "label"], line);
|
|
66
|
+
const kind = v.kind;
|
|
67
|
+
if (typeof kind !== "string" || !NON_ACTOR_SPEAKER_KINDS.includes(kind)) {
|
|
68
|
+
throw new JsonlParseError(`speaker.kind must be one of ${NON_ACTOR_SPEAKER_KINDS.join("|")}`, line);
|
|
69
|
+
}
|
|
70
|
+
const ref = { kind: kind };
|
|
71
|
+
const label = optStr(v, "label", line);
|
|
72
|
+
if (label !== undefined)
|
|
73
|
+
ref.label = label;
|
|
74
|
+
return ref;
|
|
75
|
+
}
|
|
76
|
+
requireKeys(v, ["name", "state"], line);
|
|
77
|
+
const ref = { name: str(v, "name", line) };
|
|
78
|
+
const state = optStr(v, "state", line);
|
|
79
|
+
if (state !== undefined)
|
|
80
|
+
ref.state = state;
|
|
81
|
+
return ref;
|
|
82
|
+
}
|
|
83
|
+
function parseRecord(obj, line) {
|
|
84
|
+
const kind = obj.kind;
|
|
85
|
+
if (typeof kind !== "string" || !RECORD_KINDS.includes(kind)) {
|
|
86
|
+
throw new JsonlParseError(`unknown or missing kind '${String(kind)}'`, line);
|
|
87
|
+
}
|
|
88
|
+
const source = parseSource(obj.source, line);
|
|
89
|
+
switch (kind) {
|
|
90
|
+
case "episode": {
|
|
91
|
+
requireKeys(obj, ["kind", "episode", "title", "source"], line);
|
|
92
|
+
const episode = obj.episode;
|
|
93
|
+
if (typeof episode !== "number" || !Number.isInteger(episode))
|
|
94
|
+
throw new JsonlParseError("episode must be an integer", line);
|
|
95
|
+
const rec = { kind, episode, source };
|
|
96
|
+
const title = optStr(obj, "title", line);
|
|
97
|
+
if (title !== undefined)
|
|
98
|
+
rec.title = title;
|
|
99
|
+
return rec;
|
|
100
|
+
}
|
|
101
|
+
case "scene": {
|
|
102
|
+
requireKeys(obj, ["kind", "scene", "environment", "location", "actors", "props", "source"], line);
|
|
103
|
+
const rec = { kind, source };
|
|
104
|
+
if ("scene" in obj && obj.scene !== undefined) {
|
|
105
|
+
if (typeof obj.scene !== "number" || !Number.isInteger(obj.scene))
|
|
106
|
+
throw new JsonlParseError("scene must be an integer", line);
|
|
107
|
+
rec.scene = obj.scene;
|
|
108
|
+
}
|
|
109
|
+
if ("environment" in obj && obj.environment !== undefined) {
|
|
110
|
+
if (!isObj(obj.environment))
|
|
111
|
+
throw new JsonlParseError("environment must be an object", line);
|
|
112
|
+
requireKeys(obj.environment, ["space", "time"], line);
|
|
113
|
+
rec.environment = obj.environment;
|
|
114
|
+
}
|
|
115
|
+
if ("location" in obj && obj.location !== undefined) {
|
|
116
|
+
if (!isObj(obj.location))
|
|
117
|
+
throw new JsonlParseError("location must be an object", line);
|
|
118
|
+
requireKeys(obj.location, ["name", "state"], line);
|
|
119
|
+
const loc = { name: str(obj.location, "name", line) };
|
|
120
|
+
const st = optStr(obj.location, "state", line);
|
|
121
|
+
if (st !== undefined)
|
|
122
|
+
loc.state = st;
|
|
123
|
+
rec.location = loc;
|
|
124
|
+
}
|
|
125
|
+
if ("actors" in obj && obj.actors !== undefined)
|
|
126
|
+
rec.actors = parseEntityRefs(obj.actors, "actors", line);
|
|
127
|
+
if ("props" in obj && obj.props !== undefined)
|
|
128
|
+
rec.props = parseEntityRefs(obj.props, "props", line);
|
|
129
|
+
return rec;
|
|
130
|
+
}
|
|
131
|
+
case "action":
|
|
132
|
+
case "transition": {
|
|
133
|
+
requireKeys(obj, ["kind", "content", "source"], line);
|
|
134
|
+
const content = str(obj, "content", line);
|
|
135
|
+
return { kind, content, source };
|
|
136
|
+
}
|
|
137
|
+
case "dialogue":
|
|
138
|
+
case "inner_thought": {
|
|
139
|
+
requireKeys(obj, ["kind", "speaker", "content", "emotion", "source"], line);
|
|
140
|
+
const content = str(obj, "content", line);
|
|
141
|
+
const speaker = parseSpeaker(obj.speaker, line);
|
|
142
|
+
const rec = { kind, speaker, content, source };
|
|
143
|
+
const emotion = optStr(obj, "emotion", line);
|
|
144
|
+
if (emotion !== undefined)
|
|
145
|
+
rec.emotion = emotion;
|
|
146
|
+
return rec;
|
|
147
|
+
}
|
|
148
|
+
case "note": {
|
|
149
|
+
requireKeys(obj, ["kind", "content", "category", "source"], line);
|
|
150
|
+
const content = str(obj, "content", line);
|
|
151
|
+
const rec = { kind, content, source };
|
|
152
|
+
if ("category" in obj && obj.category !== undefined) {
|
|
153
|
+
const cat = obj.category;
|
|
154
|
+
if (cat !== "author_note" && cat !== "format_note" && cat !== "unclassified") {
|
|
155
|
+
throw new JsonlParseError("note.category must be author_note|format_note|unclassified", line);
|
|
156
|
+
}
|
|
157
|
+
rec.category = cat;
|
|
158
|
+
}
|
|
159
|
+
return rec;
|
|
160
|
+
}
|
|
161
|
+
default:
|
|
162
|
+
throw new JsonlParseError(`unhandled kind '${kind}'`, line);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
// Parse full JSONL text. Blank lines are skipped; every other line must be a
|
|
166
|
+
// valid record. `lineOffset` lets callers report absolute file lines.
|
|
167
|
+
export function parseJsonl(text, lineOffset = 0) {
|
|
168
|
+
const out = [];
|
|
169
|
+
const lines = text.split("\n");
|
|
170
|
+
for (let i = 0; i < lines.length; i++) {
|
|
171
|
+
const raw = lines[i].trim();
|
|
172
|
+
if (raw === "")
|
|
173
|
+
continue;
|
|
174
|
+
let parsed;
|
|
175
|
+
try {
|
|
176
|
+
parsed = JSON.parse(raw);
|
|
177
|
+
}
|
|
178
|
+
catch {
|
|
179
|
+
throw new JsonlParseError("invalid JSON", i + 1 + lineOffset);
|
|
180
|
+
}
|
|
181
|
+
if (!isObj(parsed))
|
|
182
|
+
throw new JsonlParseError("record must be a JSON object", i + 1 + lineOffset);
|
|
183
|
+
out.push(parseRecord(parsed, i + 1 + lineOffset));
|
|
184
|
+
}
|
|
185
|
+
return out;
|
|
186
|
+
}
|
|
187
|
+
//# sourceMappingURL=jsonl-parser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jsonl-parser.js","sourceRoot":"","sources":["../../../src/domain/ingest/jsonl-parser.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { Chunk } from "./chunker.js";
|
|
2
|
+
import { type IngestRecord, type NameStateRef } from "./records.js";
|
|
3
|
+
export declare class MarkdownParseError extends Error {
|
|
4
|
+
}
|
|
5
|
+
export declare function parseEntityList(raw: string): NameStateRef[];
|
|
6
|
+
export declare function parseNormalizeMarkdown(md: string, chunk: Chunk): IngestRecord[];
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
// Deterministic normalize-markdown → records parser (§pass2). The cheap model
|
|
2
|
+
// rewrites one source chunk as a lean plain-text screenplay markdown
|
|
3
|
+
// (episode/scene headers + `- 时空/地点/人物/道具` scene bullets + `> [anchor]
|
|
4
|
+
// body` lines). Bodies are PLAIN TEXT — no inline entity tags. Scene cast/props
|
|
5
|
+
// declared via `- 人物`/`- 道具` are captured onto the scene record; entity
|
|
6
|
+
// binding is done later by pass5-extract. Source is chunk-granular.
|
|
7
|
+
import { NON_ACTOR_SPEAKER_KINDS, } from "./records.js";
|
|
8
|
+
export class MarkdownParseError extends Error {
|
|
9
|
+
}
|
|
10
|
+
const EP_RE = /^#\s*第?\s*(\d+)\s*集?\s*(.*)$/;
|
|
11
|
+
const SCENE_LABEL_RE = /^##\s*(.*)$/;
|
|
12
|
+
const ENV_RE = /^-\s*时空\s*[::]\s*(.*)$/;
|
|
13
|
+
const LOC_RE = /^-\s*地点\s*[::]\s*(.*)$/;
|
|
14
|
+
const CAST_RE = /^-\s*人物\s*[::]\s*(.*)$/;
|
|
15
|
+
const PROP_RE = /^-\s*道具\s*[::]\s*(.*)$/;
|
|
16
|
+
// dialogue/inner_thought/transition/note carry a `[label]`; everything else is
|
|
17
|
+
// a bare action line. `> ` and `[act]` are accepted but not required.
|
|
18
|
+
const ANCHOR_RE = /^(?:>\s*)?\[([^\]]*)\]\s?([\s\S]*)$/;
|
|
19
|
+
const KNOWN_LABELS = new Set(["act", "dlg", "think", "trans", "note"]);
|
|
20
|
+
const SPACE_MAP = { "内": "interior", "外": "exterior" };
|
|
21
|
+
const TIME_MAP = { "日": "day", "夜": "night" };
|
|
22
|
+
// Split a declared cast/prop list on top-level separators, keeping 【…】 (which
|
|
23
|
+
// may itself contain commas) intact, then split each item into name + 【state】.
|
|
24
|
+
export function parseEntityList(raw) {
|
|
25
|
+
const items = [];
|
|
26
|
+
let depth = 0;
|
|
27
|
+
let buf = "";
|
|
28
|
+
for (const ch of raw) {
|
|
29
|
+
if (ch === "【")
|
|
30
|
+
depth++;
|
|
31
|
+
else if (ch === "】")
|
|
32
|
+
depth = Math.max(0, depth - 1);
|
|
33
|
+
if ((ch === "," || ch === "," || ch === "、") && depth === 0) {
|
|
34
|
+
if (buf.trim())
|
|
35
|
+
items.push(buf.trim());
|
|
36
|
+
buf = "";
|
|
37
|
+
continue;
|
|
38
|
+
}
|
|
39
|
+
buf += ch;
|
|
40
|
+
}
|
|
41
|
+
if (buf.trim())
|
|
42
|
+
items.push(buf.trim());
|
|
43
|
+
const refs = [];
|
|
44
|
+
for (const item of items) {
|
|
45
|
+
const m = /^([^【]+?)\s*(?:【(.+)】)?\s*$/.exec(item);
|
|
46
|
+
if (!m)
|
|
47
|
+
continue;
|
|
48
|
+
const name = m[1].trim();
|
|
49
|
+
if (!name)
|
|
50
|
+
continue;
|
|
51
|
+
const state = m[2]?.trim();
|
|
52
|
+
refs.push(state ? { name, state } : { name });
|
|
53
|
+
}
|
|
54
|
+
return refs;
|
|
55
|
+
}
|
|
56
|
+
function parseSpeaker(field) {
|
|
57
|
+
const trimmed = field.trim();
|
|
58
|
+
const colon = trimmed.indexOf(":");
|
|
59
|
+
if (colon > 0) {
|
|
60
|
+
const kind = trimmed.slice(0, colon).trim();
|
|
61
|
+
if (NON_ACTOR_SPEAKER_KINDS.includes(kind)) {
|
|
62
|
+
const label = trimmed.slice(colon + 1).trim();
|
|
63
|
+
return label ? { kind: kind, label } : { kind: kind };
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
// A bare kind word (`group` / `system` / …) with no label is that kind, not a
|
|
67
|
+
// person named "group".
|
|
68
|
+
if (NON_ACTOR_SPEAKER_KINDS.includes(trimmed))
|
|
69
|
+
return { kind: trimmed };
|
|
70
|
+
if (!trimmed)
|
|
71
|
+
throw new MarkdownParseError("dialogue anchor missing speaker");
|
|
72
|
+
return { name: trimmed };
|
|
73
|
+
}
|
|
74
|
+
// A dialogue/inner_thought anchor may pack several simultaneous speakers
|
|
75
|
+
// (`李叔,张妈`). Split on punctuation separators only (NOT 和, which can appear
|
|
76
|
+
// inside a name); each becomes its own record with the same content.
|
|
77
|
+
function parseSpeakers(field) {
|
|
78
|
+
const parts = field.split(/[,,、;;/]/).map((s) => s.trim()).filter(Boolean);
|
|
79
|
+
if (parts.length <= 1)
|
|
80
|
+
return [parseSpeaker(field)];
|
|
81
|
+
return parts.map(parseSpeaker);
|
|
82
|
+
}
|
|
83
|
+
const NOTE_CATEGORY = { author: "author_note", format: "format_note" };
|
|
84
|
+
function anchorRecords(label, body, source) {
|
|
85
|
+
const content = body.trim();
|
|
86
|
+
const parts = label.split("|");
|
|
87
|
+
const kind = parts[0].trim();
|
|
88
|
+
switch (kind) {
|
|
89
|
+
case "act":
|
|
90
|
+
return [{ kind: "action", content, source }];
|
|
91
|
+
case "trans":
|
|
92
|
+
return [{ kind: "transition", content, source }];
|
|
93
|
+
case "dlg":
|
|
94
|
+
case "think": {
|
|
95
|
+
const emotion = parts[2]?.trim();
|
|
96
|
+
// Simultaneous speakers → one record each, same content (overlap 拆多条).
|
|
97
|
+
return parseSpeakers(parts[1] ?? "").map((speaker) => {
|
|
98
|
+
const rec = { kind: kind === "dlg" ? "dialogue" : "inner_thought", speaker, content, source };
|
|
99
|
+
if (emotion)
|
|
100
|
+
rec.emotion = emotion;
|
|
101
|
+
return rec;
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
case "note":
|
|
105
|
+
return [{ kind: "note", content, category: NOTE_CATEGORY[(parts[1] ?? "").trim()] ?? "unclassified", source }];
|
|
106
|
+
default:
|
|
107
|
+
throw new MarkdownParseError(`unknown anchor label '[${label}]'`);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
export function parseNormalizeMarkdown(md, chunk) {
|
|
111
|
+
const source = { chunk: chunk.index, line_start: chunk.core_line_start, line_end: chunk.core_line_end };
|
|
112
|
+
const records = [];
|
|
113
|
+
const lines = stripFences(md).split("\n");
|
|
114
|
+
let openScene = null;
|
|
115
|
+
for (const raw of lines) {
|
|
116
|
+
const t = raw.trim();
|
|
117
|
+
if (t === "")
|
|
118
|
+
continue;
|
|
119
|
+
if (t.startsWith("##")) {
|
|
120
|
+
const rec = { kind: "scene", source };
|
|
121
|
+
const num = /(\d+)/.exec(SCENE_LABEL_RE.exec(t)?.[1]?.trim() ?? "")?.[1];
|
|
122
|
+
if (num)
|
|
123
|
+
rec.scene = Number(num);
|
|
124
|
+
records.push(rec);
|
|
125
|
+
openScene = rec;
|
|
126
|
+
continue;
|
|
127
|
+
}
|
|
128
|
+
if (t.startsWith("#")) {
|
|
129
|
+
const ep = EP_RE.exec(t);
|
|
130
|
+
if (ep) {
|
|
131
|
+
const title = ep[2].trim();
|
|
132
|
+
const rec = { kind: "episode", episode: Number(ep[1]), source };
|
|
133
|
+
if (title)
|
|
134
|
+
rec.title = title;
|
|
135
|
+
records.push(rec);
|
|
136
|
+
}
|
|
137
|
+
continue;
|
|
138
|
+
}
|
|
139
|
+
// `- …` scene metadata bullet (only meaningful while a scene is open).
|
|
140
|
+
if (t.startsWith("-")) {
|
|
141
|
+
if (openScene) {
|
|
142
|
+
const env = ENV_RE.exec(t);
|
|
143
|
+
if (env) {
|
|
144
|
+
const e = {};
|
|
145
|
+
for (const tok of env[1].trim().split(/\s+/)) {
|
|
146
|
+
if (SPACE_MAP[tok])
|
|
147
|
+
e.space = SPACE_MAP[tok];
|
|
148
|
+
if (TIME_MAP[tok])
|
|
149
|
+
e.time = TIME_MAP[tok];
|
|
150
|
+
}
|
|
151
|
+
if (e.space || e.time)
|
|
152
|
+
openScene.environment = e;
|
|
153
|
+
}
|
|
154
|
+
else {
|
|
155
|
+
const loc = LOC_RE.exec(t);
|
|
156
|
+
const cast = CAST_RE.exec(t);
|
|
157
|
+
const prop = PROP_RE.exec(t);
|
|
158
|
+
if (loc && loc[1].trim()) {
|
|
159
|
+
const [name, state] = loc[1].split("|");
|
|
160
|
+
openScene.location = state ? { name: name.trim(), state: state.trim() } : { name: name.trim() };
|
|
161
|
+
}
|
|
162
|
+
else if (cast && cast[1].trim())
|
|
163
|
+
openScene.actors = parseEntityList(cast[1]);
|
|
164
|
+
else if (prop && prop[1].trim())
|
|
165
|
+
openScene.props = parseEntityList(prop[1]);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
continue;
|
|
169
|
+
}
|
|
170
|
+
// A `[dlg|…]`/`[think|…]`/`[trans]`/`[note]`/`[act]` anchor, else a bare
|
|
171
|
+
// action line (content = the whole line).
|
|
172
|
+
const anchor = ANCHOR_RE.exec(t);
|
|
173
|
+
if (anchor && KNOWN_LABELS.has(anchor[1].split("|")[0].trim()))
|
|
174
|
+
records.push(...anchorRecords(anchor[1], anchor[2] ?? "", source));
|
|
175
|
+
else
|
|
176
|
+
records.push({ kind: "action", content: t, source });
|
|
177
|
+
}
|
|
178
|
+
const BODY = new Set(["action", "dialogue", "inner_thought", "transition", "note"]);
|
|
179
|
+
return records.filter((r) => !(BODY.has(r.kind) && "content" in r && r.content.trim() === ""));
|
|
180
|
+
}
|
|
181
|
+
function stripFences(raw) {
|
|
182
|
+
const trimmed = raw.trim();
|
|
183
|
+
const fence = trimmed.match(/^```(?:markdown|md)?\n([\s\S]*?)\n```$/);
|
|
184
|
+
return fence ? fence[1] : trimmed;
|
|
185
|
+
}
|
|
186
|
+
//# sourceMappingURL=markdown-parser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"markdown-parser.js","sourceRoot":"","sources":["../../../src/domain/ingest/markdown-parser.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
export type SourceSpan = {
|
|
2
|
+
chunk: number;
|
|
3
|
+
line_start: number;
|
|
4
|
+
line_end: number;
|
|
5
|
+
};
|
|
6
|
+
export type NameStateRef = {
|
|
7
|
+
name: string;
|
|
8
|
+
state?: string;
|
|
9
|
+
};
|
|
10
|
+
export type SpeakerRef = {
|
|
11
|
+
name: string;
|
|
12
|
+
state?: string;
|
|
13
|
+
} | {
|
|
14
|
+
kind: "system" | "broadcast" | "offscreen" | "group";
|
|
15
|
+
label?: string;
|
|
16
|
+
};
|
|
17
|
+
export declare const NON_ACTOR_SPEAKER_KINDS: readonly ["system", "broadcast", "offscreen", "group"];
|
|
18
|
+
export type EpisodeRecord = {
|
|
19
|
+
kind: "episode";
|
|
20
|
+
episode: number;
|
|
21
|
+
title?: string;
|
|
22
|
+
source: SourceSpan;
|
|
23
|
+
};
|
|
24
|
+
export type SceneRecord = {
|
|
25
|
+
kind: "scene";
|
|
26
|
+
scene?: number;
|
|
27
|
+
environment?: {
|
|
28
|
+
space?: string;
|
|
29
|
+
time?: string;
|
|
30
|
+
};
|
|
31
|
+
location?: {
|
|
32
|
+
name: string;
|
|
33
|
+
state?: string;
|
|
34
|
+
};
|
|
35
|
+
actors?: NameStateRef[];
|
|
36
|
+
props?: NameStateRef[];
|
|
37
|
+
source: SourceSpan;
|
|
38
|
+
};
|
|
39
|
+
export type ActionRecord = {
|
|
40
|
+
kind: "action";
|
|
41
|
+
content: string;
|
|
42
|
+
source: SourceSpan;
|
|
43
|
+
};
|
|
44
|
+
export type DialogueRecord = {
|
|
45
|
+
kind: "dialogue";
|
|
46
|
+
speaker: SpeakerRef;
|
|
47
|
+
content: string;
|
|
48
|
+
emotion?: string;
|
|
49
|
+
source: SourceSpan;
|
|
50
|
+
};
|
|
51
|
+
export type InnerThoughtRecord = {
|
|
52
|
+
kind: "inner_thought";
|
|
53
|
+
speaker: SpeakerRef;
|
|
54
|
+
content: string;
|
|
55
|
+
emotion?: string;
|
|
56
|
+
source: SourceSpan;
|
|
57
|
+
};
|
|
58
|
+
export type TransitionRecord = {
|
|
59
|
+
kind: "transition";
|
|
60
|
+
content: string;
|
|
61
|
+
source: SourceSpan;
|
|
62
|
+
};
|
|
63
|
+
export type NoteRecord = {
|
|
64
|
+
kind: "note";
|
|
65
|
+
content: string;
|
|
66
|
+
category?: "author_note" | "format_note" | "unclassified";
|
|
67
|
+
source: SourceSpan;
|
|
68
|
+
};
|
|
69
|
+
export type IngestRecord = EpisodeRecord | SceneRecord | ActionRecord | DialogueRecord | InnerThoughtRecord | TransitionRecord | NoteRecord;
|
|
70
|
+
export declare const RECORD_KINDS: readonly ["episode", "scene", "action", "dialogue", "inner_thought", "transition", "note"];
|
|
71
|
+
export type RecordKind = (typeof RECORD_KINDS)[number];
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
// Typed JSONL record shapes for the ingest pipeline (§7). Records are name-based
|
|
2
|
+
// and pre-canonicalization; Pass5 assigns final ids. Content is plain text (no
|
|
3
|
+
// inline entity tags); scene-level cast/props are declared on the scene record
|
|
4
|
+
// (from source `人物:`/`道具:` lines) and augmented by the extract pass.
|
|
5
|
+
// Non-actor speaker kinds. Bit-part characters (龙套) are still actors (tagged
|
|
6
|
+
// importance=background), so they speak via actor_id — no special speaker kind.
|
|
7
|
+
export const NON_ACTOR_SPEAKER_KINDS = ["system", "broadcast", "offscreen", "group"];
|
|
8
|
+
export const RECORD_KINDS = ["episode", "scene", "action", "dialogue", "inner_thought", "transition", "note"];
|
|
9
|
+
//# sourceMappingURL=records.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"records.js","sourceRoot":"","sources":["../../../src/domain/ingest/records.ts"],"names":[],"mappings":"AAAA,iFAAiF;AACjF,+EAA+E;AAC/E,+EAA+E;AAC/E,qEAAqE;AAWrE,6EAA6E;AAC7E,gFAAgF;AAChF,MAAM,CAAC,MAAM,uBAAuB,GAAG,CAAC,QAAQ,EAAE,WAAW,EAAE,WAAW,EAAE,OAAO,CAAU,CAAC;AA2B9F,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,SAAS,EAAE,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,CAAU,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
type Obj = Record<string, unknown>;
|
|
2
|
+
export type IdMap = {
|
|
3
|
+
episodes: Record<string, string>;
|
|
4
|
+
scenes: Record<string, string>;
|
|
5
|
+
actors: Record<string, string>;
|
|
6
|
+
locations: Record<string, string>;
|
|
7
|
+
props: Record<string, string>;
|
|
8
|
+
states: Record<string, string>;
|
|
9
|
+
};
|
|
10
|
+
export declare function renumberIds(input: unknown): {
|
|
11
|
+
script: Obj;
|
|
12
|
+
idMap: IdMap;
|
|
13
|
+
};
|
|
14
|
+
export {};
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
// Deterministic final id renumbering (§ ids). Governance leaves survivor ids
|
|
2
|
+
// with gaps (merges/…) and globally-unique state ids; this one-time pass, run at
|
|
3
|
+
// the very end of ingest, renumbers everything to clean, contiguous, readable
|
|
4
|
+
// ids and rewrites all references. ids are opaque stable keys — this is only the
|
|
5
|
+
// clean initial numbering for the freshly-generated product (editing never
|
|
6
|
+
// renumbers). Pure: input never mutated; returns the doc + old→new id map.
|
|
7
|
+
//
|
|
8
|
+
// episode ep_NNN by episodes[] order
|
|
9
|
+
// scene scn_NNN global, by appearance order (scenes can move across eps)
|
|
10
|
+
// actor act_NNN by first appearance in the script (per kind, contiguous)
|
|
11
|
+
// location loc_NNN
|
|
12
|
+
// prop prp_NNN
|
|
13
|
+
// state default + st_NNN per-asset scoped (default kept)
|
|
14
|
+
const isObj = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
|
|
15
|
+
const isArr = (v) => Array.isArray(v);
|
|
16
|
+
const pad = (n) => String(n).padStart(3, "0");
|
|
17
|
+
const KINDS = [
|
|
18
|
+
{ key: "actors", idField: "actor_id", prefix: "act" },
|
|
19
|
+
{ key: "locations", idField: "location_id", prefix: "loc" },
|
|
20
|
+
{ key: "props", idField: "prop_id", prefix: "prp" },
|
|
21
|
+
];
|
|
22
|
+
export function renumberIds(input) {
|
|
23
|
+
if (!isObj(input))
|
|
24
|
+
throw new Error("renumberIds expects a script object");
|
|
25
|
+
const doc = JSON.parse(JSON.stringify(input));
|
|
26
|
+
const idMap = { episodes: {}, scenes: {}, actors: {}, locations: {}, props: {}, states: {} };
|
|
27
|
+
// 1. Asset ids by first appearance (document walk).
|
|
28
|
+
const seen = { actors: [], locations: [], props: [] };
|
|
29
|
+
const seenSet = { actors: new Set(), locations: new Set(), props: new Set() };
|
|
30
|
+
const see = (bucket, id) => { if (typeof id === "string" && !seenSet[bucket].has(id)) {
|
|
31
|
+
seenSet[bucket].add(id);
|
|
32
|
+
seen[bucket].push(id);
|
|
33
|
+
} };
|
|
34
|
+
for (const ep of isArr(doc.episodes) ? doc.episodes : []) {
|
|
35
|
+
if (!isObj(ep) || !isArr(ep.scenes))
|
|
36
|
+
continue;
|
|
37
|
+
for (const sc of ep.scenes) {
|
|
38
|
+
if (!isObj(sc))
|
|
39
|
+
continue;
|
|
40
|
+
if (isObj(sc.location))
|
|
41
|
+
see("locations", sc.location.location_id);
|
|
42
|
+
for (const a of isArr(sc.actors) ? sc.actors : [])
|
|
43
|
+
if (isObj(a))
|
|
44
|
+
see("actors", a.actor_id);
|
|
45
|
+
for (const p of isArr(sc.props) ? sc.props : [])
|
|
46
|
+
if (isObj(p))
|
|
47
|
+
see("props", p.prop_id);
|
|
48
|
+
for (const ac of isArr(sc.actions) ? sc.actions : [])
|
|
49
|
+
if (isObj(ac) && isObj(ac.speaker))
|
|
50
|
+
see("actors", ac.speaker.actor_id);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
// Append any asset present in the top-level lists but never referenced.
|
|
54
|
+
for (const { key, idField } of KINDS)
|
|
55
|
+
for (const a of isArr(doc[key]) ? doc[key] : [])
|
|
56
|
+
if (isObj(a))
|
|
57
|
+
see(key, a[idField]);
|
|
58
|
+
for (const { key, prefix } of KINDS)
|
|
59
|
+
seen[key].forEach((old, i) => { idMap[key][old] = `${prefix}_${pad(i + 1)}`; });
|
|
60
|
+
// 2. Rebuild top-level asset lists in new-id order; renumber per-asset states.
|
|
61
|
+
for (const { key, idField } of KINDS) {
|
|
62
|
+
const list = (isArr(doc[key]) ? doc[key] : []).filter(isObj);
|
|
63
|
+
const bucket = idMap[key];
|
|
64
|
+
const byNew = new Map();
|
|
65
|
+
for (const a of list) {
|
|
66
|
+
const oldId = a[idField];
|
|
67
|
+
const newId = bucket[oldId] ?? oldId;
|
|
68
|
+
a[idField] = newId;
|
|
69
|
+
// states: keep default, renumber the rest st_001.. in array order.
|
|
70
|
+
let n = 0;
|
|
71
|
+
for (const st of isArr(a.states) ? a.states : []) {
|
|
72
|
+
if (!isObj(st) || typeof st.state_id !== "string")
|
|
73
|
+
continue;
|
|
74
|
+
if (st.state_id === "default")
|
|
75
|
+
continue;
|
|
76
|
+
const ns = `st_${pad(++n)}`;
|
|
77
|
+
idMap.states[st.state_id] = ns;
|
|
78
|
+
st.state_id = ns;
|
|
79
|
+
}
|
|
80
|
+
byNew.set(newId, a);
|
|
81
|
+
}
|
|
82
|
+
doc[key] = [...byNew.entries()].sort((x, y) => (x[0] < y[0] ? -1 : 1)).map((e) => e[1]);
|
|
83
|
+
}
|
|
84
|
+
// 3. Episode / scene ids (in order).
|
|
85
|
+
let scn = 0;
|
|
86
|
+
(isArr(doc.episodes) ? doc.episodes : []).forEach((ep, ei) => {
|
|
87
|
+
if (!isObj(ep))
|
|
88
|
+
return;
|
|
89
|
+
if (typeof ep.episode_id === "string") {
|
|
90
|
+
const nid = `ep_${pad(ei + 1)}`;
|
|
91
|
+
idMap.episodes[ep.episode_id] = nid;
|
|
92
|
+
ep.episode_id = nid;
|
|
93
|
+
}
|
|
94
|
+
for (const sc of isArr(ep.scenes) ? ep.scenes : []) {
|
|
95
|
+
if (!isObj(sc))
|
|
96
|
+
continue;
|
|
97
|
+
if (typeof sc.scene_id === "string") {
|
|
98
|
+
const nid = `scn_${pad(++scn)}`;
|
|
99
|
+
idMap.scenes[sc.scene_id] = nid;
|
|
100
|
+
sc.scene_id = nid;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
});
|
|
104
|
+
// 4. Rewrite references (asset ids + state ids) throughout the scenes.
|
|
105
|
+
const remapRef = (holder, idField, kind) => {
|
|
106
|
+
if (!isObj(holder) || typeof holder[idField] !== "string")
|
|
107
|
+
return;
|
|
108
|
+
holder[idField] = idMap[kind][holder[idField]] ?? holder[idField];
|
|
109
|
+
if (typeof holder.state_id === "string" && idMap.states[holder.state_id])
|
|
110
|
+
holder.state_id = idMap.states[holder.state_id];
|
|
111
|
+
};
|
|
112
|
+
for (const ep of isArr(doc.episodes) ? doc.episodes : []) {
|
|
113
|
+
if (!isObj(ep) || !isArr(ep.scenes))
|
|
114
|
+
continue;
|
|
115
|
+
for (const sc of ep.scenes) {
|
|
116
|
+
if (!isObj(sc))
|
|
117
|
+
continue;
|
|
118
|
+
remapRef(sc.location, "location_id", "locations");
|
|
119
|
+
for (const a of isArr(sc.actors) ? sc.actors : [])
|
|
120
|
+
remapRef(a, "actor_id", "actors");
|
|
121
|
+
for (const p of isArr(sc.props) ? sc.props : [])
|
|
122
|
+
remapRef(p, "prop_id", "props");
|
|
123
|
+
for (const ac of isArr(sc.actions) ? sc.actions : [])
|
|
124
|
+
if (isObj(ac))
|
|
125
|
+
remapRef(ac.speaker, "actor_id", "actors");
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
return { script: doc, idMap };
|
|
129
|
+
}
|
|
130
|
+
//# sourceMappingURL=renumber.js.map
|