@lingjingai/scriptctl 0.49.16 → 0.50.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 (388) hide show
  1. package/README.md +8 -2
  2. package/changes/0.50.0.md +63 -0
  3. package/changes/unreleased.md +2 -1
  4. package/dist/cli.js +26 -5
  5. package/dist/cli.js.map +1 -1
  6. package/dist/domain/authoring/apply.d.ts +1 -33
  7. package/dist/domain/authoring/apply.js +1 -783
  8. package/dist/domain/authoring/apply.js.map +1 -1
  9. package/dist/domain/authoring/export.d.ts +1 -7
  10. package/dist/domain/authoring/export.js +1 -84
  11. package/dist/domain/authoring/export.js.map +1 -1
  12. package/dist/domain/authoring/parser.d.ts +2 -3
  13. package/dist/domain/authoring/parser.js +2 -914
  14. package/dist/domain/authoring/parser.js.map +1 -1
  15. package/dist/domain/authoring/serializer.d.ts +1 -2
  16. package/dist/domain/authoring/serializer.js +1 -243
  17. package/dist/domain/authoring/serializer.js.map +1 -1
  18. package/dist/domain/authoring/shared/bracket.d.ts +4 -0
  19. package/dist/domain/authoring/shared/bracket.js +95 -0
  20. package/dist/domain/authoring/shared/bracket.js.map +1 -0
  21. package/dist/domain/authoring/shared/types.d.ts +12 -0
  22. package/dist/domain/authoring/shared/types.js +2 -0
  23. package/dist/domain/authoring/shared/types.js.map +1 -0
  24. package/dist/domain/authoring/types.d.ts +2 -87
  25. package/dist/domain/authoring/types.js +2 -1
  26. package/dist/domain/authoring/types.js.map +1 -1
  27. package/dist/domain/authoring/v3/apply.d.ts +33 -0
  28. package/dist/domain/authoring/v3/apply.js +784 -0
  29. package/dist/domain/authoring/v3/apply.js.map +1 -0
  30. package/dist/domain/authoring/v3/export.d.ts +7 -0
  31. package/dist/domain/authoring/v3/export.js +85 -0
  32. package/dist/domain/authoring/v3/export.js.map +1 -0
  33. package/dist/domain/authoring/v3/parser.d.ts +3 -0
  34. package/dist/domain/authoring/v3/parser.js +823 -0
  35. package/dist/domain/authoring/v3/parser.js.map +1 -0
  36. package/dist/domain/authoring/v3/serializer.d.ts +2 -0
  37. package/dist/domain/authoring/v3/serializer.js +244 -0
  38. package/dist/domain/authoring/v3/serializer.js.map +1 -0
  39. package/dist/domain/authoring/v3/types.d.ts +76 -0
  40. package/dist/domain/authoring/v3/types.js +2 -0
  41. package/dist/domain/authoring/v3/types.js.map +1 -0
  42. package/dist/domain/authoring/v4/apply.d.ts +40 -0
  43. package/dist/domain/authoring/v4/apply.js +451 -0
  44. package/dist/domain/authoring/v4/apply.js.map +1 -0
  45. package/dist/domain/authoring/v4/parser.d.ts +2 -0
  46. package/dist/domain/authoring/v4/parser.js +729 -0
  47. package/dist/domain/authoring/v4/parser.js.map +1 -0
  48. package/dist/domain/authoring/v4/serializer.d.ts +6 -0
  49. package/dist/domain/authoring/v4/serializer.js +280 -0
  50. package/dist/domain/authoring/v4/serializer.js.map +1 -0
  51. package/dist/domain/authoring/v4/types.d.ts +50 -0
  52. package/dist/domain/authoring/v4/types.js +2 -0
  53. package/dist/domain/authoring/v4/types.js.map +1 -0
  54. package/dist/domain/ingest/apply-plan.d.ts +1 -1
  55. package/dist/domain/ingest/assembler.d.ts +9 -0
  56. package/dist/domain/ingest/assembler.js +98 -36
  57. package/dist/domain/ingest/assembler.js.map +1 -1
  58. package/dist/domain/ingest/asset-audit.d.ts +50 -0
  59. package/dist/domain/ingest/asset-audit.js +196 -0
  60. package/dist/domain/ingest/asset-audit.js.map +1 -0
  61. package/dist/domain/ingest/production-validation.d.ts +5 -4
  62. package/dist/domain/ingest/production-validation.js +10 -25
  63. package/dist/domain/ingest/production-validation.js.map +1 -1
  64. package/dist/domain/ingest/records.d.ts +1 -1
  65. package/dist/domain/ingest/records.js +1 -1
  66. package/dist/domain/ingest/records.js.map +1 -1
  67. package/dist/domain/ingest/serial-context.d.ts +1 -1
  68. package/dist/domain/ingest/validation.d.ts +1 -11
  69. package/dist/domain/ingest/validation.js +1 -199
  70. package/dist/domain/ingest/validation.js.map +1 -1
  71. package/dist/domain/ingest/video-apply.js +68 -45
  72. package/dist/domain/ingest/video-apply.js.map +1 -1
  73. package/dist/domain/script/address.d.ts +1 -32
  74. package/dist/domain/script/address.js +1 -144
  75. package/dist/domain/script/address.js.map +1 -1
  76. package/dist/domain/script/dispatch.d.ts +14 -0
  77. package/dist/domain/script/dispatch.js +47 -0
  78. package/dist/domain/script/dispatch.js.map +1 -0
  79. package/dist/domain/script/lookups.d.ts +1 -33
  80. package/dist/domain/script/lookups.js +1 -316
  81. package/dist/domain/script/lookups.js.map +1 -1
  82. package/dist/domain/script/parse.d.ts +1 -3
  83. package/dist/domain/script/parse.js +1 -164
  84. package/dist/domain/script/parse.js.map +1 -1
  85. package/dist/domain/script/patch/apply.d.ts +1 -2
  86. package/dist/domain/script/patch/apply.js +1 -30
  87. package/dist/domain/script/patch/apply.js.map +1 -1
  88. package/dist/domain/script/patch/helpers.d.ts +1 -17
  89. package/dist/domain/script/patch/helpers.js +1 -210
  90. package/dist/domain/script/patch/helpers.js.map +1 -1
  91. package/dist/domain/script/patch/inline-speaker.d.ts +1 -2
  92. package/dist/domain/script/patch/inline-speaker.js +1 -49
  93. package/dist/domain/script/patch/inline-speaker.js.map +1 -1
  94. package/dist/domain/script/patch/ops-action.d.ts +1 -12
  95. package/dist/domain/script/patch/ops-action.js +1 -366
  96. package/dist/domain/script/patch/ops-action.js.map +1 -1
  97. package/dist/domain/script/patch/ops-asset.d.ts +1 -14
  98. package/dist/domain/script/patch/ops-asset.js +1 -364
  99. package/dist/domain/script/patch/ops-asset.js.map +1 -1
  100. package/dist/domain/script/patch/ops-dialogue.d.ts +1 -2
  101. package/dist/domain/script/patch/ops-dialogue.js +1 -25
  102. package/dist/domain/script/patch/ops-dialogue.js.map +1 -1
  103. package/dist/domain/script/patch/ops-extend.d.ts +1 -8
  104. package/dist/domain/script/patch/ops-extend.js +1 -110
  105. package/dist/domain/script/patch/ops-extend.js.map +1 -1
  106. package/dist/domain/script/patch/ops-meta.d.ts +1 -5
  107. package/dist/domain/script/patch/ops-meta.js +1 -81
  108. package/dist/domain/script/patch/ops-meta.js.map +1 -1
  109. package/dist/domain/script/patch/ops-scene.d.ts +1 -6
  110. package/dist/domain/script/patch/ops-scene.js +1 -350
  111. package/dist/domain/script/patch/ops-scene.js.map +1 -1
  112. package/dist/domain/script/patch/ops-state.d.ts +1 -8
  113. package/dist/domain/script/patch/ops-state.js +1 -164
  114. package/dist/domain/script/patch/ops-state.js.map +1 -1
  115. package/dist/domain/script/patch/registry.d.ts +1 -2
  116. package/dist/domain/script/patch/registry.js +1 -52
  117. package/dist/domain/script/patch/registry.js.map +1 -1
  118. package/dist/domain/script/patch/types.d.ts +1 -10
  119. package/dist/domain/script/patch/types.js +1 -1
  120. package/dist/domain/script/patch/types.js.map +1 -1
  121. package/dist/domain/script/refs.d.ts +1 -4
  122. package/dist/domain/script/refs.js +1 -63
  123. package/dist/domain/script/refs.js.map +1 -1
  124. package/dist/domain/script/scene-refs.d.ts +1 -3
  125. package/dist/domain/script/scene-refs.js +1 -34
  126. package/dist/domain/script/scene-refs.js.map +1 -1
  127. package/dist/domain/script/schema.d.ts +1 -6
  128. package/dist/domain/script/schema.js +1 -55
  129. package/dist/domain/script/schema.js.map +1 -1
  130. package/dist/domain/script/selector.d.ts +1 -45
  131. package/dist/domain/script/selector.js +1 -184
  132. package/dist/domain/script/selector.js.map +1 -1
  133. package/dist/domain/script/shared/regex.d.ts +2 -0
  134. package/dist/domain/script/shared/regex.js +7 -0
  135. package/dist/domain/script/shared/regex.js.map +1 -0
  136. package/dist/domain/script/shared/types.d.ts +18 -0
  137. package/dist/domain/script/shared/types.js +9 -0
  138. package/dist/domain/script/shared/types.js.map +1 -0
  139. package/dist/domain/script/shared/validation.d.ts +10 -0
  140. package/dist/domain/script/shared/validation.js +2 -0
  141. package/dist/domain/script/shared/validation.js.map +1 -0
  142. package/dist/domain/script/types.d.ts +1 -123
  143. package/dist/domain/script/types.js +1 -8
  144. package/dist/domain/script/types.js.map +1 -1
  145. package/dist/domain/script/v3/address.d.ts +32 -0
  146. package/dist/domain/script/v3/address.js +145 -0
  147. package/dist/domain/script/v3/address.js.map +1 -0
  148. package/dist/domain/script/v3/lookups.d.ts +33 -0
  149. package/dist/domain/script/v3/lookups.js +317 -0
  150. package/dist/domain/script/v3/lookups.js.map +1 -0
  151. package/dist/domain/script/v3/ordinal.d.ts +8 -0
  152. package/dist/domain/script/v3/ordinal.js +92 -0
  153. package/dist/domain/script/v3/ordinal.js.map +1 -0
  154. package/dist/domain/script/v3/parse.d.ts +3 -0
  155. package/dist/domain/script/v3/parse.js +165 -0
  156. package/dist/domain/script/v3/parse.js.map +1 -0
  157. package/dist/domain/script/v3/patch/apply.d.ts +2 -0
  158. package/dist/domain/script/v3/patch/apply.js +31 -0
  159. package/dist/domain/script/v3/patch/apply.js.map +1 -0
  160. package/dist/domain/script/v3/patch/helpers.d.ts +17 -0
  161. package/dist/domain/script/v3/patch/helpers.js +211 -0
  162. package/dist/domain/script/v3/patch/helpers.js.map +1 -0
  163. package/dist/domain/script/v3/patch/inline-speaker.d.ts +2 -0
  164. package/dist/domain/script/v3/patch/inline-speaker.js +50 -0
  165. package/dist/domain/script/v3/patch/inline-speaker.js.map +1 -0
  166. package/dist/domain/script/v3/patch/ops-action.d.ts +12 -0
  167. package/dist/domain/script/v3/patch/ops-action.js +367 -0
  168. package/dist/domain/script/v3/patch/ops-action.js.map +1 -0
  169. package/dist/domain/script/v3/patch/ops-asset.d.ts +14 -0
  170. package/dist/domain/script/v3/patch/ops-asset.js +365 -0
  171. package/dist/domain/script/v3/patch/ops-asset.js.map +1 -0
  172. package/dist/domain/script/v3/patch/ops-dialogue.d.ts +2 -0
  173. package/dist/domain/script/v3/patch/ops-dialogue.js +26 -0
  174. package/dist/domain/script/v3/patch/ops-dialogue.js.map +1 -0
  175. package/dist/domain/script/v3/patch/ops-extend.d.ts +8 -0
  176. package/dist/domain/script/v3/patch/ops-extend.js +111 -0
  177. package/dist/domain/script/v3/patch/ops-extend.js.map +1 -0
  178. package/dist/domain/script/v3/patch/ops-meta.d.ts +5 -0
  179. package/dist/domain/script/v3/patch/ops-meta.js +82 -0
  180. package/dist/domain/script/v3/patch/ops-meta.js.map +1 -0
  181. package/dist/domain/script/v3/patch/ops-scene.d.ts +6 -0
  182. package/dist/domain/script/v3/patch/ops-scene.js +351 -0
  183. package/dist/domain/script/v3/patch/ops-scene.js.map +1 -0
  184. package/dist/domain/script/v3/patch/ops-state.d.ts +8 -0
  185. package/dist/domain/script/v3/patch/ops-state.js +165 -0
  186. package/dist/domain/script/v3/patch/ops-state.js.map +1 -0
  187. package/dist/domain/script/v3/patch/registry.d.ts +2 -0
  188. package/dist/domain/script/v3/patch/registry.js +53 -0
  189. package/dist/domain/script/v3/patch/registry.js.map +1 -0
  190. package/dist/domain/script/v3/patch/types.d.ts +10 -0
  191. package/dist/domain/script/v3/patch/types.js +2 -0
  192. package/dist/domain/script/v3/patch/types.js.map +1 -0
  193. package/dist/domain/script/v3/refs.d.ts +4 -0
  194. package/dist/domain/script/v3/refs.js +64 -0
  195. package/dist/domain/script/v3/refs.js.map +1 -0
  196. package/dist/domain/script/v3/scene-refs.d.ts +3 -0
  197. package/dist/domain/script/v3/scene-refs.js +35 -0
  198. package/dist/domain/script/v3/scene-refs.js.map +1 -0
  199. package/dist/domain/script/v3/schema.d.ts +6 -0
  200. package/dist/domain/script/v3/schema.js +56 -0
  201. package/dist/domain/script/v3/schema.js.map +1 -0
  202. package/dist/domain/script/v3/selector.d.ts +44 -0
  203. package/dist/domain/script/v3/selector.js +180 -0
  204. package/dist/domain/script/v3/selector.js.map +1 -0
  205. package/dist/domain/script/v3/types.d.ts +106 -0
  206. package/dist/domain/script/v3/types.js +2 -0
  207. package/dist/domain/script/v3/types.js.map +1 -0
  208. package/dist/domain/script/v3/validation.d.ts +3 -0
  209. package/dist/domain/script/v3/validation.js +200 -0
  210. package/dist/domain/script/v3/validation.js.map +1 -0
  211. package/dist/domain/script/v4/address.d.ts +61 -0
  212. package/dist/domain/script/v4/address.js +100 -0
  213. package/dist/domain/script/v4/address.js.map +1 -0
  214. package/dist/domain/script/v4/factory.d.ts +2 -0
  215. package/dist/domain/script/v4/factory.js +13 -0
  216. package/dist/domain/script/v4/factory.js.map +1 -0
  217. package/dist/domain/script/v4/from-v3.d.ts +29 -0
  218. package/dist/domain/script/v4/from-v3.js +307 -0
  219. package/dist/domain/script/v4/from-v3.js.map +1 -0
  220. package/dist/domain/script/v4/ids.d.ts +27 -0
  221. package/dist/domain/script/v4/ids.js +63 -0
  222. package/dist/domain/script/v4/ids.js.map +1 -0
  223. package/dist/domain/script/v4/ordinal.d.ts +3 -0
  224. package/dist/domain/script/v4/ordinal.js +67 -0
  225. package/dist/domain/script/v4/ordinal.js.map +1 -0
  226. package/dist/domain/script/v4/parse.d.ts +3 -0
  227. package/dist/domain/script/v4/parse.js +18 -0
  228. package/dist/domain/script/v4/parse.js.map +1 -0
  229. package/dist/domain/script/v4/patch/apply.d.ts +3 -0
  230. package/dist/domain/script/v4/patch/apply.js +24 -0
  231. package/dist/domain/script/v4/patch/apply.js.map +1 -0
  232. package/dist/domain/script/v4/patch/helpers.d.ts +32 -0
  233. package/dist/domain/script/v4/patch/helpers.js +139 -0
  234. package/dist/domain/script/v4/patch/helpers.js.map +1 -0
  235. package/dist/domain/script/v4/patch/ops-action.d.ts +13 -0
  236. package/dist/domain/script/v4/patch/ops-action.js +379 -0
  237. package/dist/domain/script/v4/patch/ops-action.js.map +1 -0
  238. package/dist/domain/script/v4/patch/ops-asset.d.ts +17 -0
  239. package/dist/domain/script/v4/patch/ops-asset.js +617 -0
  240. package/dist/domain/script/v4/patch/ops-asset.js.map +1 -0
  241. package/dist/domain/script/v4/patch/ops-extend.d.ts +11 -0
  242. package/dist/domain/script/v4/patch/ops-extend.js +86 -0
  243. package/dist/domain/script/v4/patch/ops-extend.js.map +1 -0
  244. package/dist/domain/script/v4/patch/ops-meta.d.ts +5 -0
  245. package/dist/domain/script/v4/patch/ops-meta.js +49 -0
  246. package/dist/domain/script/v4/patch/ops-meta.js.map +1 -0
  247. package/dist/domain/script/v4/patch/ops-scene-ref.d.ts +3 -0
  248. package/dist/domain/script/v4/patch/ops-scene-ref.js +98 -0
  249. package/dist/domain/script/v4/patch/ops-scene-ref.js.map +1 -0
  250. package/dist/domain/script/v4/patch/ops-structure.d.ts +6 -0
  251. package/dist/domain/script/v4/patch/ops-structure.js +236 -0
  252. package/dist/domain/script/v4/patch/ops-structure.js.map +1 -0
  253. package/dist/domain/script/v4/patch/registry.d.ts +2 -0
  254. package/dist/domain/script/v4/patch/registry.js +50 -0
  255. package/dist/domain/script/v4/patch/registry.js.map +1 -0
  256. package/dist/domain/script/v4/patch/schema.d.ts +7 -0
  257. package/dist/domain/script/v4/patch/schema.js +75 -0
  258. package/dist/domain/script/v4/patch/schema.js.map +1 -0
  259. package/dist/domain/script/v4/patch/types.d.ts +10 -0
  260. package/dist/domain/script/v4/patch/types.js +2 -0
  261. package/dist/domain/script/v4/patch/types.js.map +1 -0
  262. package/dist/domain/script/v4/selector.d.ts +11 -0
  263. package/dist/domain/script/v4/selector.js +125 -0
  264. package/dist/domain/script/v4/selector.js.map +1 -0
  265. package/dist/domain/script/v4/types.d.ts +120 -0
  266. package/dist/domain/script/v4/types.js +2 -0
  267. package/dist/domain/script/v4/types.js.map +1 -0
  268. package/dist/domain/script/v4/validation.d.ts +2 -0
  269. package/dist/domain/script/v4/validation.js +378 -0
  270. package/dist/domain/script/v4/validation.js.map +1 -0
  271. package/dist/help-text.js +146 -114
  272. package/dist/help-text.js.map +1 -1
  273. package/dist/llm/config.js +2 -0
  274. package/dist/llm/config.js.map +1 -1
  275. package/dist/llm/registry.d.ts +1 -0
  276. package/dist/llm/registry.js +3 -0
  277. package/dist/llm/registry.js.map +1 -1
  278. package/dist/llm/tasks/ingest/asset-audit.d.ts +6 -0
  279. package/dist/llm/tasks/ingest/asset-audit.js +164 -0
  280. package/dist/llm/tasks/ingest/asset-audit.js.map +1 -0
  281. package/dist/llm/tasks/ingest/asset-curate.d.ts +1 -1
  282. package/dist/llm/types.d.ts +1 -1
  283. package/dist/llm/types.js.map +1 -1
  284. package/dist/usecases/ingest/command.js +1 -1
  285. package/dist/usecases/ingest/final-asset-audit.d.ts +39 -0
  286. package/dist/usecases/ingest/final-asset-audit.js +88 -0
  287. package/dist/usecases/ingest/final-asset-audit.js.map +1 -0
  288. package/dist/usecases/ingest/pipeline.js +62 -11
  289. package/dist/usecases/ingest/pipeline.js.map +1 -1
  290. package/dist/usecases/ingest/serial-govern.d.ts +2 -1
  291. package/dist/usecases/ingest/serial-govern.js +11 -4
  292. package/dist/usecases/ingest/serial-govern.js.map +1 -1
  293. package/dist/usecases/ingest/video-pipeline.js +100 -14
  294. package/dist/usecases/ingest/video-pipeline.js.map +1 -1
  295. package/dist/usecases/ingest/view-server.js +2 -2
  296. package/dist/usecases/ingest/view-server.js.map +1 -1
  297. package/dist/usecases/script/actions.js +101 -5
  298. package/dist/usecases/script/actions.js.map +1 -1
  299. package/dist/usecases/script/actors.js +16 -7
  300. package/dist/usecases/script/actors.js.map +1 -1
  301. package/dist/usecases/script/alias.js +7 -6
  302. package/dist/usecases/script/alias.js.map +1 -1
  303. package/dist/usecases/script/assets.js +18 -2
  304. package/dist/usecases/script/assets.js.map +1 -1
  305. package/dist/usecases/script/audit-assets.d.ts +4 -0
  306. package/dist/usecases/script/audit-assets.js +40 -0
  307. package/dist/usecases/script/audit-assets.js.map +1 -0
  308. package/dist/usecases/script/command-constraints.d.ts +36 -0
  309. package/dist/usecases/script/command-constraints.js +115 -0
  310. package/dist/usecases/script/command-constraints.js.map +1 -0
  311. package/dist/usecases/script/context.js +31 -4
  312. package/dist/usecases/script/context.js.map +1 -1
  313. package/dist/usecases/script/create.js +2 -2
  314. package/dist/usecases/script/create.js.map +1 -1
  315. package/dist/usecases/script/delete.js +6 -3
  316. package/dist/usecases/script/delete.js.map +1 -1
  317. package/dist/usecases/script/describe.js +7 -4
  318. package/dist/usecases/script/describe.js.map +1 -1
  319. package/dist/usecases/script/dialogue.js +15 -5
  320. package/dist/usecases/script/dialogue.js.map +1 -1
  321. package/dist/usecases/script/dispatch.d.ts +3 -0
  322. package/dist/usecases/script/dispatch.js +10 -0
  323. package/dist/usecases/script/dispatch.js.map +1 -0
  324. package/dist/usecases/script/do.js +74 -11
  325. package/dist/usecases/script/do.js.map +1 -1
  326. package/dist/usecases/script/emotion.js +14 -3
  327. package/dist/usecases/script/emotion.js.map +1 -1
  328. package/dist/usecases/script/episodes.js +15 -4
  329. package/dist/usecases/script/episodes.js.map +1 -1
  330. package/dist/usecases/script/export-authoring.js +35 -11
  331. package/dist/usecases/script/export-authoring.js.map +1 -1
  332. package/dist/usecases/script/extend.js +23 -15
  333. package/dist/usecases/script/extend.js.map +1 -1
  334. package/dist/usecases/script/ids.js +53 -10
  335. package/dist/usecases/script/ids.js.map +1 -1
  336. package/dist/usecases/script/insert.js +74 -38
  337. package/dist/usecases/script/insert.js.map +1 -1
  338. package/dist/usecases/script/lib.d.ts +50 -1
  339. package/dist/usecases/script/lib.js +599 -61
  340. package/dist/usecases/script/lib.js.map +1 -1
  341. package/dist/usecases/script/locations.js +16 -7
  342. package/dist/usecases/script/locations.js.map +1 -1
  343. package/dist/usecases/script/merge.js +8 -5
  344. package/dist/usecases/script/merge.js.map +1 -1
  345. package/dist/usecases/script/move.js +24 -5
  346. package/dist/usecases/script/move.js.map +1 -1
  347. package/dist/usecases/script/parenthetical.d.ts +3 -0
  348. package/dist/usecases/script/parenthetical.js +55 -0
  349. package/dist/usecases/script/parenthetical.js.map +1 -0
  350. package/dist/usecases/script/props.js +16 -7
  351. package/dist/usecases/script/props.js.map +1 -1
  352. package/dist/usecases/script/refs.js +44 -0
  353. package/dist/usecases/script/refs.js.map +1 -1
  354. package/dist/usecases/script/rename.js +7 -4
  355. package/dist/usecases/script/rename.js.map +1 -1
  356. package/dist/usecases/script/scenes.js +32 -6
  357. package/dist/usecases/script/scenes.js.map +1 -1
  358. package/dist/usecases/script/script-patch.js +180 -16
  359. package/dist/usecases/script/script-patch.js.map +1 -1
  360. package/dist/usecases/script/session.d.ts +3 -0
  361. package/dist/usecases/script/session.js +25 -5
  362. package/dist/usecases/script/session.js.map +1 -1
  363. package/dist/usecases/script/split.js +12 -6
  364. package/dist/usecases/script/split.js.map +1 -1
  365. package/dist/usecases/script/states.js +45 -1
  366. package/dist/usecases/script/states.js.map +1 -1
  367. package/dist/usecases/script/synopsis.js +11 -4
  368. package/dist/usecases/script/synopsis.js.map +1 -1
  369. package/dist/usecases/script/v3/mutations.d.ts +2 -0
  370. package/dist/usecases/script/v3/mutations.js +5 -0
  371. package/dist/usecases/script/v3/mutations.js.map +1 -0
  372. package/dist/usecases/script/v4/mutations.d.ts +2 -0
  373. package/dist/usecases/script/v4/mutations.js +6 -0
  374. package/dist/usecases/script/v4/mutations.js.map +1 -0
  375. package/dist/usecases/script/v4/queries.d.ts +14 -0
  376. package/dist/usecases/script/v4/queries.js +154 -0
  377. package/dist/usecases/script/v4/queries.js.map +1 -0
  378. package/dist/usecases/script/working-copy.js +3 -3
  379. package/dist/usecases/script/working-copy.js.map +1 -1
  380. package/dist/usecases/script/write-authoring.js +99 -5
  381. package/dist/usecases/script/write-authoring.js.map +1 -1
  382. package/package.json +3 -2
  383. package/skills/scriptctl/SKILL.md +122 -282
  384. package/skills/scriptctl/references/atomic-edit-workflow.md +23 -38
  385. package/skills/scriptctl/references/bulk-authoring.md +35 -154
  386. package/skills/scriptctl/references/ingest-workflow.md +12 -11
  387. package/skills/scriptctl/references/production-writing-standard.md +38 -67
  388. package/skills/scriptctl/references/state-reference-repair.md +19 -42
