@hypit/hypit 0.1.3 → 0.1.5

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 (486) hide show
  1. package/README.md +5 -3
  2. package/dist/public/caption.d.ts +206 -183
  3. package/dist/public/composition.d.ts +25 -3
  4. package/dist/public/endpoint-kit.d.ts +24 -2
  5. package/dist/public/generation.d.ts +5 -1
  6. package/dist/public/hyperframes.d.ts +19 -1
  7. package/dist/public/narrative.d.ts +17 -3
  8. package/dist/public/performance.d.ts +1590 -0
  9. package/dist/public/program-space.d.ts +179 -32
  10. package/dist/public/runtime-kit.d.ts +21 -8
  11. package/dist/public/sound.d.ts +822 -0
  12. package/dist/public/speech.d.ts +41 -0
  13. package/dist/public/studio-adapter.d.ts +107 -16
  14. package/dist/public/temporal-markup.d.ts +9 -44
  15. package/dist/public/temporal.d.ts +37 -28
  16. package/dist/public/{semantic-track.d.ts → timeline.d.ts} +62 -49
  17. package/examples/README.md +18 -10
  18. package/examples/minimal-author-package/packages/example-component/preview/preview.svml +19 -12
  19. package/examples/minimal-author-package/packages/example-component/src/component.ts +5 -5
  20. package/examples/minimal-author-package/packages/example-component/src/fragment.ts +3 -5
  21. package/examples/minimal-author-package/packages/example-component/src/manifest.ts +8 -10
  22. package/examples/minimal-author-package/packages/example-component/src/surface.ts +2 -2
  23. package/examples/provider-package/README.md +78 -0
  24. package/examples/provider-package/hypit.runtime.json +12 -0
  25. package/examples/provider-package/packages/provider-images/package.json +11 -0
  26. package/examples/provider-package/packages/provider-images/src/activation.ts +24 -0
  27. package/examples/provider-package/packages/provider-images/src/provider.ts +122 -0
  28. package/examples/provider-package/packages/provider-images/tsconfig.json +9 -0
  29. package/examples/semantic-composition/README.md +6 -0
  30. package/examples/semantic-composition/chat.svml +6 -5
  31. package/examples/semantic-composition/packages/chat-scene/README.md +3 -3
  32. package/examples/semantic-composition/packages/chat-scene/src/activation.ts +18 -21
  33. package/examples/semantic-composition/packages/chat-scene/src/render.ts +4 -4
  34. package/examples/semantic-composition/packages/performance-styles/README.md +42 -0
  35. package/examples/semantic-composition/packages/performance-styles/package.json +25 -0
  36. package/examples/semantic-composition/packages/performance-styles/src/activation.ts +57 -0
  37. package/examples/semantic-composition/packages/performance-styles/src/render.ts +54 -0
  38. package/examples/semantic-composition/packages/performance-styles/src/studio.ts +28 -0
  39. package/examples/semantic-composition/packages/performance-styles/tsconfig.json +18 -0
  40. package/examples/semantic-composition/packages/responsive-explainer/README.md +16 -9
  41. package/examples/semantic-composition/packages/responsive-explainer/src/activation.ts +12 -12
  42. package/examples/semantic-composition/packages/responsive-explainer/src/render.ts +5 -5
  43. package/examples/semantic-composition/packages/sound-styles/README.md +36 -0
  44. package/examples/semantic-composition/packages/sound-styles/package.json +25 -0
  45. package/examples/semantic-composition/packages/sound-styles/src/activation.ts +53 -0
  46. package/examples/semantic-composition/packages/sound-styles/src/render.ts +14 -0
  47. package/examples/semantic-composition/packages/sound-styles/tsconfig.json +18 -0
  48. package/package.json +35 -15
  49. package/packages/audio-track/README.md +20 -13
  50. package/packages/audio-track/package.json +1 -1
  51. package/packages/audio-track/src/component.ts +4 -4
  52. package/packages/audio-track/src/fragment.ts +6 -5
  53. package/packages/audio-track/src/index.ts +1 -1
  54. package/packages/audio-track/src/manifest.ts +17 -16
  55. package/packages/audio-track/src/program.ts +21 -25
  56. package/packages/audio-track/src/surface.ts +19 -18
  57. package/packages/audio-track-studio/README.md +23 -0
  58. package/packages/audio-track-studio/src/index.ts +33 -19
  59. package/packages/author-kit/README.md +1 -1
  60. package/packages/background-removal/README.md +4 -7
  61. package/packages/browser-capture/package.json +1 -1
  62. package/packages/build-result/README.md +69 -0
  63. package/packages/build-result/package.json +2 -1
  64. package/packages/build-result/src/decode.ts +12 -8
  65. package/packages/build-result/src/execution-log.ts +17 -0
  66. package/packages/build-result/src/file-reference.ts +42 -0
  67. package/packages/build-result/src/index.ts +4 -0
  68. package/packages/build-result/src/replace-file-windows.ts +58 -0
  69. package/packages/build-result/src/replace-file.ts +11 -0
  70. package/packages/build-result/src/store.ts +58 -14
  71. package/packages/build-result/src/types.ts +41 -8
  72. package/packages/build-result/src/writer.ts +12 -1
  73. package/packages/build-result-fs/README.md +23 -1
  74. package/packages/build-result-s3/README.md +5 -0
  75. package/packages/build-result-s3/src/repository.ts +23 -5
  76. package/packages/caption/README.md +61 -73
  77. package/packages/caption/package.json +3 -2
  78. package/packages/caption/src/activation.ts +2 -2
  79. package/packages/caption/src/component.ts +20 -5
  80. package/packages/caption/src/display.ts +3 -18
  81. package/packages/caption/src/fragment.ts +3 -7
  82. package/packages/caption/src/index.ts +6 -5
  83. package/packages/caption/src/manifest.ts +29 -46
  84. package/packages/caption/src/style.ts +24 -135
  85. package/packages/caption/src/surface.ts +12 -92
  86. package/packages/caption/src/temporalize.ts +18 -53
  87. package/packages/caption/src/types.ts +8 -35
  88. package/packages/caption/src/visibility.ts +23 -0
  89. package/packages/caption-fine/README.md +31 -11
  90. package/packages/caption-fine/package.json +4 -2
  91. package/packages/caption-fine/src/component.ts +3 -3
  92. package/packages/caption-fine/src/fragment.ts +7 -19
  93. package/packages/caption-fine/src/index.ts +2 -0
  94. package/packages/caption-fine/src/manifest.ts +27 -18
  95. package/packages/caption-fine/src/recipe.ts +7 -0
  96. package/packages/caption-fine/src/render.ts +62 -49
  97. package/packages/caption-fine/src/schedule.ts +39 -35
  98. package/packages/caption-fine/src/style.ts +10 -9
  99. package/packages/caption-fine/src/surface.ts +62 -35
  100. package/packages/caption-fine/src/types.ts +2 -0
  101. package/packages/caption-fine-studio/README.md +24 -2
  102. package/packages/caption-fine-studio/package.json +10 -3
  103. package/packages/caption-fine-studio/src/activation.ts +3 -3
  104. package/packages/caption-fine-studio/src/index.ts +61 -40
  105. package/packages/cli/README.md +81 -3
  106. package/packages/cli/package.json +1 -0
  107. package/packages/cli/src/arguments.ts +39 -15
  108. package/packages/cli/src/build-planning.ts +9 -3
  109. package/packages/cli/src/command.ts +7 -1
  110. package/packages/cli/src/commands/environment.ts +66 -27
  111. package/packages/cli/src/commands/execution.ts +81 -26
  112. package/packages/cli/src/commands/results.ts +7 -11
  113. package/packages/cli/src/index.ts +2 -2
  114. package/packages/cli/src/machine-view.ts +15 -5
  115. package/packages/cli/src/main.ts +38 -42
  116. package/packages/cli/src/observation.ts +7 -1
  117. package/packages/cli/src/output.ts +92 -34
  118. package/packages/cli/src/result-export.ts +22 -13
  119. package/packages/cli/src/run-file.ts +19 -8
  120. package/packages/cli/src/view.ts +64 -18
  121. package/packages/comment-sticker/README.md +3 -3
  122. package/packages/comment-sticker/package.json +1 -1
  123. package/packages/comment-sticker/src/component.ts +4 -4
  124. package/packages/comment-sticker/src/fragment.ts +5 -4
  125. package/packages/comment-sticker/src/manifest.ts +7 -6
  126. package/packages/comment-sticker/src/program.ts +9 -9
  127. package/packages/comment-sticker/src/surface.ts +6 -7
  128. package/packages/comment-sticker-studio/src/index.ts +2 -1
  129. package/packages/compiler-node/src/compiler.ts +1 -0
  130. package/packages/composition/README.md +21 -0
  131. package/packages/composition/src/audio-presentation.ts +44 -0
  132. package/packages/composition/src/index.ts +3 -0
  133. package/packages/composition/src/schema.ts +8 -3
  134. package/packages/composition/src/track.ts +15 -1
  135. package/packages/credential-store-env/README.md +1 -1
  136. package/packages/deck-track/README.md +3 -3
  137. package/packages/deck-track/package.json +1 -1
  138. package/packages/deck-track/src/component.ts +5 -5
  139. package/packages/deck-track/src/fragment.ts +6 -5
  140. package/packages/deck-track/src/lower.ts +12 -12
  141. package/packages/deck-track/src/manifest.ts +8 -7
  142. package/packages/deck-track/src/program.ts +13 -16
  143. package/packages/deck-track/src/surface.ts +9 -10
  144. package/packages/driver-node/src/driver.ts +41 -3
  145. package/packages/elevenlabs-speech/README.md +27 -0
  146. package/packages/{provider-xiaomi-mimo → elevenlabs-speech}/package.json +5 -8
  147. package/packages/elevenlabs-speech/src/activation.ts +26 -0
  148. package/packages/elevenlabs-speech/src/fragment.ts +11 -0
  149. package/packages/elevenlabs-speech/src/index.ts +111 -0
  150. package/packages/elevenlabs-speech/src/surface.ts +167 -0
  151. package/packages/endpoint-kit/README.md +24 -0
  152. package/packages/endpoint-kit/src/index.ts +7 -1
  153. package/packages/estimate/README.md +56 -3
  154. package/packages/estimate/src/program.ts +7 -8
  155. package/packages/film/README.md +12 -7
  156. package/packages/film/package.json +1 -1
  157. package/packages/film/src/component.ts +4 -4
  158. package/packages/film/src/fragment.ts +6 -5
  159. package/packages/film/src/manifest.ts +11 -10
  160. package/packages/film/src/program.ts +5 -5
  161. package/packages/film/src/recipe.ts +2 -1
  162. package/packages/film/src/surface.ts +6 -6
  163. package/packages/film-studio/package.json +1 -1
  164. package/packages/film-studio/src/index.ts +2 -2
  165. package/packages/fishaudio-speech/README.md +33 -0
  166. package/packages/fishaudio-speech/package.json +21 -0
  167. package/packages/fishaudio-speech/src/activation.ts +32 -0
  168. package/packages/fishaudio-speech/src/fragment.ts +11 -0
  169. package/packages/fishaudio-speech/src/index.ts +156 -0
  170. package/packages/fishaudio-speech/src/surface.ts +192 -0
  171. package/packages/fonts-open/README.md +5 -0
  172. package/packages/fonts-open/package.json +5 -1
  173. package/packages/fonts-open/src/studio.ts +21 -0
  174. package/packages/generation/README.md +11 -1
  175. package/packages/generation/src/mapping.ts +28 -30
  176. package/packages/gpt-image/README.md +1 -2
  177. package/packages/grok-imagine/README.md +1 -2
  178. package/packages/hyperframes/README.md +7 -3
  179. package/packages/hyperframes/src/browser-program.ts +11 -2
  180. package/packages/hyperframes/src/document.ts +15 -2
  181. package/packages/interview-emoji-reveal/README.md +4 -4
  182. package/packages/interview-emoji-reveal/package.json +1 -1
  183. package/packages/interview-emoji-reveal/src/component.ts +4 -4
  184. package/packages/interview-emoji-reveal/src/fragment.ts +6 -5
  185. package/packages/interview-emoji-reveal/src/manifest.ts +9 -8
  186. package/packages/interview-emoji-reveal/src/program.ts +14 -14
  187. package/packages/interview-emoji-reveal/src/surface.ts +8 -9
  188. package/packages/media-execution/README.md +7 -3
  189. package/packages/media-execution/src/audio-presentation.ts +23 -0
  190. package/packages/media-execution/src/execute.ts +2 -0
  191. package/packages/media-pipeline/README.md +7 -3
  192. package/packages/media-pipeline/src/audio-plan.ts +4 -1
  193. package/packages/media-pipeline/src/component.ts +16 -2
  194. package/packages/media-pipeline/src/manifest.ts +3 -1
  195. package/packages/media-pipeline/src/types.ts +2 -1
  196. package/packages/media-track/README.md +14 -47
  197. package/packages/media-track/package.json +1 -1
  198. package/packages/media-track/preview/preview.svml +5 -5
  199. package/packages/media-track/src/author.ts +12 -6
  200. package/packages/media-track/src/component.ts +10 -16
  201. package/packages/media-track/src/fragment.ts +8 -7
  202. package/packages/media-track/src/index.ts +3 -1
  203. package/packages/media-track/src/lower.ts +7 -7
  204. package/packages/media-track/src/manifest.ts +16 -38
  205. package/packages/media-track/src/program.ts +62 -67
  206. package/packages/media-track/src/sampling.ts +6 -6
  207. package/packages/media-track/src/sequence.ts +8 -8
  208. package/packages/media-track/src/surface.ts +25 -43
  209. package/packages/media-track-studio/README.md +9 -0
  210. package/packages/media-track-studio/src/index.ts +23 -13
  211. package/packages/mimo-speech/README.md +1 -1
  212. package/packages/minimax-h3/README.md +1 -1
  213. package/packages/nano-banana/README.md +1 -1
  214. package/packages/narrative/README.md +23 -1
  215. package/packages/narrative/src/identity.ts +11 -0
  216. package/packages/narrative/src/index.ts +3 -0
  217. package/packages/narrative/src/schema.ts +28 -27
  218. package/packages/narrative/src/selection.ts +52 -0
  219. package/packages/narrative/src/types.ts +2 -0
  220. package/packages/package-loader-node/README.md +30 -0
  221. package/packages/package-loader-node/package.json +5 -2
  222. package/packages/package-loader-node/src/distribution-resolution.ts +10 -3
  223. package/packages/package-loader-node/src/index.ts +1 -0
  224. package/packages/package-loader-node/src/loader.ts +12 -15
  225. package/packages/package-loader-node/src/location.ts +27 -1
  226. package/packages/package-loader-node/src/module-scope.ts +183 -0
  227. package/packages/package-loader-node/src/types.ts +4 -0
  228. package/packages/performance/README.md +83 -0
  229. package/packages/performance/package.json +30 -0
  230. package/packages/performance/src/activation.ts +11 -0
  231. package/packages/performance/src/component.ts +46 -0
  232. package/packages/performance/src/index.ts +6 -0
  233. package/packages/performance/src/manifest.ts +53 -0
  234. package/packages/{media-track/src/performance.ts → performance/src/media.ts} +9 -10
  235. package/packages/performance/src/program.ts +51 -0
  236. package/packages/performance/src/style.ts +35 -0
  237. package/packages/performance/src/surface.ts +99 -0
  238. package/packages/performance-studio/README.md +25 -0
  239. package/packages/performance-studio/package.json +21 -0
  240. package/packages/performance-studio/src/activation.ts +6 -0
  241. package/packages/performance-studio/src/index.ts +84 -0
  242. package/packages/program-space/README.md +9 -18
  243. package/packages/program-space/src/activation.ts +1 -5
  244. package/packages/program-space/src/index.ts +2 -11
  245. package/packages/program-space/src/surface.ts +1 -20
  246. package/packages/project-context-node/README.md +20 -0
  247. package/packages/project-context-node/package.json +10 -0
  248. package/packages/project-context-node/src/index.ts +3 -0
  249. package/packages/{cli → project-context-node}/src/runtime-selection.ts +7 -2
  250. package/packages/provider-hyperframes-local/README.md +43 -15
  251. package/packages/provider-hyperframes-local/src/activation.ts +4 -3
  252. package/packages/provider-hyperframes-local/src/capture-process.ts +26 -4
  253. package/packages/provider-hyperframes-local/src/capture.ts +96 -26
  254. package/packages/provider-hyperframes-local/src/concurrency.ts +86 -0
  255. package/packages/provider-hyperframes-local/src/opaque-capture.ts +92 -0
  256. package/packages/provider-hyperframes-local/src/options.ts +2 -0
  257. package/packages/provider-hyperframes-local/src/program.ts +6 -3
  258. package/packages/provider-hyperframes-local/src/progress.ts +53 -0
  259. package/packages/provider-hyperframes-local/src/provider.ts +18 -5
  260. package/packages/provider-hyperframes-local/src/render.ts +48 -7
  261. package/packages/provider-hypihub/README.md +48 -17
  262. package/packages/provider-hypihub/package.json +2 -0
  263. package/packages/provider-hypihub/src/mapping.ts +31 -7
  264. package/packages/provider-hypihub/src/oauth.ts +6 -0
  265. package/packages/provider-hypihub/src/provider.ts +25 -13
  266. package/packages/provider-hypihub/src/routes.ts +1 -2
  267. package/packages/provider-hypihub/src/upload.ts +2 -0
  268. package/packages/provider-media-local/README.md +3 -4
  269. package/packages/provider-whisperx-local/README.md +57 -0
  270. package/packages/provider-whisperx-local/src/program.ts +1 -0
  271. package/packages/provider-whisperx-local/src/provider.ts +3 -0
  272. package/packages/ranking/README.md +8 -6
  273. package/packages/ranking/package.json +1 -1
  274. package/packages/ranking/src/component.ts +6 -6
  275. package/packages/ranking/src/fragment.ts +11 -7
  276. package/packages/ranking/src/manifest.ts +21 -14
  277. package/packages/ranking/src/render.ts +33 -35
  278. package/packages/ranking/src/schedule.ts +16 -19
  279. package/packages/ranking/src/surface.ts +12 -13
  280. package/packages/ranking-studio/README.md +29 -0
  281. package/packages/ranking-studio/package.json +8 -3
  282. package/packages/ranking-studio/src/index.ts +71 -12
  283. package/packages/render-hyperframes/README.md +7 -7
  284. package/packages/render-hyperframes/package.json +1 -1
  285. package/packages/render-hyperframes/src/component.ts +11 -1
  286. package/packages/render-hyperframes/src/fragment.ts +7 -4
  287. package/packages/render-hyperframes/src/manifest.ts +4 -4
  288. package/packages/render-hyperframes/src/surface.ts +6 -6
  289. package/packages/runtime/README.md +8 -1
  290. package/packages/runtime/src/catalog.ts +2 -0
  291. package/packages/runtime/src/execution.ts +15 -4
  292. package/packages/runtime/src/index.ts +2 -1
  293. package/packages/runtime/src/log.ts +51 -0
  294. package/packages/runtime/src/types.ts +5 -8
  295. package/packages/runtime-host-node/README.md +30 -0
  296. package/packages/runtime-host-node/package.json +1 -0
  297. package/packages/runtime-host-node/src/index.ts +25 -9
  298. package/packages/runtime-host-node/src/packages.ts +47 -50
  299. package/packages/runtime-kit/README.md +5 -0
  300. package/packages/runtime-kit/src/index.ts +3 -1
  301. package/packages/runtime-local/README.md +111 -4
  302. package/packages/runtime-local/src/config.ts +202 -56
  303. package/packages/runtime-local/src/control.ts +9 -1
  304. package/packages/runtime-local/src/executor.ts +66 -0
  305. package/packages/runtime-local/src/host.ts +37 -17
  306. package/packages/runtime-local/src/log.ts +48 -0
  307. package/packages/runtime-local/src/programs.ts +41 -25
  308. package/packages/runtime-local/src/result-writer.ts +2 -0
  309. package/packages/runtime-local/src/runtime.ts +10 -6
  310. package/packages/runtime-local/src/supervisor.ts +142 -0
  311. package/packages/runtime-local/src/types.ts +9 -2
  312. package/packages/runtime-local/src/worker-process.ts +7 -24
  313. package/packages/runtime-local/src/worker.ts +55 -83
  314. package/packages/screen-overlay/README.md +3 -3
  315. package/packages/screen-overlay/package.json +1 -1
  316. package/packages/screen-overlay/src/component.ts +3 -3
  317. package/packages/screen-overlay/src/fragment.ts +5 -4
  318. package/packages/screen-overlay/src/manifest.ts +7 -6
  319. package/packages/screen-overlay/src/program.ts +9 -9
  320. package/packages/screen-overlay/src/surface.ts +6 -7
  321. package/packages/script/README.md +37 -2
  322. package/packages/script/src/edit.ts +123 -73
  323. package/packages/script/src/lexical.ts +40 -6
  324. package/packages/script/src/manifest.ts +2 -2
  325. package/packages/script/src/narrative.ts +1 -0
  326. package/packages/script/src/parser.ts +36 -8
  327. package/packages/script/src/surface.ts +4 -3
  328. package/packages/script/src/types.ts +5 -1
  329. package/packages/script-studio/package.json +9 -3
  330. package/packages/script-studio/src/index.ts +2 -0
  331. package/packages/script-studio/src/projection.ts +105 -0
  332. package/packages/seedance/README.md +30 -1
  333. package/packages/seedance/src/index.ts +18 -7
  334. package/packages/seedance/src/surface.ts +17 -4
  335. package/packages/seedance-kits/README.md +10 -2
  336. package/packages/seedance-kits/kits/speaker-v1.svs +5 -5
  337. package/packages/seedream/README.md +1 -1
  338. package/packages/sound/README.md +81 -0
  339. package/packages/sound/package.json +25 -0
  340. package/packages/sound/src/activation.ts +11 -0
  341. package/packages/sound/src/component.ts +28 -0
  342. package/packages/sound/src/index.ts +5 -0
  343. package/packages/sound/src/manifest.ts +47 -0
  344. package/packages/sound/src/program.ts +84 -0
  345. package/packages/sound/src/style.ts +34 -0
  346. package/packages/sound/src/surface.ts +90 -0
  347. package/packages/sound-studio/README.md +22 -0
  348. package/packages/sound-studio/package.json +20 -0
  349. package/packages/sound-studio/src/activation.ts +6 -0
  350. package/packages/sound-studio/src/index.ts +74 -0
  351. package/packages/speech/README.md +2 -2
  352. package/packages/speech-alignment/src/align.ts +45 -21
  353. package/packages/speech-alignment/src/local.ts +8 -0
  354. package/packages/speech-alignment/src/locate.ts +1 -1
  355. package/packages/store-sqlite/README.md +7 -0
  356. package/packages/store-sqlite/src/store.ts +84 -83
  357. package/packages/studio/INSPECTOR.md +117 -0
  358. package/packages/studio/README.md +149 -14
  359. package/packages/studio/package.json +8 -7
  360. package/packages/studio/src/build-library.ts +99 -84
  361. package/packages/studio/src/companion-assembly.ts +1 -0
  362. package/packages/studio/src/domain.ts +1 -1
  363. package/packages/studio/src/fallback-companions.ts +3 -3
  364. package/packages/studio/src/feedback-server.ts +51 -0
  365. package/packages/studio/src/feedback-store.ts +66 -0
  366. package/packages/studio/src/feedback.ts +60 -0
  367. package/packages/studio/src/library-media.ts +19 -0
  368. package/packages/studio/src/parameter-values.ts +83 -1
  369. package/packages/studio/src/parameters.ts +132 -43
  370. package/packages/studio/src/preview/render.ts +5 -1
  371. package/packages/studio/src/preview/runtime-shim.ts +49 -3
  372. package/packages/studio/src/programme.ts +14 -30
  373. package/packages/studio/src/server.ts +66 -34
  374. package/packages/studio/src/shared.ts +24 -8
  375. package/packages/studio/src/snapshot.ts +21 -132
  376. package/packages/studio/src/studio-preflight.ts +3 -3
  377. package/packages/studio/src/studio-registry.ts +72 -6
  378. package/packages/studio/src/style.css +342 -190
  379. package/packages/studio/src/temporal-edit.ts +131 -0
  380. package/packages/studio/src/ui/artifact-name.ts +80 -0
  381. package/packages/studio/src/ui/artifact-preview.ts +99 -0
  382. package/packages/studio/src/ui/comments.ts +233 -0
  383. package/packages/studio/src/ui/icons.ts +10 -1
  384. package/packages/studio/src/ui/library.ts +373 -192
  385. package/packages/studio/src/ui/main.ts +291 -110
  386. package/packages/studio/src/ui/material-preview.ts +1 -1
  387. package/packages/studio/src/ui/overlay.ts +31 -26
  388. package/packages/studio/src/ui/scrub-preview.ts +108 -0
  389. package/packages/studio/src/ui/sidebar-panel.ts +31 -0
  390. package/packages/studio/src/ui/stage.ts +188 -9
  391. package/packages/studio/src/ui/timeline.ts +187 -281
  392. package/packages/studio/start.ts +19 -5
  393. package/packages/studio-adapter/README.md +151 -11
  394. package/packages/studio-adapter/src/index.ts +126 -14
  395. package/packages/temporal/README.md +6 -6
  396. package/packages/temporal/package.json +1 -1
  397. package/packages/temporal/src/component.ts +5 -6
  398. package/packages/temporal/src/index.ts +8 -6
  399. package/packages/temporal/src/location.ts +11 -11
  400. package/packages/temporal/src/projection.ts +19 -19
  401. package/packages/temporal/src/rational.ts +4 -4
  402. package/packages/temporal-markup/EDITING.md +183 -0
  403. package/packages/temporal-markup/README.md +31 -11
  404. package/packages/temporal-markup/package.json +1 -1
  405. package/packages/temporal-markup/src/index.ts +20 -25
  406. package/packages/temporal-markup/src/space.ts +10 -41
  407. package/packages/timeline/README.md +31 -0
  408. package/packages/{semantic-track → timeline}/package.json +1 -1
  409. package/packages/timeline/src/activation.ts +8 -0
  410. package/packages/timeline/src/component.ts +24 -0
  411. package/packages/timeline/src/identity.ts +60 -0
  412. package/packages/timeline/src/index.ts +6 -0
  413. package/packages/{semantic-track → timeline}/src/location.ts +20 -20
  414. package/packages/timeline/src/manifest.ts +39 -0
  415. package/packages/{semantic-track → timeline}/src/projection.ts +14 -14
  416. package/packages/timeline/src/types.ts +24 -0
  417. package/packages/timeline-author/README.md +68 -0
  418. package/packages/{speech-track → timeline-author}/package.json +6 -4
  419. package/packages/timeline-author/src/activation.ts +22 -0
  420. package/packages/{speech-track → timeline-author}/src/component.ts +15 -13
  421. package/packages/{speech-track → timeline-author}/src/fragment.ts +14 -23
  422. package/packages/timeline-author/src/index.ts +7 -0
  423. package/packages/timeline-author/src/manifest.ts +78 -0
  424. package/packages/timeline-author/src/program.ts +107 -0
  425. package/packages/timeline-author/src/surface.ts +46 -0
  426. package/packages/timeline-author/src/types.ts +6 -0
  427. package/packages/typography-track/README.md +4 -4
  428. package/packages/typography-track/package.json +1 -1
  429. package/packages/typography-track/src/component.ts +4 -4
  430. package/packages/typography-track/src/fragment.ts +4 -3
  431. package/packages/typography-track/src/manifest.ts +11 -9
  432. package/packages/typography-track/src/program.ts +15 -15
  433. package/packages/typography-track/src/surface.ts +17 -18
  434. package/packages/typography-track-studio/package.json +8 -3
  435. package/packages/typography-track-studio/src/index.ts +5 -1
  436. package/packages/video-cli/README.md +16 -4
  437. package/packages/video-cli/package.json +2 -1
  438. package/packages/video-cli/src/creation.ts +25 -9
  439. package/packages/video-cli/src/index.ts +1 -1
  440. package/packages/video-cli/src/studio-distribution.ts +2 -1
  441. package/packages/volcengine-matting/README.md +3 -3
  442. package/packages/whisperx/README.md +8 -1
  443. package/packages/workspace/src/index.ts +2 -0
  444. package/packages/workspace-fs-node/README.md +4 -1
  445. package/packages/workspace-fs-node/src/workspace.ts +3 -1
  446. package/services/whisperx/README.md +14 -0
  447. package/services/whisperx/pyproject.toml +2 -0
  448. package/services/whisperx/uv.lock +20 -20
  449. package/packages/provider-hyperframes-aws-lambda/README.md +0 -30
  450. package/packages/provider-hyperframes-aws-lambda/package.json +0 -30
  451. package/packages/provider-hyperframes-aws-lambda/src/activation.ts +0 -97
  452. package/packages/provider-hyperframes-aws-lambda/src/client.ts +0 -114
  453. package/packages/provider-hyperframes-aws-lambda/src/index.ts +0 -21
  454. package/packages/provider-hyperframes-aws-lambda/src/provider.ts +0 -522
  455. package/packages/provider-kie/README.md +0 -134
  456. package/packages/provider-kie/package.json +0 -43
  457. package/packages/provider-kie/src/activation.ts +0 -71
  458. package/packages/provider-kie/src/index.ts +0 -10
  459. package/packages/provider-kie/src/mapping.ts +0 -182
  460. package/packages/provider-kie/src/provider.ts +0 -657
  461. package/packages/provider-kie/src/routes.ts +0 -150
  462. package/packages/provider-xiaomi-mimo/README.md +0 -32
  463. package/packages/provider-xiaomi-mimo/src/activation.ts +0 -57
  464. package/packages/provider-xiaomi-mimo/src/index.ts +0 -5
  465. package/packages/provider-xiaomi-mimo/src/provider.ts +0 -214
  466. package/packages/runtime/src/environment.ts +0 -6
  467. package/packages/semantic-track/README.md +0 -21
  468. package/packages/semantic-track/src/activation.ts +0 -8
  469. package/packages/semantic-track/src/component.ts +0 -24
  470. package/packages/semantic-track/src/identity.ts +0 -58
  471. package/packages/semantic-track/src/index.ts +0 -6
  472. package/packages/semantic-track/src/manifest.ts +0 -38
  473. package/packages/semantic-track/src/types.ts +0 -26
  474. package/packages/speech-track/README.md +0 -51
  475. package/packages/speech-track/src/activation.ts +0 -19
  476. package/packages/speech-track/src/index.ts +0 -7
  477. package/packages/speech-track/src/manifest.ts +0 -73
  478. package/packages/speech-track/src/program.ts +0 -64
  479. package/packages/speech-track/src/surface.ts +0 -35
  480. package/packages/speech-track/src/types.ts +0 -6
  481. package/packages/speech-track-studio/README.md +0 -3
  482. package/packages/speech-track-studio/package.json +0 -14
  483. package/packages/speech-track-studio/src/activation.ts +0 -7
  484. package/packages/speech-track-studio/src/index.ts +0 -40
  485. /package/packages/{cli → project-context-node}/src/project-context.ts +0 -0
  486. /package/packages/{speech-track → timeline-author}/preview/Track.png +0 -0
