@hypit/hypit 0.1.4 → 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 (449) hide show
  1. package/README.md +4 -2
  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 +77 -15
  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 +32 -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 +28 -17
  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 +11 -0
  63. package/packages/build-result/src/decode.ts +2 -0
  64. package/packages/build-result/src/execution-log.ts +17 -0
  65. package/packages/build-result/src/index.ts +1 -0
  66. package/packages/build-result/src/store.ts +14 -1
  67. package/packages/build-result/src/types.ts +3 -0
  68. package/packages/build-result-s3/src/repository.ts +4 -0
  69. package/packages/caption/README.md +61 -73
  70. package/packages/caption/package.json +3 -2
  71. package/packages/caption/src/activation.ts +2 -2
  72. package/packages/caption/src/component.ts +20 -5
  73. package/packages/caption/src/display.ts +3 -18
  74. package/packages/caption/src/fragment.ts +3 -7
  75. package/packages/caption/src/index.ts +6 -5
  76. package/packages/caption/src/manifest.ts +29 -46
  77. package/packages/caption/src/style.ts +24 -135
  78. package/packages/caption/src/surface.ts +12 -92
  79. package/packages/caption/src/temporalize.ts +18 -53
  80. package/packages/caption/src/types.ts +8 -35
  81. package/packages/caption/src/visibility.ts +23 -0
  82. package/packages/caption-fine/README.md +14 -9
  83. package/packages/caption-fine/package.json +4 -2
  84. package/packages/caption-fine/src/component.ts +3 -3
  85. package/packages/caption-fine/src/fragment.ts +7 -19
  86. package/packages/caption-fine/src/index.ts +2 -0
  87. package/packages/caption-fine/src/manifest.ts +26 -17
  88. package/packages/caption-fine/src/recipe.ts +7 -0
  89. package/packages/caption-fine/src/render.ts +14 -13
  90. package/packages/caption-fine/src/schedule.ts +39 -35
  91. package/packages/caption-fine/src/style.ts +10 -9
  92. package/packages/caption-fine/src/surface.ts +62 -35
  93. package/packages/caption-fine/src/types.ts +2 -0
  94. package/packages/caption-fine-studio/README.md +24 -2
  95. package/packages/caption-fine-studio/package.json +3 -1
  96. package/packages/caption-fine-studio/src/activation.ts +3 -3
  97. package/packages/caption-fine-studio/src/index.ts +54 -42
  98. package/packages/cli/README.md +57 -4
  99. package/packages/cli/package.json +1 -0
  100. package/packages/cli/src/arguments.ts +25 -6
  101. package/packages/cli/src/build-planning.ts +3 -2
  102. package/packages/cli/src/command.ts +6 -0
  103. package/packages/cli/src/commands/environment.ts +28 -18
  104. package/packages/cli/src/commands/execution.ts +81 -26
  105. package/packages/cli/src/commands/results.ts +7 -11
  106. package/packages/cli/src/index.ts +2 -2
  107. package/packages/cli/src/machine-view.ts +3 -2
  108. package/packages/cli/src/main.ts +34 -42
  109. package/packages/cli/src/observation.ts +7 -1
  110. package/packages/cli/src/output.ts +65 -23
  111. package/packages/cli/src/view.ts +64 -18
  112. package/packages/comment-sticker/README.md +3 -3
  113. package/packages/comment-sticker/package.json +1 -1
  114. package/packages/comment-sticker/src/component.ts +4 -4
  115. package/packages/comment-sticker/src/fragment.ts +5 -4
  116. package/packages/comment-sticker/src/manifest.ts +7 -6
  117. package/packages/comment-sticker/src/program.ts +9 -9
  118. package/packages/comment-sticker/src/surface.ts +6 -7
  119. package/packages/composition/README.md +21 -0
  120. package/packages/composition/src/audio-presentation.ts +44 -0
  121. package/packages/composition/src/index.ts +3 -0
  122. package/packages/composition/src/schema.ts +8 -3
  123. package/packages/composition/src/track.ts +15 -1
  124. package/packages/credential-store-env/README.md +1 -1
  125. package/packages/deck-track/README.md +3 -3
  126. package/packages/deck-track/package.json +1 -1
  127. package/packages/deck-track/src/component.ts +5 -5
  128. package/packages/deck-track/src/fragment.ts +6 -5
  129. package/packages/deck-track/src/lower.ts +12 -12
  130. package/packages/deck-track/src/manifest.ts +8 -7
  131. package/packages/deck-track/src/program.ts +13 -16
  132. package/packages/deck-track/src/surface.ts +9 -10
  133. package/packages/driver-node/src/driver.ts +41 -3
  134. package/packages/elevenlabs-speech/README.md +27 -0
  135. package/packages/{provider-xiaomi-mimo → elevenlabs-speech}/package.json +5 -8
  136. package/packages/elevenlabs-speech/src/activation.ts +26 -0
  137. package/packages/elevenlabs-speech/src/fragment.ts +11 -0
  138. package/packages/elevenlabs-speech/src/index.ts +111 -0
  139. package/packages/elevenlabs-speech/src/surface.ts +167 -0
  140. package/packages/endpoint-kit/README.md +24 -0
  141. package/packages/endpoint-kit/src/index.ts +7 -1
  142. package/packages/film/README.md +12 -7
  143. package/packages/film/package.json +1 -1
  144. package/packages/film/src/component.ts +4 -4
  145. package/packages/film/src/fragment.ts +6 -5
  146. package/packages/film/src/manifest.ts +11 -10
  147. package/packages/film/src/program.ts +5 -5
  148. package/packages/film/src/recipe.ts +2 -1
  149. package/packages/film/src/surface.ts +6 -6
  150. package/packages/film-studio/package.json +1 -1
  151. package/packages/film-studio/src/index.ts +2 -2
  152. package/packages/fishaudio-speech/README.md +33 -0
  153. package/packages/fishaudio-speech/package.json +21 -0
  154. package/packages/fishaudio-speech/src/activation.ts +32 -0
  155. package/packages/fishaudio-speech/src/fragment.ts +11 -0
  156. package/packages/fishaudio-speech/src/index.ts +156 -0
  157. package/packages/fishaudio-speech/src/surface.ts +192 -0
  158. package/packages/generation/README.md +11 -1
  159. package/packages/generation/src/mapping.ts +28 -30
  160. package/packages/gpt-image/README.md +1 -2
  161. package/packages/grok-imagine/README.md +1 -2
  162. package/packages/hyperframes/README.md +7 -3
  163. package/packages/hyperframes/src/browser-program.ts +11 -2
  164. package/packages/hyperframes/src/document.ts +15 -2
  165. package/packages/interview-emoji-reveal/README.md +4 -4
  166. package/packages/interview-emoji-reveal/package.json +1 -1
  167. package/packages/interview-emoji-reveal/src/component.ts +4 -4
  168. package/packages/interview-emoji-reveal/src/fragment.ts +6 -5
  169. package/packages/interview-emoji-reveal/src/manifest.ts +9 -8
  170. package/packages/interview-emoji-reveal/src/program.ts +14 -14
  171. package/packages/interview-emoji-reveal/src/surface.ts +8 -9
  172. package/packages/media-execution/README.md +7 -3
  173. package/packages/media-execution/src/audio-presentation.ts +23 -0
  174. package/packages/media-execution/src/execute.ts +2 -0
  175. package/packages/media-pipeline/README.md +7 -3
  176. package/packages/media-pipeline/src/audio-plan.ts +4 -1
  177. package/packages/media-pipeline/src/component.ts +16 -2
  178. package/packages/media-pipeline/src/manifest.ts +3 -1
  179. package/packages/media-pipeline/src/types.ts +2 -1
  180. package/packages/media-track/README.md +14 -47
  181. package/packages/media-track/package.json +1 -1
  182. package/packages/media-track/preview/preview.svml +5 -5
  183. package/packages/media-track/src/author.ts +12 -6
  184. package/packages/media-track/src/component.ts +10 -16
  185. package/packages/media-track/src/fragment.ts +8 -7
  186. package/packages/media-track/src/index.ts +3 -1
  187. package/packages/media-track/src/lower.ts +7 -7
  188. package/packages/media-track/src/manifest.ts +16 -38
  189. package/packages/media-track/src/program.ts +62 -67
  190. package/packages/media-track/src/sampling.ts +6 -6
  191. package/packages/media-track/src/sequence.ts +8 -8
  192. package/packages/media-track/src/surface.ts +25 -43
  193. package/packages/media-track-studio/README.md +9 -0
  194. package/packages/media-track-studio/src/index.ts +16 -11
  195. package/packages/mimo-speech/README.md +1 -1
  196. package/packages/minimax-h3/README.md +1 -1
  197. package/packages/nano-banana/README.md +1 -1
  198. package/packages/narrative/README.md +23 -1
  199. package/packages/narrative/src/identity.ts +11 -0
  200. package/packages/narrative/src/index.ts +3 -0
  201. package/packages/narrative/src/schema.ts +28 -27
  202. package/packages/narrative/src/selection.ts +52 -0
  203. package/packages/narrative/src/types.ts +2 -0
  204. package/packages/package-loader-node/README.md +30 -0
  205. package/packages/package-loader-node/package.json +5 -2
  206. package/packages/package-loader-node/src/distribution-resolution.ts +10 -3
  207. package/packages/package-loader-node/src/index.ts +1 -0
  208. package/packages/package-loader-node/src/loader.ts +12 -15
  209. package/packages/package-loader-node/src/location.ts +27 -1
  210. package/packages/package-loader-node/src/module-scope.ts +183 -0
  211. package/packages/package-loader-node/src/types.ts +4 -0
  212. package/packages/performance/README.md +83 -0
  213. package/packages/performance/package.json +30 -0
  214. package/packages/performance/src/activation.ts +11 -0
  215. package/packages/performance/src/component.ts +46 -0
  216. package/packages/performance/src/index.ts +6 -0
  217. package/packages/performance/src/manifest.ts +53 -0
  218. package/packages/{media-track/src/performance.ts → performance/src/media.ts} +9 -10
  219. package/packages/performance/src/program.ts +51 -0
  220. package/packages/performance/src/style.ts +35 -0
  221. package/packages/performance/src/surface.ts +99 -0
  222. package/packages/performance-studio/README.md +25 -0
  223. package/packages/performance-studio/package.json +21 -0
  224. package/packages/performance-studio/src/activation.ts +6 -0
  225. package/packages/performance-studio/src/index.ts +84 -0
  226. package/packages/program-space/README.md +9 -18
  227. package/packages/program-space/src/activation.ts +1 -5
  228. package/packages/program-space/src/index.ts +2 -11
  229. package/packages/program-space/src/surface.ts +1 -20
  230. package/packages/project-context-node/README.md +20 -0
  231. package/packages/project-context-node/package.json +10 -0
  232. package/packages/project-context-node/src/index.ts +3 -0
  233. package/packages/{cli → project-context-node}/src/runtime-selection.ts +7 -2
  234. package/packages/provider-hyperframes-local/README.md +43 -15
  235. package/packages/provider-hyperframes-local/src/activation.ts +4 -3
  236. package/packages/provider-hyperframes-local/src/capture-process.ts +26 -4
  237. package/packages/provider-hyperframes-local/src/capture.ts +96 -26
  238. package/packages/provider-hyperframes-local/src/concurrency.ts +86 -0
  239. package/packages/provider-hyperframes-local/src/opaque-capture.ts +92 -0
  240. package/packages/provider-hyperframes-local/src/options.ts +2 -0
  241. package/packages/provider-hyperframes-local/src/program.ts +6 -3
  242. package/packages/provider-hyperframes-local/src/progress.ts +53 -0
  243. package/packages/provider-hyperframes-local/src/provider.ts +18 -5
  244. package/packages/provider-hyperframes-local/src/render.ts +48 -7
  245. package/packages/provider-hypihub/README.md +48 -17
  246. package/packages/provider-hypihub/package.json +2 -0
  247. package/packages/provider-hypihub/src/mapping.ts +31 -7
  248. package/packages/provider-hypihub/src/oauth.ts +6 -0
  249. package/packages/provider-hypihub/src/provider.ts +25 -13
  250. package/packages/provider-hypihub/src/routes.ts +1 -2
  251. package/packages/provider-hypihub/src/upload.ts +2 -0
  252. package/packages/provider-media-local/README.md +3 -4
  253. package/packages/provider-whisperx-local/src/program.ts +1 -0
  254. package/packages/provider-whisperx-local/src/provider.ts +3 -0
  255. package/packages/ranking/README.md +8 -6
  256. package/packages/ranking/package.json +1 -1
  257. package/packages/ranking/src/component.ts +6 -6
  258. package/packages/ranking/src/fragment.ts +11 -7
  259. package/packages/ranking/src/manifest.ts +21 -14
  260. package/packages/ranking/src/render.ts +22 -26
  261. package/packages/ranking/src/schedule.ts +16 -19
  262. package/packages/ranking/src/surface.ts +12 -13
  263. package/packages/ranking-studio/README.md +18 -0
  264. package/packages/ranking-studio/src/index.ts +61 -9
  265. package/packages/render-hyperframes/README.md +7 -7
  266. package/packages/render-hyperframes/package.json +1 -1
  267. package/packages/render-hyperframes/src/component.ts +11 -1
  268. package/packages/render-hyperframes/src/fragment.ts +7 -4
  269. package/packages/render-hyperframes/src/manifest.ts +4 -4
  270. package/packages/render-hyperframes/src/surface.ts +6 -6
  271. package/packages/runtime/README.md +8 -1
  272. package/packages/runtime/src/execution.ts +15 -4
  273. package/packages/runtime/src/index.ts +2 -1
  274. package/packages/runtime/src/log.ts +51 -0
  275. package/packages/runtime/src/types.ts +5 -8
  276. package/packages/runtime-host-node/README.md +30 -0
  277. package/packages/runtime-host-node/package.json +1 -0
  278. package/packages/runtime-host-node/src/index.ts +24 -9
  279. package/packages/runtime-host-node/src/packages.ts +47 -50
  280. package/packages/runtime-kit/README.md +5 -0
  281. package/packages/runtime-kit/src/index.ts +3 -1
  282. package/packages/runtime-local/README.md +92 -4
  283. package/packages/runtime-local/src/config.ts +202 -56
  284. package/packages/runtime-local/src/control.ts +9 -1
  285. package/packages/runtime-local/src/executor.ts +66 -0
  286. package/packages/runtime-local/src/host.ts +37 -17
  287. package/packages/runtime-local/src/log.ts +48 -0
  288. package/packages/runtime-local/src/programs.ts +2 -1
  289. package/packages/runtime-local/src/result-writer.ts +2 -0
  290. package/packages/runtime-local/src/runtime.ts +8 -6
  291. package/packages/runtime-local/src/supervisor.ts +142 -0
  292. package/packages/runtime-local/src/types.ts +9 -2
  293. package/packages/runtime-local/src/worker-process.ts +7 -24
  294. package/packages/runtime-local/src/worker.ts +55 -83
  295. package/packages/screen-overlay/README.md +3 -3
  296. package/packages/screen-overlay/package.json +1 -1
  297. package/packages/screen-overlay/src/component.ts +3 -3
  298. package/packages/screen-overlay/src/fragment.ts +5 -4
  299. package/packages/screen-overlay/src/manifest.ts +7 -6
  300. package/packages/screen-overlay/src/program.ts +9 -9
  301. package/packages/screen-overlay/src/surface.ts +6 -7
  302. package/packages/script/README.md +15 -2
  303. package/packages/script/src/manifest.ts +2 -2
  304. package/packages/script/src/narrative.ts +1 -0
  305. package/packages/script/src/surface.ts +4 -3
  306. package/packages/script/src/types.ts +1 -1
  307. package/packages/script-studio/package.json +9 -3
  308. package/packages/script-studio/src/index.ts +2 -0
  309. package/packages/script-studio/src/projection.ts +105 -0
  310. package/packages/seedance/README.md +30 -1
  311. package/packages/seedance/src/index.ts +18 -7
  312. package/packages/seedance/src/surface.ts +17 -4
  313. package/packages/seedance-kits/README.md +7 -1
  314. package/packages/seedream/README.md +1 -1
  315. package/packages/sound/README.md +81 -0
  316. package/packages/sound/package.json +25 -0
  317. package/packages/sound/src/activation.ts +11 -0
  318. package/packages/sound/src/component.ts +28 -0
  319. package/packages/sound/src/index.ts +5 -0
  320. package/packages/sound/src/manifest.ts +47 -0
  321. package/packages/sound/src/program.ts +84 -0
  322. package/packages/sound/src/style.ts +34 -0
  323. package/packages/sound/src/surface.ts +90 -0
  324. package/packages/sound-studio/README.md +22 -0
  325. package/packages/sound-studio/package.json +20 -0
  326. package/packages/sound-studio/src/activation.ts +6 -0
  327. package/packages/sound-studio/src/index.ts +74 -0
  328. package/packages/speech/README.md +2 -2
  329. package/packages/speech-alignment/src/local.ts +8 -0
  330. package/packages/speech-alignment/src/locate.ts +1 -1
  331. package/packages/store-sqlite/README.md +7 -0
  332. package/packages/store-sqlite/src/store.ts +84 -83
  333. package/packages/studio/INSPECTOR.md +15 -2
  334. package/packages/studio/README.md +88 -14
  335. package/packages/studio/package.json +8 -7
  336. package/packages/studio/src/companion-assembly.ts +1 -0
  337. package/packages/studio/src/domain.ts +1 -1
  338. package/packages/studio/src/fallback-companions.ts +3 -3
  339. package/packages/studio/src/feedback-server.ts +51 -0
  340. package/packages/studio/src/feedback-store.ts +66 -0
  341. package/packages/studio/src/feedback.ts +60 -0
  342. package/packages/studio/src/parameter-values.ts +43 -1
  343. package/packages/studio/src/parameters.ts +114 -24
  344. package/packages/studio/src/preview/render.ts +5 -1
  345. package/packages/studio/src/preview/runtime-shim.ts +49 -3
  346. package/packages/studio/src/programme.ts +14 -30
  347. package/packages/studio/src/server.ts +10 -6
  348. package/packages/studio/src/shared.ts +4 -2
  349. package/packages/studio/src/snapshot.ts +21 -132
  350. package/packages/studio/src/studio-preflight.ts +3 -3
  351. package/packages/studio/src/studio-registry.ts +50 -6
  352. package/packages/studio/src/style.css +209 -48
  353. package/packages/studio/src/ui/comments.ts +233 -0
  354. package/packages/studio/src/ui/icons.ts +5 -0
  355. package/packages/studio/src/ui/main.ts +145 -86
  356. package/packages/studio/src/ui/overlay.ts +12 -8
  357. package/packages/studio/src/ui/scrub-preview.ts +108 -0
  358. package/packages/studio/src/ui/stage.ts +67 -4
  359. package/packages/studio/src/ui/timeline.ts +177 -108
  360. package/packages/studio/start.ts +4 -2
  361. package/packages/studio-adapter/README.md +130 -11
  362. package/packages/studio-adapter/src/index.ts +100 -13
  363. package/packages/temporal/README.md +6 -6
  364. package/packages/temporal/package.json +1 -1
  365. package/packages/temporal/src/component.ts +5 -6
  366. package/packages/temporal/src/index.ts +8 -6
  367. package/packages/temporal/src/location.ts +11 -11
  368. package/packages/temporal/src/projection.ts +19 -19
  369. package/packages/temporal/src/rational.ts +4 -4
  370. package/packages/temporal-markup/EDITING.md +2 -2
  371. package/packages/temporal-markup/README.md +27 -11
  372. package/packages/temporal-markup/package.json +1 -1
  373. package/packages/temporal-markup/src/index.ts +20 -25
  374. package/packages/temporal-markup/src/space.ts +10 -41
  375. package/packages/timeline/README.md +31 -0
  376. package/packages/{semantic-track → timeline}/package.json +1 -1
  377. package/packages/timeline/src/activation.ts +8 -0
  378. package/packages/timeline/src/component.ts +24 -0
  379. package/packages/timeline/src/identity.ts +60 -0
  380. package/packages/timeline/src/index.ts +6 -0
  381. package/packages/{semantic-track → timeline}/src/location.ts +20 -20
  382. package/packages/timeline/src/manifest.ts +39 -0
  383. package/packages/{semantic-track → timeline}/src/projection.ts +14 -14
  384. package/packages/timeline/src/types.ts +24 -0
  385. package/packages/timeline-author/README.md +68 -0
  386. package/packages/{speech-track → timeline-author}/package.json +6 -4
  387. package/packages/timeline-author/src/activation.ts +22 -0
  388. package/packages/{speech-track → timeline-author}/src/component.ts +15 -13
  389. package/packages/{speech-track → timeline-author}/src/fragment.ts +14 -23
  390. package/packages/timeline-author/src/index.ts +7 -0
  391. package/packages/timeline-author/src/manifest.ts +78 -0
  392. package/packages/timeline-author/src/program.ts +107 -0
  393. package/packages/timeline-author/src/surface.ts +46 -0
  394. package/packages/timeline-author/src/types.ts +6 -0
  395. package/packages/typography-track/README.md +4 -4
  396. package/packages/typography-track/package.json +1 -1
  397. package/packages/typography-track/src/component.ts +4 -4
  398. package/packages/typography-track/src/fragment.ts +4 -3
  399. package/packages/typography-track/src/manifest.ts +11 -9
  400. package/packages/typography-track/src/program.ts +15 -15
  401. package/packages/typography-track/src/surface.ts +17 -18
  402. package/packages/video-cli/README.md +4 -1
  403. package/packages/video-cli/package.json +2 -1
  404. package/packages/video-cli/src/creation.ts +14 -4
  405. package/packages/video-cli/src/index.ts +1 -1
  406. package/packages/video-cli/src/studio-distribution.ts +2 -1
  407. package/packages/volcengine-matting/README.md +3 -3
  408. package/packages/whisperx/README.md +1 -1
  409. package/services/whisperx/README.md +14 -0
  410. package/services/whisperx/pyproject.toml +2 -0
  411. package/services/whisperx/uv.lock +20 -20
  412. package/packages/provider-hyperframes-aws-lambda/README.md +0 -30
  413. package/packages/provider-hyperframes-aws-lambda/package.json +0 -30
  414. package/packages/provider-hyperframes-aws-lambda/src/activation.ts +0 -97
  415. package/packages/provider-hyperframes-aws-lambda/src/client.ts +0 -114
  416. package/packages/provider-hyperframes-aws-lambda/src/index.ts +0 -21
  417. package/packages/provider-hyperframes-aws-lambda/src/provider.ts +0 -522
  418. package/packages/provider-kie/README.md +0 -134
  419. package/packages/provider-kie/package.json +0 -43
  420. package/packages/provider-kie/src/activation.ts +0 -71
  421. package/packages/provider-kie/src/index.ts +0 -10
  422. package/packages/provider-kie/src/mapping.ts +0 -182
  423. package/packages/provider-kie/src/provider.ts +0 -657
  424. package/packages/provider-kie/src/routes.ts +0 -150
  425. package/packages/provider-xiaomi-mimo/README.md +0 -32
  426. package/packages/provider-xiaomi-mimo/src/activation.ts +0 -57
  427. package/packages/provider-xiaomi-mimo/src/index.ts +0 -5
  428. package/packages/provider-xiaomi-mimo/src/provider.ts +0 -214
  429. package/packages/runtime/src/environment.ts +0 -6
  430. package/packages/semantic-track/README.md +0 -21
  431. package/packages/semantic-track/src/activation.ts +0 -8
  432. package/packages/semantic-track/src/component.ts +0 -24
  433. package/packages/semantic-track/src/identity.ts +0 -58
  434. package/packages/semantic-track/src/index.ts +0 -6
  435. package/packages/semantic-track/src/manifest.ts +0 -38
  436. package/packages/semantic-track/src/types.ts +0 -26
  437. package/packages/speech-track/README.md +0 -51
  438. package/packages/speech-track/src/activation.ts +0 -19
  439. package/packages/speech-track/src/index.ts +0 -7
  440. package/packages/speech-track/src/manifest.ts +0 -73
  441. package/packages/speech-track/src/program.ts +0 -64
  442. package/packages/speech-track/src/surface.ts +0 -35
  443. package/packages/speech-track/src/types.ts +0 -6
  444. package/packages/speech-track-studio/README.md +0 -3
  445. package/packages/speech-track-studio/package.json +0 -14
  446. package/packages/speech-track-studio/src/activation.ts +0 -7
  447. package/packages/speech-track-studio/src/index.ts +0 -40
  448. /package/packages/{cli → project-context-node}/src/project-context.ts +0 -0
  449. /package/packages/{speech-track → timeline-author}/preview/Track.png +0 -0
