@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
@@ -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:*",
@@ -1,3 +1,4 @@
1
+ import { fileReferenceIdentity } from "@hypit/build-result";
1
2
  import { isAbsolute, relative, resolve, sep } from "node:path";
2
3
 
3
4
  import { buildIdCreatedAt } from "@hypit/protocol";
@@ -5,17 +6,16 @@ import type { BuildView, NodeRuntimeHost, RuntimeHostTransientExecution } from "
5
6
  import type { StoredValue, TypeRef } from "@hypit/protocol";
6
7
  import type {
7
8
  BuildResultFileRange,
8
- BuildResultFileRef,
9
9
  BuildResultManifest,
10
10
  BuildResultRepository,
11
11
  FinishedBuildResultManifest,
12
- RepositoryBuildResultOutput,
13
12
  } from "@hypit/build-result";
14
13
 
15
14
  import { resolveBuildResultValue } from "@hypit/cli";
16
15
  import { videoCliDistribution } from "@hypit/video-cli";
17
16
 
18
- import type { StudioArtifactView, StudioLibraryView, StudioTaskView } from "./shared.js";
17
+ import type { StudioArtifactView, StudioLibraryRequest, StudioLibraryView, StudioTaskView } from "./shared.js";
18
+ import { mergeStudioArtifacts } from "./library-media.js";
19
19
 
20
20
  type RuntimeControl = Awaited<ReturnType<NodeRuntimeHost["openControl"]>>;
21
21
 