@@ -1,5 +1,44 @@
1
1
  import type { CanonicalValue, ValueSchema } from "@hypit/protocol";
2
2
  import { formatSvsValue } from "@hypit/svs";
3
+ import type { StudioInspectorField, StudioParameterControl, StudioParameterOption, StudioNumberPresentation } from "@hypit/studio-adapter";
4
+
5
+ export const parameterOption = (option: StudioParameterOption): Exclude<StudioParameterOption, string> =>
6
+ typeof option === "string" ? { value: option, label: option } : option;
7
+
8
+ // Keep binary floating-point residue out of decimal controls (0.55 × 100 is 55).
9
+ const scaledDecimal = (value: number, scale: number): number =>
10
+ scale === 1 ? value : Number((value * scale).toPrecision(15));
11
+
12
+ export function parameterNumber(value: CanonicalValue, presentation: StudioNumberPresentation = {}): { value: number; suffix: string } {
13
+ let held = value;
14
+ let suffix = "";
15
+ if (presentation.suffixes !== undefined) {
16
+ if (typeof held !== "string") throw new Error("A suffixed number must be authored as text.");
17
+ const text = held.trim();
18
+ const found = [...presentation.suffixes].sort((a, b) => b.length - a.length).find(item => text.endsWith(item));
19
+ if (found === undefined) throw new Error("The authored unit is not supported by this field.");
20
+ suffix = found;
21
+ held = text.slice(0, text.length - suffix.length).trim();
22
+ }
23
+ if (typeof held !== "number" && (typeof held !== "string" || !/^[+-]?(?:\d+(?:\.\d*)?|\.\d+)(?:e[+-]?\d+)?$/iu.test(held.trim()))) {
24
+ throw new Error("This field needs a numeric value.");
25
+ }
26
+ const number = scaledDecimal(Number(held), presentation.scale ?? 1);
27
+ if (!Number.isFinite(number)) throw new Error("This field needs a finite number.");
28
+ return { value: number, suffix };
29
+ }
30
+
31
+ /** Decode the displayed edit before validating and serializing the authored value. */
32
+ export function parameterAuthorValue(field: StudioInspectorField, displayed: CanonicalValue): CanonicalValue {
33
+ if (field.control !== "number") return displayed;
34
+ if (typeof displayed !== "number" || !Number.isFinite(displayed)) throw new Error(`${field.label} expects a finite number.`);
35
+ const presentation = field.number ?? {};
36
+ if (presentation.minimum !== undefined && displayed < presentation.minimum) throw new Error(`${field.label} must be at least ${presentation.minimum}.`);
37
+ if (presentation.maximum !== undefined && displayed > presentation.maximum) throw new Error(`${field.label} must be at most ${presentation.maximum}.`);
38
+ const value = scaledDecimal(displayed, 1 / (presentation.scale ?? 1));
39
+ if (!Number.isFinite(value)) throw new Error(`${field.label} cannot be represented.`);
40
+ return presentation.suffixes === undefined ? value : `${value}${parameterNumber(field.value, presentation).suffix}`;
41
+ }
3
42
 