@@ -18,7 +18,20 @@ its color is How, and the object's frame is Where. One field has one owner and o
18
18
  ## Controls describe the editing task
19
19
 
20
20
  `bindings` exposes actual author endpoints; `inspector` chooses which to show. A resolved field is
21
- shown only when its binding is writable. The finite controls are independent of the three domains:
21
+ shown when selected by the Companion, including read-only bindings. The interface orders available
22
+ domains as Where, When, How. Read-only values and editable controls share the same sections.
23
+
24
+ A projected entity may supply a few computed `inspector` facts without binding them to Source:
25
+
26
+ ```ts
27
+ inspector: [{ id: "range", label: "Range", domain: "when",
28
+ section: { id: "placement", label: "Placement" }, value: "15–105", unit: "f" }]
29
+ ```
30
+
31
+ The resolved DTO carries an `edit: { language, source }` only for writable author fields.
32
+ The UI uses plain selectable text otherwise; the server requires that endpoint for writes.
33
+ Choose facts that explain the selected object or its controls. Component headers organize lanes;
34
+ the selected entities own their details. The finite controls are independent of the three domains:
22
35
 
23
36
  | Control | Use |
24
37
  | --- | --- |
@@ -30,7 +43,7 @@ shown only when its binding is writable. The finite controls are independent of
30
43
  | `list` | An ordered value described by an array schema, such as a palette or repeated settings. |
