@lingjingai/scriptctl 0.34.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.
Files changed (375) hide show
  1. package/README.md +30 -5
  2. package/changes/0.35.0.md +22 -0
  3. package/changes/0.36.0.md +22 -0
  4. package/changes/unreleased.md +3 -5
  5. package/dist/cli.d.ts +2 -1
  6. package/dist/cli.js +56 -128
  7. package/dist/cli.js.map +1 -1
  8. package/dist/common.d.ts +0 -16
  9. package/dist/common.js +2 -342
  10. package/dist/common.js.map +1 -1
  11. package/dist/domain/ingest/apply-plan.d.ts +23 -0
  12. package/dist/domain/ingest/apply-plan.js +210 -0
  13. package/dist/domain/ingest/apply-plan.js.map +1 -0
  14. package/dist/domain/ingest/assembler.d.ts +57 -0
  15. package/dist/domain/ingest/assembler.js +181 -0
  16. package/dist/domain/ingest/assembler.js.map +1 -0
  17. package/dist/domain/ingest/chunker.d.ts +9 -0
  18. package/dist/domain/ingest/chunker.js +38 -0
  19. package/dist/domain/ingest/chunker.js.map +1 -0
  20. package/dist/domain/ingest/evidence.d.ts +5 -0
  21. package/dist/domain/ingest/evidence.js +66 -0
  22. package/dist/domain/ingest/evidence.js.map +1 -0
  23. package/dist/domain/ingest/govern.d.ts +3 -0
  24. package/dist/domain/ingest/govern.js +127 -0
  25. package/dist/domain/ingest/govern.js.map +1 -0
  26. package/dist/domain/ingest/jsonl-parser.d.ts +6 -0
  27. package/dist/domain/ingest/jsonl-parser.js +187 -0
  28. package/dist/domain/ingest/jsonl-parser.js.map +1 -0
  29. package/dist/domain/ingest/markdown-parser.d.ts +6 -0
  30. package/dist/domain/ingest/markdown-parser.js +186 -0
  31. package/dist/domain/ingest/markdown-parser.js.map +1 -0
  32. package/dist/domain/ingest/records.d.ts +71 -0
  33. package/dist/domain/ingest/records.js +9 -0
  34. package/dist/domain/ingest/records.js.map +1 -0
  35. package/dist/domain/ingest/renumber.d.ts +14 -0
  36. package/dist/domain/ingest/renumber.js +130 -0
  37. package/dist/domain/ingest/renumber.js.map +1 -0
  38. package/dist/domain/ingest/script-v3.d.ts +94 -0
  39. package/dist/domain/ingest/script-v3.js +7 -0
  40. package/dist/domain/ingest/script-v3.js.map +1 -0
  41. package/dist/domain/ingest/state-reconcile.d.ts +11 -0
  42. package/dist/domain/ingest/state-reconcile.js +90 -0
  43. package/dist/domain/ingest/state-reconcile.js.map +1 -0
  44. package/dist/domain/ingest/validation.d.ts +11 -0
  45. package/dist/domain/ingest/validation.js +168 -0
  46. package/dist/domain/ingest/validation.js.map +1 -0
  47. package/dist/domain/ingest/video-aggregate.d.ts +23 -0
  48. package/dist/domain/ingest/video-aggregate.js +89 -0
  49. package/dist/domain/ingest/video-aggregate.js.map +1 -0
  50. package/dist/domain/ingest/video-apply.d.ts +37 -0
  51. package/dist/domain/ingest/video-apply.js +236 -0
  52. package/dist/domain/ingest/video-apply.js.map +1 -0
  53. package/dist/domain/ingest/video-md-parser.d.ts +2 -0
  54. package/dist/domain/ingest/video-md-parser.js +233 -0
  55. package/dist/domain/ingest/video-md-parser.js.map +1 -0
  56. package/dist/domain/ingest/video-records.d.ts +56 -0
  57. package/dist/domain/ingest/video-records.js +9 -0
  58. package/dist/domain/ingest/video-records.js.map +1 -0
  59. package/dist/domain/loom/index.d.ts +2 -1
  60. package/dist/domain/loom/index.js +12 -10
  61. package/dist/domain/loom/index.js.map +1 -1
  62. package/dist/domain/loom/types.d.ts +3 -2
  63. package/dist/domain/script/lookups.d.ts +3 -2
  64. package/dist/domain/script/lookups.js +25 -8
  65. package/dist/domain/script/lookups.js.map +1 -1
  66. package/dist/domain/script/patch/apply.js +2 -2
  67. package/dist/domain/script/patch/apply.js.map +1 -1
  68. package/dist/domain/script/patch/helpers.d.ts +3 -7
  69. package/dist/domain/script/patch/helpers.js +23 -96
  70. package/dist/domain/script/patch/helpers.js.map +1 -1
  71. package/dist/domain/script/patch/ops-action.d.ts +0 -2
  72. package/dist/domain/script/patch/ops-action.js +34 -100
  73. package/dist/domain/script/patch/ops-action.js.map +1 -1
  74. package/dist/domain/script/patch/ops-asset.d.ts +1 -0
  75. package/dist/domain/script/patch/ops-asset.js +102 -155
  76. package/dist/domain/script/patch/ops-asset.js.map +1 -1
  77. package/dist/domain/script/patch/ops-dialogue.d.ts +1 -4
  78. package/dist/domain/script/patch/ops-dialogue.js +43 -220
  79. package/dist/domain/script/patch/ops-dialogue.js.map +1 -1
  80. package/dist/domain/script/patch/ops-extend.js +8 -2
  81. package/dist/domain/script/patch/ops-extend.js.map +1 -1
  82. package/dist/domain/script/patch/ops-meta.js.map +1 -1
  83. package/dist/domain/script/patch/ops-scene.js +26 -39
  84. package/dist/domain/script/patch/ops-scene.js.map +1 -1
  85. package/dist/domain/script/patch/ops-state.d.ts +3 -3
  86. package/dist/domain/script/patch/ops-state.js +33 -49
  87. package/dist/domain/script/patch/ops-state.js.map +1 -1
  88. package/dist/domain/script/patch/registry.js +9 -13
  89. package/dist/domain/script/patch/registry.js.map +1 -1
  90. package/dist/domain/script/refs.js +23 -111
  91. package/dist/domain/script/refs.js.map +1 -1
  92. package/dist/domain/script/scene-refs.d.ts +3 -0
  93. package/dist/domain/script/scene-refs.js +35 -0
  94. package/dist/domain/script/scene-refs.js.map +1 -0
  95. package/dist/domain/script/schema.js +17 -21
  96. package/dist/domain/script/schema.js.map +1 -1
  97. package/dist/domain/script/text-util.d.ts +7 -0
  98. package/dist/domain/script/text-util.js +91 -0
  99. package/dist/domain/script/text-util.js.map +1 -0
  100. package/dist/help-text.js +145 -414
  101. package/dist/help-text.js.map +1 -1
  102. package/dist/infra/converters.js +1 -1
  103. package/dist/infra/converters.js.map +1 -1
  104. package/dist/infra/episode-title.d.ts +4 -0
  105. package/dist/infra/episode-title.js +129 -0
  106. package/dist/infra/episode-title.js.map +1 -0
  107. package/dist/infra/ingest/review-renderer.d.ts +1 -0
  108. package/dist/infra/ingest/review-renderer.js +431 -0
  109. package/dist/infra/ingest/review-renderer.js.map +1 -0
  110. package/dist/infra/ingest/source-resolver.d.ts +21 -0
  111. package/dist/infra/ingest/source-resolver.js +51 -0
  112. package/dist/infra/ingest/source-resolver.js.map +1 -0
  113. package/dist/infra/ingest/text-reader.d.ts +3 -0
  114. package/dist/infra/ingest/text-reader.js +27 -0
  115. package/dist/infra/ingest/text-reader.js.map +1 -0
  116. package/dist/infra/ingest/video-discovery.d.ts +8 -0
  117. package/dist/infra/ingest/video-discovery.js +60 -0
  118. package/dist/infra/ingest/video-discovery.js.map +1 -0
  119. package/dist/infra/ingest/workspace-store.d.ts +18 -0
  120. package/dist/infra/ingest/workspace-store.js +70 -0
  121. package/dist/infra/ingest/workspace-store.js.map +1 -0
  122. package/dist/infra/llm/anthropic-model.d.ts +11 -0
  123. package/dist/infra/llm/anthropic-model.js +109 -0
  124. package/dist/infra/llm/anthropic-model.js.map +1 -0
  125. package/dist/infra/llm/gemini-upload.d.ts +9 -0
  126. package/dist/infra/llm/gemini-upload.js +94 -0
  127. package/dist/infra/llm/gemini-upload.js.map +1 -0
  128. package/dist/infra/llm/gemini-video-model.d.ts +47 -0
  129. package/dist/infra/llm/gemini-video-model.js +167 -0
  130. package/dist/infra/llm/gemini-video-model.js.map +1 -0
  131. package/dist/infra/llm/openai-compatible-model.d.ts +13 -0
  132. package/dist/infra/llm/openai-compatible-model.js +143 -0
  133. package/dist/infra/llm/openai-compatible-model.js.map +1 -0
  134. package/dist/infra/llm/proxy.d.ts +1 -0
  135. package/dist/infra/llm/proxy.js +30 -0
  136. package/dist/infra/llm/proxy.js.map +1 -0
  137. package/dist/infra/llm/retry.d.ts +5 -0
  138. package/dist/infra/llm/retry.js +20 -0
  139. package/dist/infra/llm/retry.js.map +1 -0
  140. package/dist/llm/composition.d.ts +5 -0
  141. package/dist/llm/composition.js +5 -0
  142. package/dist/llm/composition.js.map +1 -0
  143. package/dist/llm/config.d.ts +26 -0
  144. package/dist/llm/config.js +201 -0
  145. package/dist/llm/config.js.map +1 -0
  146. package/dist/llm/registry.d.ts +44 -0
  147. package/dist/llm/registry.js +48 -0
  148. package/dist/llm/registry.js.map +1 -0
  149. package/dist/llm/router.d.ts +23 -0
  150. package/dist/llm/router.js +0 -0
  151. package/dist/llm/router.js.map +1 -0
  152. package/dist/llm/tasks/ingest/asset-curate.d.ts +13 -0
  153. package/dist/llm/tasks/ingest/asset-curate.js +45 -0
  154. package/dist/llm/tasks/ingest/asset-curate.js.map +1 -0
  155. package/dist/llm/tasks/ingest/asset-extract.d.ts +12 -0
  156. package/dist/llm/tasks/ingest/asset-extract.js +51 -0
  157. package/dist/llm/tasks/ingest/asset-extract.js.map +1 -0
  158. package/dist/llm/tasks/ingest/asset-govern.d.ts +22 -0
  159. package/dist/llm/tasks/ingest/asset-govern.js +143 -0
  160. package/dist/llm/tasks/ingest/asset-govern.js.map +1 -0
  161. package/dist/llm/tasks/ingest/mention-resolve.d.ts +9 -0
  162. package/dist/llm/tasks/ingest/mention-resolve.js +39 -0
  163. package/dist/llm/tasks/ingest/mention-resolve.js.map +1 -0
  164. package/dist/llm/tasks/ingest/plot-speaker.d.ts +11 -0
  165. package/dist/llm/tasks/ingest/plot-speaker.js +72 -0
  166. package/dist/llm/tasks/ingest/plot-speaker.js.map +1 -0
  167. package/dist/llm/tasks/ingest/roster-merge.d.ts +46 -0
  168. package/dist/llm/tasks/ingest/roster-merge.js +235 -0
  169. package/dist/llm/tasks/ingest/roster-merge.js.map +1 -0
  170. package/dist/llm/tasks/ingest/state-merge.d.ts +10 -0
  171. package/dist/llm/tasks/ingest/state-merge.js +84 -0
  172. package/dist/llm/tasks/ingest/state-merge.js.map +1 -0
  173. package/dist/llm/tasks/ingest/state-reconcile.d.ts +8 -0
  174. package/dist/llm/tasks/ingest/state-reconcile.js +44 -0
  175. package/dist/llm/tasks/ingest/state-reconcile.js.map +1 -0
  176. package/dist/llm/tasks/ingest/text-normalize.d.ts +10 -0
  177. package/dist/llm/tasks/ingest/text-normalize.js +89 -0
  178. package/dist/llm/tasks/ingest/text-normalize.js.map +1 -0
  179. package/dist/llm/tasks/ingest/video-correct.d.ts +30 -0
  180. package/dist/llm/tasks/ingest/video-correct.js +144 -0
  181. package/dist/llm/tasks/ingest/video-correct.js.map +1 -0
  182. package/dist/llm/tasks/ingest/video-transcribe.d.ts +4 -0
  183. package/dist/llm/tasks/ingest/video-transcribe.js +105 -0
  184. package/dist/llm/tasks/ingest/video-transcribe.js.map +1 -0
  185. package/dist/llm/tasks/schemas.d.ts +5 -0
  186. package/dist/llm/tasks/schemas.js +107 -0
  187. package/dist/llm/tasks/schemas.js.map +1 -0
  188. package/dist/llm/types.d.ts +97 -0
  189. package/dist/llm/types.js +13 -0
  190. package/dist/llm/types.js.map +1 -0
  191. package/dist/usecases/doctor.d.ts +1 -1
  192. package/dist/usecases/doctor.js +36 -9
  193. package/dist/usecases/doctor.js.map +1 -1
  194. package/dist/usecases/ingest/command.d.ts +5 -0
  195. package/dist/usecases/ingest/command.js +57 -0
  196. package/dist/usecases/ingest/command.js.map +1 -0
  197. package/dist/usecases/ingest/fanout.d.ts +10 -0
  198. package/dist/usecases/ingest/fanout.js +23 -0
  199. package/dist/usecases/ingest/fanout.js.map +1 -0
  200. package/dist/usecases/ingest/pass4-mention-resolve.d.ts +11 -0
  201. package/dist/usecases/ingest/pass4-mention-resolve.js +52 -0
  202. package/dist/usecases/ingest/pass4-mention-resolve.js.map +1 -0
  203. package/dist/usecases/ingest/pass5-extract.d.ts +7 -0
  204. package/dist/usecases/ingest/pass5-extract.js +50 -0
  205. package/dist/usecases/ingest/pass5-extract.js.map +1 -0
  206. package/dist/usecases/ingest/pass5-govern.d.ts +13 -0
  207. package/dist/usecases/ingest/pass5-govern.js +155 -0
  208. package/dist/usecases/ingest/pass5-govern.js.map +1 -0
  209. package/dist/usecases/ingest/pipeline.d.ts +28 -0
  210. package/dist/usecases/ingest/pipeline.js +144 -0
  211. package/dist/usecases/ingest/pipeline.js.map +1 -0
  212. package/dist/usecases/ingest/publish-command.d.ts +4 -0
  213. package/dist/usecases/ingest/publish-command.js +77 -0
  214. package/dist/usecases/ingest/publish-command.js.map +1 -0
  215. package/dist/usecases/ingest/status.d.ts +39 -0
  216. package/dist/usecases/ingest/status.js +155 -0
  217. package/dist/usecases/ingest/status.js.map +1 -0
  218. package/dist/usecases/ingest/video-pass3.d.ts +26 -0
  219. package/dist/usecases/ingest/video-pass3.js +0 -0
  220. package/dist/usecases/ingest/video-pass3.js.map +1 -0
  221. package/dist/usecases/ingest/video-pipeline.d.ts +32 -0
  222. package/dist/usecases/ingest/video-pipeline.js +202 -0
  223. package/dist/usecases/ingest/video-pipeline.js.map +1 -0
  224. package/dist/usecases/ingest/view-command.d.ts +4 -0
  225. package/dist/usecases/ingest/view-command.js +51 -0
  226. package/dist/usecases/ingest/view-command.js.map +1 -0
  227. package/dist/usecases/script/actions.js +2 -2
  228. package/dist/usecases/script/actions.js.map +1 -1
  229. package/dist/usecases/script/actor.js.map +1 -1
  230. package/dist/usecases/script/actors.js +1 -0
  231. package/dist/usecases/script/actors.js.map +1 -1
  232. package/dist/usecases/script/add-actor.js.map +1 -1
  233. package/dist/usecases/script/add-episode.js.map +1 -1
  234. package/dist/usecases/script/add-location.js.map +1 -1
  235. package/dist/usecases/script/add-prop.js.map +1 -1
  236. package/dist/usecases/script/alias.js.map +1 -1
  237. package/dist/usecases/script/assets.js +2 -1
  238. package/dist/usecases/script/assets.js.map +1 -1
  239. package/dist/usecases/script/context.js.map +1 -1
  240. package/dist/usecases/script/create.js +3 -6
  241. package/dist/usecases/script/create.js.map +1 -1
  242. package/dist/usecases/script/delete.js.map +1 -1
  243. package/dist/usecases/script/describe.js.map +1 -1
  244. package/dist/usecases/script/dialogue.js +6 -13
  245. package/dist/usecases/script/dialogue.js.map +1 -1
  246. package/dist/usecases/script/do.js +1 -1
  247. package/dist/usecases/script/do.js.map +1 -1
  248. package/dist/usecases/script/episodes.js.map +1 -1
  249. package/dist/usecases/script/{add-speaker.d.ts → importance.d.ts} +1 -1
  250. package/dist/usecases/script/importance.js +17 -0
  251. package/dist/usecases/script/importance.js.map +1 -0
  252. package/dist/usecases/script/insert.js.map +1 -1
  253. package/dist/usecases/script/issues.js.map +1 -1
  254. package/dist/usecases/script/lib.d.ts +19 -6
  255. package/dist/usecases/script/lib.js +173 -99
  256. package/dist/usecases/script/lib.js.map +1 -1
  257. package/dist/usecases/script/locations.js +1 -0
  258. package/dist/usecases/script/locations.js.map +1 -1
  259. package/dist/usecases/script/merge.js.map +1 -1
  260. package/dist/usecases/script/move.js.map +1 -1
  261. package/dist/usecases/script/props.js +1 -0
  262. package/dist/usecases/script/props.js.map +1 -1
  263. package/dist/usecases/script/refs.js.map +1 -1
  264. package/dist/usecases/script/rename.js.map +1 -1
  265. package/dist/usecases/script/replace.js.map +1 -1
  266. package/dist/usecases/script/role.js.map +1 -1
  267. package/dist/usecases/script/scenes.js +8 -15
  268. package/dist/usecases/script/scenes.js.map +1 -1
  269. package/dist/usecases/script/script-patch.js +1 -1
  270. package/dist/usecases/script/script-patch.js.map +1 -1
  271. package/dist/usecases/script/script-validate.js +1 -1
  272. package/dist/usecases/script/script-validate.js.map +1 -1
  273. package/dist/usecases/script/session.d.ts +4 -4
  274. package/dist/usecases/script/session.js +57 -78
  275. package/dist/usecases/script/session.js.map +1 -1
  276. package/dist/usecases/script/split.js.map +1 -1
  277. package/dist/usecases/script/state-add.js.map +1 -1
  278. package/dist/usecases/script/state-delete.js.map +1 -1
  279. package/dist/usecases/script/state-rename.js.map +1 -1
  280. package/dist/usecases/script/states.js +58 -13
  281. package/dist/usecases/script/states.js.map +1 -1
  282. package/dist/usecases/script/summary.js +8 -0
  283. package/dist/usecases/script/summary.js.map +1 -1
  284. package/dist/usecases/script/synopsis-generate.d.ts +4 -5
  285. package/dist/usecases/script/synopsis-generate.js +30 -46
  286. package/dist/usecases/script/synopsis-generate.js.map +1 -1
  287. package/dist/usecases/script/transition.js.map +1 -1
  288. package/dist/usecases/script/type.js.map +1 -1
  289. package/dist/usecases/script/worldview.js.map +1 -1
  290. package/package.json +11 -3
  291. package/scripts/install-skill.mjs +120 -0
  292. package/skills/scriptctl/SKILL.md +293 -0
  293. package/skills/scriptctl/references/atomic-write-workflow.md +117 -0
  294. package/skills/scriptctl/references/ingest-workflow.md +85 -0
  295. package/skills/scriptctl/references/state-reference-repair.md +59 -0
  296. package/dist/domain/direct/runner.d.ts +0 -25
  297. package/dist/domain/direct/runner.js +0 -88
  298. package/dist/domain/direct/runner.js.map +0 -1
  299. package/dist/domain/direct/stage.d.ts +0 -108
  300. package/dist/domain/direct/stage.js +0 -134
  301. package/dist/domain/direct/stage.js.map +0 -1
  302. package/dist/domain/direct/stages/asset-curation.d.ts +0 -2
  303. package/dist/domain/direct/stages/asset-curation.js +0 -10
  304. package/dist/domain/direct/stages/asset-curation.js.map +0 -1
  305. package/dist/domain/direct/stages/batch-extract.d.ts +0 -2
  306. package/dist/domain/direct/stages/batch-extract.js +0 -12
  307. package/dist/domain/direct/stages/batch-extract.js.map +0 -1
  308. package/dist/domain/direct/stages/batch-plan.d.ts +0 -2
  309. package/dist/domain/direct/stages/batch-plan.js +0 -9
  310. package/dist/domain/direct/stages/batch-plan.js.map +0 -1
  311. package/dist/domain/direct/stages/episode-merge.d.ts +0 -2
  312. package/dist/domain/direct/stages/episode-merge.js +0 -11
  313. package/dist/domain/direct/stages/episode-merge.js.map +0 -1
  314. package/dist/domain/direct/stages/episode-plan.d.ts +0 -2
  315. package/dist/domain/direct/stages/episode-plan.js +0 -9
  316. package/dist/domain/direct/stages/episode-plan.js.map +0 -1
  317. package/dist/domain/direct/stages/episode-synopsis.d.ts +0 -2
  318. package/dist/domain/direct/stages/episode-synopsis.js +0 -12
  319. package/dist/domain/direct/stages/episode-synopsis.js.map +0 -1
  320. package/dist/domain/direct/stages/episode-titles.d.ts +0 -2
  321. package/dist/domain/direct/stages/episode-titles.js +0 -12
  322. package/dist/domain/direct/stages/episode-titles.js.map +0 -1
  323. package/dist/domain/direct/stages/index.d.ts +0 -19
  324. package/dist/domain/direct/stages/index.js +0 -41
  325. package/dist/domain/direct/stages/index.js.map +0 -1
  326. package/dist/domain/direct/stages/metadata.d.ts +0 -2
  327. package/dist/domain/direct/stages/metadata.js +0 -11
  328. package/dist/domain/direct/stages/metadata.js.map +0 -1
  329. package/dist/domain/direct/stages/script-merge.d.ts +0 -2
  330. package/dist/domain/direct/stages/script-merge.js +0 -15
  331. package/dist/domain/direct/stages/script-merge.js.map +0 -1
  332. package/dist/domain/direct/stages/script-synopsis.d.ts +0 -2
  333. package/dist/domain/direct/stages/script-synopsis.js +0 -12
  334. package/dist/domain/direct/stages/script-synopsis.js.map +0 -1
  335. package/dist/domain/direct/stages/source-prepare.d.ts +0 -2
  336. package/dist/domain/direct/stages/source-prepare.js +0 -9
  337. package/dist/domain/direct/stages/source-prepare.js.map +0 -1
  338. package/dist/domain/direct/stages/state-binding.d.ts +0 -2
  339. package/dist/domain/direct/stages/state-binding.js +0 -9
  340. package/dist/domain/direct/stages/state-binding.js.map +0 -1
  341. package/dist/domain/direct/stages/state-curation.d.ts +0 -2
  342. package/dist/domain/direct/stages/state-curation.js +0 -10
  343. package/dist/domain/direct/stages/state-curation.js.map +0 -1
  344. package/dist/domain/direct/stages/validate.d.ts +0 -2
  345. package/dist/domain/direct/stages/validate.js +0 -10
  346. package/dist/domain/direct/stages/validate.js.map +0 -1
  347. package/dist/domain/direct-core.d.ts +0 -313
  348. package/dist/domain/direct-core.js +0 -8516
  349. package/dist/domain/direct-core.js.map +0 -1
  350. package/dist/domain/script/validate.d.ts +0 -22
  351. package/dist/domain/script/validate.js +0 -997
  352. package/dist/domain/script/validate.js.map +0 -1
  353. package/dist/infra/providers.d.ts +0 -97
  354. package/dist/infra/providers.js +0 -1396
  355. package/dist/infra/providers.js.map +0 -1
  356. package/dist/usecases/direct.d.ts +0 -27
  357. package/dist/usecases/direct.js +0 -4172
  358. package/dist/usecases/direct.js.map +0 -1
  359. package/dist/usecases/parse.d.ts +0 -15
  360. package/dist/usecases/parse.js +0 -429
  361. package/dist/usecases/parse.js.map +0 -1
  362. package/dist/usecases/script/add-speaker.js +0 -22
  363. package/dist/usecases/script/add-speaker.js.map +0 -1
  364. package/dist/usecases/script/export.d.ts +0 -3
  365. package/dist/usecases/script/export.js +0 -111
  366. package/dist/usecases/script/export.js.map +0 -1
  367. package/dist/usecases/script/overlap.d.ts +0 -3
  368. package/dist/usecases/script/overlap.js +0 -21
  369. package/dist/usecases/script/overlap.js.map +0 -1
  370. package/dist/usecases/script/speakers.d.ts +0 -3
  371. package/dist/usecases/script/speakers.js +0 -28
  372. package/dist/usecases/script/speakers.js.map +0 -1
  373. package/dist/usecases/script/state-change.d.ts +0 -3
  374. package/dist/usecases/script/state-change.js +0 -24
  375. package/dist/usecases/script/state-change.js.map +0 -1
