@vfrey/vfrey 0.0.1 → 1.0.0-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (603) hide show
  1. package/LICENSE +33 -0
  2. package/README.md +78 -3
  3. package/accounts.example.json +61 -0
  4. package/accounts.first-run.json +41 -0
  5. package/bin/vfrey.mjs +36 -0
  6. package/integration-tools/README.md +43 -0
  7. package/integration-tools/image/pillow.md +32 -0
  8. package/integration-tools/image/playwright.md +33 -0
  9. package/integration-tools/image/resvg.md +36 -0
  10. package/integration-tools/image/satori.md +36 -0
  11. package/integration-tools/image/sharp.md +38 -0
  12. package/integration-tools/video/blender.md +34 -0
  13. package/integration-tools/video/ffmpeg.md +41 -0
  14. package/integration-tools/video/manim.md +37 -0
  15. package/integration-tools/video/motion-canvas.md +37 -0
  16. package/integration-tools/video/remotion.md +50 -0
  17. package/integration-tools/video/revideo.md +32 -0
  18. package/package.json +74 -6
  19. package/skills/vfrey-orchestrator/SKILL.md +15 -0
  20. package/skills/vfrey-orchestrator/channel-video/SKILL.md +41 -0
  21. package/skills/vfrey-product/SKILL.md +63 -0
  22. package/skills/vfrey-product/examples/concurrency-vs-parallelism/framey/cook-one.svg +14 -0
  23. package/skills/vfrey-product/examples/concurrency-vs-parallelism/framey/cook-two.svg +22 -0
  24. package/skills/vfrey-product/examples/concurrency-vs-parallelism/framey/index.html +70 -0
  25. package/skills/vfrey-product/examples/concurrency-vs-parallelism/remotion/cook-one.svg +14 -0
  26. package/skills/vfrey-product/examples/concurrency-vs-parallelism/remotion/cook-two.svg +22 -0
  27. package/skills/vfrey-product/examples/concurrency-vs-parallelism/remotion/index.tsx +49 -0
  28. package/skills/vfrey-product/examples/concurrency-vs-parallelism/script.json +15 -0
  29. package/skills/vfrey-product/examples/octopus-facts/index.html +60 -0
  30. package/skills/vfrey-product/examples/octopus-facts/octopus.svg +8 -0
  31. package/skills/vfrey-product/examples/octopus-facts/script.json +14 -0
  32. package/skills/vfrey-product/push/SKILL.md +15 -0
  33. package/skills/vfrey-product/scenes/NOTICE +5 -0
  34. package/skills/vfrey-product/scenes/blocks.md +57 -0
  35. package/skills/vfrey-product/scenes/craft.md +118 -0
  36. package/skills/vfrey-product/scenes/motion.md +88 -0
  37. package/src/analytics/dashboard.ts +109 -0
  38. package/src/analytics/index.ts +260 -0
  39. package/src/api/client.ts +282 -0
  40. package/src/api/commands.ts +330 -0
  41. package/src/api/config.ts +34 -0
  42. package/src/api/creators.ts +463 -0
  43. package/src/api/credentials.ts +152 -0
  44. package/src/api/mail.ts +333 -0
  45. package/src/api/topics.ts +207 -0
  46. package/src/api/types.ts +205 -0
  47. package/src/cli.ts +467 -0
  48. package/src/cloud/executor.ts +281 -0
  49. package/src/cloud/job.ts +106 -0
  50. package/src/cloud/render-job.ts +187 -0
  51. package/src/config.ts +309 -0
  52. package/src/dashboard-link.ts +180 -0
  53. package/src/dashboard-start.ts +103 -0
  54. package/src/desk/channel.ts +64 -0
  55. package/src/desk/cli.ts +216 -0
  56. package/src/desk/creators-route.ts +129 -0
  57. package/src/desk/fonts/JetBrainsMono-OFL.txt +93 -0
  58. package/src/desk/fonts/google-sans-flex-latin.woff2 +0 -0
  59. package/src/desk/fonts/jetbrains-mono-medium.woff2 +0 -0
  60. package/src/desk/http.ts +460 -0
  61. package/src/desk/mail-route.ts +103 -0
  62. package/src/desk/overlay.ts +112 -0
  63. package/src/desk/preview.ts +422 -0
  64. package/src/desk/screens.ts +149 -0
  65. package/src/desk/secrets.ts +143 -0
  66. package/src/desk/series.ts +127 -0
  67. package/src/desk/state.ts +77 -0
  68. package/src/desk/studio-route.ts +119 -0
  69. package/src/desk/tick-runner.ts +66 -0
  70. package/src/desk/tick.ts +56 -0
  71. package/src/desk/topics-route.ts +41 -0
  72. package/src/desk/ui/app.css +505 -0
  73. package/src/desk/ui/app.js +185 -0
  74. package/src/desk/ui/apple-icon.png +0 -0
  75. package/src/desk/ui/components.js +79 -0
  76. package/src/desk/ui/core.js +156 -0
  77. package/src/desk/ui/favicon.ico +0 -0
  78. package/src/desk/ui/icon.svg +1 -0
  79. package/src/desk/ui/icons.js +49 -0
  80. package/src/desk/ui/index.html +41 -0
  81. package/src/desk/ui/metrics-math.d.ts +22 -0
  82. package/src/desk/ui/metrics-math.js +135 -0
  83. package/src/desk/ui/theme.js +5 -0
  84. package/src/desk/ui/views-creators.js +209 -0
  85. package/src/desk/ui/views-keys.js +114 -0
  86. package/src/desk/ui/views-mail.js +188 -0
  87. package/src/desk/ui/views-misc.js +123 -0
  88. package/src/desk/ui/views-review.js +119 -0
  89. package/src/desk/ui/views-runs.js +350 -0
  90. package/src/desk/ui/views-screens.js +163 -0
  91. package/src/desk/ui/views-series.js +318 -0
  92. package/src/desk/ui/views-topics.js +87 -0
  93. package/src/desk/verbs.ts +361 -0
  94. package/src/doctor.ts +212 -0
  95. package/src/drain.ts +14 -0
  96. package/src/engage/index.ts +217 -0
  97. package/src/generate/index.ts +110 -0
  98. package/src/generate/script.ts +152 -0
  99. package/src/generate/title.ts +78 -0
  100. package/src/help.ts +233 -0
  101. package/src/home.ts +45 -0
  102. package/src/llm/client.ts +177 -0
  103. package/src/log.ts +7 -0
  104. package/src/oauth/tokens.ts +189 -0
  105. package/src/oauth/vault.ts +72 -0
  106. package/src/pipeline/review.ts +642 -0
  107. package/src/pipeline/run.ts +443 -0
  108. package/src/pipeline/series-guard.ts +26 -0
  109. package/src/pipeline/source-fetch.ts +69 -0
  110. package/src/pipeline/stages.ts +728 -0
  111. package/src/pipeline/topics-source.ts +90 -0
  112. package/src/product/commands.ts +296 -0
  113. package/src/product/config-file.ts +38 -0
  114. package/src/product/engine-choice.ts +89 -0
  115. package/src/product/engines.ts +103 -0
  116. package/src/product/insights.ts +50 -0
  117. package/src/product/keys.ts +67 -0
  118. package/src/product/paths.ts +18 -0
  119. package/src/product/probes.ts +88 -0
  120. package/src/product/push-flow.ts +90 -0
  121. package/src/product/render-video.ts +21 -0
  122. package/src/product/short.ts +62 -0
  123. package/src/product/update.ts +32 -0
  124. package/src/project/canonical.ts +14 -0
  125. package/src/project/commands.ts +177 -0
  126. package/src/project/dashboard-status.ts +28 -0
  127. package/src/project/discover.ts +19 -0
  128. package/src/project/index-file.ts +73 -0
  129. package/src/project/marker.ts +87 -0
  130. package/src/project/migrate.ts +201 -0
  131. package/src/project/names.ts +27 -0
  132. package/src/project/notice.ts +16 -0
  133. package/src/project/open.ts +88 -0
  134. package/src/project/scaffold.ts +112 -0
  135. package/src/project/templates.ts +42 -0
  136. package/src/project/videos.ts +64 -0
  137. package/src/publish/facebook.ts +91 -0
  138. package/src/publish/index.ts +12 -0
  139. package/src/publish/instagram.ts +97 -0
  140. package/src/publish/rate.ts +62 -0
  141. package/src/publish/session.ts +242 -0
  142. package/src/publish/tiktok.ts +202 -0
  143. package/src/publish/youtube.ts +177 -0
  144. package/src/queue/desk-ops.ts +1170 -0
  145. package/src/queue/seal.ts +3 -0
  146. package/src/queue/store.ts +1006 -0
  147. package/src/remotion/AiLabel.tsx +26 -0
  148. package/src/remotion/Root.tsx +73 -0
  149. package/src/remotion/defaults.ts +26 -0
  150. package/src/remotion/films/claude/ClaudeFilm.tsx +1014 -0
  151. package/src/remotion/films/engine/EngineMark.tsx +17 -0
  152. package/src/remotion/films/rea/ReaShort.tsx +552 -0
  153. package/src/remotion/films/rea/drawings.tsx +907 -0
  154. package/src/remotion/films/rea/timing.ts +144 -0
  155. package/src/remotion/index.ts +4 -0
  156. package/src/remotion/templates/EditorialSplit.tsx +39 -0
  157. package/src/remotion/templates/KineticType.tsx +39 -0
  158. package/src/remotion/templates/SignalBoard.tsx +50 -0
  159. package/src/remotion/timing.ts +22 -0
  160. package/src/render/chrome.ts +78 -0
  161. package/src/render/engine-mark.ts +29 -0
  162. package/src/render/framey-template.ts +130 -0
  163. package/src/render/html-engine.ts +149 -0
  164. package/src/render/node-crypto-stub.ts +11 -0
  165. package/src/render/probe.ts +29 -0
  166. package/src/render/props.ts +17 -0
  167. package/src/render/vertical-short.ts +35 -0
  168. package/src/render/webpack.ts +33 -0
  169. package/src/render/worker.ts +65 -0
  170. package/src/scene/assets/fonts/TitanOne-OFL.txt +94 -0
  171. package/src/scene/assets/fonts/titan-one.woff2 +0 -0
  172. package/src/scene/assets/gsap/LICENSE.txt +8 -0
  173. package/src/scene/assets/gsap/gsap.min.js +11 -0
  174. package/src/scene/audio.ts +54 -0
  175. package/src/scene/blocks/LICENSE +190 -0
  176. package/src/scene/blocks/NOTICE +5 -0
  177. package/src/scene/blocks/bar-chart-race/bar-chart-race.html +585 -0
  178. package/src/scene/blocks/beat-freeze-cut/beat-freeze-cut.html +874 -0
  179. package/src/scene/blocks/camcorder-hud/camcorder-hud.html +164 -0
  180. package/src/scene/blocks/camera-dolly-zoom/camera-dolly-zoom.html +355 -0
  181. package/src/scene/blocks/code-diff/code-diff.html +817 -0
  182. package/src/scene/blocks/code-snippet-apple-terminal-pro/code-snippet-apple-terminal-pro.html +248 -0
  183. package/src/scene/blocks/code-typing/code-typing.html +764 -0
  184. package/src/scene/blocks/data-chart/data-chart.html +452 -0
  185. package/src/scene/blocks/flowchart-vertical/flowchart-vertical.html +454 -0
  186. package/src/scene/blocks/hw-scribble-transition/hw-scribble-transition.html +153 -0
  187. package/src/scene/blocks/index.json +824 -0
  188. package/src/scene/blocks/lt-accent-underline/lt-accent-underline.html +107 -0
  189. package/src/scene/blocks/lt-bold-block/lt-bold-block.html +109 -0
  190. package/src/scene/blocks/lt-clean-bar/lt-clean-bar.html +112 -0
  191. package/src/scene/blocks/lt-dark-card/lt-dark-card.html +111 -0
  192. package/src/scene/blocks/lt-kicker-name/lt-kicker-name.html +114 -0
  193. package/src/scene/blocks/lt-mask-reveal/lt-mask-reveal.html +120 -0
  194. package/src/scene/blocks/lt-neon-border/lt-neon-border.html +391 -0
  195. package/src/scene/blocks/lt-stack-bars/lt-stack-bars.html +109 -0
  196. package/src/scene/blocks/macos-notification/macos-notification.html +194 -0
  197. package/src/scene/blocks/mk-background/mk-background.html +236 -0
  198. package/src/scene/blocks/mk-callout-highlight/mk-callout-highlight.html +183 -0
  199. package/src/scene/blocks/mk-clone-wall-transition/mk-clone-wall-transition.html +226 -0
  200. package/src/scene/blocks/mk-line-graph/mk-line-graph.html +293 -0
  201. package/src/scene/blocks/mk-progress-stat/mk-progress-stat.html +186 -0
  202. package/src/scene/blocks/mk-specs-list/mk-specs-list.html +223 -0
  203. package/src/scene/blocks/news-ticker/news-ticker.html +409 -0
  204. package/src/scene/blocks/organic-light-leak-overlay/organic-light-leak-overlay.html +126 -0
  205. package/src/scene/blocks/oscilloscope-trace/oscilloscope-trace.html +519 -0
  206. package/src/scene/blocks/snow/snow.html +205 -0
  207. package/src/scene/blocks/split-flap-board/split-flap-board.html +347 -0
  208. package/src/scene/blocks/spotify-card/spotify-card.html +294 -0
  209. package/src/scene/blocks/starfield/starfield.html +188 -0
  210. package/src/scene/blocks/thread-message-stack/thread-message-stack.html +239 -0
  211. package/src/scene/blocks/week-in-merges/week-in-merges.html +470 -0
  212. package/src/scene/blocks/x-post/x-post.html +437 -0
  213. package/src/scene/blocks/yt-comment-card/yt-comment-card.html +319 -0
  214. package/src/scene/blocks/yt-lcd-background/yt-lcd-background.html +307 -0
  215. package/src/scene/blocks/yt-prism-title/yt-prism-title.html +205 -0
  216. package/src/scene/blocks.ts +229 -0
  217. package/src/scene/command.ts +272 -0
  218. package/src/scene/figure.ts +181 -0
  219. package/src/scene/glyphs.ts +107 -0
  220. package/src/scene/init.ts +86 -0
  221. package/src/scene/inspect/css-tree.d.ts +6 -0
  222. package/src/scene/inspect/page-scripts.ts +272 -0
  223. package/src/scene/inspect/report.ts +405 -0
  224. package/src/scene/inspect/run.ts +200 -0
  225. package/src/scene/inspect/source.ts +236 -0
  226. package/src/scene/label.ts +131 -0
  227. package/src/scene/net-guard.ts +74 -0
  228. package/src/scene/render.ts +292 -0
  229. package/src/scene/runtime/browser.ts +199 -0
  230. package/src/scene/runtime/core.ts +181 -0
  231. package/src/scene/runtime/react.tsx +115 -0
  232. package/src/scene/runtime/transitions.ts +133 -0
  233. package/src/scene/sanitize.ts +181 -0
  234. package/src/scene/scene.ts +152 -0
  235. package/src/scene/studio-command.ts +48 -0
  236. package/src/scene/studio-skin.ts +59 -0
  237. package/src/scene/studio.ts +337 -0
  238. package/src/scene/supply.ts +111 -0
  239. package/src/scene/timing.ts +288 -0
  240. package/src/scene/transitions/LICENSE +190 -0
  241. package/src/scene/transitions/NOTICE +5 -0
  242. package/src/scene/transitions/SOURCE.json +24 -0
  243. package/src/scene/transitions/transitions.global.js +38 -0
  244. package/src/scene/transitions.ts +26 -0
  245. package/src/service/all-projects.ts +153 -0
  246. package/src/service/commands.ts +256 -0
  247. package/src/service/due.ts +82 -0
  248. package/src/service/lock.ts +101 -0
  249. package/src/service/log-file.ts +56 -0
  250. package/src/service/state.ts +41 -0
  251. package/src/service/units.ts +90 -0
  252. package/src/service/worker.ts +51 -0
  253. package/src/skill-agents.ts +74 -0
  254. package/src/skill-install.ts +334 -0
  255. package/src/sync-write.ts +21 -0
  256. package/src/tick-report.ts +205 -0
  257. package/src/tts.ts +124 -0
  258. package/vendor/@vfrey/contracts/dist/account.d.ts +97 -0
  259. package/vendor/@vfrey/contracts/dist/account.js +27 -0
  260. package/vendor/@vfrey/contracts/dist/checks.d.ts +8 -0
  261. package/vendor/@vfrey/contracts/dist/checks.js +1 -0
  262. package/vendor/@vfrey/contracts/dist/credentials/crypto.d.ts +4 -0
  263. package/vendor/@vfrey/contracts/dist/credentials/crypto.js +38 -0
  264. package/vendor/@vfrey/contracts/dist/domain/advice-persona.d.ts +10 -0
  265. package/vendor/@vfrey/contracts/dist/domain/advice-persona.js +24 -0
  266. package/vendor/@vfrey/contracts/dist/domain/backoff.d.ts +13 -0
  267. package/vendor/@vfrey/contracts/dist/domain/backoff.js +27 -0
  268. package/vendor/@vfrey/contracts/dist/domain/cadence.d.ts +29 -0
  269. package/vendor/@vfrey/contracts/dist/domain/cadence.js +95 -0
  270. package/vendor/@vfrey/contracts/dist/domain/creators.d.ts +146 -0
  271. package/vendor/@vfrey/contracts/dist/domain/creators.js +2 -0
  272. package/vendor/@vfrey/contracts/dist/domain/disclosure.d.ts +127 -0
  273. package/vendor/@vfrey/contracts/dist/domain/disclosure.js +250 -0
  274. package/vendor/@vfrey/contracts/dist/domain/errors.d.ts +34 -0
  275. package/vendor/@vfrey/contracts/dist/domain/errors.js +68 -0
  276. package/vendor/@vfrey/contracts/dist/domain/redact.d.ts +1 -0
  277. package/vendor/@vfrey/contracts/dist/domain/redact.js +21 -0
  278. package/vendor/@vfrey/contracts/dist/domain/revenue.d.ts +13 -0
  279. package/vendor/@vfrey/contracts/dist/domain/revenue.js +16 -0
  280. package/vendor/@vfrey/contracts/dist/domain/safety.d.ts +20 -0
  281. package/vendor/@vfrey/contracts/dist/domain/safety.js +61 -0
  282. package/vendor/@vfrey/contracts/dist/domain/similarity.d.ts +13 -0
  283. package/vendor/@vfrey/contracts/dist/domain/similarity.js +100 -0
  284. package/vendor/@vfrey/contracts/dist/domain/templates.d.ts +18 -0
  285. package/vendor/@vfrey/contracts/dist/domain/templates.js +67 -0
  286. package/vendor/@vfrey/contracts/dist/domain/tiktok-chunks.d.ts +19 -0
  287. package/vendor/@vfrey/contracts/dist/domain/tiktok-chunks.js +52 -0
  288. package/vendor/@vfrey/contracts/dist/domain/topics.d.ts +78 -0
  289. package/vendor/@vfrey/contracts/dist/domain/topics.js +4 -0
  290. package/vendor/@vfrey/contracts/dist/domain/types.d.ts +216 -0
  291. package/vendor/@vfrey/contracts/dist/domain/types.js +1 -0
  292. package/vendor/@vfrey/contracts/dist/domain/variation.d.ts +57 -0
  293. package/vendor/@vfrey/contracts/dist/domain/variation.js +278 -0
  294. package/vendor/@vfrey/contracts/dist/events.d.ts +20 -0
  295. package/vendor/@vfrey/contracts/dist/events.js +1 -0
  296. package/vendor/@vfrey/contracts/dist/http.d.ts +11 -0
  297. package/vendor/@vfrey/contracts/dist/http.js +37 -0
  298. package/vendor/@vfrey/contracts/dist/index.d.ts +22 -0
  299. package/vendor/@vfrey/contracts/dist/index.js +22 -0
  300. package/vendor/@vfrey/contracts/dist/log.d.ts +2 -0
  301. package/vendor/@vfrey/contracts/dist/log.js +10 -0
  302. package/vendor/@vfrey/contracts/dist/mail.d.ts +55 -0
  303. package/vendor/@vfrey/contracts/dist/mail.js +1 -0
  304. package/vendor/@vfrey/contracts/package.json +18 -0
  305. package/vendor/@vfrey/ingest/dist/index.d.ts +41 -0
  306. package/vendor/@vfrey/ingest/dist/index.js +221 -0
  307. package/vendor/@vfrey/ingest/dist/parse.d.ts +5 -0
  308. package/vendor/@vfrey/ingest/dist/parse.js +165 -0
  309. package/vendor/@vfrey/ingest/package.json +21 -0
  310. package/vendor/framey/LICENSE +190 -0
  311. package/vendor/framey/NOTICE +15 -0
  312. package/vendor/framey/SOURCE.json +24 -0
  313. package/vendor/framey/STUDIO-SOURCE.json +9 -0
  314. package/vendor/framey/bin/framey-localize-fonts.mjs +12 -0
  315. package/vendor/framey/bin/framey.mjs +16 -0
  316. package/vendor/framey/dist/add-VMJD5KBS.js +75 -0
  317. package/vendor/framey/dist/animatedGifPrep-QPKGJ6PM.js +43 -0
  318. package/vendor/framey/dist/api.d.ts +211 -0
  319. package/vendor/framey/dist/api.js +76 -0
  320. package/vendor/framey/dist/appHistory-WW56FZTT.js +31 -0
  321. package/vendor/framey/dist/asset-WQKGOELE.js +26 -0
  322. package/vendor/framey/dist/audio-RSJWVWRA.js +1936 -0
  323. package/vendor/framey/dist/batchRender-3HPICDCT.js +366 -0
  324. package/vendor/framey/dist/beats-HL2BDUZI.js +273 -0
  325. package/vendor/framey/dist/benchmark-RWCWHI5Z.js +230 -0
  326. package/vendor/framey/dist/browser-ECYET3Q2.js +206 -0
  327. package/vendor/framey/dist/bundleWithLocalizedFonts-ALYBQEQT.js +52 -0
  328. package/vendor/framey/dist/captureCompositionFrame-4DA6SEH2.js +94 -0
  329. package/vendor/framey/dist/catalog-5JVDEUWK.js +979 -0
  330. package/vendor/framey/dist/catch-up-NEBCL5NO.js +106 -0
  331. package/vendor/framey/dist/check-F5N544ML.js +111 -0
  332. package/vendor/framey/dist/checkBrowser-LZ66CMJG.js +110 -0
  333. package/vendor/framey/dist/chunk-2K7Z2HVP.js +372 -0
  334. package/vendor/framey/dist/chunk-2UZQHDM7.js +323 -0
  335. package/vendor/framey/dist/chunk-2X4PQEYM.js +34 -0
  336. package/vendor/framey/dist/chunk-3422KMTD.js +168 -0
  337. package/vendor/framey/dist/chunk-3FYD4YEK.js +72 -0
  338. package/vendor/framey/dist/chunk-3GXQPCJC.js +682 -0
  339. package/vendor/framey/dist/chunk-3LM6YPBR.js +179 -0
  340. package/vendor/framey/dist/chunk-442JNXRM.js +20 -0
  341. package/vendor/framey/dist/chunk-4BNN5FGX.js +182 -0
  342. package/vendor/framey/dist/chunk-4P7NX5BM.js +11532 -0
  343. package/vendor/framey/dist/chunk-4UMPIPCQ.js +88 -0
  344. package/vendor/framey/dist/chunk-4YYJOFKS.js +28 -0
  345. package/vendor/framey/dist/chunk-54HJ63Q2.js +29 -0
  346. package/vendor/framey/dist/chunk-5ETJX6WM.js +89 -0
  347. package/vendor/framey/dist/chunk-5SG54JRS.js +68 -0
  348. package/vendor/framey/dist/chunk-634HSJ3J.js +58 -0
  349. package/vendor/framey/dist/chunk-66LREXGS.js +48 -0
  350. package/vendor/framey/dist/chunk-6BEFEWFB.js +25 -0
  351. package/vendor/framey/dist/chunk-6BNTGNGD.js +286 -0
  352. package/vendor/framey/dist/chunk-6DDPOHMK.js +140 -0
  353. package/vendor/framey/dist/chunk-6GV5XSOR.js +214 -0
  354. package/vendor/framey/dist/chunk-6JR2XUEE.js +127 -0
  355. package/vendor/framey/dist/chunk-73QVATIM.js +362 -0
  356. package/vendor/framey/dist/chunk-7FMUTGOH.js +279 -0
  357. package/vendor/framey/dist/chunk-7JQFJ6JJ.js +291 -0
  358. package/vendor/framey/dist/chunk-AHPGAESX.js +113 -0
  359. package/vendor/framey/dist/chunk-AHX34EFP.js +15 -0
  360. package/vendor/framey/dist/chunk-AJ5CSAEZ.js +487 -0
  361. package/vendor/framey/dist/chunk-B7RJV74O.js +5047 -0
  362. package/vendor/framey/dist/chunk-BL4U6U52.js +254 -0
  363. package/vendor/framey/dist/chunk-BSQ7XANM.js +210 -0
  364. package/vendor/framey/dist/chunk-BZ56MTDX.js +6 -0
  365. package/vendor/framey/dist/chunk-C5BO7PMT.js +282 -0
  366. package/vendor/framey/dist/chunk-CFUCHO4T.js +358 -0
  367. package/vendor/framey/dist/chunk-CZGHFATT.js +31 -0
  368. package/vendor/framey/dist/chunk-DLA44CMS.js +5649 -0
  369. package/vendor/framey/dist/chunk-DPVXBVLL.js +31292 -0
  370. package/vendor/framey/dist/chunk-DQBY7FRR.js +397 -0
  371. package/vendor/framey/dist/chunk-EAMLBAHA.js +154 -0
  372. package/vendor/framey/dist/chunk-EOVYQ3IG.js +143 -0
  373. package/vendor/framey/dist/chunk-EVMY7IPL.js +612 -0
  374. package/vendor/framey/dist/chunk-FG4BBFZI.js +122 -0
  375. package/vendor/framey/dist/chunk-FI4I7CME.js +56 -0
  376. package/vendor/framey/dist/chunk-FLREUEHW.js +2081 -0
  377. package/vendor/framey/dist/chunk-FUFP7A7S.js +1126 -0
  378. package/vendor/framey/dist/chunk-FV3PIKGH.js +56 -0
  379. package/vendor/framey/dist/chunk-FXMKHHPO.js +123 -0
  380. package/vendor/framey/dist/chunk-GGZAM5VH.js +1187 -0
  381. package/vendor/framey/dist/chunk-GKZEVJIB.js +39 -0
  382. package/vendor/framey/dist/chunk-GMECXFAN.js +57 -0
  383. package/vendor/framey/dist/chunk-GNEFDLFB.js +621 -0
  384. package/vendor/framey/dist/chunk-GPMLSOEG.js +19274 -0
  385. package/vendor/framey/dist/chunk-GPYVT5EE.js +59 -0
  386. package/vendor/framey/dist/chunk-H6IEMZEV.js +40 -0
  387. package/vendor/framey/dist/chunk-HEFQCIXR.js +170 -0
  388. package/vendor/framey/dist/chunk-HFQ4CWHA.js +118 -0
  389. package/vendor/framey/dist/chunk-HPDTCOKE.js +304 -0
  390. package/vendor/framey/dist/chunk-HTUHQKDB.js +548 -0
  391. package/vendor/framey/dist/chunk-HU2SPFNG.js +103 -0
  392. package/vendor/framey/dist/chunk-HVW7ABXD.js +19 -0
  393. package/vendor/framey/dist/chunk-IG7NDKXO.js +26 -0
  394. package/vendor/framey/dist/chunk-II3J3WXK.js +246 -0
  395. package/vendor/framey/dist/chunk-IR35BCLK.js +13 -0
  396. package/vendor/framey/dist/chunk-ISN5GRYI.js +20 -0
  397. package/vendor/framey/dist/chunk-IUONB55J.js +669 -0
  398. package/vendor/framey/dist/chunk-IVSUQR2B.js +161 -0
  399. package/vendor/framey/dist/chunk-IXU6PQSW.js +259 -0
  400. package/vendor/framey/dist/chunk-IZCW2NKT.js +29 -0
  401. package/vendor/framey/dist/chunk-JGXJU5PF.js +68 -0
  402. package/vendor/framey/dist/chunk-JHOCK3DG.js +27 -0
  403. package/vendor/framey/dist/chunk-JVBRJMOP.js +121 -0
  404. package/vendor/framey/dist/chunk-K4MJX7SR.js +17 -0
  405. package/vendor/framey/dist/chunk-K4WKGXRC.js +18 -0
  406. package/vendor/framey/dist/chunk-KGPLIH7B.js +127 -0
  407. package/vendor/framey/dist/chunk-KLIKCX6Q.js +63 -0
  408. package/vendor/framey/dist/chunk-KXTKKBOC.js +61 -0
  409. package/vendor/framey/dist/chunk-KZI44OPA.js +185 -0
  410. package/vendor/framey/dist/chunk-LEKZNRKI.js +45 -0
  411. package/vendor/framey/dist/chunk-LFGJWOVA.js +61 -0
  412. package/vendor/framey/dist/chunk-LLMSX6V6.js +17 -0
  413. package/vendor/framey/dist/chunk-LTGTN2TH.js +195 -0
  414. package/vendor/framey/dist/chunk-M2WBOQ2Q.js +54 -0
  415. package/vendor/framey/dist/chunk-MI5FTLYK.js +399 -0
  416. package/vendor/framey/dist/chunk-MLQP2QUF.js +1809 -0
  417. package/vendor/framey/dist/chunk-MMQ52NIZ.js +956 -0
  418. package/vendor/framey/dist/chunk-ND46XKK3.js +742 -0
  419. package/vendor/framey/dist/chunk-NYEXNSHM.js +504 -0
  420. package/vendor/framey/dist/chunk-O4YRB27L.js +57 -0
  421. package/vendor/framey/dist/chunk-O7BGSQ5F.js +92 -0
  422. package/vendor/framey/dist/chunk-OFQWTKPW.js +117 -0
  423. package/vendor/framey/dist/chunk-P5ZBLXJ6.js +91 -0
  424. package/vendor/framey/dist/chunk-P6LJ4Y32.js +4662 -0
  425. package/vendor/framey/dist/chunk-PKZ7RK5N.js +281 -0
  426. package/vendor/framey/dist/chunk-PURHAXFL.js +15 -0
  427. package/vendor/framey/dist/chunk-Q5X2B5WT.js +29 -0
  428. package/vendor/framey/dist/chunk-QAMKOG67.js +248 -0
  429. package/vendor/framey/dist/chunk-R6YBK4XX.js +514 -0
  430. package/vendor/framey/dist/chunk-RGLQURIX.js +2997 -0
  431. package/vendor/framey/dist/chunk-RNV3DM4S.js +3573 -0
  432. package/vendor/framey/dist/chunk-ROEW726S.js +4638 -0
  433. package/vendor/framey/dist/chunk-RQVDTPGD.js +6 -0
  434. package/vendor/framey/dist/chunk-RVZHGOGR.js +26 -0
  435. package/vendor/framey/dist/chunk-RXATE6FZ.js +385 -0
  436. package/vendor/framey/dist/chunk-S3S4TGEH.js +424 -0
  437. package/vendor/framey/dist/chunk-SDYDNHEE.js +11202 -0
  438. package/vendor/framey/dist/chunk-SSWBU67I.js +173 -0
  439. package/vendor/framey/dist/chunk-ST35C4K6.js +28 -0
  440. package/vendor/framey/dist/chunk-SZNTYTIV.js +990 -0
  441. package/vendor/framey/dist/chunk-T2EUWCJE.js +29 -0
  442. package/vendor/framey/dist/chunk-T6AGUTZJ.js +444 -0
  443. package/vendor/framey/dist/chunk-THJALHFJ.js +11131 -0
  444. package/vendor/framey/dist/chunk-TIQB63MX.js +18128 -0
  445. package/vendor/framey/dist/chunk-U242RTCT.js +134 -0
  446. package/vendor/framey/dist/chunk-UJZREAV6.js +3901 -0
  447. package/vendor/framey/dist/chunk-UMD3V7CU.js +264 -0
  448. package/vendor/framey/dist/chunk-UOFAE5RF.js +42 -0
  449. package/vendor/framey/dist/chunk-UTEIUGAZ.js +29 -0
  450. package/vendor/framey/dist/chunk-VAS6HQX3.js +138 -0
  451. package/vendor/framey/dist/chunk-VC76R6W2.js +27 -0
  452. package/vendor/framey/dist/chunk-VFZ7W5W7.js +226 -0
  453. package/vendor/framey/dist/chunk-VHNLZAE2.js +348 -0
  454. package/vendor/framey/dist/chunk-VMC4WSH5.js +278 -0
  455. package/vendor/framey/dist/chunk-VORQIH64.js +108 -0
  456. package/vendor/framey/dist/chunk-VTXFRIHO.js +186 -0
  457. package/vendor/framey/dist/chunk-W2LGJSEN.js +182 -0
  458. package/vendor/framey/dist/chunk-WKBM7NDG.js +32 -0
  459. package/vendor/framey/dist/chunk-WMQNIQDJ.js +2057 -0
  460. package/vendor/framey/dist/chunk-WN4XZC5F.js +504 -0
  461. package/vendor/framey/dist/chunk-WQ6ZXHFQ.js +133 -0
  462. package/vendor/framey/dist/chunk-X7HBSTCZ.js +53 -0
  463. package/vendor/framey/dist/chunk-X7MTZ4T2.js +6 -0
  464. package/vendor/framey/dist/chunk-XPTOJZJF.js +308 -0
  465. package/vendor/framey/dist/chunk-XT6MXC7A.js +6 -0
  466. package/vendor/framey/dist/chunk-XT7X6QCP.js +6 -0
  467. package/vendor/framey/dist/chunk-XTMDWNEC.js +2820 -0
  468. package/vendor/framey/dist/chunk-XUHOIDKG.js +6 -0
  469. package/vendor/framey/dist/chunk-XX7LTW5Y.js +138 -0
  470. package/vendor/framey/dist/chunk-Y3YGTZEG.js +382 -0
  471. package/vendor/framey/dist/chunk-Y5SBSGN7.js +346 -0
  472. package/vendor/framey/dist/chunk-YCMVI4MZ.js +625 -0
  473. package/vendor/framey/dist/chunk-YOR4CTCE.js +261 -0
  474. package/vendor/framey/dist/chunk-YPRBGITP.js +2748 -0
  475. package/vendor/framey/dist/chunk-ZKDMAOFU.js +32 -0
  476. package/vendor/framey/dist/chunk-ZW6DURPF.js +1318 -0
  477. package/vendor/framey/dist/clean-ZJOGDKDM.js +336 -0
  478. package/vendor/framey/dist/cli.js +439 -0
  479. package/vendor/framey/dist/cloudrun-HGJ3B6ZV.js +767 -0
  480. package/vendor/framey/dist/commands/contrast-audit.browser.js +643 -0
  481. package/vendor/framey/dist/commands/layout-audit.browser.js +2914 -0
  482. package/vendor/framey/dist/commands/motion-sample.browser.js +74 -0
  483. package/vendor/framey/dist/commands/motion-signature.browser.js +475 -0
  484. package/vendor/framey/dist/compare-W7UY3BAZ.js +463 -0
  485. package/vendor/framey/dist/compiler-TM3W6GYF.js +136 -0
  486. package/vendor/framey/dist/component-QF5VGYMU.js +176 -0
  487. package/vendor/framey/dist/compositions-XT3PMNDF.js +238 -0
  488. package/vendor/framey/dist/contactSheet-7W6GYHBQ.js +24 -0
  489. package/vendor/framey/dist/deploy-6FJPWKF2.js +299 -0
  490. package/vendor/framey/dist/destroy-HE2RIPKZ.js +57 -0
  491. package/vendor/framey/dist/deterministicFonts-RADD3BSX.js +50 -0
  492. package/vendor/framey/dist/dist-4S2FGGVY.js +422 -0
  493. package/vendor/framey/dist/dist-BE4B2EZE.js +32 -0
  494. package/vendor/framey/dist/dist-EWXJGN63.js +129 -0
  495. package/vendor/framey/dist/docs-VKIRFEEX.js +131 -0
  496. package/vendor/framey/dist/doctor-2UNJ2G7U.js +74 -0
  497. package/vendor/framey/dist/dom-37K6YOH4.js +14 -0
  498. package/vendor/framey/dist/dotEnv-7PZQTVIM.js +54 -0
  499. package/vendor/framey/dist/events-ACY3P2PA.js +76 -0
  500. package/vendor/framey/dist/events-IHB3B2MK.js +69 -0
  501. package/vendor/framey/dist/ffmpeg-DR5LGGSK.js +63 -0
  502. package/vendor/framey/dist/figma-BODVUPHB.js +63 -0
  503. package/vendor/framey/dist/fontData.generated-NXAOI4GH.js +13 -0
  504. package/vendor/framey/dist/fontLocalizeCli.js +142 -0
  505. package/vendor/framey/dist/gpuPolicy-XLEXORZY.js +49 -0
  506. package/vendor/framey/dist/grade-compare-GAXFQ74C.js +661 -0
  507. package/vendor/framey/dist/gsapParser-IEUSLYDJ.js +2885 -0
  508. package/vendor/framey/dist/gsapParserAcorn-LZJKCFQI.js +30 -0
  509. package/vendor/framey/dist/help-VCB5X2HS.js +184 -0
  510. package/vendor/framey/dist/history-ENGZEVFT.js +471 -0
  511. package/vendor/framey/dist/hyperframe.manifest.json +22 -0
  512. package/vendor/framey/dist/hyperframe.runtime.iife.js +1132 -0
  513. package/vendor/framey/dist/hyperframes-player.global.js +478 -0
  514. package/vendor/framey/dist/hyperframes-slideshow.global.js +148 -0
  515. package/vendor/framey/dist/info-WPCJHBMU.js +182 -0
  516. package/vendor/framey/dist/init-G4WGLYGD.js +1176 -0
  517. package/vendor/framey/dist/inspect-5IQ6CNEQ.js +106 -0
  518. package/vendor/framey/dist/installer-ML4HWUV7.js +40 -0
  519. package/vendor/framey/dist/keyframes-Q6XJO7VW.js +2755 -0
  520. package/vendor/framey/dist/lambda-A7JC74JF.js +468 -0
  521. package/vendor/framey/dist/layout-YET6XNXA.js +95 -0
  522. package/vendor/framey/dist/lint-I7FZN2VJ.js +162 -0
  523. package/vendor/framey/dist/lintProject-PDB3UN72.js +30 -0
  524. package/vendor/framey/dist/manager-CD6LJ7ZN.js +45 -0
  525. package/vendor/framey/dist/manager-WA4F2GST.js +67 -0
  526. package/vendor/framey/dist/media-treatment-BXYS4WVA.js +1030 -0
  527. package/vendor/framey/dist/media-use-LWH3MANK.js +113 -0
  528. package/vendor/framey/dist/models-K363FYM4.js +195 -0
  529. package/vendor/framey/dist/motionShot-GPAVWXLH.js +640 -0
  530. package/vendor/framey/dist/normalize-FASIPBUM.js +24 -0
  531. package/vendor/framey/dist/normalize-audio-VDWYRHN6.js +268 -0
  532. package/vendor/framey/dist/open-E3TB6P6J.js +128 -0
  533. package/vendor/framey/dist/parakeetRunner-UP34UOI2.js +58 -0
  534. package/vendor/framey/dist/pipeline-VXIUYEBU.js +64 -0
  535. package/vendor/framey/dist/play-BUTDQ4DV.js +353 -0
  536. package/vendor/framey/dist/policies-OLDYGFK5.js +309 -0
  537. package/vendor/framey/dist/preflight-2KZ2GWAZ.js +55 -0
  538. package/vendor/framey/dist/present-GXYSM7NX.js +353 -0
  539. package/vendor/framey/dist/preview-EKZ33JOJ.js +1910 -0
  540. package/vendor/framey/dist/producer-SKU5EV3J.js +13 -0
  541. package/vendor/framey/dist/progress-ZWB4Z4ET.js +76 -0
  542. package/vendor/framey/dist/projectConfig-3MZAYVTS.js +60 -0
  543. package/vendor/framey/dist/publication-DTKWNF74.js +33 -0
  544. package/vendor/framey/dist/remove-background-OY5L7XN2.js +265 -0
  545. package/vendor/framey/dist/render-CDV4GDFX.js +187 -0
  546. package/vendor/framey/dist/render-YE5YAMOD.js +2620 -0
  547. package/vendor/framey/dist/render-batch-ZAMFPCLL.js +274 -0
  548. package/vendor/framey/dist/renderSetupWorker.js +120 -0
  549. package/vendor/framey/dist/resolver-D5BIPSEW.js +42 -0
  550. package/vendor/framey/dist/runtimeVersion.js +18 -0
  551. package/vendor/framey/dist/sam-WFZXI4F7.js +23 -0
  552. package/vendor/framey/dist/shaderTransitionWorker.js +44 -0
  553. package/vendor/framey/dist/sherpa-RQWLV7I3.js +79 -0
  554. package/vendor/framey/dist/sherpaWorker.js +84 -0
  555. package/vendor/framey/dist/sites-AMOVABTK.js +54 -0
  556. package/vendor/framey/dist/skill-ZHVLH7KX.js +15 -0
  557. package/vendor/framey/dist/slideshow-SJGK4RQS.js +24 -0
  558. package/vendor/framey/dist/snapshot-TUXL6LBQ.js +1515 -0
  559. package/vendor/framey/dist/src-JHQGB2S6.js +215 -0
  560. package/vendor/framey/dist/src-Z5PGEMXB.js +532 -0
  561. package/vendor/framey/dist/state-B6H3WHCF.js +28 -0
  562. package/vendor/framey/dist/staticProjectServer-DFVZOUGI.js +63 -0
  563. package/vendor/framey/dist/studio/assets/hyperframes-player-DLaKjw0L.js +478 -0
  564. package/vendor/framey/dist/studio/assets/index-BX3KHhGX.js +71 -0
  565. package/vendor/framey/dist/studio/assets/index-CYbvOVp-.css +1 -0
  566. package/vendor/framey/dist/studio/assets/index-Dp3QEUGL.js +402 -0
  567. package/vendor/framey/dist/studio/assets/index-qrTAXbqc.js +531 -0
  568. package/vendor/framey/dist/studio/favicon.svg +14 -0
  569. package/vendor/framey/dist/studio/icons/timeline/audio.svg +7 -0
  570. package/vendor/framey/dist/studio/icons/timeline/captions.svg +5 -0
  571. package/vendor/framey/dist/studio/icons/timeline/composition.svg +12 -0
  572. package/vendor/framey/dist/studio/icons/timeline/image.svg +18 -0
  573. package/vendor/framey/dist/studio/icons/timeline/music.svg +10 -0
  574. package/vendor/framey/dist/studio/icons/timeline/text.svg +3 -0
  575. package/vendor/framey/dist/studio/index.html +23 -0
  576. package/vendor/framey/dist/studio-api-2NECGRMB.js +179 -0
  577. package/vendor/framey/dist/studioSelectionClient-IUUPKUHZ.js +25 -0
  578. package/vendor/framey/dist/studioServer-N2OPUMOQ.js +1569 -0
  579. package/vendor/framey/dist/synthesize-PKTB5ATG.js +183 -0
  580. package/vendor/framey/dist/system-7F3UEHQT.js +27 -0
  581. package/vendor/framey/dist/telemetry-DQGPEKM6.js +145 -0
  582. package/vendor/framey/dist/telemetry-UN55N6U6.js +77 -0
  583. package/vendor/framey/dist/timeline-LHUUMK63.js +1295 -0
  584. package/vendor/framey/dist/tokens-OLECWDFK.js +92 -0
  585. package/vendor/framey/dist/transcribe-O7HQKMIV.js +331 -0
  586. package/vendor/framey/dist/transcribe-UJESPBT5.js +76 -0
  587. package/vendor/framey/dist/tts-YCCQHZD4.js +234 -0
  588. package/vendor/framey/dist/urlDownloader-H2LXLG4U.js +48 -0
  589. package/vendor/framey/dist/usage-HG4WMM7A.js +2167 -0
  590. package/vendor/framey/dist/validate-F2XMN6EV.js +87 -0
  591. package/vendor/framey/dist/vendor/npm/gsap@3.15.0/GSAP-LICENSE.txt +8 -0
  592. package/vendor/framey/dist/vendor/npm/gsap@3.15.0/dist/CustomEase.min.js +11 -0
  593. package/vendor/framey/dist/vendor/npm/gsap@3.15.0/dist/MotionPathPlugin.min.js +11 -0
  594. package/vendor/framey/dist/vendor/npm/gsap@3.15.0/dist/gsap.min.js +11 -0
  595. package/vendor/framey/dist/warmCheck.js +220 -0
  596. package/vendor/framey/dist/warmCheckClient.js +139 -0
  597. package/vendor/framey/dist/workspaceBuildCheck-XYD2YTFW.js +133 -0
  598. package/vendor/framey-player/LICENSE +190 -0
  599. package/vendor/framey-player/NOTICE +16 -0
  600. package/vendor/framey-player/SOURCE.json +6 -0
  601. package/vendor/framey-player/hyperframes-player.global.js +478 -0
  602. package/vendor/framey.pin +1 -0
  603. package/bin/index.js +0 -3