@@ -24,7 +24,8 @@ export type StudioBuildLibrary = {
24
24
  readonly runtime?: Pick<RuntimeControl, "activity">;
25
25
  /** Runtime-owned, disposable execution for the current authoring session. */
26
26
  readonly transientExecution?: RuntimeHostTransientExecution;
27
- readonly library: (before?: string) => Promise<StudioLibraryView>;
27
+ readonly library: (request: StudioLibraryRequest) => Promise<StudioLibraryView>;
28
+ readonly renameArtifact: (build: string, output: string, displayName: string | null) => Promise<string | undefined>;
28
29
  readonly resolveHistoricalOutput: (
29
30
  build: string,
30
31
  output: string,
@@ -36,7 +37,6 @@ export type StudioBuildLibrary = {
36
37
  readonly openArtifact: (
37
38
  build: string,
38
39
  output: string,
39
- valuePath: string,
40
40
  ) => Promise<{
41
41
  readonly mediaType: string;
42
42
  readonly size: number;
@@ -51,7 +51,7 @@ function projectPath(root: string, path: string): string {
51
51
 
52
52
  function isWithin(root: string, path: string): boolean {
53
53
  const rel = relative(resolve(root), projectPath(root, path));
54
- return rel === "" || (!rel.startsWith("..") && !isAbsolute(rel));
54
+ return rel === "" || (rel !== ".." && !rel.startsWith(`..${sep}`) && !isAbsolute(rel));
55
55
  }
56
56
 
57
57
  /**
@@ -65,15 +65,9 @@ function presentedPath(root: string, path: string): string {
65
65
  return (relative(resolve(root), absolute) || ".").split(sep).join("/");
66
66
  }
67
67
 
68
- function buildBelongsTo(root: string, view: BuildView): boolean {
69
- return view.source !== undefined
70
- && (isWithin(root, view.run?.path ?? view.source.path) || isWithin(root, view.source.path));
71
- }
72
-
73
68
  function taskStatus(view: BuildView): StudioTaskView["status"] {
74
- if (view.issue !== undefined) return "blocked";
69
+ if (view.issue !== undefined) return "attention";
75
70
  if (view.activity === "submitting" || view.activity === "ready") return "queued";
76
- if (view.activity === "saving-result") return "active";
77
71
  return view.activity;
78
72
  }
79
73
 
@@ -83,18 +77,20 @@ function taskView(
83
77
  result?: BuildResultManifest,
84
78
  ): StudioTaskView {
85
79
  if (view.source === undefined) throw new Error(`Active Build ${view.id} has no source`);
80
+ const detail = view.issue?.message ?? view.stop?.reason;
86
81
  return {
87
82
  id: view.id,
88
83
  ...(result?.title === undefined ? {} : { title: result.title }),
89
84
  ...(result?.note === undefined ? {} : { note: result.note }),
90
85
  ...(result?.highlightedOutputs === undefined ? {} : { highlightedOutputs: result.highlightedOutputs }),
91
86
  createdAt: view.createdAt,
87
+ ongoing: true,
92
88
  status: taskStatus(view),
89
+ ...(detail === undefined ? {} : { detail }),
90
+ ...(view.requests === undefined ? {} : { requests: view.requests }),
93
91
  source: presentedPath(root, view.source.path),
94
92
  ...(view.run === undefined ? {} : { run: presentedPath(root, view.run.path) }),
95
93
  targets: result?.targets ?? view.targets,
96
- acceptedRecords: view.acceptedRecords,
97
- outstandingCommands: view.outstandingCommands,
98
94
  operations: view.operations.map((operation) => ({
99
95
  status: operation.status,
100
96
  ...(operation.progress?.phase === undefined ? {} : { phase: operation.progress.phase }),
@@ -112,107 +108,117 @@ function resultTaskView(root: string, result: FinishedBuildResultManifest): Stud
112
108
  ...(result.note === undefined ? {} : { note: result.note }),
113
109
  ...(result.highlightedOutputs === undefined ? {} : { highlightedOutputs: result.highlightedOutputs }),
114
110
  createdAt: buildIdCreatedAt(result.id)!,
111
+ finishedAt: result.finishedAt,
112
+ ongoing: false,
115
113
  status: result.outcome,
114
+ ...(result.failure === undefined ? {} : { detail: result.failure }),
116
115
  source: presentedPath(root, result.source.path),
117
116
  ...(result.run === undefined ? {} : { run: presentedPath(root, result.run.path) }),
118
117
  targets: result.targets,
119
- acceptedRecords: Object.keys(result.outputs).length,
120
- outstandingCommands: 0,
121
118
  operations: [],
122
119
  };
123
120
  }
124
121
 
125
- function presentedValuePath(path: readonly (string | number)[]): string {
126
- return path.reduce<string>((current, segment) => typeof segment === "number"
127
- ? `${current}[${segment}]`
128
- : /^[A-Za-z_$][A-Za-z0-9_$]*$/u.test(segment)
129
- ? `${current}.${segment}`
130
- : `${current}[${JSON.stringify(segment)}]`, "$");
131
- }
132
-
133
- function filesInResolvedOutput(resolved: RepositoryBuildResultOutput): readonly {
134
- readonly valuePath: string;
135
- readonly file: BuildResultFileRef;
136
- }[] {
137
- if (resolved.value.kind === "build-file") return [{ valuePath: "$", file: resolved.value }];
138
- if (resolved.value.kind === "value") {
139
- return resolved.value.document.resources.map((binding) => ({
140
- valuePath: presentedValuePath(binding.at),
141
- file: binding.file,
142
- }));
143
- }
144
- return [];
122
+ function isMedia(mediaType: string): boolean {
123
+ return /^(image|video|audio)\//u.test(mediaType);
145
124
  }
146
125
 
147
126
  async function artifactsForResults(
148
127
  root: string,
149
128
  repository: BuildResultRepository,
150
129
  manifests: readonly BuildResultManifest[],
130
+ media?: StudioLibraryRequest["media"],
151
131
  ): Promise<readonly StudioArtifactView[]> {
152
132
  const nested = await Promise.all(manifests.flatMap((manifest) =>
153
- Object.keys(manifest.outputs).map(async (output) => {
154
- const resolved = await repository.resolve(manifest.id, output);
155
- if (resolved === undefined) return [];
156
- return filesInResolvedOutput(resolved).map(({ valuePath, file }) => ({
157
- id: `${manifest.id}:${output}:${valuePath}`,
133
+ Object.entries(manifest.outputs).map(async ([output, entry]): Promise<StudioArtifactView[]> => {
134
+ // Composite Outputs remain intact. Listing media never opens their Value Documents.
135
+ if (entry.value.kind !== "build-file" && entry.value.kind !== "external-file" && entry.value.kind !== "build-output") return [];
136
+ const description = entry.value.kind === "build-file" || entry.value.kind === "external-file"
137
+ ? { kind: "resource", mediaType: entry.value.mediaType }
138
+ : await repository.describeOutput(manifest.id, output);
139
+ if (description?.kind !== "resource" || (description.mediaType === undefined || !isMedia(description.mediaType))) return [];
140
+ if (media !== undefined && !description.mediaType.startsWith(`${media}/`)) return [];
141
+ const resolved = entry.value.kind === "build-file"
142
+ ? { build: manifest.id, output, value: entry.value }
143
+ : await repository.resolve(manifest.id, output);
144
+ if (resolved === undefined || (resolved.value.kind !== "build-file" && resolved.value.kind !== "external-file")) return [];
145
+ const file = resolved.value;
146
+ const source = presentedPath(root, manifest.source.path);
147
+ const run = manifest.run === undefined ? undefined : presentedPath(root, manifest.run.path);
148
+ return [{
149
+ id: fileReferenceIdentity(resolved.build, file),
158
150
  build: manifest.id,
159
151
  createdAt: buildIdCreatedAt(manifest.id)!,
160
152
  output,
153
+ nameEditable: manifest.outcome !== undefined,
154
+ ...(entry.displayName === undefined ? {} : { displayName: entry.displayName }),
161
155
  highlighted: manifest.highlightedOutputs?.includes(output) === true,
162
156
  ...(manifest.title === undefined ? {} : { buildTitle: manifest.title }),
163
157
  ...(manifest.note === undefined ? {} : { buildNote: manifest.note }),
164
- valuePath,
165
- ownerBuild: resolved.build,
158
+ ...(file.kind === "external-file" ? {} : { ownerBuild: file.build ?? resolved.build }),
166
159
  ownerOutput: resolved.output,
167
- filePath: file.path,
160
+ filePath: file.kind === "external-file" ? file.uri : file.path,
168
161
  size: file.size,
169
162
  mediaType: file.mediaType,
170
- source: presentedPath(root, manifest.source.path),
171
- ...(manifest.run === undefined ? {} : { run: presentedPath(root, manifest.run.path) }),
172
- }));
163
+ source,
164
+ ...(run === undefined ? {} : { run }),
165
+ origins: [{ build: manifest.id, output, source, ...(run === undefined ? {} : { run }) }],
166
+ }];
173
167
  })));
174
- return nested.flat().sort((left, right) =>
175
- Number(right.highlighted) - Number(left.highlighted)
176
- || right.createdAt - left.createdAt
177
- || left.output.localeCompare(right.output)
178
- || left.valuePath.localeCompare(right.valuePath));
168
+ return mergeStudioArtifacts(nested.flat());
179
169
  }
180
170
 
181
- /** Build the Studio library from execution status and project-owned Build Results. */
182
- export async function readStudioLibrary(input: {
171
+ /** Query only the selected library view, through Runtime and Repository interfaces. */
172
+ export async function readStudioLibrary(input: StudioLibraryRequest & {
183
173
  readonly profile?: string;
184
174
  readonly workspaceRoot: string;
185
175
  readonly runtime?: Pick<RuntimeControl, "activity">;
186
176
  readonly results: BuildResultRepository;
187
- readonly before?: string;
188
177
  }): Promise<StudioLibraryView> {
189
- const page = await input.results.browse({
190
- limit: 25,
191
- ...(input.before === undefined ? {} : { before: input.before }),
192
- });
193
- const manifests = page.results.filter((manifest) =>
194
- isWithin(input.workspaceRoot, manifest.run?.path ?? manifest.source.path)
195
- || isWithin(input.workspaceRoot, manifest.source.path));
196
- const resultsByBuild = new Map(manifests.map((manifest) => [manifest.id, manifest]));
178
+ const matches = (item: { readonly id: string; readonly source: { readonly path: string }; readonly run?: { readonly path: string } }) =>
179
+ (isWithin(input.workspaceRoot, item.run?.path ?? item.source.path) || isWithin(input.workspaceRoot, item.source.path))
180
+ && (input.build === undefined || item.id === input.build)
181
+ && (input.run === undefined || (item.run !== undefined
182
+ && projectPath(input.workspaceRoot, item.run.path) === projectPath(input.workspaceRoot, input.run)));
183
+ // Read activity before Results so a Build that finishes during this query is still represented.
197
184
  const active = input.runtime === undefined || input.before !== undefined
198
- ? []
199
- : (await input.runtime.activity()).builds;
200
- const views = active.filter((view) => buildBelongsTo(input.workspaceRoot, view));
185
+ ? [] : (await input.runtime.activity()).builds;
186
+ const views = active.filter((view) => view.source !== undefined && matches({ ...view, source: view.source }));
187
+ let page = input.build === undefined
188
+ ? await input.results.browse({ limit: 25, ...(input.before === undefined ? {} : { before: input.before }) })
189
+ : { results: [await input.results.read(input.build)].filter((item): item is BuildResultManifest => item !== undefined) };
190
+ const manifests = page.results.filter(matches);
191
+ const resultsByBuild = new Map(manifests.map((manifest) => [manifest.id, manifest]));
192
+ await Promise.all(views.filter((view) => !resultsByBuild.has(view.id)).map(async (view) => {
193
+ const result = await input.results.read(view.id);
194
+ if (result !== undefined && matches(result)) resultsByBuild.set(view.id, result);
195
+ }));
196
+ let artifacts: readonly StudioArtifactView[] = [];
197
+ if (input.section === "artifacts") {
198
+ artifacts = await artifactsForResults(input.workspaceRoot, input.results, [...resultsByBuild.values()], input.media);
199
+ // Page through Result metadata until there is a useful media page. The repository still
200
+ // owns Build order and cursors; no media directory or secondary persistent index is needed.
201
+ while (artifacts.length < 25 && "next" in page && page.next !== undefined) {
202
+ const cursor = page.next;
203
+ page = await input.results.browse({ limit: 25, before: cursor });
204
+ if ("next" in page && page.next === cursor) throw new Error("Result pagination did not advance");
205
+ artifacts = mergeStudioArtifacts([...artifacts,
206
+ ...await artifactsForResults(input.workspaceRoot, input.results, page.results.filter(matches), input.media)]);
207
+ }
208
+ }
201
209
  return {
210
+ section: input.section,
202
211
  environment: resolve(input.workspaceRoot),
203
212
  ...(input.profile === undefined ? {} : { runtime: resolve(input.profile) }),
204
- ...(page.next === undefined ? {} : { next: page.next }),
205
- tasks: [
206
- ...views.map((view) => taskView(
207
- input.workspaceRoot,
208
- view,
209
- resultsByBuild.get(view.id),
210
- )),
213
+ ...("next" in page && page.next !== undefined ? { next: page.next } : {}),
214
+ tasks: input.section !== "tasks" ? [] : [
215
+ ...views.map((view) => taskView(input.workspaceRoot, view, resultsByBuild.get(view.id))),
211
216
  ...manifests
212
- .filter((manifest) => !views.some((view) => view.id === manifest.id))
217
+ .filter((manifest): manifest is FinishedBuildResultManifest => manifest.outcome !== undefined
218
+ && !views.some((view) => view.id === manifest.id))
213
219
  .map((manifest) => resultTaskView(input.workspaceRoot, manifest)),
214
220
  ].sort((left, right) => right.createdAt - left.createdAt || left.id.localeCompare(right.id)),
215
- artifacts: await artifactsForResults(input.workspaceRoot, input.results, manifests),
221
+ artifacts,
216
222
  };
217
223
  }
218
224
 
@@ -245,31 +251,40 @@ export async function openStudioBuildLibrary(
245
251
  throw error;
246
252
  }
247
253
  const results = openedResults.repository;
254
+ let presentationWrite: Promise<unknown> = Promise.resolve();
248
255
  return {
249
256
  ...(resolvedProfile === undefined ? {} : { profile: resolvedProfile }),
250
257
  ...(runtime === undefined ? {} : { runtime }),
251
258
  ...(transientExecution === undefined ? {} : { transientExecution }),
252
- async library(before) {
259
+ async library(request) {
253
260
  return await readStudioLibrary({
254
261
  ...(resolvedProfile === undefined ? {} : { profile: resolvedProfile }),
255
262
  workspaceRoot,
256
263
  ...(runtime === undefined ? {} : { runtime }),
257
264
  results,
258
- ...(before === undefined ? {} : { before }),
265
+ ...request,
266
+ });
267
+ },
268
+ async renameArtifact(build, output, displayName) {
269
+ const saved = presentationWrite.then(async () => {
270
+ const updated = await results.updatePresentation(build, { outputDisplayNames: { [output]: displayName } });
271
+ return updated.outputs[output]?.displayName;
259
272
  });
273
+ presentationWrite = saved.catch(() => undefined);
274
+ return await saved;
260
275
  },
261
276
  async resolveHistoricalOutput(build, output) {
262
277
  return await resolveBuildResultValue(results, build, output);
263
278
  },
264
- async openArtifact(build, output, valuePath) {
279
+ async openArtifact(build, output) {
265
280
  const resolved = await results.resolve(build, output);
266
281
  if (resolved === undefined) return undefined;
267
- const match = filesInResolvedOutput(resolved).find((item) => item.valuePath === valuePath);
268
- if (match === undefined) return undefined;
282
+ if ((resolved.value.kind !== "build-file" && resolved.value.kind !== "external-file") || !isMedia(resolved.value.mediaType)) return undefined;
283
+ const file = resolved.value;
269
284
  return {
270
- mediaType: match.file.mediaType,
271
- size: match.file.size,
272
- open: async (range) => await results.openFile(resolved.build, match.file, range),
285
+ mediaType: file.mediaType,
286
+ size: file.size,
287
+ open: async (range) => await results.openFile(resolved.build, file, range),
273
288
  };
274
289
  },
275
290
  async close() {
@@ -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
+ }
@@ -0,0 +1,19 @@
1
+ import type { StudioArtifactView } from "./shared.js";
2
+
3
+ /** Merge known references, without reading or comparing media bytes. */
4
+ export function mergeStudioArtifacts(items: readonly StudioArtifactView[]): StudioArtifactView[] {
5
+ const files = new Map<string, StudioArtifactView>();
6
+ for (const item of items) {
7
+ const prior = files.get(item.id);
8
+ if (prior === undefined) {
9
+ files.set(item.id, item);
10
+ continue;
11
+ }
12
+ const latest = item.createdAt > prior.createdAt ? item : prior;
13
+ const origins = new Map([...prior.origins, ...item.origins].map((origin) =>
14
+ [JSON.stringify([origin.build, origin.output]), origin]));
15
+ files.set(item.id, { ...latest, highlighted: prior.highlighted || item.highlighted, origins: [...origins.values()] });
16
+ }
17
+ return [...files.values()].sort((left, right) => Number(right.highlighted) - Number(left.highlighted)
18
+ || right.createdAt - left.createdAt || left.output.localeCompare(right.output));
19
+ }