4
43
  function fail(path: string, expectation: string): never {
5
44
  throw new Error(`${path} ${expectation}.`);
@@ -76,6 +115,49 @@ export function validateParameterValue(value: CanonicalValue, schema: ValueSchem
76
115
 
77
116
  export function serializeParameterValue(value: CanonicalValue, language: "svml" | "svs" | "svrun"): string {
78
117
  if (language === "svs") return formatSvsValue(value);
79
- if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") return String(value);
118
+ if (typeof value === "string") return value.replaceAll("&", "&amp;").replaceAll('"', "&quot;").replaceAll("'", "&apos;").replaceAll("<", "&lt;").replaceAll(">", "&gt;");
119
+ if (typeof value === "number" || typeof value === "boolean") return String(value);
80
120
  throw new Error(`${language.toUpperCase()} parameter bindings currently accept scalar values only.`);
81
121
  }
122
+
123
+ /** Record alternatives are selected by an explicitly literal-valued field. */
124
+ export function parameterRecordVariants(schema: ValueSchema): readonly {
125
+ key: string; value: CanonicalValue; schema: Extract<ValueSchema, { kind: "object" }>;
126
+ }[] {
127
+ if (schema.kind !== "oneOf" || !schema.variants.every(variant => variant.kind === "object")) return [];
128
+ const records = schema.variants as readonly Extract<ValueSchema, { kind: "object" }>[];
129
+ const key = Object.keys(records[0]?.fields ?? {}).find(name => records.every(record => record.fields[name]?.schema.kind === "literal")
130
+ && new Set(records.map(record => JSON.stringify((record.fields[name]!.schema as { value: CanonicalValue }).value))).size === records.length);
131
+ return key === undefined ? [] : records.map(record => ({ key, value: (record.fields[key]!.schema as { value: CanonicalValue }).value, schema: record }));
132
+ }
133
+
134
+ export function parameterRecordSchema(schema: ValueSchema, value: CanonicalValue): Extract<ValueSchema, { kind: "object" }> | undefined {
135
+ if (schema.kind === "object") return schema;
136
+ if (value === null || Array.isArray(value) || typeof value !== "object") return undefined;
137
+ return parameterRecordVariants(schema).find(variant => (value as Readonly<Record<string, CanonicalValue>>)[variant.key] === variant.value)?.schema;
138
+ }
139
+
140
+ /** Replace only a Companion-declared group; unrelated attributes and child content survive. */
141
+ export function serializeAttributeGroup(field: StudioInspectorField, value: CanonicalValue): string {
142
+ const group = field.edit?.attributes;
143
+ if (!group || value === null || Array.isArray(value) || typeof value !== "object") throw new Error("Expected an attribute record.");
144
+ const entries = Object.entries(value);
145
+ if (entries.some(([name]) => !Object.hasOwn(group.ranges, name))) throw new Error("Attribute is outside this group.");
146
+ let text = field.edit!.source.preimage;
147
+ const ranges = Object.values(group.ranges).filter((range): range is NonNullable<typeof range> => range !== null);
148
+ for (const range of ranges.sort((a, b) => b.start - a.start)) text = text.slice(0, range.start) + text.slice(range.end);
149
+ const attributes = entries.map(([name, held]) => ` ${name}="${serializeParameterValue(held, field.edit!.language)}"`).join("");
150
+ return text.slice(0, group.insertionOffset) + attributes + text.slice(group.insertionOffset);
151
+ }
152
+
153
+ export function parameterControlForSchema(schema: ValueSchema | undefined): StudioParameterControl | undefined {
154
+ if (schema === undefined) return undefined;
155
+ if (schema.kind === "boolean") return "boolean";
156
+ if (schema.kind === "number") return "number";
157
+ if (schema.kind === "string") return schema.enum === undefined
158
+ ? schema.format === "color" ? "color" : "text"
159
+ : "select";
160
+ if (schema.kind === "array") return "list";
161
+ if (schema.kind === "object" || parameterRecordVariants(schema).length > 0) return "record";
162
+ return undefined;
163
+ }
@@ -5,7 +5,6 @@ import type {
5
5
  StudioInspectorFieldDeclaration,
6
6
  StudioSourceBinding,
7
7
  StudioSourceBindingDeclaration,
8
- StudioParameterControl,
9
8
  StudioRecipeReferenceBindingDeclaration,
10
9
  StudioEntityDraft,
11
10
  StudioEditSource,
@@ -17,6 +16,11 @@ import type {
17
16
  StudioTimelineGesture,
18
17
  } from "@hypit/studio-adapter";
19
18
  import { parseSvs } from "@hypit/svs";
19
+ import { parseOpeningTag } from "@hypit/markup";
20
+ import { parameterControlForSchema, parameterRecordSchema } from "./parameter-values.js";
21
+ import type { CanonicalValue } from "@hypit/protocol";
22
+
23
+ import type { StudioCompanionRegistry } from "./studio-registry.js";
20
24
 
21
25
  import type { Range } from "./shared.js";
22
26
  import type { Placement } from "./observe.js";
@@ -30,6 +34,7 @@ export type StudioSourceFile = {
30
34
  };
31
35
 
32
36
  type AuthorElement = {
37
+ readonly range: Range;
33
38
  readonly authorElement?: string;
34
39
  readonly authorEndpoints: Readonly<Record<string, string>>;
35
40
  readonly id?: string;
@@ -48,6 +53,7 @@ function authoredElements(placements: readonly Placement[]): readonly AuthorElem
48
53
  ...(placement.authorElement === undefined ? {} : { authorElement: placement.authorElement }),
49
54
  authorEndpoints: placement.authorEndpoints ?? {},
50
55
  ...(placement.id === undefined ? {} : { id: placement.id }),
56
+ range: placement.range,
51
57
  sourcePath: placement.sourcePath,
52
58
  attributes: placement.attributes,
53
59
  references: placement.referenceAttributes,
@@ -60,6 +66,7 @@ function authoredElements(placements: readonly Placement[]): readonly AuthorElem
60
66
  ...(child.authorElement === undefined ? {} : { authorElement: child.authorElement }),
61
67
  authorEndpoints: child.authorEndpoints ?? {},
62
68
  ...(child.id === undefined ? {} : { id: child.id }),
69
+ range: child.range,
63
70
  sourcePath: child.sourcePath,
64
71
  attributes: child.attributes,
65
72
  references: child.referenceAttributes,
@@ -175,7 +182,8 @@ function recipeParameters(input: {
175
182
  return input.recipe.bindings.flatMap((declaration): readonly StudioSourceBinding[] => {
176
183
  const property = recipe.properties.find((candidate) => candidate.name === declaration.name);
177
184
  if (property === undefined) {
178
- if (declaration.fallback === undefined) return [];
185
+ const fallback = typeof declaration.fallback === "function" ? declaration.fallback(recipe.value.properties) : declaration.fallback;
186
+ if (fallback === undefined) return [];
179
187
  const close = recipe.range.end - 1;
180
188
  const lineStart = Math.max(source.text.lastIndexOf("\n", close - 1), source.text.lastIndexOf("\r", close - 1)) + 1;
181
189
  const closeIndent = source.text.slice(lineStart, close);
@@ -189,7 +197,7 @@ function recipeParameters(input: {
189
197
  id: `${input.draft.id}:${input.referenceName}:${declaration.name}`,
190
198
  binding: `${input.referenceName}.${declaration.name}`,
191
199
  name: declaration.name,
192
- value: declaration.fallback,
200
+ value: fallback,
193
201
  ...(declaration.schema === undefined ? {} : { schema: declaration.schema }),
194
202
  language: "svs" as const,
195
203
  writable: declaration.writable ?? true,
@@ -220,6 +228,57 @@ function recipeParameters(input: {
220
228
  });
221
229
  }
222
230
 
231
+ function attributeGroup(file: StudioSourceFile, target: AuthorElement, draft: StudioEntityDraft,
232
+ declaration: StudioSourceBindingDeclaration, binding: string, root: string): readonly StudioSourceBinding[] {
233
+ if (declaration.schema === undefined) throw new Error(`Attribute group ${binding} needs a schema.`);
234
+ const tag = parseOpeningTag({ name: file.path, text: file.text }, target.range.start);
235
+ const sourceRange = { start: target.range.start, end: tag.end };
236
+ const preimage = file.text.slice(sourceRange.start, sourceRange.end);
237
+ const opening = /^<[\w:.-]+/u.exec(preimage);
238
+ if (!opening) throw new Error(`Cannot locate opening tag for ${binding}.`);
239
+ const fallback = typeof declaration.fallback === "function" ? declaration.fallback(target.attributes) : declaration.fallback;
240
+ const value: Record<string, CanonicalValue> = fallback !== null && typeof fallback === "object" && !Array.isArray(fallback) ? { ...(fallback as Readonly<Record<string, CanonicalValue>>) } : {};
241
+ const ranges: Record<string, Range | null> = {};
242
+ let writable = declaration.writable === true;
243
+ for (const name of declaration.attributes!) {
244
+ const range = target.attributeValueRanges[name];
245
+ ranges[name] = null;
246
+ if (range === undefined) continue;
247
+ if (target.references[name] !== undefined) { writable = false; value[name] = target.references[name]!; continue; }
248
+ value[name] = target.attributes[name] ?? target.references[name] ?? "";
249
+ const before = file.text.slice(target.range.start, range.start);
250
+ const escaped = name.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
251
+ const prefix = new RegExp(`\\s+${escaped}\\s*=\\s*["']$`, "u").exec(before);
252
+ if (!prefix) throw new Error(`Cannot locate scalar attribute ${name}.`);
253
+ ranges[name] = { start: prefix.index, end: range.end - target.range.start + 1 };
254
+ }
255
+ const schema = parameterRecordSchema(declaration.schema, value);
256
+ for (const [name, held] of Object.entries(value)) {
257
+ if (target.references[name] !== undefined || typeof held !== "string") continue;
258
+ const kind = schema?.fields[name]?.schema.kind;
259
+ if (kind === "number" && held.trim() !== "") value[name] = Number(held);
260
+ if (kind === "boolean" && (held === "true" || held === "false")) value[name] = held === "true";
261
+ }
262
+ return [{ id: `${draft.id}:${binding}`, binding, name: declaration.name, value, schema: declaration.schema,
263
+ language: file.language, writable, source: { path: relative(root, sourceAbsolute(root, target.sourcePath)),
264
+ range: sourceRange, preimage }, attributes: { insertionOffset: opening[0].length, ranges } }];
265
+ }
266
+
267
+ function omittedAttribute(file: StudioSourceFile, target: AuthorElement, draft: StudioEntityDraft,
268
+ declaration: StudioSourceBindingDeclaration, binding: string, root: string): readonly StudioSourceBinding[] {
269
+ const value = typeof declaration.fallback === "function" ? declaration.fallback(target.attributes) : declaration.fallback;
270
+ if (value === undefined) return [];
271
+ const tag = /^<[\w:.-]+/u.exec(file.text.slice(target.range.start));
272
+ if (tag === null) throw new Error(`Cannot locate opening tag for ${binding}.`);
273
+ const at = target.range.start + tag[0].length;
274
+ return [{ id: `${draft.id}:${binding}`, binding, name: declaration.name, value,
275
+ ...(declaration.schema === undefined ? {} : { schema: declaration.schema }),
276
+ language: file.language, writable: declaration.writable === true,
277
+ source: { path: relative(root, sourceAbsolute(root, target.sourcePath)),
278
+ range: { start: at, end: at }, preimage: "", prefix: ` ${declaration.name}="`, suffix: '"' },
279
+ }];
280
+ }
281
+
223
282
  function referencedParameters(input: {
224
283
  readonly root: string;
225
284
  readonly files: readonly StudioSourceFile[];
@@ -238,8 +297,25 @@ function referencedParameters(input: {
238
297
  const file = sourceFor(input.root, target.sourcePath, input.files);
239
298
  if (file === undefined) return [];
240
299
  return input.declarations.flatMap((declaration) => {
300
+ if (declaration.attributes) return attributeGroup(file, target, input.draft, declaration, `${input.referenceName}.${declaration.name}`, input.root);
301
+ const nestedPath = target.references[declaration.name];
302
+ const referenced = nestedPath === undefined || declaration.referenced === undefined ? [] : referencedParameters({
303
+ root: input.root, files: input.files, draft: input.draft, placements: input.placements,
304
+ referenceName: `${input.referenceName}.${declaration.name}`,
305
+ referencePath: nestedPath,
306
+ ...(target.resolvedReferences[declaration.name] === undefined ? {} : { referenceRef: target.resolvedReferences[declaration.name] }),
307
+ declarations: declaration.referenced,
308
+ });
309
+ const recipe = nestedPath === undefined || declaration.recipe === undefined ? [] : recipeParameters({
310
+ root: input.root, files: input.files, draft: input.draft, placements: input.placements,
311
+ current: file, referenceName: `${input.referenceName}.${declaration.name}`,
312
+ referencePath: nestedPath,
313
+ ...(target.resolvedReferences[declaration.name] === undefined ? {} : { referenceRef: target.resolvedReferences[declaration.name] }), recipe: declaration.recipe,
314
+ through: declaration.recipe.through ?? [],
315
+ });
316
+ const nested = [...referenced, ...recipe];
241
317
  const range = target.attributeValueRanges[declaration.name];
242
- if (range === undefined) return [];
318
+ if (range === undefined) return [...omittedAttribute(file, target, input.draft, declaration, `${input.referenceName}.${declaration.name}`, input.root), ...nested];
243
319
  const preimage = file.text.slice(range.start, range.end);
244
320
  const reference = target.references[declaration.name];
245
321
  const value = reference === undefined ? (target.attributes[declaration.name] ?? preimage) : reference;
@@ -263,7 +339,7 @@ function referencedParameters(input: {
263
339
  ...(!writable
264
340
  ? { disabledReason: reference === undefined ? "该几何值由组件声明为只读。" : "引用由作者在 SVML 中绑定,面板不替换引用关系。" }
265
341
  : {}),
266
- } satisfies StudioSourceBinding];
342
+ } satisfies StudioSourceBinding, ...nested];
267
343
  });
268
344
  }
269
345
 
@@ -280,6 +356,37 @@ function parameterReference(
280
356
  return ref === undefined ? { path } : { path, ref };
281
357
  }
282
358
 
359
+ /** Resolve only references opted into by the consuming Companion. */
360
+ export function composeParameterDeclarations(input: {
361
+ readonly placement: StudioPlacement | undefined;
362
+ readonly draft: StudioEntityDraft;
363
+ readonly placements: readonly Placement[];
364
+ readonly registry: StudioCompanionRegistry;
365
+ readonly bindings: readonly StudioSourceBindingDeclaration[];
366
+ readonly inspector: readonly StudioInspectorFieldDeclaration[];
367
+ }): { bindings: readonly StudioSourceBindingDeclaration[]; inspector: readonly StudioInspectorFieldDeclaration[] } {
368
+ const inspector = [...input.inspector];
369
+ const element = input.placement === undefined ? undefined : elementFor(input.placement, input.draft);
370
+ const expand = (declarations: readonly StudioSourceBindingDeclaration[], owner: AuthorElement | undefined,
371
+ prefix: string, seen: ReadonlySet<string>): readonly StudioSourceBindingDeclaration[] => declarations.map(declaration => {
372
+ const path = prefix ? `${prefix}.${declaration.name}` : declaration.name;
373
+ const reference = prefix ? owner?.references[declaration.name] : input.draft.parameterReferences?.[declaration.name] ?? owner?.references[declaration.name];
374
+ const resolved = !prefix && input.draft.parameterReferences?.[declaration.name] !== undefined ? undefined : owner?.resolvedReferences[declaration.name];
375
+ const target = input.placements.find(candidate => resolved !== undefined
376
+ ? candidate.records.includes(resolved) || candidate.outputs.includes(resolved)
377
+ : candidate.id === reference && candidate.sourcePath === owner?.sourcePath);
378
+ const companion = declaration.companion && target !== undefined
379
+ ? input.registry.parameterCompanionFor(target.module, target.surface) : undefined;
380
+ const key = target?.authorElement ?? `${target?.sourcePath}:${target?.range.start}`;
381
+ if (companion !== undefined && seen.has(key)) throw new Error(`Circular Studio parameter reference at ${path}.`);
382
+ if (companion !== undefined) inspector.push(...companion.inspector.map(field => ({ ...field, binding: `${path}.${field.binding}` })));
383
+ const next = target === undefined ? undefined : elementFor(target, { ...input.draft, authoredId: target.id ?? "", elementRange: target.range });
384
+ const nested = [...(declaration.referenced ?? []), ...(companion?.bindings ?? [])];
385
+ return { ...declaration, referenced: expand(nested, next, path, new Set([...seen, key])) };
386
+ });
387
+ return { bindings: expand(input.bindings, element, "", new Set()), inspector };
388
+ }
389
+
283
390
  /**
284
391
  * Expose only attributes a package explicitly registered. The source range is
285
392
  * still discovered by the generic markup frontend, while the meaning and
@@ -302,8 +409,9 @@ export function sourceBindingsForDraft(input: {
302
409
 
303
410
  const direct = input.declarations.flatMap((declaration) => {
304
411
  const name = declaration.name;
412
+ if (declaration.attributes) return attributeGroup(file, element, input.draft, declaration, name, input.root);
305
413
  const range = element.attributeValueRanges[name];
306
- if (range === undefined) return [];
414
+ if (range === undefined) return omittedAttribute(file, element, input.draft, declaration, name, input.root);
307
415
  const preimage = file.text.slice(range.start, range.end);
308
416
  const reference = element.references[name];
309
417
  const value = reference === undefined
@@ -364,29 +472,17 @@ export function sourceBindingsForDraft(input: {
364
472
  return [...direct, ...recipes];
365
473
  }
366
474
 
367
- function controlForSchema(schema: StudioSourceBinding["schema"]): StudioParameterControl | undefined {
368
- if (schema === undefined) return undefined;
369
- if (schema.kind === "boolean") return "boolean";
370
- if (schema.kind === "number") return "number";
371
- if (schema.kind === "string") return schema.enum === undefined
372
- ? schema.format === "color" ? "color" : "text"
373
- : "select";
374
- if (schema.kind === "array") return "list";
375
- if (schema.kind === "object") return "record";
376
- return undefined;
377
- }
378
-
379
- /** Resolve the Companion's visible field table against real writable bindings. */
475
+ /** Resolve the Companion's visible field table against real bindings and entity facts. */
380
476
  export function inspectorFieldsForBindings(
381
477
  draft: StudioEntityDraft,
382
478
  bindings: readonly StudioSourceBinding[],
383
479
  declarations: readonly StudioInspectorFieldDeclaration[],
384
480
  ): readonly StudioInspectorField[] {
385
481
  const byBinding = new Map(bindings.map((binding) => [binding.binding, binding] as const));
386
- return declarations.flatMap((declaration): readonly StudioInspectorField[] => {
482
+ const fields = declarations.flatMap((declaration): readonly StudioInspectorField[] => {
387
483
  const binding = byBinding.get(declaration.binding);
388
- if (binding === undefined || !binding.writable) return [];
389
- const control = declaration.control ?? controlForSchema(binding.schema);
484
+ if (binding === undefined) return [];
485
+ const control = declaration.control ?? (binding.attributes ? "record" : parameterControlForSchema(binding.schema));
390
486
  if (control === undefined) {
391
487
  throw new Error(`Studio Inspector binding ${declaration.binding} has neither a control nor a supported public schema.`);
392
488
  }
@@ -400,10 +496,12 @@ export function inspectorFieldsForBindings(
400
496
  ...(declaration.options !== undefined || schemaOptions === undefined
401
497
  ? {}
402
498
  : { options: schemaOptions }),
403
- language: binding.language,
404
- source: binding.source,
499
+ ...(binding.writable ? { edit: { language: binding.language, source: binding.source, ...(binding.attributes ? { attributes: binding.attributes } : {}) } } : {}),
405
500
  }];
406
501
  });
502
+ return [...fields, ...(draft.inspector ?? []).map((fact): StudioInspectorField => ({
503
+ ...fact, id: `${draft.id}:inspector:fact:${fact.id}`, control: "text",
504
+ }))];
407
505
  }
408
506
 
409
507
  /** Runtime authority, rather than a Companion allowlist, makes timing fields writable. */
@@ -484,7 +582,7 @@ export function resolveTimelineEditHandles(
484
582
  moveEffect?: "translate-window" | "move-start",
485
583
  ): StudioEditHandle => {
486
584
  const unavailable = affected.find(({ endpoint }) => endpoint.authority.kind === "fixed");
487
- if (unavailable !== undefined) return disabled(gesture, "该端点由 Program 或 Segment 结构固定,不能从组件时间线反写。");
585
+ if (unavailable !== undefined) return disabled(gesture, "该时间表达未开放时间轴回写。");
488
586
  const projected: ({ readonly missing: string } | StudioEditSource)[] = [];
489
587
  for (const { endpoint, role } of affected) {
490
588
  if (endpoint.authority.kind !== "parameter") continue;
@@ -527,24 +625,15 @@ export function resolveTimelineEditHandles(
527
625
  }
528
626
  const start = { endpoint: projection.start, role: "start" as const };
529
627
  const end = { endpoint: projection.end, role: "end" as const };
530
- const move = projection.end.authority.kind === "parameter" && projection.end.authority.relation === "after-start"
531
- ? [start]
532
- : projection.start.authority.kind === "parameter" && projection.start.authority.relation === "before-end"
533
- ? [end]
534
- : [start, end];
535
- const trimStart = projection.start.authority.kind === "parameter" && projection.start.authority.relation === "before-end"
536
- ? [start]
537
- : projection.end.authority.kind === "parameter" && projection.end.authority.relation === "after-start"
538
- ? [start, end]
539
- : [start];
540
- const trimEnd = projection.end.authority.kind === "parameter" && projection.end.authority.relation === "after-start"
541
- ? [end]
542
- : projection.start.authority.kind === "parameter" && projection.start.authority.relation === "before-end"
543
- ? [start, end]
544
- : [end];
628
+ if (projection.end.authority.kind === "parameter" && projection.end.authority.relation === "after-start") {
629
+ return [handle("move", [start], "translate-window"), handle("trim-end", [end])];
630
+ }
631
+ if (projection.start.authority.kind === "parameter" && projection.start.authority.relation === "before-end") {
632
+ return [handle("move", [end], "translate-window"), handle("trim-start", [start])];
633
+ }
545
634
  return [
546
- handle("move", move, "translate-window"),
547
- handle("trim-start", trimStart),
548
- handle("trim-end", trimEnd),
635
+ handle("move", [start, end], "translate-window"),
636
+ handle("trim-start", [start]),
637
+ handle("trim-end", [end]),
549
638
  ];
550
639
  }
@@ -45,7 +45,11 @@ export function renderPreview(input: RenderInput): string {
45
45
  data-loop="${clip.source.loop}"
46
46
  data-phase="${clip.source.phaseSample / 48_000}"
47
47
  data-playback-rate="${clip.playbackRate}"
48
- data-gain="${clip.gain}"></audio>`;
48
+ data-gain="${clip.gain}"
49
+ data-presentation="${encodeURIComponent(JSON.stringify({
50
+ gainEnvelope: clip.gainEnvelope, audibility: clip.audibility,
51
+ fadeInSamples: clip.fadeInSamples, fadeOutSamples: clip.fadeOutSamples,
52
+ }))}"></audio>`;
49
53
  }).join("");
50
54
  return injectRuntimeShim(html, audio);
51
55
  }
@@ -1,3 +1,5 @@
1
+ import { audioEnvelopeGainAt } from "@hypit/composition";
2
+
1
3
  /**
2
4
  * Studio's frame driver for a compiled HyperFrames document.
3
5
  *
@@ -48,6 +50,7 @@ function shim(): string {
48
50
  rate: parseFloat(element.getAttribute('data-playback-rate') || '1') || 1
49
51
  });
50
52
  }
53
+ var audioContext;
51
54
  var programmeAudio = [];
52
55
  for (var element of document.querySelectorAll('.hypit-studio-audio')) {
53
56
  programmeAudio.push({
@@ -59,10 +62,51 @@ function shim(): string {
59
62
  loop: element.getAttribute('data-loop') === 'true',
60
63
  phase: parseFloat(element.getAttribute('data-phase') || '0') || 0,
61
64
  rate: parseFloat(element.getAttribute('data-playback-rate') || '1') || 1,
62
- gain: parseFloat(element.getAttribute('data-gain') || '1') || 1
65
+ gain: Number(element.getAttribute('data-gain') ?? '1'),
66
+ presentation: JSON.parse(decodeURIComponent(element.getAttribute('data-presentation') || '%7B%7D'))
63
67
  });
64
68
  }
65
69
 
70
+ function scheduleEnvelope(param, points, sample, now) {
71
+ param.cancelScheduledValues(now);
72
+ param.setValueAtTime(audioEnvelopeGainAt(points, sample), now);
73
+ for (var point of points || []) {
74
+ if (point.sample > sample) param.linearRampToValueAtTime(point.gain, now + (point.sample - sample) / 48000);
75
+ }
76
+ }
77
+
78
+ // Each factor has its own GainNode so intersecting ramps multiply exactly.
79
+ // These are the same absolute-sample envelopes consumed by the render mixer.
80
+ function placeAudioGain(record, seconds) {
81
+ if (!record.nodes) {
82
+ var source = audioContext.createMediaElementSource(record.element);
83
+ record.nodes = Array.from({ length: 5 }, function () { return audioContext.createGain(); });
84
+ var previous = source;
85
+ for (var node of record.nodes) { previous.connect(node); previous = node; }
86
+ previous.connect(audioContext.destination);
87
+ record.element.volume = 1;
88
+ }
89
+ var sample = seconds * 48000;
90
+ var now = audioContext.currentTime;
91
+ var p = record.presentation;
92
+ var start = record.start * 48000, end = (record.start + record.duration) * 48000;
93
+ record.nodes[0].gain.setValueAtTime(record.gain, now);
94
+ scheduleEnvelope(record.nodes[1].gain, p.gainEnvelope, sample, now);
95
+ scheduleEnvelope(record.nodes[2].gain, p.fadeInSamples > 0
96
+ ? [{ sample: start, gain: 0 }, { sample: start + p.fadeInSamples, gain: 1 }] : undefined, sample, now);
97
+ scheduleEnvelope(record.nodes[3].gain, p.fadeOutSamples > 0
98
+ ? [{ sample: end - p.fadeOutSamples, gain: 1 }, { sample: end, gain: 0 }] : undefined, sample, now);
99
+ var gate = record.nodes[4].gain;
100
+ gate.cancelScheduledValues(now);
101
+ gate.setValueAtTime(p.audibility === undefined || p.audibility.some(function (span) {
102
+ return sample >= span.startSample && sample < span.endSampleExclusive;
103
+ }) ? 1 : 0, now);
104
+ for (var span of p.audibility || []) {
105
+ if (span.startSample > sample) gate.setValueAtTime(1, now + (span.startSample - sample) / 48000);
106
+ if (span.endSampleExclusive > sample) gate.setValueAtTime(0, now + (span.endSampleExclusive - sample) / 48000);
107
+ }
108
+ }
109
+
66
110
  function seekDecoded(element, target) {
67
111
  if (Math.abs(element.currentTime - target) < 0.0005 && element.readyState >= 2) return Promise.resolve();
68
112
  return new Promise(function (resolve) {
@@ -148,7 +192,7 @@ function shim(): string {
148
192
  } else {
149
193
  if (Math.abs(element.currentTime - target) > 0.08) element.currentTime = target;
150
194
  element.playbackRate = record.rate;
151
- element.volume = Math.max(0, Math.min(1, record.gain));
195
+ placeAudioGain(record, currentSeconds + frameSeconds / 2);
152
196
  if (element.paused) {
153
197
  var started = element.play();
154
198
  if (started) started.catch(function () {});
@@ -169,6 +213,8 @@ function shim(): string {
169
213
  };
170
214
  window.__hypitPlayFrame = function (frame) {
171
215
  playing = true;
216
+ if (programmeAudio.length && !audioContext) audioContext = new AudioContext();
217
+ if (audioContext && audioContext.state === 'suspended') audioContext.resume();
172
218
  return apply(frame / fps, false);
173
219
  };
174
220
  window.__hypitFrameReady = apply(0, true);
@@ -178,7 +224,7 @@ function shim(): string {
178
224
  }
179
225
 
180
226
  export function injectRuntimeShim(html: string, audio = ""): string {
181
- const script = audio + shim();
227
+ const script = audio + shim().replace("(function () {", `(function () {\n${audioEnvelopeGainAt.toString()}`);
182
228
  const at = html.lastIndexOf("</body>");
183
229
  return at < 0 ? html + script : html.slice(0, at) + script + html.slice(at);
184
230
  }
@@ -4,13 +4,13 @@ import { sameType } from "@hypit/protocol";
4
4
  import type { Composition } from "@hypit/composition";
5
5
  import { compositionTypes } from "@hypit/composition";
6
6
  import {
7
- projectSemanticProgramSpace,
7
+ projectTimelineSpace,
8
8
  semanticAnchorFrames,
9
- semanticTrackSpans,
10
- } from "@hypit/semantic-track";
11
- import type { SemanticTrack } from "@hypit/semantic-track";
12
- import { semanticTrackTypes } from "@hypit/semantic-track";
13
- import { assertProgramSpaceIdentity, programSpaceTypes } from "@hypit/program-space";
9
+ timelineSpans,
10
+ } from "@hypit/timeline";
11
+ import type { Timeline } from "@hypit/timeline";
12
+ import { timelineTypes } from "@hypit/timeline";
13
+ import { assertProgramSpaceIdentity } from "@hypit/program-space";
14
14
  import type { ProgramSpace } from "@hypit/program-space";
15
15
  import type { StudioResolvedTrack, StudioTemporalBinding } from "@hypit/studio-adapter";
16
16
  import type { RuntimeHostTransientExecution } from "@hypit/runtime-host-node";
@@ -36,7 +36,6 @@ export type Preview = {
36
36
  readonly values: ReadonlyMap<string, unknown>;
37
37
  readonly temporalBindings: ReadonlyMap<string, readonly StudioTemporalBinding[]>;
38
38
  readonly composition: Composition;
39
- readonly timing: "measured" | "authored";
40
39
  readonly narrativeId?: string;
41
40
  readonly timingOutput?: { readonly name: string; readonly ref: string };
42
41
  readonly timingCandidateId?: string;
@@ -173,11 +172,11 @@ export async function preview(input: {
173
172
  const timingType = timingOutput?.typeRef ?? timingRecord?.type;
174
173
  const timingValue = selectedValue(executed.state, input.timeRef);
175
174
  if (timingValue?.kind !== "inline" || timingType === undefined) throw new Error("Studio requires a resolved film time source.");
176
- const semantic = sameType(timingType, semanticTrackTypes.track) ? timingValue.value as unknown as SemanticTrack : undefined;
177
- if (semantic === undefined && !sameType(timingType, programSpaceTypes.programSpace)) throw new Error("Unsupported Studio time source.");
178
- const spans = semantic === undefined ? [] : semanticTrackSpans(semantic);
179
- const anchors = semantic === undefined ? new Map<string, number>() : semanticAnchorFrames(semantic);
180
- const space = semantic === undefined ? timingValue.value as unknown as ProgramSpace : projectSemanticProgramSpace(semantic);
175
+ if (!sameType(timingType, timelineTypes.track)) throw new Error("Studio requires the declared Timeline.");
176
+ const semantic = timingValue.value as unknown as Timeline;
177
+ const spans = timelineSpans(semantic);
178
+ const anchors = semanticAnchorFrames(semantic);
179
+ const space = projectTimelineSpace(semantic);
181
180
  assertProgramSpaceIdentity(space);
182
181
  const rate = space.frameRate;
183
182
  const compositionValue = selectedValue(executed.state, input.compositionRef);
@@ -227,22 +226,8 @@ export async function preview(input: {
227
226
  const stored = selectedValue(executed.state, target.ref);
228
227
  if (stored?.kind === "inline") values.set(target.ref, stored.value);
229
228
  }
230
- // Author Records are already deterministic inline values from this exact
231
- // compilation. Studio Track Companions may need them to name a resolved projection
232
- // (for example Caption cue text); exposing them here avoids recomputing the
233
- // domain value or turning a Record into a fake graph target.
234
- for (const placement of input.source.observations.placements) {
235
- for (const value of placement.values) {
236
- const suffixes = [`::record::${value.id}`, `::output::${value.id}`];
237
- for (const reference of input.projections.flatMap((projection) => projection.trace.references)) {
238
- if (suffixes.some((suffix) => reference.ref.endsWith(suffix))) values.set(reference.ref, value.value);
239
- }
240
- }
241
- }
242
- // Script is a raw Surface, so its inline Records are not among the structured
243
- // element observations above. They are still ordinary Author values from
244
- // the same compilation and are needed to turn Caption atom ids back into the
245
- // text the author actually sees.
229
+ // Author records from this compilation already carry exact qualified references.
230
+ // Expose referenced inline values to Companions without guessing their owner by suffix.
246
231
  for (const record of input.source.compiled.program.records) {
247
232
  if (record.value.kind !== "inline") continue;
248
233
  if (input.projections.some((projection) => projection.trace.references
@@ -257,8 +242,7 @@ export async function preview(input: {
257
242
  values,
258
243
  temporalBindings,
259
244
  composition,
260
- timing: semantic === undefined ? "authored" : "measured",
261
- ...(semantic === undefined ? {} : { narrativeId: semantic.narrativeId }),
245
+ ...(semantic.narrativeId === undefined ? {} : { narrativeId: semantic.narrativeId }),
262
246
  timingOutput: { name: timingOutput?.name ?? space.id, ref: input.timeRef },
263
247
  ...(timingCandidateId === undefined ? {} : { timingCandidateId }),
264
248
  timingCandidateOrigin: timingCandidateId === undefined ? "source" : "run",