@@ -0,0 +1,127 @@
1
+ // Deterministic governance core (§9.6/§9.8/§9.9 minus LLM). Given the provisional
2
+ // initial script it: (1) assigns each asset's `default` state by highest explicit
3
+ // frequency (tie → codepoint-smallest state name) and (2) materializes inherited
4
+ // state onto every entity reference so the final product is self-contained
5
+ // (§15.2). Identity merge / drop / audit are LLM stages layered on separately;
6
+ // this keep-all core always produces a valid, materialized v3 doc.
7
+ const isObj = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
8
+ const isArr = (v) => Array.isArray(v);
9
+ function assetIndex(list) {
10
+ const map = new Map();
11
+ if (!isArr(list))
12
+ return map;
13
+ for (const a of list) {
14
+ if (!isObj(a))
15
+ continue;
16
+ const id = a.actor_id ?? a.location_id ?? a.prop_id;
17
+ if (typeof id === "string")
18
+ map.set(id, a);
19
+ }
20
+ return map;
21
+ }
22
+ // Walk the doc in order, collecting entity refs (scene cast/props, scene
23
+ // location, dialogue speakers) as mutable holders plus their explicit state id.
24
+ function collectRefs(doc) {
25
+ const refs = [];
26
+ const push = (holder, idField) => {
27
+ if (!isObj(holder) || typeof holder[idField] !== "string")
28
+ return;
29
+ refs.push({ assetId: holder[idField], holder, explicit: typeof holder.state_id === "string" ? holder.state_id : undefined });
30
+ };
31
+ for (const ep of isArr(doc.episodes) ? doc.episodes : []) {
32
+ if (!isObj(ep) || !isArr(ep.scenes))
33
+ continue;
34
+ for (const sc of ep.scenes) {
35
+ if (!isObj(sc))
36
+ continue;
37
+ push(sc.location, "location_id");
38
+ for (const a of isArr(sc.actors) ? sc.actors : [])
39
+ push(a, "actor_id");
40
+ for (const p of isArr(sc.props) ? sc.props : [])
41
+ push(p, "prop_id");
42
+ for (const ac of isArr(sc.actions) ? sc.actions : []) {
43
+ if (isObj(ac))
44
+ push(ac.speaker, "actor_id");
45
+ }
46
+ }
47
+ }
48
+ return refs;
49
+ }
50
+ function pickDefault(states, counts) {
51
+ const candidates = states.filter((s) => (counts.get(s.state_id) ?? 0) > 0);
52
+ if (candidates.length === 0)
53
+ return null;
54
+ let best = candidates[0];
55
+ for (const s of candidates.slice(1)) {
56
+ const c = counts.get(s.state_id) ?? 0;
57
+ const bc = counts.get(best.state_id) ?? 0;
58
+ if (c > bc || (c === bc && s.state_name < best.state_name))
59
+ best = s;
60
+ }
61
+ return best.state_id;
62
+ }
63
+ export function governDeterministic(input) {
64
+ if (!isObj(input))
65
+ throw new Error("govern expects a script object");
66
+ const doc = JSON.parse(JSON.stringify(input)); // pure: never mutate input
67
+ const actors = assetIndex(doc.actors);
68
+ const locations = assetIndex(doc.locations);
69
+ const props = assetIndex(doc.props);
70
+ const all = new Map([...actors, ...locations, ...props]);
71
+ const refs = collectRefs(doc);
72
+ // 1. Count explicit state usage per asset.
73
+ const counts = new Map();
74
+ for (const ref of refs) {
75
+ if (ref.explicit === undefined)
76
+ continue;
77
+ if (!counts.has(ref.assetId))
78
+ counts.set(ref.assetId, new Map());
79
+ const m = counts.get(ref.assetId);
80
+ m.set(ref.explicit, (m.get(ref.explicit) ?? 0) + 1);
81
+ }
82
+ // 2. Per asset: pick default winner, rebuild states[] so exactly one 'default'.
83
+ const remap = new Map(); // assetId -> (oldStateId -> newStateId)
84
+ for (const [assetId, asset] of all) {
85
+ const states = (isArr(asset.states) ? asset.states : []).filter(isObj);
86
+ const local = new Map();
87
+ const winner = pickDefault(states, counts.get(assetId) ?? new Map());
88
+ let out;
89
+ if (winner === null) {
90
+ // No explicit states used: keep a single synthetic default.
91
+ out = [{ state_id: "default", state_name: states.find((s) => s.state_id === "default")?.state_name ?? "default", description: "" }];
92
+ }
93
+ else {
94
+ out = [];
95
+ for (const s of states) {
96
+ if (s.state_id === "default")
97
+ continue; // drop synthetic default
98
+ if (s.state_id === winner) {
99
+ local.set(s.state_id, "default");
100
+ out.unshift({ state_id: "default", state_name: s.state_name, description: s.description ?? "" });
101
+ }
102
+ else {
103
+ local.set(s.state_id, s.state_id);
104
+ out.push({ state_id: s.state_id, state_name: s.state_name, description: s.description ?? "" });
105
+ }
106
+ }
107
+ }
108
+ asset.states = out;
109
+ remap.set(assetId, local);
110
+ }
111
+ // 3. Materialize: walk refs in order, inherit last explicit state per asset.
112
+ const last = new Map();
113
+ for (const ref of refs) {
114
+ const local = remap.get(ref.assetId);
115
+ let resolved;
116
+ if (ref.explicit !== undefined) {
117
+ resolved = local?.get(ref.explicit) ?? ref.explicit;
118
+ last.set(ref.assetId, resolved);
119
+ }
120
+ else {
121
+ resolved = last.get(ref.assetId) ?? "default";
122
+ }
123
+ ref.holder.state_id = resolved;
124
+ }
125
+ return doc;
126
+ }
127
+ //# sourceMappingURL=govern.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"govern.js","sourceRoot":"","sources":["../../../src/domain/ingest/govern.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import { type IngestRecord } from "./records.js";
2
+ export declare class JsonlParseError extends Error {
3
+ readonly line: number;
4
+ constructor(message: string, line: number);
5
+ }
6
+ export declare function parseJsonl(text: string, lineOffset?: number): IngestRecord[];
@@ -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":"AAAA,6EAA6E;AAC7E,6EAA6E;AAC7E,6DAA6D;AAE7D,OAAO,EAKL,uBAAuB,EACvB,YAAY,GACb,MAAM,cAAc,CAAC;AAEtB,MAAM,OAAO,eAAgB,SAAQ,KAAK;IACF;IAAtC,YAAY,OAAe,EAAW,IAAY;QAChD,KAAK,CAAC,QAAQ,IAAI,KAAK,OAAO,EAAE,CAAC,CAAC;QADE,SAAI,GAAJ,IAAI,CAAQ;IAElD,CAAC;CACF;AAID,SAAS,KAAK,CAAC,CAAU;IACvB,OAAO,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;AAClE,CAAC;AAED,SAAS,WAAW,CAAC,GAAQ,EAAE,OAAiB,EAAE,IAAY;IAC5D,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;QACnC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC;YAAE,MAAM,IAAI,eAAe,CAAC,kBAAkB,GAAG,GAAG,EAAE,IAAI,CAAC,CAAC;IACxF,CAAC;AACH,CAAC;AAED,SAAS,WAAW,CAAC,CAAU,EAAE,IAAY;IAC3C,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;QAAE,MAAM,IAAI,eAAe,CAAC,gBAAgB,EAAE,IAAI,CAAC,CAAC;IACjE,WAAW,CAAC,CAAC,EAAE,CAAC,OAAO,EAAE,YAAY,EAAE,UAAU,CAAC,EAAE,IAAI,CAAC,CAAC;IAC1D,MAAM,EAAE,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAE,GAAG,CAAC,CAAC;IAC1C,IAAI,CAAC,CAAC,KAAK,EAAE,UAAU,EAAE,QAAQ,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,IAAI,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC;QACxG,MAAM,IAAI,eAAe,CAAC,gDAAgD,EAAE,IAAI,CAAC,CAAC;IACpF,CAAC;IACD,IAAK,UAAqB,IAAK,QAAmB;QAAE,MAAM,IAAI,eAAe,CAAC,sCAAsC,EAAE,IAAI,CAAC,CAAC;IAC5H,OAAO,EAAE,KAAK,EAAE,KAAe,EAAE,UAAU,EAAE,UAAoB,EAAE,QAAQ,EAAE,QAAkB,EAAE,CAAC;AACpG,CAAC;AAED,SAAS,GAAG,CAAC,GAAQ,EAAE,GAAW,EAAE,IAAY;IAC9C,MAAM,CAAC,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;IACnB,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,EAAE;QAAE,MAAM,IAAI,eAAe,CAAC,IAAI,GAAG,8BAA8B,EAAE,IAAI,CAAC,CAAC;IAC9G,OAAO,CAAC,CAAC;AACX,CAAC;AAED,SAAS,MAAM,CAAC,GAAQ,EAAE,GAAW,EAAE,IAAY;IACjD,IAAI,CAAC,CAAC,GAAG,IAAI,GAAG,CAAC,IAAI,GAAG,CAAC,GAAG,CAAC,KAAK,SAAS;QAAE,OAAO,SAAS,CAAC;IAC9D,MAAM,CAAC,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;IACnB,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,EAAE;QAAE,MAAM,IAAI,eAAe,CAAC,IAAI,GAAG,8BAA8B,EAAE,IAAI,CAAC,CAAC;IAC9G,OAAO,CAAC,CAAC;AACX,CAAC;AAED,SAAS,eAAe,CAAC,CAAU,EAAE,GAAW,EAAE,IAAY;IAC5D,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;QAAE,MAAM,IAAI,eAAe,CAAC,IAAI,GAAG,oBAAoB,EAAE,IAAI,CAAC,CAAC;IACpF,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;QACpB,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC;YAAE,MAAM,IAAI,eAAe,CAAC,IAAI,GAAG,2BAA2B,EAAE,IAAI,CAAC,CAAC;QACtF,WAAW,CAAC,IAAI,EAAE,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,IAAI,CAAC,CAAC;QAC3C,MAAM,GAAG,GAAiB,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,CAAC;QAC5D,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC;QAC1C,IAAI,KAAK,KAAK,SAAS;YAAE,GAAG,CAAC,KAAK,GAAG,KAAK,CAAC;QAC3C,OAAO,GAAG,CAAC;IACb,CAAC,CAAC,CAAC;AACL,CAAC;AAED,SAAS,YAAY,CAAC,CAAU,EAAE,IAAY;IAC5C,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;QAAE,MAAM,IAAI,eAAe,CAAC,wCAAwC,EAAE,IAAI,CAAC,CAAC;IACzF,IAAI,MAAM,IAAI,CAAC,EAAE,CAAC;QAChB,WAAW,CAAC,CAAC,EAAE,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,IAAI,CAAC,CAAC;QACxC,MAAM,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC;QACpB,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,CAAE,uBAA6C,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;YAC/F,MAAM,IAAI,eAAe,CAAC,+BAA+B,uBAAuB,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;QACtG,CAAC;QACD,MAAM,GAAG,GAAe,EAAE,IAAI,EAAE,IAAgD,EAAE,CAAC;QACnF,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC;QACvC,IAAI,KAAK,KAAK,SAAS;YAAE,GAAG,CAAC,KAAK,GAAG,KAAK,CAAC;QAC3C,OAAO,GAAG,CAAC;IACb,CAAC;IACD,WAAW,CAAC,CAAC,EAAE,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,IAAI,CAAC,CAAC;IACxC,MAAM,GAAG,GAAe,EAAE,IAAI,EAAE,GAAG,CAAC,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,CAAC;IACvD,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC;IACvC,IAAI,KAAK,KAAK,SAAS;QAAE,GAAG,CAAC,KAAK,GAAG,KAAK,CAAC;IAC3C,OAAO,GAAG,CAAC;AACb,CAAC;AAED,SAAS,WAAW,CAAC,GAAQ,EAAE,IAAY;IACzC,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC;IACtB,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,CAAE,YAAkC,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QACpF,MAAM,IAAI,eAAe,CAAC,4BAA4B,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;IAC/E,CAAC;IACD,MAAM,MAAM,GAAG,WAAW,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IAE7C,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,SAAS,CAAC,CAAC,CAAC;YACf,WAAW,CAAC,GAAG,EAAE,CAAC,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,QAAQ,CAAC,EAAE,IAAI,CAAC,CAAC;YAC/D,MAAM,OAAO,GAAG,GAAG,CAAC,OAAO,CAAC;YAC5B,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,OAAO,CAAC;gBAAE,MAAM,IAAI,eAAe,CAAC,4BAA4B,EAAE,IAAI,CAAC,CAAC;YAC7H,MAAM,GAAG,GAAG,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAkB,CAAC;YACtD,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC;YACzC,IAAI,KAAK,KAAK,SAAS;gBAAG,GAA0B,CAAC,KAAK,GAAG,KAAK,CAAC;YACnE,OAAO,GAAG,CAAC;QACb,CAAC;QACD,KAAK,OAAO,CAAC,CAAC,CAAC;YACb,WAAW,CAAC,GAAG,EAAE,CAAC,MAAM,EAAE,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,QAAQ,EAAE,OAAO,EAAE,QAAQ,CAAC,EAAE,IAAI,CAAC,CAAC;YAClG,MAAM,GAAG,GAA4B,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;YACtD,IAAI,OAAO,IAAI,GAAG,IAAI,GAAG,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;gBAC9C,IAAI,OAAO,GAAG,CAAC,KAAK,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC;oBAAE,MAAM,IAAI,eAAe,CAAC,0BAA0B,EAAE,IAAI,CAAC,CAAC;gBAC/H,GAAG,CAAC,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC;YACxB,CAAC;YACD,IAAI,aAAa,IAAI,GAAG,IAAI,GAAG,CAAC,WAAW,KAAK,SAAS,EAAE,CAAC;gBAC1D,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,WAAW,CAAC;oBAAE,MAAM,IAAI,eAAe,CAAC,+BAA+B,EAAE,IAAI,CAAC,CAAC;gBAC9F,WAAW,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,EAAE,IAAI,CAAC,CAAC;gBACtD,GAAG,CAAC,WAAW,GAAG,GAAG,CAAC,WAAW,CAAC;YACpC,CAAC;YACD,IAAI,UAAU,IAAI,GAAG,IAAI,GAAG,CAAC,QAAQ,KAAK,SAAS,EAAE,CAAC;gBACpD,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC;oBAAE,MAAM,IAAI,eAAe,CAAC,4BAA4B,EAAE,IAAI,CAAC,CAAC;gBACxF,WAAW,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,IAAI,CAAC,CAAC;gBACnD,MAAM,GAAG,GAA4B,EAAE,IAAI,EAAE,GAAG,CAAC,GAAG,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,CAAC;gBAC/E,MAAM,EAAE,GAAG,MAAM,CAAC,GAAG,CAAC,QAAQ,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC;gBAC/C,IAAI,EAAE,KAAK,SAAS;oBAAE,GAAG,CAAC,KAAK,GAAG,EAAE,CAAC;gBACrC,GAAG,CAAC,QAAQ,GAAG,GAAG,CAAC;YACrB,CAAC;YACD,IAAI,QAAQ,IAAI,GAAG,IAAI,GAAG,CAAC,MAAM,KAAK,SAAS;gBAAE,GAAG,CAAC,MAAM,GAAG,eAAe,CAAC,GAAG,CAAC,MAAM,EAAE,QAAQ,EAAE,IAAI,CAAC,CAAC;YAC1G,IAAI,OAAO,IAAI,GAAG,IAAI,GAAG,CAAC,KAAK,KAAK,SAAS;gBAAE,GAAG,CAAC,KAAK,GAAG,eAAe,CAAC,GAAG,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC;YACrG,OAAO,GAA8B,CAAC;QACxC,CAAC;QACD,KAAK,QAAQ,CAAC;QACd,KAAK,YAAY,CAAC,CAAC,CAAC;YAClB,WAAW,CAAC,GAAG,EAAE,CAAC,MAAM,EAAE,SAAS,EAAE,QAAQ,CAAC,EAAE,IAAI,CAAC,CAAC;YACtD,MAAM,OAAO,GAAG,GAAG,CAAC,GAAG,EAAE,SAAS,EAAE,IAAI,CAAC,CAAC;YAC1C,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAkB,CAAC;QACnD,CAAC;QACD,KAAK,UAAU,CAAC;QAChB,KAAK,eAAe,CAAC,CAAC,CAAC;YACrB,WAAW,CAAC,GAAG,EAAE,CAAC,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,QAAQ,CAAC,EAAE,IAAI,CAAC,CAAC;YAC5E,MAAM,OAAO,GAAG,GAAG,CAAC,GAAG,EAAE,SAAS,EAAE,IAAI,CAAC,CAAC;YAC1C,MAAM,OAAO,GAAG,YAAY,CAAC,GAAG,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;YAChD,MAAM,GAAG,GAA4B,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC;YACxE,MAAM,OAAO,GAAG,MAAM,CAAC,GAAG,EAAE,SAAS,EAAE,IAAI,CAAC,CAAC;YAC7C,IAAI,OAAO,KAAK,SAAS;gBAAE,GAAG,CAAC,OAAO,GAAG,OAAO,CAAC;YACjD,OAAO,GAA8B,CAAC;QACxC,CAAC;QACD,KAAK,MAAM,CAAC,CAAC,CAAC;YACZ,WAAW,CAAC,GAAG,EAAE,CAAC,MAAM,EAAE,SAAS,EAAE,UAAU,EAAE,QAAQ,CAAC,EAAE,IAAI,CAAC,CAAC;YAClE,MAAM,OAAO,GAAG,GAAG,CAAC,GAAG,EAAE,SAAS,EAAE,IAAI,CAAC,CAAC;YAC1C,MAAM,GAAG,GAA4B,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC;YAC/D,IAAI,UAAU,IAAI,GAAG,IAAI,GAAG,CAAC,QAAQ,KAAK,SAAS,EAAE,CAAC;gBACpD,MAAM,GAAG,GAAG,GAAG,CAAC,QAAQ,CAAC;gBACzB,IAAI,GAAG,KAAK,aAAa,IAAI,GAAG,KAAK,aAAa,IAAI,GAAG,KAAK,cAAc,EAAE,CAAC;oBAC7E,MAAM,IAAI,eAAe,CAAC,4DAA4D,EAAE,IAAI,CAAC,CAAC;gBAChG,CAAC;gBACD,GAAG,CAAC,QAAQ,GAAG,GAAG,CAAC;YACrB,CAAC;YACD,OAAO,GAA8B,CAAC;QACxC,CAAC;QACD;YACE,MAAM,IAAI,eAAe,CAAC,mBAAmB,IAAI,GAAG,EAAE,IAAI,CAAC,CAAC;IAChE,CAAC;AACH,CAAC;AAED,6EAA6E;AAC7E,sEAAsE;AACtE,MAAM,UAAU,UAAU,CAAC,IAAY,EAAE,UAAU,GAAG,CAAC;IACrD,MAAM,GAAG,GAAmB,EAAE,CAAC;IAC/B,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC/B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,MAAM,GAAG,GAAG,KAAK,CAAC,CAAC,CAAE,CAAC,IAAI,EAAE,CAAC;QAC7B,IAAI,GAAG,KAAK,EAAE;YAAE,SAAS;QACzB,IAAI,MAAe,CAAC;QACpB,IAAI,CAAC;YACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAC3B,CAAC;QAAC,MAAM,CAAC;YACP,MAAM,IAAI,eAAe,CAAC,cAAc,EAAE,CAAC,GAAG,CAAC,GAAG,UAAU,CAAC,CAAC;QAChE,CAAC;QACD,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC;YAAE,MAAM,IAAI,eAAe,CAAC,8BAA8B,EAAE,CAAC,GAAG,CAAC,GAAG,UAAU,CAAC,CAAC;QAClG,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,GAAG,UAAU,CAAC,CAAC,CAAC;IACpD,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC"}
@@ -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"}