@@ -0,0 +1,1295 @@
1
+ import { createRequire as __hf_createRequire } from "node:module";
2
+ import { fileURLToPath as __hf_fileURLToPath } from "node:url";
3
+ import { dirname as __hf_dirname } from "node:path";
4
+ var require = __hf_createRequire(import.meta.url);
5
+ var __filename = __hf_fileURLToPath(import.meta.url);
6
+ var __dirname = __hf_dirname(__filename);
7
+ import {
8
+ NEVER_VISIBLE,
9
+ describeProject
10
+ } from "./chunk-73QVATIM.js";
11
+ import "./chunk-LLMSX6V6.js";
12
+ import {
13
+ resolveExtraPositionals
14
+ } from "./chunk-5SG54JRS.js";
15
+ import "./chunk-K4WKGXRC.js";
16
+ import {
17
+ withMeta
18
+ } from "./chunk-O4YRB27L.js";
19
+ import {
20
+ resolveProject
21
+ } from "./chunk-O7BGSQ5F.js";
22
+ import {
23
+ applyFileMutations,
24
+ duplicateElementInHtml
25
+ } from "./chunk-THJALHFJ.js";
26
+ import {
27
+ patchElementInHtml,
28
+ removeElementFromHtml,
29
+ splitElementInHtml
30
+ } from "./chunk-IUONB55J.js";
31
+ import "./chunk-6JR2XUEE.js";
32
+ import "./chunk-MI5FTLYK.js";
33
+ import {
34
+ fileContentVersion
35
+ } from "./chunk-YPRBGITP.js";
36
+ import "./chunk-7JQFJ6JJ.js";
37
+ import {
38
+ readCompositionFps
39
+ } from "./chunk-KXTKKBOC.js";
40
+ import "./chunk-P5ZBLXJ6.js";
41
+ import {
42
+ ensureDOMParser
43
+ } from "./chunk-442JNXRM.js";
44
+ import "./chunk-FLREUEHW.js";
45
+ import "./chunk-EOVYQ3IG.js";
46
+ import "./chunk-GNEFDLFB.js";
47
+ import "./chunk-2UZQHDM7.js";
48
+ import "./chunk-NYEXNSHM.js";
49
+ import {
50
+ assertKnownFlags
51
+ } from "./chunk-U242RTCT.js";
52
+ import {
53
+ defineCommand
54
+ } from "./chunk-S3S4TGEH.js";
55
+ import "./chunk-54HJ63Q2.js";
56
+ import "./chunk-ISN5GRYI.js";
57
+ import "./chunk-VORQIH64.js";
58
+ import {
59
+ setCommandExitCode
60
+ } from "./chunk-JVBRJMOP.js";
61
+ import "./chunk-KLIKCX6Q.js";
62
+ import "./chunk-EVMY7IPL.js";
63
+ import "./chunk-7FMUTGOH.js";
64
+ import "./chunk-TIQB63MX.js";
65
+ import "./chunk-IZCW2NKT.js";
66
+ import {
67
+ ensureHfIds
68
+ } from "./chunk-RNV3DM4S.js";
69
+ import {
70
+ fpsToNumber,
71
+ parseFpsWithDefault
72
+ } from "./chunk-DLA44CMS.js";
73
+ import "./chunk-UJZREAV6.js";
74
+ import "./chunk-VC76R6W2.js";
75
+ import "./chunk-X7HBSTCZ.js";
76
+ import "./chunk-B7RJV74O.js";
77
+ import "./chunk-DPVXBVLL.js";
78
+ import "./chunk-OFQWTKPW.js";
79
+ import "./chunk-634HSJ3J.js";
80
+ import "./chunk-FXMKHHPO.js";
81
+ import "./chunk-RQVDTPGD.js";
82
+ import "./chunk-AHX34EFP.js";
83
+ import "./chunk-T2EUWCJE.js";
84
+ import "./chunk-T6AGUTZJ.js";
85
+ import "./chunk-XT6MXC7A.js";
86
+ import "./chunk-K4MJX7SR.js";
87
+ import "./chunk-4UMPIPCQ.js";
88
+ import "./chunk-4P7NX5BM.js";
89
+ import "./chunk-VAS6HQX3.js";
90
+ import "./chunk-6BNTGNGD.js";
91
+ import "./chunk-CZGHFATT.js";
92
+ import "./chunk-PKZ7RK5N.js";
93
+ import "./chunk-W2LGJSEN.js";
94
+ import {
95
+ isInsideSpan,
96
+ sameInstant,
97
+ spansShareTime
98
+ } from "./chunk-MMQ52NIZ.js";
99
+ import "./chunk-BSQ7XANM.js";
100
+ import "./chunk-SDYDNHEE.js";
101
+ import "./chunk-RXATE6FZ.js";
102
+ import "./chunk-3422KMTD.js";
103
+ import "./chunk-3GXQPCJC.js";
104
+ import "./chunk-M2WBOQ2Q.js";
105
+
106
+ // src/timeline/formatTimeline.ts
107
+ var BAR_WIDTH = 40;
108
+ var n = (v) => String(Math.round(v * 1e3) / 1e3);
109
+ function bar(row, total) {
110
+ if (total <= 0) return " ".repeat(BAR_WIDTH);
111
+ const known = row.durationAuthored || row.duration > 0;
112
+ const from = Math.max(0, Math.min(BAR_WIDTH - 1, Math.floor(row.absStart / total * BAR_WIDTH)));
113
+ const to = known ? row.absEnd / total * BAR_WIDTH : BAR_WIDTH;
114
+ const width = Math.max(1, Math.min(BAR_WIDTH, Math.ceil(to)) - from);
115
+ const fill = known ? "\u2588" : "\u2591";
116
+ return " ".repeat(from) + fill.repeat(width) + " ".repeat(BAR_WIDTH - from - width);
117
+ }
118
+ function durationNote(row) {
119
+ switch (row.durationSource) {
120
+ case "media":
121
+ case "default":
122
+ return `duration=${row.durationSource}`;
123
+ case "inner":
124
+ return "duration=inferred";
125
+ case "pending":
126
+ return `pending: ${row.pendingReason}`;
127
+ case "authored":
128
+ case null:
129
+ return false;
130
+ }
131
+ }
132
+ function syncNote(frames) {
133
+ if (!frames) return false;
134
+ return `out-of-sync=${frames > 0 ? "+" : ""}${frames}f`;
135
+ }
136
+ function details(row) {
137
+ const lanes = row.lanes.map(
138
+ (l) => `${l.target}[${l.points.map((p) => `${n(p.t)}:${n(p.v)}`).join(" ")}]`
139
+ );
140
+ return [
141
+ row.src && `src=${row.src}`,
142
+ row.volume !== null && `vol=${row.volume}`,
143
+ row.playbackRate !== null && `rate=${n(row.playbackRate)}`,
144
+ row.audioGroup && `group=${row.audioGroup}`,
145
+ syncNote(row.syncOffsetFrames),
146
+ durationNote(row),
147
+ row.sourceFile && !row.children.length && "children=unread",
148
+ row.laneError && `lanes unreadable: ${row.laneError}`,
149
+ ...lanes,
150
+ ...row.warnings.filter((w) => w.startsWith(NEVER_VISIBLE)).map((w) => `warning: ${w}`)
151
+ ].filter(Boolean).join(" ");
152
+ }
153
+ var span = (a, b) => `${n(a)}-${n(b)}s`;
154
+ function line(row, total) {
155
+ const times = row.host ? `${span(row.absStart, row.absEnd)} (local ${span(row.start, row.end)}) nested in ${row.host} ${row.file}` : span(row.start, row.end);
156
+ return ` |${bar(row, total)}| ${row.ref} ${row.id} ${times} ${details(row)}`.trimEnd();
157
+ }
158
+ function header({ kind, rows }) {
159
+ const nested = rows.filter((r) => r.nested || r.parentRow).length;
160
+ const split = nested ? `: ${rows.length - nested} top-level, ${nested} nested` : "";
161
+ return `${kind} (${rows.length}${split})`;
162
+ }
163
+ function formatTimeline(timeline) {
164
+ const out = [`timeline ${n(timeline.duration)}s`];
165
+ for (const track of timeline.tracks) {
166
+ out.push("", header(track));
167
+ for (const row of track.rows) out.push(line(row, timeline.duration));
168
+ }
169
+ return out.join("\n");
170
+ }
171
+
172
+ // src/timeline/a2Commands.ts
173
+ import { readFileSync as readFileSync2 } from "fs";
174
+ import { join, relative } from "path";
175
+
176
+ // src/timeline/resolveRef.ts
177
+ function targetFor(row) {
178
+ if (row.ref.startsWith("#")) return { id: row.ref.slice(1) };
179
+ if (row.ref.startsWith("hf:")) return { hfId: row.ref.slice(3) };
180
+ return row.id && row.id !== row.kind ? { id: row.id } : null;
181
+ }
182
+ function resolveRef(timeline, ref) {
183
+ const rows = timeline.tracks.flatMap((track) => track.rows);
184
+ const matches = ref.startsWith("#") ? rows.filter((row2) => row2.ref === ref || row2.id === ref.slice(1)) : ref.startsWith("hf:") ? rows.filter((row2) => row2.ref === ref) : (() => {
185
+ const match = /^(video|graphics|captions|audio)\/(\d+)$/.exec(ref);
186
+ if (!match) return [];
187
+ const row2 = timeline.tracks.find((track) => track.kind === match[1])?.rows.find((candidate) => candidate.index === Number(match[2]));
188
+ return row2 ? [row2] : [];
189
+ })();
190
+ if (matches.length !== 1) {
191
+ return {
192
+ ok: false,
193
+ reason: matches.length === 0 ? `${ref} was not found` : `${ref} matches ${matches.length} rows`,
194
+ fix: 'add id="<name>" to the element in its source file, then retry with #<name>'
195
+ };
196
+ }
197
+ const row = matches[0];
198
+ const target = targetFor(row);
199
+ if (!target) {
200
+ return {
201
+ ok: false,
202
+ reason: `${ref} has no stable element id in ${row.file}`,
203
+ fix: `add id="<name>" to the element in ${row.file}, then retry with #<name>`
204
+ };
205
+ }
206
+ return { ok: true, row, target };
207
+ }
208
+
209
+ // src/timeline/timeExpr.ts
210
+ function parseTimeExpression(expression, context) {
211
+ const raw = expression.trim();
212
+ if (raw === "end") return { ok: true, seconds: context.duration };
213
+ const frames = /^(-?\d+(?:\.\d+)?)f$/.exec(raw);
214
+ if (frames) return { ok: true, seconds: Number(frames[1]) / context.fps };
215
+ const absolute = /^\d+(?:\.\d+)?$/.test(raw);
216
+ const relative2 = /^[+-]\d+(?:\.\d+)?$/.test(raw);
217
+ if (absolute) return { ok: true, seconds: Number(raw) };
218
+ if (relative2) return { ok: true, seconds: context.row.start + Number(raw) };
219
+ const anchor = /^(after|before|start-of|end-of):(.+)$/.exec(raw);
220
+ if (!anchor) return { ok: false, reason: `invalid time expression: ${expression}` };
221
+ const row = context.resolveAnchor(anchor[2]);
222
+ if (!row) return { ok: false, reason: `anchor ref not found: ${anchor[2]}` };
223
+ switch (anchor[1]) {
224
+ case "after":
225
+ case "end-of":
226
+ return { ok: true, seconds: row.end };
227
+ case "before":
228
+ case "start-of":
229
+ return { ok: true, seconds: row.start };
230
+ }
231
+ return { ok: false, reason: `invalid time anchor: ${anchor[1]}` };
232
+ }
233
+
234
+ // src/timeline/a2Shared.ts
235
+ import { readFileSync } from "fs";
236
+
237
+ // src/timeline/a2Mutations.ts
238
+ function parseSetAssignments(values) {
239
+ const assignments = [];
240
+ for (const value of values) {
241
+ const match = /^(volume|rate|track)=(.+)$/.exec(value);
242
+ if (!match) {
243
+ return {
244
+ ok: false,
245
+ reason: `unsupported set assignment ${value}`,
246
+ fix: "use volume=<number>, rate=<number>, or track=<number>"
247
+ };
248
+ }
249
+ const fieldValue = match[1];
250
+ if (!fieldValue) {
251
+ return {
252
+ ok: false,
253
+ reason: `unsupported set assignment ${value}`,
254
+ fix: "use volume=<number>, rate=<number>, or track=<number>"
255
+ };
256
+ }
257
+ const field = parseSetField(fieldValue);
258
+ const number = Number(match[2]);
259
+ if (!Number.isFinite(number) || field === "track" && !Number.isInteger(number)) {
260
+ return {
261
+ ok: false,
262
+ reason: `${field} must be a valid ${field === "track" ? "integer" : "number"}`,
263
+ fix: `pass ${field}=<number>`
264
+ };
265
+ }
266
+ if (field === "rate" && number <= 0) {
267
+ return { ok: false, reason: "rate must be positive", fix: "pass rate=<positive number>" };
268
+ }
269
+ assignments.push({ field, value: String(number) });
270
+ }
271
+ return { ok: true, assignments };
272
+ }
273
+ function parseSetField(value) {
274
+ switch (value) {
275
+ case "volume":
276
+ case "rate":
277
+ case "track":
278
+ return value;
279
+ }
280
+ throw new Error(`unsupported set field ${value}`);
281
+ }
282
+
283
+ // src/timeline/a2Shared.ts
284
+ var FIELDS_READ_BY_VERB = {
285
+ move: ["time", "overwrite"],
286
+ trim: ["start", "end", "duration", "overwrite"],
287
+ split: ["time"],
288
+ delete: ["start", "end"],
289
+ set: ["volume", "rate", "track"],
290
+ duplicate: ["at"]
291
+ };
292
+ var allRows = (timeline) => timeline.tracks.flatMap((track) => track.rows);
293
+ function refusal(reason, fix, json) {
294
+ setCommandExitCode(2);
295
+ const payload = { ok: false, reason, fix };
296
+ console.error(json ? JSON.stringify(payload, null, 2) : `${reason}; ${fix}.`);
297
+ }
298
+ var isFileChanged = (error) => error instanceof Error && error.message === "file changed since the timeline was read";
299
+ function refuse(kind, detail, json) {
300
+ refusal(`${kind}: ${detail.reason}`, detail.fix, json);
301
+ }
302
+ function publicReceipt(receipt) {
303
+ return {
304
+ file: receipt.sourceFile,
305
+ version: receipt.version,
306
+ writeToken: receipt.writeToken,
307
+ changed: receipt.changed,
308
+ backupPath: receipt.backupPath
309
+ };
310
+ }
311
+ function fpsFor(indexPath) {
312
+ const parsed = parseFpsWithDefault(
313
+ readCompositionFps(readFileSync(indexPath, "utf-8")) ?? void 0
314
+ );
315
+ return fpsToNumber(parsed.ok ? parsed.value : { num: 30, den: 1 });
316
+ }
317
+ function declaredFps(source) {
318
+ const raw = readCompositionFps(source);
319
+ if (raw === null) return null;
320
+ const parsed = parseFpsWithDefault(raw);
321
+ return parsed.ok ? fpsToNumber(parsed.value) : null;
322
+ }
323
+ function splitBaseId(row) {
324
+ return row.ref.startsWith("hf:") ? row.ref.slice(3) : row.id;
325
+ }
326
+ function nextFreeSplitId(source, base) {
327
+ const document = new DOMParser().parseFromString(source, "text/html");
328
+ const existing = new Set(Array.from(document.querySelectorAll("[id]"), (element) => element.id));
329
+ const match = /^(.*)-(\d+)$/.exec(base);
330
+ const prefix = match && existing.has(match[1]) ? match[1] : base;
331
+ let suffix = 2;
332
+ while (existing.has(`${prefix}-${suffix}`)) suffix += 1;
333
+ return `${prefix}-${suffix}`;
334
+ }
335
+ function parseMutationTime(context, expression, fix) {
336
+ const value = context.parseTime(expression);
337
+ if (!value.ok) return { ok: false, reason: value.reason, fix };
338
+ if (value.seconds < 0 || value.seconds > context.duration) {
339
+ return {
340
+ ok: false,
341
+ reason: `time ${value.seconds} is outside the composition duration`,
342
+ fix: "pass a time between 0 and the composition duration"
343
+ };
344
+ }
345
+ return { ok: true, seconds: value.seconds };
346
+ }
347
+ function diff(before, after) {
348
+ if (before === after) return "";
349
+ const beforeLines = before.split("\n");
350
+ const afterLines = after.split("\n");
351
+ let prefix = 0;
352
+ while (prefix < beforeLines.length && prefix < afterLines.length && beforeLines[prefix] === afterLines[prefix]) {
353
+ prefix += 1;
354
+ }
355
+ let suffix = 0;
356
+ while (suffix < beforeLines.length - prefix && suffix < afterLines.length - prefix && beforeLines[beforeLines.length - suffix - 1] === afterLines[afterLines.length - suffix - 1]) {
357
+ suffix += 1;
358
+ }
359
+ const changedBefore = beforeLines.slice(prefix, beforeLines.length - suffix);
360
+ const changedAfter = afterLines.slice(prefix, afterLines.length - suffix);
361
+ const lines = [
362
+ "--- before",
363
+ "+++ after",
364
+ ...changedBefore.map((line2) => `-${line2}`),
365
+ ...changedAfter.map((line2) => `+${line2}`)
366
+ ];
367
+ const output = lines.join("\n");
368
+ return output.length <= 8e3 ? output : `${output.slice(0, 7997)}...`;
369
+ }
370
+ function isAncestorOf(ancestor, row, timeline) {
371
+ for (let pointer = row.parentRow; pointer; ) {
372
+ const parent = rowAt(timeline, pointer);
373
+ if (parent === ancestor) return true;
374
+ pointer = parent.parentRow;
375
+ }
376
+ return false;
377
+ }
378
+ function sameLineage(a, b, timeline) {
379
+ return isAncestorOf(a, b, timeline) || isAncestorOf(b, a, timeline);
380
+ }
381
+ function overlap(row, timeline, start, end) {
382
+ return allRows(timeline).find(
383
+ (candidate) => candidate !== row && !sameLineage(candidate, row, timeline) && candidate.file === row.file && candidate.trackIndex === row.trackIndex && spansShareTime(start, end, candidate.start, candidate.end)
384
+ );
385
+ }
386
+ function moveMutation(context, args) {
387
+ const expression = typeof args.time === "string" ? args.time : "";
388
+ const time = parseMutationTime(context, expression, "pass a valid time expression");
389
+ if (!time.ok) return time;
390
+ const end = time.seconds + context.row.duration;
391
+ if (end > context.duration) {
392
+ return {
393
+ ok: false,
394
+ reason: `move would end at ${end}, beyond composition duration ${context.duration}`,
395
+ fix: `choose a start at or before the latest valid start ${context.duration - context.row.duration}`
396
+ };
397
+ }
398
+ const operations = [
399
+ { type: "html-attribute", property: "data-start", value: String(time.seconds) }
400
+ ];
401
+ if (context.row.durationAuthored) {
402
+ operations.push(
403
+ { type: "html-attribute", property: "data-duration", value: String(context.row.duration) },
404
+ { type: "html-attribute", property: "data-end", value: null }
405
+ );
406
+ }
407
+ const patched = patchElementInHtml(context.before, context.resolved.target, operations);
408
+ if (!patched.matched) {
409
+ return { ok: false, reason: `${context.ref} was not found`, fix: "choose an existing clip" };
410
+ }
411
+ return {
412
+ ok: true,
413
+ after: patched.html,
414
+ nextStart: time.seconds,
415
+ nextDuration: context.row.duration
416
+ };
417
+ }
418
+ function splitMutation(context, args) {
419
+ const expression = typeof args.time === "string" ? args.time : "";
420
+ const time = parseMutationTime(context, expression, "pass a valid time expression");
421
+ if (!time.ok) return time;
422
+ const split = splitSource(
423
+ context,
424
+ context.before,
425
+ context.resolved.target,
426
+ time.seconds,
427
+ context.row.duration
428
+ );
429
+ if (!split.ok) return split;
430
+ return {
431
+ ok: true,
432
+ after: split.html,
433
+ nextStart: context.row.start,
434
+ nextDuration: context.row.duration
435
+ };
436
+ }
437
+ function splitSource(context, source, target, seconds, duration) {
438
+ const split = splitElementInHtml(
439
+ source,
440
+ target,
441
+ seconds,
442
+ nextFreeSplitId(source, splitBaseId(context.row)),
443
+ { start: context.row.start, duration, track: context.row.trackIndex }
444
+ );
445
+ if (!split.matched || !split.newId) {
446
+ return {
447
+ ok: false,
448
+ reason: `${context.ref} cannot be split at ${seconds}`,
449
+ fix: "choose a time inside the clip"
450
+ };
451
+ }
452
+ return { ok: true, html: split.html, newId: split.newId };
453
+ }
454
+ function trimMutation(context, args) {
455
+ const bounds = trimBounds(context, args);
456
+ if (!bounds.ok) return bounds;
457
+ const patched = patchElementInHtml(context.before, context.resolved.target, [
458
+ { type: "html-attribute", property: "data-start", value: String(bounds.nextStart) },
459
+ { type: "html-attribute", property: "data-duration", value: String(bounds.nextDuration) }
460
+ ]);
461
+ if (!patched.matched) {
462
+ return { ok: false, reason: `${context.ref} was not found`, fix: "choose an existing clip" };
463
+ }
464
+ return {
465
+ ok: true,
466
+ after: patched.html,
467
+ nextStart: bounds.nextStart,
468
+ nextDuration: bounds.nextDuration
469
+ };
470
+ }
471
+ function trimBounds(context, args) {
472
+ const input = trimInput(args);
473
+ if (!input.ok) return input;
474
+ const start = trimStart(context, input.start);
475
+ if (!start.ok) return start;
476
+ return finishTrim(
477
+ context,
478
+ start.seconds,
479
+ trimEnd(context, input.end),
480
+ trimDuration(context, input.duration)
481
+ );
482
+ }
483
+ function trimInput(args) {
484
+ const input = {
485
+ start: typeof args.start === "string" ? args.start : void 0,
486
+ end: typeof args.end === "string" ? args.end : void 0,
487
+ duration: typeof args.duration === "string" ? args.duration : void 0
488
+ };
489
+ if (input.start || input.end || input.duration) return { ok: true, ...input };
490
+ return {
491
+ ok: false,
492
+ reason: "trim requires --start, --end, or --duration",
493
+ fix: "pass one trim option"
494
+ };
495
+ }
496
+ var leavesNoLength = (start, duration) => duration <= 0 || sameInstant(start, start + duration);
497
+ function finishTrim(context, nextStart, end, duration) {
498
+ if (end && !end.ok) return end;
499
+ if (duration && !duration.ok) return duration;
500
+ const nextDuration = duration?.seconds ?? (end ? durationUntil(nextStart, end.seconds) : context.row.duration);
501
+ if (leavesNoLength(nextStart, nextDuration)) {
502
+ return {
503
+ ok: false,
504
+ reason: "trim duration must be positive",
505
+ fix: "choose a later end or positive duration"
506
+ };
507
+ }
508
+ return { ok: true, nextStart, nextDuration };
509
+ }
510
+ function trimStart(context, expression) {
511
+ if (!expression) return { ok: true, seconds: context.row.start };
512
+ return parseMutationTime(context, expression, "pass a valid time expression");
513
+ }
514
+ function durationUntil(start, end) {
515
+ let duration = end - start;
516
+ while (duration > 0 && start + duration > end) duration = nextSmaller(duration);
517
+ return duration;
518
+ }
519
+ var float = new DataView(new ArrayBuffer(8));
520
+ function nextSmaller(positive) {
521
+ float.setFloat64(0, positive);
522
+ float.setBigUint64(0, float.getBigUint64(0) - 1n);
523
+ return float.getFloat64(0);
524
+ }
525
+ function trimEnd(context, expression) {
526
+ if (!expression) return void 0;
527
+ return parseMutationTime(context, expression, "pass a valid time expression");
528
+ }
529
+ function trimDuration(context, expression) {
530
+ if (!expression) return void 0;
531
+ return parseMutationTime(context, expression, "pass a valid duration");
532
+ }
533
+ function deleteMutation(context, args) {
534
+ const { row, resolved } = context;
535
+ const range = deleteRange(context, args);
536
+ if (!range.ok) return range;
537
+ let html = context.before;
538
+ if (!sameInstant(range.end, row.end)) {
539
+ const tail = splitSource(context, html, resolved.target, range.end, row.duration);
540
+ if (!tail.ok) return tail;
541
+ html = tail.html;
542
+ }
543
+ let removed = resolved.target;
544
+ if (!sameInstant(range.start, row.start)) {
545
+ const middle = splitSource(context, html, resolved.target, range.start, range.end - row.start);
546
+ if (!middle.ok) return middle;
547
+ html = middle.html;
548
+ removed = { id: middle.newId };
549
+ }
550
+ return {
551
+ ok: true,
552
+ after: removeElementFromHtml(html, removed),
553
+ nextStart: row.start,
554
+ nextDuration: row.duration
555
+ };
556
+ }
557
+ function deleteRange(context, args) {
558
+ const { row } = context;
559
+ const bound = (value, fallback) => typeof value === "string" ? parseMutationTime(context, value, "pass a valid time expression") : { ok: true, seconds: fallback };
560
+ const start = bound(args.start, row.start);
561
+ if (!start.ok) return start;
562
+ const end = bound(args.end, row.end);
563
+ if (!end.ok) return end;
564
+ const inside = (seconds) => sameInstant(seconds, row.start) || sameInstant(seconds, row.end) || seconds > row.start && seconds < row.end;
565
+ if (!inside(start.seconds) || !inside(end.seconds)) {
566
+ return {
567
+ ok: false,
568
+ reason: `delete range ${start.seconds}-${end.seconds} is not inside ${context.ref} (${row.start}-${row.end})`,
569
+ fix: "pass --start and --end inside the clip"
570
+ };
571
+ }
572
+ if (end.seconds <= start.seconds || sameInstant(start.seconds, end.seconds)) {
573
+ return {
574
+ ok: false,
575
+ reason: "delete range must be positive",
576
+ fix: "pass an --end later than --start"
577
+ };
578
+ }
579
+ return { ok: true, start: start.seconds, end: end.seconds };
580
+ }
581
+ function setOperation(assignment) {
582
+ const property = assignment.field === "volume" ? "data-volume" : assignment.field === "rate" ? "data-playback-rate" : "data-track-index";
583
+ return { type: "html-attribute", property, value: assignment.value };
584
+ }
585
+ function setMutation(context, args) {
586
+ const positionalAssignments = positional(args).slice(1).filter((value) => typeof value === "string");
587
+ const namedAssignments = ["volume", "rate", "track"].flatMap((field) => {
588
+ const value = args[field];
589
+ return typeof value === "string" ? [`${field}=${value}`] : [];
590
+ });
591
+ const assignments = parseSetAssignments([...positionalAssignments, ...namedAssignments]);
592
+ if (!assignments.ok) return assignments;
593
+ const patched = patchElementInHtml(
594
+ context.before,
595
+ context.resolved.target,
596
+ assignments.assignments.map(setOperation)
597
+ );
598
+ if (!patched.matched) {
599
+ return { ok: false, reason: `${context.ref} was not found`, fix: "choose an existing clip" };
600
+ }
601
+ return {
602
+ ok: true,
603
+ after: patched.html,
604
+ nextStart: context.row.start,
605
+ nextDuration: context.row.duration
606
+ };
607
+ }
608
+ function duplicateMutation(context, args) {
609
+ const expression = typeof args.at === "string" ? args.at : String(context.row.end);
610
+ const time = parseMutationTime(context, expression, "pass a valid insertion time");
611
+ if (!time.ok) return time;
612
+ const duplicate = duplicateElementInHtml(
613
+ context.before,
614
+ context.resolved.target,
615
+ `${splitBaseId(context.row)}-copy`,
616
+ time.seconds
617
+ );
618
+ if (!duplicate.matched) {
619
+ return { ok: false, reason: `${context.ref} was not found`, fix: "choose an existing clip" };
620
+ }
621
+ return {
622
+ ok: true,
623
+ after: duplicate.html,
624
+ nextStart: time.seconds,
625
+ nextDuration: context.row.duration
626
+ };
627
+ }
628
+ function decideMutation(verb, context, args) {
629
+ switch (verb) {
630
+ case "move":
631
+ return moveMutation(context, args);
632
+ case "trim":
633
+ return trimMutation(context, args);
634
+ case "split":
635
+ return splitMutation(context, args);
636
+ case "delete":
637
+ return deleteMutation(context, args);
638
+ case "set":
639
+ return setMutation(context, args);
640
+ case "duplicate":
641
+ return duplicateMutation(context, args);
642
+ }
643
+ }
644
+ function rowAt(timeline, pointer) {
645
+ const track = timeline.tracks.find((candidate) => candidate.kind === pointer.kind);
646
+ if (!track) throw new Error(`missing track ${pointer.kind}`);
647
+ const row = track.rows[pointer.index];
648
+ if (!row) throw new Error(`missing row ${pointer.kind}/${pointer.index}`);
649
+ return row;
650
+ }
651
+ function positional(args) {
652
+ return Array.isArray(args._) ? args._.filter((value) => typeof value === "string") : [];
653
+ }
654
+ function isRecord(value) {
655
+ return typeof value === "object" && value !== null && !Array.isArray(value);
656
+ }
657
+ function mutationConflict(verb, overwrite, row, timeline, nextStart, nextDuration) {
658
+ if (verb === "duplicate") {
659
+ const conflict2 = allRows(timeline).find(
660
+ (candidate) => !sameLineage(candidate, row, timeline) && candidate.file === row.file && candidate.trackIndex === row.trackIndex && isInsideSpan(nextStart, candidate.start, candidate.end)
661
+ );
662
+ if (!conflict2) return null;
663
+ return {
664
+ reason: `duplicate insertion at ${nextStart} falls inside ${conflict2.ref}`,
665
+ fix: "choose a clip boundary or split the spanning clip first"
666
+ };
667
+ }
668
+ if (verb !== "move" && verb !== "trim" || overwrite) return null;
669
+ const conflict = overlap(row, timeline, nextStart, nextStart + nextDuration);
670
+ if (!conflict) return null;
671
+ return {
672
+ reason: `${row.ref} would overlap ${conflict.ref} at ${nextStart}-${nextStart + nextDuration}`,
673
+ fix: "pass --overwrite or move the named neighbour"
674
+ };
675
+ }
676
+
677
+ // src/timeline/a2Commands.ts
678
+ async function runIds(args) {
679
+ const project = resolveProject(typeof args.dir === "string" ? args.dir : void 0);
680
+ const json = args.json === true;
681
+ ensureDOMParser();
682
+ const beforeTimeline = await describeProject(project.indexPath);
683
+ const files = [.../* @__PURE__ */ new Set(["index.html", ...allRows(beforeTimeline).map((row) => row.file)])];
684
+ const inputs = files.flatMap((file) => {
685
+ const before = readFileSync2(join(project.dir, file), "utf-8");
686
+ const after = ensureHfIds(before);
687
+ return after === before ? [] : [
688
+ {
689
+ sourceFile: file,
690
+ absPath: join(project.dir, file),
691
+ before,
692
+ after,
693
+ expectedVersion: fileContentVersion(before)
694
+ }
695
+ ];
696
+ });
697
+ let receipts = [];
698
+ try {
699
+ if (inputs.length > 0) receipts = applyFileMutations(project.dir, inputs);
700
+ } catch (error) {
701
+ if (isFileChanged(error)) return refusal(error.message, "re-run framey timeline ids", json);
702
+ throw error;
703
+ }
704
+ const afterTimeline = await describeProject(project.indexPath);
705
+ const result = {
706
+ ok: true,
707
+ receipt: receipts.map((receipt) => publicReceipt(receipt)),
708
+ file: files,
709
+ before: allRows(beforeTimeline),
710
+ after: allRows(afterTimeline),
711
+ diff: "",
712
+ warnings: []
713
+ };
714
+ if (json) console.log(JSON.stringify(withMeta(result), null, 2));
715
+ else console.log(`ids: stamped ${receipts.length} file${receipts.length === 1 ? "" : "s"}`);
716
+ }
717
+ var PLAN_VERBS = /* @__PURE__ */ new Set(["move", "trim", "split", "delete", "set", "duplicate"]);
718
+ function preparePlanEdit(edit, timeline, sourceByFile) {
719
+ if (!isRecord(edit) || typeof edit.verb !== "string" || typeof edit.ref !== "string") {
720
+ return {
721
+ ok: false,
722
+ reason: "each edit needs a verb and ref",
723
+ fix: "pass {verb, ref, ...} objects"
724
+ };
725
+ }
726
+ if (!PLAN_VERBS.has(edit.verb)) {
727
+ return {
728
+ ok: false,
729
+ reason: `unsupported edit verb ${edit.verb}`,
730
+ fix: "use move, trim, split, delete, set, or duplicate"
731
+ };
732
+ }
733
+ const fields = FIELDS_READ_BY_VERB[edit.verb];
734
+ const unused = Object.keys(edit).find(
735
+ (key) => key !== "verb" && key !== "ref" && !fields.includes(key)
736
+ );
737
+ if (unused) {
738
+ return {
739
+ ok: false,
740
+ reason: `${edit.verb} does not use ${unused}`,
741
+ fix: `remove ${unused}; ${edit.verb} takes ${fields.join(", ")}`
742
+ };
743
+ }
744
+ const resolved = resolveRef(timeline, edit.ref);
745
+ if (!resolved.ok) return resolved;
746
+ const before = sourceByFile.get(resolved.row.file);
747
+ return before === void 0 ? { ok: false, reason: `${resolved.row.file} was not found`, fix: "choose an existing clip" } : { ok: true, edit, row: resolved.row, before, resolved };
748
+ }
749
+ function applyPlanEdit(edit, timeline, project, sourceByFile) {
750
+ const prepared = preparePlanEdit(edit, timeline, sourceByFile);
751
+ if (!prepared.ok) return prepared;
752
+ const { edit: planEdit, row, before, resolved } = prepared;
753
+ const verb = planEdit.verb;
754
+ const context = {
755
+ ref: planEdit.ref,
756
+ row,
757
+ before,
758
+ resolved,
759
+ parseTime: (expression) => parseTimeExpression(expression, {
760
+ row,
761
+ duration: timeline.duration,
762
+ fps: fpsFor(project.indexPath),
763
+ resolveAnchor: (anchorRef) => {
764
+ const anchor = resolveRef(timeline, anchorRef);
765
+ return anchor.ok ? anchor.row : void 0;
766
+ }
767
+ }),
768
+ duration: row.nested && row.hostRow ? rowAt(timeline, row.hostRow).duration : timeline.duration
769
+ };
770
+ const decision = decideMutation(verb, context, { ...planEdit, _: [planEdit.ref] });
771
+ if (!decision.ok) return { ok: false, reason: decision.reason, fix: decision.fix };
772
+ const conflict = mutationConflict(
773
+ verb,
774
+ planEdit.overwrite === true,
775
+ row,
776
+ timeline,
777
+ decision.nextStart,
778
+ decision.nextDuration
779
+ );
780
+ if (conflict) return { ok: false, reason: conflict.reason, fix: conflict.fix };
781
+ return { ok: true, file: row.file, after: decision.after };
782
+ }
783
+ function readEditPlan(file) {
784
+ const raw = file === "-" ? readFileSync2(0, "utf-8") : readFileSync2(file, "utf-8");
785
+ try {
786
+ const edits = JSON.parse(raw);
787
+ return Array.isArray(edits) ? { ok: true, edits } : { ok: false, reason: "edit plan must be a JSON array", fix: "pass a JSON array of edits" };
788
+ } catch {
789
+ return { ok: false, reason: "edit plan is not valid JSON", fix: "pass a JSON array of edits" };
790
+ }
791
+ }
792
+ function readPlanSources(timeline, project) {
793
+ const sourceByFile = /* @__PURE__ */ new Map();
794
+ const beforeByFile = /* @__PURE__ */ new Map();
795
+ for (const fileName of new Set(allRows(timeline).map((row) => row.file))) {
796
+ const source = readFileSync2(join(project.dir, fileName), "utf-8");
797
+ sourceByFile.set(fileName, source);
798
+ beforeByFile.set(fileName, source);
799
+ }
800
+ return { sourceByFile, beforeByFile };
801
+ }
802
+ async function applyPlanEdits(edits, timeline, project, sourceByFile) {
803
+ for (const edit of edits) {
804
+ const result = applyPlanEdit(edit, timeline, project, sourceByFile);
805
+ if (!result.ok) return result;
806
+ sourceByFile.set(result.file, result.after);
807
+ timeline = await describeProject(project.indexPath, void 0, sourceByFile);
808
+ }
809
+ return { ok: true };
810
+ }
811
+ async function runApply(args) {
812
+ const project = resolveProject(typeof args.dir === "string" ? args.dir : void 0);
813
+ const json = args.json === true;
814
+ const plan = args.plan === true;
815
+ const file = typeof args.file === "string" ? args.file : positional(args)[1];
816
+ if (!file)
817
+ return refuse(
818
+ "timeline apply",
819
+ { reason: "an edit plan is required", fix: "pass an edits.json path or -" },
820
+ json
821
+ );
822
+ const planInput = readEditPlan(file);
823
+ if (!planInput.ok) return refuse("timeline apply", planInput, json);
824
+ ensureDOMParser();
825
+ const timeline = await describeProject(project.indexPath);
826
+ const { sourceByFile, beforeByFile } = readPlanSources(timeline, project);
827
+ const editsResult = await applyPlanEdits(planInput.edits, timeline, project, sourceByFile);
828
+ if (!editsResult.ok) return refuse("timeline apply", editsResult, json);
829
+ const inputs = [...sourceByFile].flatMap(([fileName, after]) => {
830
+ const before = beforeByFile.get(fileName);
831
+ return after === before ? [] : [
832
+ {
833
+ sourceFile: fileName,
834
+ absPath: join(project.dir, fileName),
835
+ before,
836
+ after,
837
+ expectedVersion: fileContentVersion(before)
838
+ }
839
+ ];
840
+ });
841
+ const afterTimeline = await describeProject(project.indexPath, void 0, sourceByFile);
842
+ const result = {
843
+ ok: true,
844
+ planned: plan,
845
+ receipt: null,
846
+ file: inputs.map((input) => input.sourceFile),
847
+ before: allRows(timeline),
848
+ after: allRows(afterTimeline),
849
+ diff: inputs.map((input) => diff(input.before, input.after)).filter(Boolean).join("\n"),
850
+ warnings: []
851
+ };
852
+ if (!plan) {
853
+ const receipts = inputs.length > 0 ? applyFileMutations(project.dir, inputs) : [];
854
+ result.receipt = receipts.map((receipt) => publicReceipt(receipt));
855
+ }
856
+ if (json) console.log(JSON.stringify(withMeta(result), null, 2));
857
+ else
858
+ console.log(
859
+ `${plan ? "planned" : "applied"} ${inputs.length} file${inputs.length === 1 ? "" : "s"}`
860
+ );
861
+ }
862
+ function isUndoReceipt(value) {
863
+ return isRecord(value) && typeof value.file === "string" && typeof value.version === "string" && typeof value.backupPath === "string";
864
+ }
865
+ function readUndoInput(input) {
866
+ let raw;
867
+ try {
868
+ raw = readFileSync2(input, "utf-8");
869
+ } catch {
870
+ raw = input;
871
+ }
872
+ let parsed;
873
+ try {
874
+ parsed = JSON.parse(raw);
875
+ } catch {
876
+ return {
877
+ ok: false,
878
+ reason: "undo receipt is not valid JSON",
879
+ fix: "pass the applied JSON receipt"
880
+ };
881
+ }
882
+ const value = isRecord(parsed) && "receipt" in parsed ? parsed.receipt : parsed;
883
+ const values = Array.isArray(value) ? value : [value];
884
+ if (!values.every(isUndoReceipt)) {
885
+ return {
886
+ ok: false,
887
+ reason: "undo receipt is missing file, version, or backupPath",
888
+ fix: "pass an applied timeline receipt"
889
+ };
890
+ }
891
+ return { ok: true, receipts: values, batch: Array.isArray(value) };
892
+ }
893
+ function refuseUndoError(error, projectDir, json) {
894
+ if (isRecord(error) && error.code === "ENOENT" && typeof error.path === "string")
895
+ return refuse(
896
+ "timeline undo",
897
+ {
898
+ reason: `undo file is missing: ${relative(projectDir, error.path).split("\\").join("/")}`,
899
+ fix: "restore the missing target or backup file before retrying undo"
900
+ },
901
+ json
902
+ );
903
+ if (isFileChanged(error))
904
+ return refusal(error.message, "read the latest timeline before retrying undo", json);
905
+ throw error;
906
+ }
907
+ async function runUndo(args) {
908
+ const project = resolveProject(typeof args.dir === "string" ? args.dir : void 0, {
909
+ requireIndex: false
910
+ });
911
+ const json = args.json === true;
912
+ const input = typeof args.receipt === "string" ? args.receipt : positional(args)[1];
913
+ if (!input)
914
+ return refuse(
915
+ "timeline undo",
916
+ { reason: "an undo receipt is required", fix: "pass the receipt JSON or its file" },
917
+ json
918
+ );
919
+ const undo = readUndoInput(input);
920
+ if (!undo.ok) return refuse("timeline undo", undo, json);
921
+ let receipts;
922
+ try {
923
+ const inputs = undo.receipts.map((receipt) => {
924
+ const target = join(project.dir, receipt.file);
925
+ return {
926
+ sourceFile: receipt.file,
927
+ absPath: target,
928
+ before: readFileSync2(target, "utf-8"),
929
+ after: readFileSync2(join(project.dir, receipt.backupPath), "utf-8"),
930
+ expectedVersion: receipt.version
931
+ };
932
+ });
933
+ receipts = applyFileMutations(project.dir, inputs);
934
+ } catch (error) {
935
+ return refuseUndoError(error, project.dir, json);
936
+ }
937
+ const result = {
938
+ ok: true,
939
+ receipt: receipts.map((receipt) => publicReceipt(receipt)),
940
+ file: undo.batch ? undo.receipts.map((receipt) => receipt.file) : undo.receipts[0].file
941
+ };
942
+ if (json) console.log(JSON.stringify(withMeta(result), null, 2));
943
+ else
944
+ console.log(
945
+ undo.batch ? `undid ${receipts.length} file${receipts.length === 1 ? "" : "s"}` : `undid ${undo.receipts[0].file}`
946
+ );
947
+ }
948
+
949
+ // src/timeline/a2MutationCommand.ts
950
+ import { readFileSync as readFileSync3 } from "fs";
951
+ import { join as join2 } from "path";
952
+ async function runMutation(verb, args) {
953
+ const setup = await prepareMutation(args);
954
+ if (!setup.ok) return refusal(setup.reason, setup.fix, setup.json);
955
+ const decision = decideMutation(verb, setup.context, args);
956
+ if (!decision.ok) return refusal(decision.reason, decision.fix, setup.json);
957
+ await finishMutation(setup, verb, decision);
958
+ }
959
+ async function prepareMutation(args) {
960
+ const project = resolveProject(typeof args.dir === "string" ? args.dir : void 0);
961
+ const ref = typeof args.ref === "string" ? args.ref : "";
962
+ const json = args.json === true;
963
+ const plan = args.plan === true;
964
+ const overwrite = args.overwrite === true;
965
+ const snap = args.snap === true;
966
+ ensureDOMParser();
967
+ const indexSource = readFileSync3(project.indexPath, "utf-8");
968
+ const initialTimeline = await describeProject(
969
+ project.indexPath,
970
+ void 0,
971
+ /* @__PURE__ */ new Map([["index.html", indexSource]])
972
+ );
973
+ const projectFps = declaredFps(indexSource);
974
+ if (snap && projectFps === null) {
975
+ return {
976
+ ok: false,
977
+ reason: "project fps is unknown",
978
+ fix: "set data-fps on the project, then rerun with --snap",
979
+ json
980
+ };
981
+ }
982
+ const initialResolved = resolveRef(initialTimeline, ref);
983
+ if (!initialResolved.ok)
984
+ return { ok: false, reason: initialResolved.reason, fix: initialResolved.fix, json };
985
+ const initialRow = initialResolved.row;
986
+ const filePath = join2(project.dir, initialRow.file);
987
+ const before = readFileSync3(filePath, "utf-8");
988
+ const expectedVersion = fileContentVersion(before);
989
+ const sources = /* @__PURE__ */ new Map([
990
+ ["index.html", indexSource],
991
+ [initialRow.file, before]
992
+ ]);
993
+ const timeline = await describeProject(project.indexPath, void 0, sources);
994
+ const resolved = resolveRef(timeline, ref);
995
+ if (!resolved.ok) return { ok: false, reason: resolved.reason, fix: resolved.fix, json };
996
+ const row = resolved.row;
997
+ const anchor = (anchorRef) => {
998
+ const found = resolveRef(timeline, anchorRef);
999
+ return found.ok ? found.row : void 0;
1000
+ };
1001
+ const parseTime = (expression) => {
1002
+ const parsed = parseTimeExpression(expression, {
1003
+ row,
1004
+ duration: timeline.duration,
1005
+ fps: fpsFor(project.indexPath),
1006
+ resolveAnchor: anchor
1007
+ });
1008
+ if (!parsed.ok || !snap) return parsed;
1009
+ return { ok: true, seconds: Math.round(parsed.seconds * projectFps) / projectFps };
1010
+ };
1011
+ return {
1012
+ ok: true,
1013
+ project,
1014
+ ref,
1015
+ json,
1016
+ plan,
1017
+ overwrite,
1018
+ timeline,
1019
+ indexSource,
1020
+ row,
1021
+ resolved,
1022
+ filePath,
1023
+ before,
1024
+ expectedVersion,
1025
+ context: {
1026
+ ref,
1027
+ row,
1028
+ before,
1029
+ resolved,
1030
+ parseTime,
1031
+ // Nested rows use the visible host clip duration as their composition bound.
1032
+ duration: row.nested && row.hostRow ? rowAt(timeline, row.hostRow).duration : timeline.duration
1033
+ }
1034
+ };
1035
+ }
1036
+ async function finishMutation(setup, verb, decision) {
1037
+ const { after, nextStart, nextDuration } = decision;
1038
+ const { ref, row, timeline, json, overwrite, project, before } = setup;
1039
+ const refusalMessage = mutationRefusal(verb, after, before, ref);
1040
+ if (refusalMessage) return refusal(refusalMessage.reason, refusalMessage.fix, json);
1041
+ const conflict = mutationConflict(verb, overwrite, row, timeline, nextStart, nextDuration);
1042
+ if (conflict) return refusal(conflict.reason, conflict.fix, json);
1043
+ const describeSource = (source) => describeProject(
1044
+ project.indexPath,
1045
+ void 0,
1046
+ /* @__PURE__ */ new Map([
1047
+ ["index.html", setup.indexSource],
1048
+ [row.file, source]
1049
+ ])
1050
+ );
1051
+ const describedBefore = await describeSource(before);
1052
+ const result = mutationResult(row, describedBefore, setup.plan);
1053
+ if (setup.plan) return printPlan(result, json, timeline, describeSource, after, before);
1054
+ return applyAndPrint({
1055
+ setup,
1056
+ verb,
1057
+ json,
1058
+ row,
1059
+ nextStart,
1060
+ nextDuration,
1061
+ after,
1062
+ before,
1063
+ result,
1064
+ describeSource
1065
+ });
1066
+ }
1067
+ async function applyAndPrint(args) {
1068
+ const receipt = applyMutation(args.setup, args.after);
1069
+ if (receipt && "error" in receipt)
1070
+ return refusal(receipt.error, "re-run framey timeline", args.json);
1071
+ if (!receipt && args.after !== args.before) {
1072
+ return refusal("mutation produced no receipt", "re-run framey timeline", args.json);
1073
+ }
1074
+ args.result.after = rowsForFile(await args.describeSource(args.after), args.row.file);
1075
+ args.result.receipt = receipt ? publicReceipt(receipt) : null;
1076
+ if (args.json) {
1077
+ console.log(JSON.stringify(withMeta(args.result), null, 2));
1078
+ return;
1079
+ }
1080
+ console.log(
1081
+ `${args.verb} ${args.row.ref}: ${args.row.start}-${args.row.end}s -> ${args.nextStart}-${args.nextStart + args.nextDuration}s
1082
+ receipt: ${receipt?.version ?? "unchanged"}`
1083
+ );
1084
+ }
1085
+ function rowsForFile(timeline, file) {
1086
+ return allRows(timeline).filter((candidate) => candidate.file === file);
1087
+ }
1088
+ function mutationResult(row, before, planned) {
1089
+ return {
1090
+ ok: true,
1091
+ receipt: null,
1092
+ file: row.file,
1093
+ before: rowsForFile(before, row.file),
1094
+ after: [],
1095
+ warnings: row.warnings,
1096
+ planned
1097
+ };
1098
+ }
1099
+ async function printPlan(result, json, timeline, describeSource, after, before) {
1100
+ const plannedTimeline = await describeSource(after);
1101
+ result.after = rowsForFile(plannedTimeline, result.file);
1102
+ if (json) console.log(JSON.stringify(withMeta(result), null, 2));
1103
+ else
1104
+ console.log(
1105
+ `${formatTimeline(timeline)}
1106
+
1107
+ planned:
1108
+ ${formatTimeline(plannedTimeline)}
1109
+
1110
+ diff:
1111
+ ${diff(before, after)}`
1112
+ );
1113
+ }
1114
+ function applyMutation(setup, after) {
1115
+ try {
1116
+ return applyFileMutations(setup.project.dir, [
1117
+ {
1118
+ sourceFile: setup.row.file,
1119
+ absPath: setup.filePath,
1120
+ before: setup.before,
1121
+ after,
1122
+ expectedVersion: setup.expectedVersion
1123
+ }
1124
+ ])[0];
1125
+ } catch (error) {
1126
+ if (isFileChanged(error)) return { error: error.message };
1127
+ throw error;
1128
+ }
1129
+ }
1130
+ function mutationRefusal(verb, after, before, ref) {
1131
+ if (verb !== "delete" || after !== before) return null;
1132
+ return { reason: `${ref} was not found`, fix: "choose an existing clip" };
1133
+ }
1134
+
1135
+ // src/commands/timeline.ts
1136
+ var examples = [
1137
+ ["Show every track and clip of the project in the current directory", "framey timeline"],
1138
+ ["Move a clip without writing", "framey timeline move '#hero' +2 --plan"],
1139
+ ["Delete a clip and return a receipt", "framey timeline delete '#hero' --json"]
1140
+ ];
1141
+ var MUTATION_OPTIONS = {
1142
+ time: { type: "positional", required: true },
1143
+ at: { type: "string" },
1144
+ start: { type: "string" },
1145
+ end: { type: "string" },
1146
+ duration: { type: "string" },
1147
+ volume: { type: "string" },
1148
+ rate: { type: "string" },
1149
+ track: { type: "string" },
1150
+ overwrite: { type: "boolean", default: false }
1151
+ };
1152
+ function mutationCommand(verb) {
1153
+ const fields = FIELDS_READ_BY_VERB[verb];
1154
+ return defineCommand({
1155
+ meta: { name: verb, description: `${verb} a timeline clip` },
1156
+ args: {
1157
+ ref: { type: "positional", required: true },
1158
+ ...verb === "set" && { assignment: { type: "positional", required: false } },
1159
+ ...Object.fromEntries(fields.map((field) => [field, MUTATION_OPTIONS[field]])),
1160
+ dir: { type: "string" },
1161
+ plan: { type: "boolean", default: false },
1162
+ json: { type: "boolean", default: false },
1163
+ ...verb !== "set" && { snap: { type: "boolean", default: false } }
1164
+ },
1165
+ async run({ args }) {
1166
+ await runMutation(verb, args);
1167
+ }
1168
+ });
1169
+ }
1170
+ var subCommands = {
1171
+ move: () => mutationCommand("move"),
1172
+ trim: () => mutationCommand("trim"),
1173
+ split: () => mutationCommand("split"),
1174
+ delete: () => mutationCommand("delete"),
1175
+ set: () => mutationCommand("set"),
1176
+ duplicate: () => mutationCommand("duplicate"),
1177
+ ids: () => defineCommand({
1178
+ meta: { name: "ids", description: "Stamp stable ids on timeline clips" },
1179
+ args: { dir: { type: "string" }, json: { type: "boolean", default: false } },
1180
+ async run({ args }) {
1181
+ await runIds(args);
1182
+ }
1183
+ }),
1184
+ apply: () => defineCommand({
1185
+ meta: { name: "apply", description: "Apply an atomic timeline edit plan" },
1186
+ args: {
1187
+ file: { type: "positional", required: true },
1188
+ dir: { type: "string" },
1189
+ json: { type: "boolean", default: false },
1190
+ plan: { type: "boolean", default: false }
1191
+ },
1192
+ async run({ args }) {
1193
+ await runApply(args);
1194
+ }
1195
+ }),
1196
+ undo: () => defineCommand({
1197
+ meta: { name: "undo", description: "Restore a timeline mutation receipt" },
1198
+ args: {
1199
+ receipt: { type: "positional", required: true },
1200
+ dir: { type: "string" },
1201
+ json: { type: "boolean", default: false }
1202
+ },
1203
+ async run({ args }) {
1204
+ await runUndo(args);
1205
+ }
1206
+ })
1207
+ };
1208
+ function isTimelineSubcommand(first, rawArgs) {
1209
+ if (!first || !Object.hasOwn(subCommands, first)) return false;
1210
+ const separator = rawArgs.indexOf("--");
1211
+ return separator < 0 || rawArgs.indexOf(first) < separator;
1212
+ }
1213
+ var timeline_default = defineCommand({
1214
+ meta: { name: "timeline", description: "Print and edit the project's tracks and clips" },
1215
+ args: {
1216
+ dir: { type: "positional", description: "Project directory", required: false },
1217
+ component: {
1218
+ type: "string",
1219
+ description: "Unique component selector, or JSON target {selector|hfId|ref}; runtime inspection"
1220
+ },
1221
+ at: { type: "string", description: "Global second; requires the inspector service" },
1222
+ range: {
1223
+ type: "string",
1224
+ description: "Global start,end (half-open); requires the inspector service"
1225
+ },
1226
+ boundary: {
1227
+ type: "string",
1228
+ description: "Global boundary second; requires the inspector service"
1229
+ },
1230
+ generation: {
1231
+ type: "string",
1232
+ description: "Inspector generation for a continued runtime query"
1233
+ },
1234
+ offset: {
1235
+ type: "string",
1236
+ description: "Group offset for a continued runtime query"
1237
+ },
1238
+ json: { type: "boolean", description: "Output as JSON", default: false }
1239
+ },
1240
+ subCommands,
1241
+ setup({ args, rawArgs, cmd }) {
1242
+ const first = args._[0];
1243
+ if (!first || isTimelineSubcommand(first, rawArgs)) return;
1244
+ assertKnownFlags({ args: cmd.args }, rawArgs);
1245
+ const separator = rawArgs.indexOf("--");
1246
+ const directoryIndex = rawArgs.indexOf(first);
1247
+ if (separator < 0 || directoryIndex < separator) rawArgs.splice(directoryIndex, 0, "--");
1248
+ },
1249
+ async run({ args, rawArgs, cmd }) {
1250
+ if (isTimelineSubcommand(args._[0], rawArgs)) return;
1251
+ resolveExtraPositionals({ args: cmd.args }, "timeline", args);
1252
+ const project = resolveProject(args.dir);
1253
+ if ([args.component, args.at, args.range, args.boundary].some((v) => v !== void 0)) {
1254
+ const url = process.env.HF_INSPECT_URL;
1255
+ if (!url || !/^http:\/\/(127\.0\.0\.1|localhost):\d+$/.test(url))
1256
+ throw new Error(
1257
+ "Runtime timeline queries require HF_INSPECT_URL from the existing inspector service."
1258
+ );
1259
+ const info = await fetch(`${url}/info`, { signal: AbortSignal.timeout(5e3) }).then(
1260
+ (r) => r.json()
1261
+ );
1262
+ const { realpathSync } = await import("fs");
1263
+ const { dirname } = await import("path");
1264
+ if (realpathSync(info.project) !== realpathSync(dirname(project.indexPath)))
1265
+ throw new Error("Inspector service belongs to another project");
1266
+ const component = args.component?.trim().startsWith("{") ? JSON.parse(args.component) : args.component ? { selector: args.component } : void 0;
1267
+ const response = await fetch(`${url}/timeline`, {
1268
+ method: "POST",
1269
+ headers: { "Content-Type": "application/json" },
1270
+ body: JSON.stringify({
1271
+ component,
1272
+ at: args.at === void 0 ? void 0 : Number(args.at),
1273
+ range: args.range?.split(",").map(Number),
1274
+ boundary: args.boundary === void 0 ? void 0 : Number(args.boundary),
1275
+ generation: args.generation,
1276
+ offset: args.offset === void 0 ? void 0 : Number(args.offset)
1277
+ }),
1278
+ signal: AbortSignal.timeout(6e4)
1279
+ });
1280
+ const result = await response.json();
1281
+ if (!response.ok) throw new Error(result.error ?? "Timeline query failed");
1282
+ console.log(args.json ? JSON.stringify(result) : result.text);
1283
+ return;
1284
+ }
1285
+ ensureDOMParser();
1286
+ const timeline = await describeProject(project.indexPath);
1287
+ console.log(
1288
+ args.json ? JSON.stringify(withMeta({ timeline }), null, 2) : formatTimeline(timeline)
1289
+ );
1290
+ }
1291
+ });
1292
+ export {
1293
+ timeline_default as default,
1294
+ examples
1295
+ };