31
44
  | `record` | Named values described by an object schema, such as one shadow's parameters. |
32
45
 
33
- Lists and records retain Apply/Reset drafts. Their schema owns value shape. There is no separate
46
+ Lists and records save complete, valid values when editing ends. Incomplete edits show a completion hint; their schema owns value shape. There is no separate
34
47
  palette database, font control protocol, generic CSS editor, or component-supplied DOM renderer.
35
48
  Use text for an expression whose parts cannot meaningfully be edited as one number.
36
49
 
@@ -72,14 +72,78 @@ transient processing require the selected Runtime.
72
72
 
73
73
  ## Opening and editing a session
74
74
 
75
+ The CLI prints the actual session URL and its direct `#comments` URL after the server chooses a port.
76
+ Open the latter to review the current composition before export. Browser playback creates no export
77
+ Build or encoded video; an export remains a separate Run execution when the user wants the file.
78
+
79
+ The top-right **Studio / Comments** tabs change the layout around the same composition player.
80
+ Comments gives the picture the available height with a notes column on the right. Click the picture
81
+ to play or pause; the wider progress control seeks, with a hovered-frame preview that leaves the
82
+ main playhead alone. The hover picture uses one lazy, muted instance of the current preview document,
83
+ released when leaving Comments. It needs no Build or thumbnail files.
84
+
85
+ Studio retains picture selection and its right-click menu for overlapping Companion entities.
86
+ Comments uses viewing controls without selecting objects. Switching views preserves the composition
87
+ time and Studio's selection; comments themselves only refer to a time and the user's words.
88
+
89
+ ### Comments are project files
90
+
91
+ Studio saves comments in `<workspace>/FEEDBACK.json`, creating it on the first saved comment.
92
+ This path is Studio's project-file convention, rooted in the resolved workspace; it is independent
93
+ of the Runtime, Result repository and Agent implementation.
94
+ Each comment records its reviewed Run relative to that workspace, so the file can hold notes for
95
+ several Runs while the UI shows the current Run. Times are seconds, including fractional seconds:
96
+
97
+ ```json
98
+ {
99
+ "comments": [
100
+ {
101
+ "id": "caption-size",
102
+ "run": "runs/main.svrun",
103
+ "at": 12.5,
104
+ "text": "Make this caption larger.",
105
+ "resolved": false
106
+ }
107
+ ]
108
+ }
109
+ ```
110
+
111
+ `id`, `run`, `at` and `text` are required. `resolved` defaults to false; setting it to true marks
112
+ the comment complete, and false reopens it. Deleting removes the entry. Following a note seeks to
113
+ its saved time; a changed composition can show something different at that time.
114
+
115
+ Focusing the comment composer pauses the picture and captures the current frame. The time chip
116
+ captures a new time. The draft keeps its time while the user writes. Click a saved timestamp to
117
+ revisit it. Comments can be edited, completed, reopened and deleted from the UI or by editing the file.
118
+ The list is ordered by timestamp. Its `#1`, `#2` labels follow submission order within the current
119
+ Run (the file's array order) and appear beside the completion control. Changing a timestamp or
120
+ filtering Open/Done preserves those numbers; deleting a note closes its gap in the numbering.
121
+ The stored `id` remains the stable identity. Clicking a note's text or time seeks
122
+ to its frame. The composer has an icon-only send control; emoji and drawing buttons are inactive placeholders.
123
+ Clicking outside the selected note clears its highlight without discarding an edit. Enter sends a
124
+ new note or saves an edited one; Shift+Enter or Alt+Enter inserts a line break. IME confirmation stays
125
+ with the text input rather than submitting the comment.
126
+
127
+ File changes refresh comments through filesystem events, without polling or recompiling the video.
128
+ Studio reads the file afresh for each edit, preserves unrelated notes and project-added fields, and
129
+ rejects an edit to a comment that has changed since it was displayed. An invalid manually edited
130
+ file remains intact and its error is shown. Unsent text stays in the browser. Agent notification is
131
+ a separate, planned connection; **Send comment** currently saves the note only.
132
+
133
+ ### Composition editing
134
+
75
135
  The selected targets must reach one Film and its resolved time source. Studio rejects several
76
- distinct Films in one view; use separate Runs/sessions for those. A SemanticTrack supplies the
77
- Script lane and performance timing, including wordless Segments with media spans. A declared
78
- ProgramSpace supplies authored animation time without a Script lane. Both show their component
79
- tracks and use the same rendering and parameter-editing machinery. When the snapshot contains
80
- a semantic timeline, its lane and label stay pinned directly below the time ruler while
81
- component tracks scroll. Its presence follows the resolved semantic timeline, including
82
- wordless content, rather than a component name or the presence of spoken words.
136
+ distinct Films in one view; use separate Runs/sessions for those. A Timeline supplies the
137
+ placed material and semantic timing, including wordless Segments. The ruler always shows program
138
+ time. When placed Segments are present, its left Timeline header spans the time ticks and the
139
+ Segment, Word and Selection/Moment bands. Empty Word or marker bands are omitted based on the
140
+ whole work, not the visible window or playhead. With no Segments, only the ordinary time ruler remains.
141
+ The complete ruler area stays pinned while component tracks scroll.
142
+
143
+ Semantic objects retain declaration-order drawing within each band. Their fine borders distinguish
144
+ adjacent and overlapping intervals without inventing time gaps. Selection raises an object above
145
+ its peers; playback highlighting changes color without changing that order. Right-click an overlap
146
+ to choose a covered object. These are editor presentation rules, independent of Film paint order.
83
147
 
84
148
  Open the URL printed by Vite. Studio requests port 5179 by default, accepts `--port`,
85
149
  and Vite can choose another available port when it is occupied. Reuse that process
@@ -90,11 +154,14 @@ package code or imports that introduce new packages. Browser refresh does not re
90
154
  server-side package modules.
91
155
 
92
156
  The Source pane can edit the selected `.svml`, `.svs` or `.svrun` file. The Inspector
93
- shows project facts when no entity is selected and only declared writable fields for
157
+ shows project facts when no entity is selected and declared facts and author fields for
94
158
  the selected entity. A reference can resolve to a shared Frame or Recipe, so one edit
95
- may affect several consumers. Structured fields use Apply/Reset for their local draft.
159
+ may affect several consumers. Structured fields save together when editing ends and the value is complete; missing required values stay in the editor with a completion hint.
96
160
  Check save status; source conflicts reject stale edits rather than overwrite newer files.
97
161
 
162
+ The Timeline owns the editor's complete range; displayed objects do not extend it. Take placement
163
+ and complete extent are reference information in Studio.
164
+
98
165
  Timeline gestures use explicit temporal authority. Moving a shared Selection or
99
166
  Moment edits Script and moves its consumers after recompilation. A parameter-based
100
167
  handle edits its exact authored parameter. Fixed or derived values with no supported
@@ -137,12 +204,11 @@ at runtime. Ship the Companion's compiled JavaScript with its component package.
137
204
  The companion owns what its Track means: matching, required same-Surface values,
138
205
  entities, lane range, finite chrome, title and ordered text/material layers,
139
206
  source bindings, Inspector fields and executed temporal lineage. Inspector fields
140
- select real writable bindings and organize them under the Studio-owned
141
- `Where / How / When` domains, optional companion-owned pages and sections. A
207
+ select real bindings or package-owned facts and organize them under the Studio-owned
208
+ `Where / When / How` domains, optional companion-owned pages and sections. A
142
209
  source binding is never shown merely because Studio can reach it. Material layers carry a
143
- Resource id or Surface identity, never a Studio HTTP URL. Studio always owns
144
- time formatting and transport resolution, so chrome and material cannot hide a
145
- title or its time.
210
+ Resource id or Surface identity, never a Studio HTTP URL. Studio owns time formatting and transport resolution. Compact chrome shows one primary label;
211
+ computed time remains available in its tooltip rather than competing with that label.
146
212
  Studio owns session-wide behavior and chrome: Companion assembly, single-row overlap display,
147
213
  fallback defaults, selection treatment, playback, zoom,
148
214
  scrolling, the finite Inspector control set and source mutation transport. A
@@ -184,3 +250,11 @@ semantics.
184
250
 
185
251
  Read [`@hypit/studio-adapter`](../studio-adapter/README.md) for the Companion ABI,
186
252
  project activation example, value projection and Inspector declarations.
253
+
254
+ ## Composition audio preview
255
+
256
+ The preview consumes generic AudioClips: source sampling, fixed gain, program-sample gain envelopes,
257
+ audibility regions and target-relative fades. Web Audio gain nodes schedule the independent factors
258
+ on the same clock, including silence and amplification above unity. Visual video elements stay muted;
259
+ the Film's selected AudioTracks own composition sound. Seeking is silent. This path is independent of
260
+ which component emitted a clip.
@@ -12,34 +12,35 @@
12
12
  "@hypit/build-result": "workspace:*",
13
13
  "@hypit/caption-fine-studio": "workspace:*",
14
14
  "@hypit/cli": "workspace:*",
15
+ "@hypit/comment-sticker-studio": "workspace:*",
15
16
  "@hypit/compiler-node": "workspace:*",
16
17
  "@hypit/component-kit": "workspace:*",
17
18
  "@hypit/composition": "workspace:*",
18
- "@hypit/comment-sticker-studio": "workspace:*",
19
19
  "@hypit/core": "workspace:*",
20
- "@hypit/driver-node": "workspace:*",
21
20
  "@hypit/deck-track-studio": "workspace:*",
21
+ "@hypit/driver-node": "workspace:*",
22
22
  "@hypit/elaborator": "workspace:*",
23
23
  "@hypit/film-studio": "workspace:*",
24
24
  "@hypit/hyperframes": "workspace:*",
25
25
  "@hypit/markup": "workspace:*",
26
26
  "@hypit/media-track-studio": "workspace:*",
27
- "@hypit/narrative": "workspace:*",
28
27
  "@hypit/package-loader-node": "workspace:*",
28
+ "@hypit/performance-studio": "workspace:*",
29
+ "@hypit/sound-studio": "workspace:*",
29
30
  "@hypit/program-space": "workspace:*",
31
+ "@hypit/project-context-node": "workspace:*",
30
32
  "@hypit/protocol": "workspace:*",
31
33
  "@hypit/ranking-studio": "workspace:*",
32
34
  "@hypit/run": "workspace:*",
33
35
  "@hypit/runtime": "workspace:*",
34
36
  "@hypit/runtime-host-node": "workspace:*",
35
- "@hypit/script-studio": "workspace:*",
36
37
  "@hypit/screen-overlay-studio": "workspace:*",
38
+ "@hypit/script-studio": "workspace:*",
37
39
  "@hypit/speech": "workspace:*",
38
- "@hypit/semantic-track": "workspace:*",
40
+ "@hypit/studio-adapter": "workspace:*",
39
41
  "@hypit/svs": "workspace:*",
40
42
  "@hypit/temporal": "workspace:*",
41
- "@hypit/studio-adapter": "workspace:*",
42
- "@hypit/speech-track-studio": "workspace:*",
43
+ "@hypit/timeline": "workspace:*",
43
44
  "@hypit/typography-track-studio": "workspace:*",
44
45
  "@hypit/validation": "workspace:*",
45
46
  "@hypit/video-cli": "workspace:*",
@@ -34,6 +34,7 @@ export async function loadStudioCompanionRegistry(input: {
34
34
  {
35
35
  films: contributions.flatMap((item) => item.films),
36
36
  scripts: contributions.flatMap((item) => item.scripts),
37
+ parameters: contributions.flatMap((item) => item.parameters),
37
38
  },
38
39
  );
39
40
  }
@@ -33,7 +33,7 @@ export type StudioDomain = {
33
33
 
34
34
  /**
35
35
  * Assemble Studio from the same recursive package selection as the official CLI.
36
- * The application owns this video-domain view; packages never register Studio metadata.
36
+ * The application assembles the video-domain view; selected packages contribute Studio Companions through host facets.
37
37
  */
38
38
  export async function loadStudioDomain(input: {
39
39
  readonly run: string;
@@ -1,7 +1,7 @@
1
1
  import type { StudioTrackCompanion, StudioTrackCompanionContext, StudioEntityDraft } from "@hypit/studio-adapter";
2
2
  import { artifactPreview, previewLayer, temporalLineageFor, temporalSemanticSource } from "@hypit/studio-adapter";
3
3
  import { compositionTypes } from "@hypit/composition";
4
- import { semanticTrackTypes } from "@hypit/semantic-track";
4
+ import { timelineTypes } from "@hypit/timeline";
5
5
 
6
6
  type TerminalVisualTrack = {
7
7
  readonly presents?: readonly {
@@ -79,8 +79,8 @@ function projectTerminalAudio(context: StudioTrackCompanionContext): readonly St
79
79
  /** Cross-domain terminal protocols understood even when no Companion is installed. */
80
80
  export const fallbackStudioTrackCompanions: readonly StudioTrackCompanion[] = [
81
81
  {
82
- id: "@hypit/studio#semantic-track", role: "semantic-track", output: { type: semanticTrackTypes.track },
83
- family: "semantic", tone: "teal", label: "Semantic", icon: "brand",
82
+ id: "@hypit/studio#timeline", role: "timeline", output: { type: timelineTypes.track },
83
+ family: "semantic", tone: "teal", label: "Timeline", icon: "brand",
84
84
  lane: { heightPx: 45 },
85
85
  },
86
86
  {
@@ -0,0 +1,51 @@
1
+ import { watch } from "node:fs";
2
+ import { relative } from "node:path";
3
+ import type { Plugin } from "vite";
4
+ import { createFeedbackStore, FeedbackConflict } from "./feedback-store.js";
5
+ import { readFeedbackMutation } from "./feedback.js";
6
+ import type { FeedbackDocument, FeedbackView } from "./feedback.js";
7
+
8
+ /** Review storage is separate from compilation, Results and Agent delivery. */
9
+ export function studioFeedbackPlugin(workspaceRoot: string, runPath: string): Plugin {
10
+ const store = createFeedbackStore(workspaceRoot);
11
+ const run = relative(workspaceRoot, runPath).replaceAll("\\", "/");
12
+ const view = (document: FeedbackDocument): FeedbackView => ({
13
+ file: "FEEDBACK.json", run, comments: document.comments.filter((comment) => comment.run === run),
14
+ });
15
+ return {
16
+ name: "hypit-studio-feedback",
17
+ configureServer(server) {
18
+ const watcher = watch(workspaceRoot, (_event, filename) => {
19
+ if (filename === null || filename.toString() === "FEEDBACK.json") {
20
+ server.ws.send({ type: "custom", event: "studio:feedback-changed", data: {} });
21
+ }
22
+ });
23
+ server.httpServer?.once("close", () => watcher.close());
24
+ server.middlewares.use((request, response, next) => {
25
+ if (new URL(request.url ?? "/", "http://studio.hypit.local").pathname !== "/__studio/feedback") return next();
26
+ response.setHeader("content-type", "application/json; charset=utf-8");
27
+ response.setHeader("cache-control", "no-store");
28
+ void (async () => {
29
+ try {
30
+ if (request.method === "GET") {
31
+ response.end(JSON.stringify(view(await store.read())));
32
+ return;
33
+ }
34
+ if (request.method !== "POST") { response.statusCode = 405; response.end(); return; }
35
+ const chunks: Buffer[] = [];
36
+ for await (const chunk of request) chunks.push(Buffer.from(chunk));
37
+ const mutation = readFeedbackMutation(JSON.parse(Buffer.concat(chunks).toString("utf8")));
38
+ const comment = mutation.type === "delete" ? mutation.before : mutation.comment;
39
+ if (comment.run !== run) throw new Error("The comment belongs to another Run.");
40
+ const result = view(await store.mutate(mutation));
41
+ response.end(JSON.stringify(result));
42
+ server.ws.send({ type: "custom", event: "studio:feedback-changed", data: {} });
43
+ } catch (error) {
44
+ response.statusCode = error instanceof FeedbackConflict ? 409 : 400;
45
+ response.end(JSON.stringify({ error: error instanceof Error ? error.message : String(error) }));
46
+ }
47
+ })();
48
+ });
49
+ },
50
+ };
51
+ }
@@ -0,0 +1,66 @@
1
+ import { isDeepStrictEqual } from "node:util";
2
+ import { randomUUID } from "node:crypto";
3
+ import { readFile, rename, unlink, writeFile } from "node:fs/promises";
4
+ import { join } from "node:path";
5
+ import { readFeedbackDocument } from "./feedback.js";
6
+ import type { FeedbackDocument, FeedbackMutation } from "./feedback.js";
7
+
8
+ export class FeedbackConflict extends Error {}
9
+
10
+ /** The file is authoritative; every operation reads it afresh and edits one note. */
11
+ export function createFeedbackStore(workspaceRoot: string) {
12
+ const path = join(workspaceRoot, "FEEDBACK.json");
13
+ let pending: Promise<unknown> = Promise.resolve();
14
+ const readText = async (): Promise<string | undefined> => {
15
+ try { return await readFile(path, "utf8"); }
16
+ catch (error) {
17
+ if ((error as NodeJS.ErrnoException).code === "ENOENT") return undefined;
18
+ throw error;
19
+ }
20
+ };
21
+ const decode = (text: string | undefined): FeedbackDocument => text === undefined
22
+ ? { comments: [] } : readFeedbackDocument(JSON.parse(text));
23
+
24
+ const apply = async (mutation: FeedbackMutation): Promise<FeedbackDocument> => {
25
+ const previous = await readText();
26
+ const document = decode(previous);
27
+ const comments = [...document.comments];
28
+ if (mutation.type === "add") {
29
+ if (comments.some((comment) => comment.id === mutation.comment.id)) throw new FeedbackConflict("This comment already exists.");
30
+ comments.push(mutation.comment);
31
+ } else {
32
+ const index = comments.findIndex((comment) => comment.id === mutation.before.id);
33
+ if (index < 0 || !isDeepStrictEqual(comments[index], mutation.before)) {
34
+ throw new FeedbackConflict("This comment changed outside this view. Your unsaved text is kept in the editor; reopen the comment to edit its latest version.");
35
+ }
36
+ if (mutation.type === "delete") comments.splice(index, 1);
37
+ else {
38
+ if (mutation.comment.id !== mutation.before.id || mutation.comment.run !== mutation.before.run) {
39
+ throw new Error("Editing a comment preserves its id and Run.");
40
+ }
41
+ comments[index] = mutation.comment;
42
+ }
43
+ }
44
+ const next = { ...document, comments };
45
+ const temporary = join(workspaceRoot, `.FEEDBACK.${randomUUID()}.tmp`);
46
+ try {
47
+ await writeFile(temporary, `${JSON.stringify(next, null, 2)}\n`, { encoding: "utf8", flag: "wx" });
48
+ if (await readText() !== previous) throw new FeedbackConflict("FEEDBACK.json changed while saving. Your draft is kept; please try again.");
49
+ await rename(temporary, path);
50
+ } finally {
51
+ await unlink(temporary).catch((error: NodeJS.ErrnoException) => { if (error.code !== "ENOENT") throw error; });
52
+ }
53
+ return next;
54
+ };
55
+
56
+ return {
57
+ path,
58
+ read: async (): Promise<FeedbackDocument> => decode(await readText()),
59
+ mutate(mutation: FeedbackMutation): Promise<FeedbackDocument> {
60
+ // Serialize browser submissions, without keeping a second copy of the document.
61
+ const result = pending.then(() => apply(mutation));
62
+ pending = result.catch(() => undefined);
63
+ return result;
64
+ },
65
+ };
66
+ }
@@ -0,0 +1,60 @@
1
+ /** Project-owned review notes. Times are seconds in the reviewed Run. */
2
+ export type FeedbackComment = {
3
+ readonly id: string;
4
+ readonly run: string;
5
+ readonly at: number;
6
+ readonly text: string;
7
+ readonly resolved?: boolean;
8
+ };
9
+
10
+ export type FeedbackDocument = { readonly comments: readonly FeedbackComment[] };
11
+ export type FeedbackView = FeedbackDocument & { readonly file: string; readonly run: string };
12
+ export type FeedbackMutation =
13
+ | { readonly type: "add"; readonly comment: FeedbackComment }
14
+ | { readonly type: "replace"; readonly before: FeedbackComment; readonly comment: FeedbackComment }
15
+ | { readonly type: "delete"; readonly before: FeedbackComment };
16
+
17
+ function record(value: unknown): value is Record<string, unknown> {
18
+ return typeof value === "object" && value !== null && !Array.isArray(value);
19
+ }
20
+
21
+ function nonempty(value: unknown): value is string {
22
+ return typeof value === "string" && value.trim().length > 0;
23
+ }
24
+
25
+ function time(value: unknown): value is number {
26
+ return typeof value === "number" && Number.isFinite(value) && value >= 0;
27
+ }
28
+
29
+ export function readFeedbackComment(value: unknown): FeedbackComment {
30
+ if (!record(value) || !nonempty(value.id) || !nonempty(value.run) || !nonempty(value.text) || !time(value.at)) {
31
+ throw new Error("Each comment needs an id, run, non-empty text and a non-negative time in seconds.");
32
+ }
33
+ if (value.resolved !== undefined && typeof value.resolved !== "boolean") throw new Error("Comment resolved must be true or false.");
34
+ // Preserve any project-added fields when Studio edits this document.
35
+ return value as FeedbackComment;
36
+ }
37
+
38
+ export function readFeedbackDocument(value: unknown): FeedbackDocument {
39
+ if (!record(value) || !Array.isArray(value.comments)) throw new Error("FEEDBACK.json needs a comments array.");
40
+ const ids = new Set<string>();
41
+ for (const entry of value.comments) {
42
+ const comment = readFeedbackComment(entry);
43
+ if (ids.has(comment.id)) throw new Error(`Duplicate comment id: ${comment.id}`);
44
+ ids.add(comment.id);
45
+ }
46
+ return value as FeedbackDocument;
47
+ }
48
+
49
+ export function readFeedbackMutation(value: unknown): FeedbackMutation {
50
+ if (!record(value)) throw new Error("Expected a comment operation.");
51
+ if (value.type === "add") return { type: "add", comment: readFeedbackComment(value.comment) };
52
+ if (value.type === "delete") return { type: "delete", before: readFeedbackComment(value.before) };
53
+ if (value.type === "replace") return { type: "replace", before: readFeedbackComment(value.before), comment: readFeedbackComment(value.comment) };
54
+ throw new Error("Unknown comment operation.");
55
+ }
56
+
57
+ export function feedbackClock(seconds: number): string {
58
+ const ticks = Math.round(seconds * 100);
59
+ return `${String(Math.floor(ticks / 6000)).padStart(2, "0")}:${String(Math.floor(ticks / 100) % 60).padStart(2, "0")}.${String(ticks % 100).padStart(2, "0")}`;
60
+ }
@@ -1,6 +1,6 @@
1
1
  import type { CanonicalValue, ValueSchema } from "@hypit/protocol";
2
2
  import { formatSvsValue } from "@hypit/svs";
3
- import type { StudioInspectorField, StudioParameterOption, StudioNumberPresentation } from "@hypit/studio-adapter";
3
+ import type { StudioInspectorField, StudioParameterControl, StudioParameterOption, StudioNumberPresentation } from "@hypit/studio-adapter";
4
4
 
5
5
  export const parameterOption = (option: StudioParameterOption): Exclude<StudioParameterOption, string> =>
6
6
  typeof option === "string" ? { value: option, label: option } : option;
@@ -119,3 +119,45 @@ export function serializeParameterValue(value: CanonicalValue, language: "svml"
119
119
  if (typeof value === "number" || typeof value === "boolean") return String(value);
120
120
  throw new Error(`${language.toUpperCase()} parameter bindings currently accept scalar values only.`);
121
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
+ }