@@ -0,0 +1,82 @@
1
+ import { WORLDVIEW_VALUES, } from "../../../../common.js";
2
+ import { isList, opErr, strOf } from "../../shared.js";
3
+ import { findEpisode, nextEpisodeId, } from "../lookups.js";
4
+ function requiredSynopsis(op, kind) {
5
+ const raw = "synopsis" in op ? op["synopsis"] : op["value"];
6
+ const synopsis = strOf(raw).trim();
7
+ if (!synopsis) {
8
+ throw opErr("SCRIPT OP BLOCKED: Synopsis missing", "Synopsis missing.", {
9
+ required: ["synopsis: non-empty text"],
10
+ received: ["<empty>"],
11
+ nextSteps: ["Pass a non-empty synopsis field."],
12
+ op: kind,
13
+ errorCode: "SYNOPSIS_MISSING",
14
+ });
15
+ }
16
+ return synopsis;
17
+ }
18
+ export function op_episode_add(__ctx) {
19
+ const { script, op, sourceText, applied, kind } = __ctx;
20
+ // Append an empty episode. Scenes/actions are added afterwards with
21
+ // scene.insert / action.insert. episode_id auto-allocates as ep_NNN.
22
+ const epId = strOf(op["episode_id"] ?? op["id"]).trim() || nextEpisodeId(script);
23
+ if (!/^ep_\d+$/.test(epId)) {
24
+ throw opErr("SCRIPT OP BLOCKED: Episode id invalid", "Episode id must use ep_NNN format.", {
25
+ required: ["episode_id: ep_NNN"], received: [epId],
26
+ nextSteps: ["Pass --id ep_004 or omit to auto-allocate."],
27
+ op: kind, errorCode: "EPISODE_ID_INVALID",
28
+ });
29
+ }
30
+ if (!isList(script["episodes"]))
31
+ script["episodes"] = [];
32
+ const eps = script["episodes"];
33
+ if (eps.some((e) => strOf(e["episode_id"]) === epId)) {
34
+ throw opErr("SCRIPT OP BLOCKED: Episode id exists", "Episode id exists.", {
35
+ required: ["unused episode_id"], received: [epId],
36
+ nextSteps: ["Use another --id or omit it to auto-allocate."],
37
+ op: kind, errorCode: "EPISODE_ID_EXISTS",
38
+ });
39
+ }
40
+ eps.push({ episode_id: epId, title: strOf(op["title"]).trim(), scenes: [] });
41
+ applied.push(kind);
42
+ }
43
+ export function op_episode_synopsis_set(__ctx) {
44
+ const { script, op, sourceText, applied, kind } = __ctx;
45
+ const episodeId = strOf(op["episode_id"] ?? op["target"] ?? op["at"]).trim();
46
+ if (!episodeId) {
47
+ throw opErr("SCRIPT OP BLOCKED: Episode id missing", "Episode id missing.", {
48
+ required: ["episode_id: ep_NNN"],
49
+ received: ["<empty>"],
50
+ nextSteps: ["Pass the episode id whose synopsis should be updated."],
51
+ op: kind,
52
+ errorCode: "EPISODE_ID_MISSING",
53
+ });
54
+ }
55
+ const episode = findEpisode(script, episodeId);
56
+ episode["synopsis"] = requiredSynopsis(op, kind);
57
+ applied.push(kind);
58
+ }
59
+ export function op_meta_worldview_set(__ctx) {
60
+ const { script, op, sourceText, applied, kind } = __ctx;
61
+ // 0.6.0 dot-style equivalent of the legacy `set_worldview` op.
62
+ const worldview = strOf(op["worldview"] ?? op["value"]).trim();
63
+ if (!WORLDVIEW_VALUES.includes(worldview)) {
64
+ throw opErr("SCRIPT OP BLOCKED: Worldview invalid", "Worldview invalid.", {
65
+ required: [`worldview: one of ${WORLDVIEW_VALUES.join(", ")}`],
66
+ received: [worldview || "<empty>"],
67
+ nextSteps: ["Use a supported worldview enum."],
68
+ op: kind,
69
+ errorCode: "WORLDVIEW_INVALID",
70
+ });
71
+ }
72
+ script["worldview"] = worldview;
73
+ if ("worldview_raw" in op)
74
+ script["worldview_raw"] = strOf(op["worldview_raw"]).trim();
75
+ applied.push(kind);
76
+ }
77
+ export function op_meta_synopsis_set(__ctx) {
78
+ const { script, op, sourceText, applied, kind } = __ctx;
79
+ script["synopsis"] = requiredSynopsis(op, kind);
80
+ applied.push(kind);
81
+ }
82
+ //# sourceMappingURL=ops-meta.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ops-meta.js","sourceRoot":"","sources":["../../../../../src/domain/script/v3/patch/ops-meta.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import type { OpCtx } from "./types.js";
2
+ export declare function op_scene_insert(__ctx: OpCtx): void;
3
+ export declare function op_scene_split(__ctx: OpCtx): void;
4
+ export declare function op_scene_merge(__ctx: OpCtx): void;
5
+ export declare function op_scene_delete(__ctx: OpCtx): void;
6
+ export declare function op_scene_move(__ctx: OpCtx): void;
@@ -0,0 +1,351 @@
1
+ import { asList, isDict, isList, opErr, strOf } from "../../shared.js";
2
+ import { ensureRefId, findEpisode, nextSceneId, sceneIdExists } from "../lookups.js";
3
+ import { parseSceneRef } from "../address.js";
4
+ import { sceneRefs, setSceneRefs } from "../scene-refs.js";
5
+ import { mergeExtendInto } from "./ops-extend.js";
6
+ export function op_scene_insert(__ctx) {
7
+ const { script, op, applied, kind } = __ctx;
8
+ // Insert a new empty scene into an episode. Position resolved from
9
+ // --at <idx> | --before <ep/scn> | --after <ep/scn> | default-append.
10
+ // Requires --location to anchor the scene (v3 scene.location, single-valued).
11
+ const epId = strOf(op["at"] ?? op["episode_id"]);
12
+ const ep = findEpisode(script, epId);
13
+ const scenes = asList(ep["scenes"]);
14
+ const locationId = strOf(op["location"] ?? op["location_id"]).trim();
15
+ if (!locationId) {
16
+ throw opErr("SCRIPT OP BLOCKED: location required", "Scene insert requires --location.", {
17
+ required: ["location: existing location_id"],
18
+ received: ["<empty>"],
19
+ nextSteps: ["Pass --location <loc_id>."],
20
+ op: kind,
21
+ errorCode: "SCENE_LOCATION_MISSING",
22
+ });
23
+ }
24
+ ensureRefId(script, "location", locationId);
25
+ let insertIndex;
26
+ if (op["before"]) {
27
+ const [bEp, bScn] = parseSceneRef(op["before"]);
28
+ if (bEp !== epId) {
29
+ throw opErr("SCRIPT OP BLOCKED: before address mismatch", "--before must point at the same episode.", {
30
+ required: [`${epId}/<scn>`],
31
+ received: [strOf(op["before"])],
32
+ nextSteps: ["Use a sibling scene address."],
33
+ op: kind,
34
+ errorCode: "INSERT_REF_MISMATCH",
35
+ });
36
+ }
37
+ insertIndex = scenes.findIndex((s) => strOf(s["scene_id"]) === bScn);
38
+ if (insertIndex < 0) {
39
+ throw opErr("SCRIPT OP BLOCKED: before scene not found", "before scene not found.", {
40
+ required: ["existing scene_id"],
41
+ received: [bScn],
42
+ nextSteps: ["Inspect scenes."],
43
+ op: kind,
44
+ errorCode: "SCENE_NOT_FOUND",
45
+ });
46
+ }
47
+ }
48
+ else if (op["after"]) {
49
+ const [aEp, aScn] = parseSceneRef(op["after"]);
50
+ if (aEp !== epId) {
51
+ throw opErr("SCRIPT OP BLOCKED: after address mismatch", "--after must point at the same episode.", {
52
+ required: [`${epId}/<scn>`],
53
+ received: [strOf(op["after"])],
54
+ nextSteps: ["Use a sibling scene address."],
55
+ op: kind,
56
+ errorCode: "INSERT_REF_MISMATCH",
57
+ });
58
+ }
59
+ const found = scenes.findIndex((s) => strOf(s["scene_id"]) === aScn);
60
+ if (found < 0) {
61
+ throw opErr("SCRIPT OP BLOCKED: after scene not found", "after scene not found.", {
62
+ required: ["existing scene_id"],
63
+ received: [aScn],
64
+ nextSteps: ["Inspect scenes."],
65
+ op: kind,
66
+ errorCode: "SCENE_NOT_FOUND",
67
+ });
68
+ }
69
+ insertIndex = found + 1;
70
+ }
71
+ else if (op["at_index"] !== undefined && op["at_index"] !== null) {
72
+ const n = Number(op["at_index"]);
73
+ if (!Number.isInteger(n) || n < 0 || n > scenes.length) {
74
+ throw opErr("SCRIPT OP BLOCKED: at_index out of range", "at_index out of range.", {
75
+ required: [`0..${scenes.length}`],
76
+ received: [String(op["at_index"])],
77
+ nextSteps: ["Use a valid integer index."],
78
+ op: kind,
79
+ errorCode: "AT_INDEX_OUT_OF_RANGE",
80
+ });
81
+ }
82
+ insertIndex = n;
83
+ }
84
+ else {
85
+ insertIndex = scenes.length;
86
+ }
87
+ const newSceneId = strOf(op["scene_id"]).trim() || nextSceneId(script);
88
+ if (sceneIdExists(script, newSceneId)) {
89
+ throw opErr("SCRIPT OP BLOCKED: New scene id exists", "New scene id exists.", {
90
+ required: ["unused scene_id"],
91
+ received: [newSceneId],
92
+ nextSteps: ["Pass --scene-id <unused> or omit."],
93
+ op: kind,
94
+ errorCode: "NEW_SCENE_ID_EXISTS",
95
+ });
96
+ }
97
+ const time = strOf(op["time"]).trim() || "day";
98
+ const space = strOf(op["space"]).trim() || "interior";
99
+ const newScene = {
100
+ scene_id: newSceneId,
101
+ environment: { time, space },
102
+ location: { location_id: locationId },
103
+ actors: [],
104
+ props: [],
105
+ actions: [],
106
+ };
107
+ scenes.splice(insertIndex, 0, newScene);
108
+ ep["scenes"] = scenes;
109
+ applied.push(kind);
110
+ }
111
+ export function op_scene_split(__ctx) {
112
+ const { script, op, applied, kind } = __ctx;
113
+ const [epId, sceneId] = parseSceneRef(op["at"]);
114
+ const splitAt = op["at_index"] ?? op["action_index"];
115
+ if (typeof splitAt !== "number" || !Number.isInteger(splitAt)) {
116
+ throw opErr("SCRIPT OP BLOCKED: Split index invalid", "Split index invalid.", {
117
+ required: ["at_index: integer between existing actions"],
118
+ received: [JSON.stringify(op)],
119
+ nextSteps: ["Inspect actions and use a valid index."],
120
+ op: kind,
121
+ errorCode: "SPLIT_INDEX_INVALID",
122
+ });
123
+ }
124
+ const ep = findEpisode(script, epId);
125
+ const scenes = asList(ep["scenes"]);
126
+ const index = scenes.findIndex((s) => s["scene_id"] === sceneId);
127
+ if (index < 0) {
128
+ throw opErr("SCRIPT OP BLOCKED: Scene not found", "Scene not found.", {
129
+ required: ["existing scene_id"],
130
+ received: [sceneId],
131
+ nextSteps: ["Inspect scenes and fix the address."],
132
+ op: kind,
133
+ errorCode: "SCENE_NOT_FOUND",
134
+ });
135
+ }
136
+ const scene = scenes[index];
137
+ const actions = asList(scene["actions"]);
138
+ if (splitAt <= 0 || splitAt >= actions.length) {
139
+ throw opErr("SCRIPT OP BLOCKED: Split index invalid", "Split index out of bounds.", {
140
+ required: [`0 < at_index < ${actions.length}`],
141
+ received: [String(splitAt)],
142
+ nextSteps: ["Choose an action boundary inside the scene."],
143
+ op: kind,
144
+ errorCode: "SPLIT_INDEX_INVALID",
145
+ });
146
+ }
147
+ const newSceneId = strOf(op["new_scene_id"]) || nextSceneId(script);
148
+ if (sceneIdExists(script, newSceneId)) {
149
+ throw opErr("SCRIPT OP BLOCKED: New scene id exists", "New scene id exists.", {
150
+ required: ["unused new_scene_id"],
151
+ received: [newSceneId],
152
+ nextSteps: ["Choose an unused scene id or omit new_scene_id."],
153
+ op: kind,
154
+ errorCode: "NEW_SCENE_ID_EXISTS",
155
+ });
156
+ }
157
+ // The split-off scene inherits the same cast/props/location (v3 shape).
158
+ const bag = sceneRefs(scene);
159
+ const loc = asList(bag["locations"])[0];
160
+ const newScene = {
161
+ scene_id: newSceneId,
162
+ environment: { ...(isDict(scene["environment"]) ? scene["environment"] : {}) },
163
+ location: loc ? { ...loc } : null,
164
+ actors: asList(bag["actors"]).map((r) => ({ ...r })),
165
+ props: asList(bag["props"]).map((r) => ({ ...r })),
166
+ actions: actions.slice(splitAt),
167
+ };
168
+ scene["actions"] = actions.slice(0, splitAt);
169
+ scenes.splice(index + 1, 0, newScene);
170
+ applied.push(kind);
171
+ }
172
+ export function op_scene_merge(__ctx) {
173
+ const { script, op, applied, kind } = __ctx;
174
+ // {from, into}: source disappears, into keeps.
175
+ const fromRaw = op["from"] ?? op["remove_scene_id"];
176
+ const intoRaw = op["into"] ?? op["keep_scene_id"];
177
+ let fromEp, fromScn, intoEp, intoScn;
178
+ if (typeof fromRaw === "string" && fromRaw.includes("/")) {
179
+ [fromEp, fromScn] = parseSceneRef(fromRaw);
180
+ }
181
+ else {
182
+ fromEp = strOf(op["episode_id"]);
183
+ fromScn = strOf(fromRaw);
184
+ }
185
+ if (typeof intoRaw === "string" && intoRaw.includes("/")) {
186
+ [intoEp, intoScn] = parseSceneRef(intoRaw);
187
+ }
188
+ else {
189
+ intoEp = strOf(op["episode_id"]);
190
+ intoScn = strOf(intoRaw);
191
+ }
192
+ if (fromEp !== intoEp) {
193
+ throw opErr("SCRIPT OP BLOCKED: Merge cross-episode", "Scene merge must be within one episode.", {
194
+ required: ["same episode_id on both sides"],
195
+ received: [`${fromEp}/${fromScn} → ${intoEp}/${intoScn}`],
196
+ nextSteps: ["Move one scene first, or merge same-episode scenes."],
197
+ op: kind,
198
+ errorCode: "MERGE_CROSS_EPISODE",
199
+ });
200
+ }
201
+ if (fromScn === intoScn) {
202
+ throw opErr("SCRIPT OP BLOCKED: Merge self", "Cannot merge a scene into itself.", {
203
+ required: ["distinct from / into scenes"],
204
+ received: [`${fromScn} → ${intoScn}`],
205
+ nextSteps: ["Pick two different scenes to merge."],
206
+ op: kind,
207
+ errorCode: "MERGE_SELF",
208
+ });
209
+ }
210
+ const ep = findEpisode(script, fromEp);
211
+ const scenes = asList(ep["scenes"]);
212
+ const intoScene = scenes.find((s) => s["scene_id"] === intoScn);
213
+ const fromScene = scenes.find((s) => s["scene_id"] === fromScn);
214
+ if (!intoScene || !fromScene) {
215
+ throw opErr("SCRIPT OP BLOCKED: Scene not found", "Scene not found.", {
216
+ required: ["existing scene_id on both sides"],
217
+ received: [`from=${fromScn}, into=${intoScn}`],
218
+ nextSteps: ["Inspect scenes and fix the address."],
219
+ op: kind,
220
+ errorCode: "SCENE_NOT_FOUND",
221
+ });
222
+ }
223
+ intoScene["actions"].push(...asList(fromScene["actions"]));
224
+ const intoBag = sceneRefs(intoScene);
225
+ const fromBag = sceneRefs(fromScene);
226
+ // Actor refs are ordered instances and may repeat. Props/location retain
227
+ // their set semantics; into wins for the single-valued location.
228
+ for (const [field, idKey] of [["actors", "actor_id"], ["locations", "location_id"], ["props", "prop_id"]]) {
229
+ if (field === "actors") {
230
+ intoBag[field].push(...asList(fromBag[field]));
231
+ continue;
232
+ }
233
+ const existingIds = new Set();
234
+ for (const ref of asList(intoBag[field]))
235
+ existingIds.add(ref[idKey]);
236
+ for (const ref of asList(fromBag[field])) {
237
+ if (!existingIds.has(ref[idKey])) {
238
+ if (!isList(intoBag[field]))
239
+ intoBag[field] = [];
240
+ intoBag[field].push(ref);
241
+ }
242
+ }
243
+ }
244
+ setSceneRefs(intoScene, intoBag);
245
+ mergeExtendInto(fromScene, intoScene);
246
+ ep["scenes"] = scenes.filter((s) => s !== fromScene);
247
+ applied.push(kind);
248
+ }
249
+ export function op_scene_delete(__ctx) {
250
+ const { script, op, applied, kind } = __ctx;
251
+ const [epId, sceneId] = parseSceneRef(op["at"]);
252
+ const ep = findEpisode(script, epId);
253
+ const scenes = asList(ep["scenes"]);
254
+ const scene = scenes.find((s) => s["scene_id"] === sceneId);
255
+ if (!scene) {
256
+ throw opErr("SCRIPT OP BLOCKED: Scene not found", "Scene not found.", {
257
+ required: ["existing scene_id"],
258
+ received: [`${epId}/${sceneId}`],
259
+ nextSteps: ["Inspect scenes."],
260
+ op: kind,
261
+ errorCode: "SCENE_NOT_FOUND",
262
+ });
263
+ }
264
+ const actions = asList(scene["actions"]);
265
+ const force = Boolean(op["force"]);
266
+ if (actions.length > 0 && !force) {
267
+ throw opErr("SCRIPT OP BLOCKED: Scene non-empty", `Scene has ${actions.length} action(s).`, {
268
+ required: ["empty scene, or force=true"],
269
+ received: [`actions=${actions.length}`],
270
+ nextSteps: ["Pass --force to delete with actions, or move/delete actions first."],
271
+ op: kind,
272
+ errorCode: "SCENE_NON_EMPTY",
273
+ });
274
+ }
275
+ ep["scenes"] = scenes.filter((s) => s !== scene);
276
+ applied.push(kind);
277
+ }
278
+ export function op_scene_move(__ctx) {
279
+ const { script, op, applied, kind } = __ctx;
280
+ const [fromEp, fromScn] = parseSceneRef(op["at"] ?? op["from"]);
281
+ const toEpRaw = strOf(op["to"]);
282
+ let toEp;
283
+ let toAnchorScn = null;
284
+ if (toEpRaw.includes("/")) {
285
+ const [a, b] = parseSceneRef(toEpRaw);
286
+ toEp = a;
287
+ toAnchorScn = b;
288
+ }
289
+ else {
290
+ toEp = toEpRaw;
291
+ }
292
+ if (!toEp) {
293
+ throw opErr("SCRIPT OP BLOCKED: to address invalid", "to address invalid.", {
294
+ required: ["to: ep_NNN or ep_NNN/scn_NNN"],
295
+ received: [toEpRaw],
296
+ nextSteps: ["Pass a target episode id."],
297
+ op: kind,
298
+ errorCode: "SCENE_MOVE_TO_INVALID",
299
+ });
300
+ }
301
+ const fromEpisode = findEpisode(script, fromEp);
302
+ const fromScenes = asList(fromEpisode["scenes"]);
303
+ const sourceIdx = fromScenes.findIndex((s) => s["scene_id"] === fromScn);
304
+ if (sourceIdx < 0) {
305
+ throw opErr("SCRIPT OP BLOCKED: Scene not found", "Source scene not found.", {
306
+ required: ["existing scene_id"],
307
+ received: [`${fromEp}/${fromScn}`],
308
+ nextSteps: ["Inspect scenes."],
309
+ op: kind,
310
+ errorCode: "SCENE_NOT_FOUND",
311
+ });
312
+ }
313
+ const [moved] = fromScenes.splice(sourceIdx, 1);
314
+ fromEpisode["scenes"] = fromScenes;
315
+ const toEpisode = findEpisode(script, toEp);
316
+ const toScenes = asList(toEpisode["scenes"]);
317
+ let destIdx;
318
+ if (op["at_index"] !== undefined && op["at_index"] !== null) {
319
+ const n = Number(op["at_index"]);
320
+ if (!Number.isInteger(n) || n < 0 || n > toScenes.length) {
321
+ throw opErr("SCRIPT OP BLOCKED: at_index out of range", "at_index out of range.", {
322
+ required: [`0..${toScenes.length}`],
323
+ received: [String(op["at_index"])],
324
+ nextSteps: ["Use a valid integer index."],
325
+ op: kind,
326
+ errorCode: "AT_INDEX_OUT_OF_RANGE",
327
+ });
328
+ }
329
+ destIdx = n;
330
+ }
331
+ else if (toAnchorScn) {
332
+ const found = toScenes.findIndex((s) => s["scene_id"] === toAnchorScn);
333
+ if (found < 0) {
334
+ throw opErr("SCRIPT OP BLOCKED: Target scene not found", "Target scene not found.", {
335
+ required: ["existing scene_id in target episode"],
336
+ received: [`${toEp}/${toAnchorScn}`],
337
+ nextSteps: ["Inspect the target episode."],
338
+ op: kind,
339
+ errorCode: "SCENE_NOT_FOUND",
340
+ });
341
+ }
342
+ destIdx = found;
343
+ }
344
+ else {
345
+ destIdx = toScenes.length;
346
+ }
347
+ toScenes.splice(destIdx, 0, moved);
348
+ toEpisode["scenes"] = toScenes;
349
+ applied.push(kind);
350
+ }
351
+ //# sourceMappingURL=ops-scene.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ops-scene.js","sourceRoot":"","sources":["../../../../../src/domain/script/v3/patch/ops-scene.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ import type { OpCtx } from "./types.js";
2
+ export declare function op_state_add(__ctx: OpCtx): void;
3
+ export declare function op_state_rename(__ctx: OpCtx): void;
4
+ export declare function op_state_describe(__ctx: OpCtx): void;
5
+ export declare function op_state_delete(__ctx: OpCtx): void;
6
+ export declare function op_scene_ref_set(__ctx: OpCtx): void;
7
+ export declare function op_scene_ref_clear(__ctx: OpCtx): void;
8
+ export declare function op_scene_ref_remove(__ctx: OpCtx): void;
@@ -0,0 +1,165 @@
1
+ import { stateRejectionReason } from "../../text-util.js";
2
+ import { asList, isDict, isList, opErr, strOf } from "../../shared.js";
3
+ import { findScene, idKeyForKind, nextStateId, pluralForKind } from "../lookups.js";
4
+ import { parseAssetTarget, parseSceneRef, parseStateTarget } from "../address.js";
5
+ import { sceneRefs, setSceneRefs } from "../scene-refs.js";
6
+ import { contextRefIndex, contextRefsForKind, matchingContextRefIndexes, resolveAssetByTarget, resolveState, sceneRefOccurrence, setContextState, validateStateForTarget, } from "./helpers.js";
7
+ export function op_state_add(__ctx) {
8
+ const { script, op, applied, kind } = __ctx;
9
+ const [targetKind, targetId] = parseAssetTarget(op["target"]);
10
+ const asset = resolveAssetByTarget(script, targetKind, targetId);
11
+ const name = strOf(op["name"] || op["state_name"]).trim();
12
+ const description = strOf(op["description"]).trim();
13
+ const stateId = strOf(op["state_id"]).trim() || nextStateId(script);
14
+ if (!name) {
15
+ throw opErr("SCRIPT OP BLOCKED: State name empty", "State name empty.", {
16
+ required: ["name"], received: [JSON.stringify(op)],
17
+ nextSteps: ["Provide a state name."], op: kind, errorCode: "STATE_NAME_EMPTY",
18
+ });
19
+ }
20
+ const reason = stateRejectionReason(targetKind, name);
21
+ if (reason) {
22
+ throw opErr("SCRIPT OP BLOCKED: State label invalid", "State label invalid.", {
23
+ required: ["one clear state label"], received: [name],
24
+ nextSteps: ["Do not combine multiple states into one label."], op: kind, errorCode: "STATE_LABEL_INVALID",
25
+ });
26
+ }
27
+ if (!isList(asset["states"]))
28
+ asset["states"] = [];
29
+ const existingStates = asset["states"];
30
+ if (existingStates.some((s) => strOf(s["state_id"]) === stateId)) {
31
+ throw opErr("SCRIPT OP BLOCKED: State id exists", "State id exists.", { required: ["unused state_id"], received: [stateId], nextSteps: ["Use another state_id or edit the existing state."], op: kind, errorCode: "STATE_ID_EXISTS" });
32
+ }
33
+ if (existingStates.some((s) => strOf(s["state_name"] || s["name"]) === name)) {
34
+ throw opErr("SCRIPT OP BLOCKED: State name exists", "State name exists.", { required: ["unused state name"], received: [name], nextSteps: ["Rename the existing state or choose another name."], op: kind, errorCode: "STATE_NAME_EXISTS" });
35
+ }
36
+ existingStates.push({ state_id: stateId, state_name: name, description });
37
+ op["state_id"] = stateId;
38
+ applied.push(kind);
39
+ }
40
+ export function op_state_rename(__ctx) {
41
+ const { script, op, applied, kind } = __ctx;
42
+ const [targetKind, targetId, stateId] = parseStateTarget(op["target"]);
43
+ const state = resolveState(script, targetKind, targetId, stateId);
44
+ const name = strOf(op["name"] || op["state_name"]).trim();
45
+ if (!name) {
46
+ throw opErr("SCRIPT OP BLOCKED: State name empty", "State name empty.", { required: ["name"], received: [JSON.stringify(op)], nextSteps: ["Provide a state name."], op: kind, errorCode: "STATE_NAME_EMPTY" });
47
+ }
48
+ const reason = stateRejectionReason(targetKind, name);
49
+ if (reason) {
50
+ throw opErr("SCRIPT OP BLOCKED: State label invalid", "State label invalid.", { required: ["one clear state label"], received: [name], nextSteps: ["Do not combine multiple states into one label."], op: kind, errorCode: "STATE_LABEL_INVALID" });
51
+ }
52
+ state["state_name"] = name;
53
+ applied.push(kind);
54
+ }
55
+ export function op_state_describe(__ctx) {
56
+ const { script, op, applied, kind } = __ctx;
57
+ const [targetKind, targetId, stateId] = parseStateTarget(op["target"]);
58
+ const state = resolveState(script, targetKind, targetId, stateId);
59
+ state["description"] = strOf(op["description"]).trim();
60
+ applied.push(kind);
61
+ }
62
+ export function op_state_delete(__ctx) {
63
+ const { script, op, applied, kind } = __ctx;
64
+ const [targetKind, targetId, stateId] = parseStateTarget(op["target"]);
65
+ const asset = resolveAssetByTarget(script, targetKind, targetId);
66
+ resolveState(script, targetKind, targetId, stateId);
67
+ // v3 invariant: every asset keeps exactly one 'default' state.
68
+ if (stateId === "default") {
69
+ throw opErr("SCRIPT OP BLOCKED: Cannot delete default state", "The 'default' state cannot be deleted.", {
70
+ required: ["a non-default state_id"], received: [stateId],
71
+ nextSteps: ["Delete a specific state; the default is the always-present baseline."], op: kind, errorCode: "STATE_DEFAULT_PROTECTED",
72
+ });
73
+ }
74
+ const strategy = strOf(op["strategy"]).trim();
75
+ const replacement = strOf(op["replacement"]).trim();
76
+ if (strategy !== "replace" && strategy !== "remove") {
77
+ throw opErr("SCRIPT OP BLOCKED: Delete strategy invalid", "Delete strategy invalid.", { required: ["strategy: replace or remove"], received: [strategy || "<empty>"], nextSteps: ["Choose replace with --replacement, or remove."], op: kind, errorCode: "DELETE_STRATEGY_INVALID" });
78
+ }
79
+ if (strategy === "replace") {
80
+ if (!replacement) {
81
+ throw opErr("SCRIPT OP BLOCKED: Replacement missing", "Replacement missing.", { required: ["replacement state_id"], received: ["<empty>"], nextSteps: ["Pass --replacement with an existing state_id."], op: kind, errorCode: "REPLACEMENT_MISSING" });
82
+ }
83
+ validateStateForTarget(script, targetKind, targetId, replacement);
84
+ }
85
+ const idKey = idKeyForKind(targetKind);
86
+ // Scrub scene refs that carried the deleted state: replace → replacement,
87
+ // remove → clear to null (state lives only on scene refs in v3).
88
+ for (const ep of asList(script["episodes"])) {
89
+ for (const scene of asList(ep["scenes"])) {
90
+ const bag = sceneRefs(scene);
91
+ let touched = false;
92
+ for (const ref of contextRefsForKind(bag, targetKind)) {
93
+ if (strOf(ref[idKey]) === targetId && strOf(ref["state_id"]) === stateId) {
94
+ ref["state_id"] = strategy === "replace" ? replacement : null;
95
+ touched = true;
96
+ }
97
+ }
98
+ if (touched)
99
+ setSceneRefs(scene, bag);
100
+ }
101
+ }
102
+ asset["states"] = asList(asset["states"]).filter((s) => strOf(s["state_id"]) !== stateId);
103
+ applied.push(kind);
104
+ }
105
+ export function op_scene_ref_set(__ctx) {
106
+ const { script, op, applied, kind } = __ctx;
107
+ const [epId, sceneId] = parseSceneRef(op["at"]);
108
+ const [targetKind, targetId] = parseAssetTarget(op["target"]);
109
+ const append = Boolean(op["append"]);
110
+ const occurrence = sceneRefOccurrence(op["occurrence"], kind);
111
+ if (append && occurrence !== undefined) {
112
+ throw opErr("SCRIPT OP BLOCKED: scene ref append is ambiguous", "append and occurrence cannot be combined.", {
113
+ required: ["append=true, or occurrence=<n>"],
114
+ received: ["append=true", `occurrence=${occurrence}`],
115
+ nextSteps: ["Append a new ref or update an existing occurrence."],
116
+ op: kind,
117
+ errorCode: "SCENE_REF_APPEND_FLAG_CONFLICT",
118
+ });
119
+ }
120
+ setContextState(script, epId, sceneId, targetKind, targetId, strOf(op["state"] || op["state_id"]).trim(), { append, occurrence, op: kind });
121
+ applied.push(kind);
122
+ }
123
+ export function op_scene_ref_clear(__ctx) {
124
+ const { script, op, applied, kind } = __ctx;
125
+ const [epId, sceneId] = parseSceneRef(op["at"]);
126
+ const [targetKind, targetId] = parseAssetTarget(op["target"]);
127
+ setContextState(script, epId, sceneId, targetKind, targetId, null, {
128
+ occurrence: sceneRefOccurrence(op["occurrence"], kind),
129
+ op: kind,
130
+ });
131
+ applied.push(kind);
132
+ }
133
+ export function op_scene_ref_remove(__ctx) {
134
+ const { script, op, applied, kind } = __ctx;
135
+ const [epId, sceneId] = parseSceneRef(op["at"]);
136
+ const [targetKind, targetId] = parseAssetTarget(op["target"]);
137
+ const scene = findScene(script, epId, sceneId);
138
+ const bag = sceneRefs(scene);
139
+ const idKey = idKeyForKind(targetKind);
140
+ const refs = contextRefsForKind(bag, targetKind);
141
+ const occurrence = sceneRefOccurrence(op["occurrence"], kind);
142
+ const removeIndex = contextRefIndex(refs, idKey, targetId, occurrence, kind);
143
+ const matchingIndexes = matchingContextRefIndexes(refs, idKey, targetId);
144
+ if (targetKind === "actor"
145
+ && removeIndex !== undefined
146
+ && matchingIndexes.length === 1
147
+ && asList(scene["actions"]).some((action) => {
148
+ const speaker = action["speaker"];
149
+ return isDict(speaker) && strOf(speaker["actor_id"]) === targetId;
150
+ })) {
151
+ throw opErr("SCRIPT OP BLOCKED: Actor is used in scene", "Cannot remove an actor reference while the actor speaks in this scene.", {
152
+ required: ["all dialogue/inner_thought speaker refs moved or removed before scene actor removal"],
153
+ received: [`${epId}/${sceneId} actor:${targetId}`],
154
+ nextSteps: ["Reassign or remove the actor's lines, then remove the scene ref."],
155
+ op: kind,
156
+ errorCode: "ACTOR_IN_USE_IN_SCENE",
157
+ });
158
+ }
159
+ if (removeIndex !== undefined)
160
+ refs.splice(removeIndex, 1);
161
+ bag[pluralForKind(targetKind)] = refs;
162
+ setSceneRefs(scene, bag);
163
+ applied.push(kind);
164
+ }
165
+ //# sourceMappingURL=ops-state.js.map