allyhub 0.3.0 → 0.4.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 (643) hide show
  1. package/dist/commands/add.js +2 -2
  2. package/dist/commands/auth.js +4 -4
  3. package/dist/commands/cloud-tools.js +9 -10
  4. package/dist/commands/dev.js +1 -1
  5. package/dist/commands/doctor.js +4 -4
  6. package/dist/commands/frames/piece.js +1 -1
  7. package/dist/commands/frames.js +6 -6
  8. package/dist/commands/index.js +1 -1
  9. package/dist/commands/inspect/contrast.js +1 -1
  10. package/dist/commands/inspect/layout.js +1 -1
  11. package/dist/commands/orgs.js +2 -2
  12. package/dist/commands/render.js +2 -2
  13. package/dist/commands/sheet.js +2 -2
  14. package/dist/commands/slides.js +3 -0
  15. package/dist/main.js +3 -3
  16. package/dist/text/facts-text.js +5 -5
  17. package/dist/text/format.js +2 -2
  18. package/dist/works.js +1 -1
  19. package/editor-web/assets/browser-B31cR_c2.js +105 -0
  20. package/editor-web/assets/dist-6TNEuNMX.js +4 -0
  21. package/editor-web/assets/dist-Cm2TIjW5.js +2 -0
  22. package/editor-web/assets/dist-Cpt0p8bX.js +6 -0
  23. package/editor-web/assets/dist-D2GccKEJ.js +1 -0
  24. package/editor-web/assets/dist-Z0zvYXmu.js +233 -0
  25. package/editor-web/assets/dist-fs4ONrUV.js +32 -0
  26. package/editor-web/assets/index-CAcsAZ9u.js +70 -0
  27. package/editor-web/assets/index-DlcJckhO.css +2 -0
  28. package/editor-web/assets/list-D2v7U8K8.js +1 -0
  29. package/editor-web/assets/react-D0RmGe2w.js +101 -0
  30. package/editor-web/assets/rolldown-runtime-XKyaHtl9.js +1 -0
  31. package/editor-web/assets/text-align-start-B3k2cx5f.js +1 -0
  32. package/editor-web/assets/undo-2-Ecr7-Obc.js +1 -0
  33. package/editor-web/index.html +4 -4
  34. package/node_modules/@allyhub-next/audio/package.json +1 -1
  35. package/node_modules/@allyhub-next/browser/package.json +1 -1
  36. package/node_modules/@allyhub-next/build/dist/data.js +1 -1
  37. package/node_modules/@allyhub-next/build/dist/meta-worker.d.ts +10 -0
  38. package/node_modules/@allyhub-next/build/dist/meta-worker.js +2 -2
  39. package/node_modules/@allyhub-next/build/dist/model-info.js +2 -1
  40. package/node_modules/@allyhub-next/build/dist/plugin.d.ts +2 -0
  41. package/node_modules/@allyhub-next/build/dist/plugin.js +9 -8
  42. package/node_modules/@allyhub-next/build/dist/prepare.d.ts +13 -1
  43. package/node_modules/@allyhub-next/build/dist/prepare.js +2 -2
  44. package/node_modules/@allyhub-next/build/dist/scan.d.ts +1 -1
  45. package/node_modules/@allyhub-next/build/dist/scan.js +1 -1
  46. package/node_modules/@allyhub-next/build/dist/types.js +3 -3
  47. package/node_modules/@allyhub-next/build/package.json +1 -1
  48. package/node_modules/@allyhub-next/check/dist/check.js +3 -3
  49. package/node_modules/@allyhub-next/check/dist/generated.d.ts +1 -1
  50. package/node_modules/@allyhub-next/check/package.json +1 -1
  51. package/node_modules/@allyhub-next/cloud/dist/index.js +1 -1
  52. package/node_modules/@allyhub-next/cloud/dist/signin.js +2 -2
  53. package/node_modules/@allyhub-next/cloud/dist/token.js +1 -1
  54. package/node_modules/@allyhub-next/cloud/package.json +1 -1
  55. package/node_modules/@allyhub-next/components/package.json +1 -1
  56. package/node_modules/@allyhub-next/dev-server/dist/card.d.ts +2 -11
  57. package/node_modules/@allyhub-next/dev-server/dist/card.js +1 -1
  58. package/node_modules/@allyhub-next/dev-server/dist/exports.d.ts +2 -2
  59. package/node_modules/@allyhub-next/dev-server/dist/exports.js +1 -1
  60. package/node_modules/@allyhub-next/dev-server/dist/index.d.ts +1 -1
  61. package/node_modules/@allyhub-next/dev-server/dist/index.js +1 -1
  62. package/node_modules/@allyhub-next/dev-server/dist/live.d.ts +3 -0
  63. package/node_modules/@allyhub-next/dev-server/dist/live.js +1 -1
  64. package/node_modules/@allyhub-next/dev-server/dist/project.d.ts +3 -0
  65. package/node_modules/@allyhub-next/dev-server/dist/project.js +1 -1
  66. package/node_modules/@allyhub-next/dev-server/dist/reveal.d.ts +6 -0
  67. package/node_modules/@allyhub-next/dev-server/dist/reveal.js +2 -0
  68. package/node_modules/@allyhub-next/dev-server/dist/server.js +1 -1
  69. package/node_modules/@allyhub-next/dev-server/dist/stage.d.ts +2 -0
  70. package/node_modules/@allyhub-next/dev-server/dist/stage.js +22 -2
  71. package/node_modules/@allyhub-next/dev-server/dist/tools.d.ts +2 -0
  72. package/node_modules/@allyhub-next/dev-server/dist/tools.js +1 -1
  73. package/node_modules/@allyhub-next/dev-server/package.json +1 -1
  74. package/node_modules/@allyhub-next/doc/dist/docx.d.ts +28 -0
  75. package/node_modules/@allyhub-next/doc/dist/docx.js +4 -0
  76. package/node_modules/@allyhub-next/doc/dist/html.d.ts +3 -0
  77. package/node_modules/@allyhub-next/doc/dist/html.js +1 -1
  78. package/node_modules/@allyhub-next/doc/package.json +5 -1
  79. package/node_modules/@allyhub-next/export/dist/deck-fonts.d.ts +24 -0
  80. package/node_modules/@allyhub-next/export/dist/deck-fonts.js +2 -0
  81. package/node_modules/@allyhub-next/export/dist/deck-pptx.d.ts +12 -0
  82. package/node_modules/@allyhub-next/export/dist/deck-pptx.js +2 -0
  83. package/node_modules/@allyhub-next/export/dist/export.d.ts +12 -3
  84. package/node_modules/@allyhub-next/export/dist/export.js +2 -2
  85. package/node_modules/@allyhub-next/export/dist/index.d.ts +1 -0
  86. package/node_modules/@allyhub-next/export/dist/index.js +1 -1
  87. package/node_modules/@allyhub-next/export/dist/names.d.ts +11 -6
  88. package/node_modules/@allyhub-next/export/dist/names.js +1 -1
  89. package/node_modules/@allyhub-next/export/package.json +1 -1
  90. package/node_modules/@allyhub-next/formats/dist/data/script.d.ts +22 -0
  91. package/node_modules/@allyhub-next/formats/dist/data/script.js +1 -1
  92. package/node_modules/@allyhub-next/formats/dist/data/slides.d.ts +1494 -0
  93. package/node_modules/@allyhub-next/formats/dist/data/slides.js +2 -0
  94. package/node_modules/@allyhub-next/formats/dist/index.d.ts +2 -0
  95. package/node_modules/@allyhub-next/formats/dist/index.js +1 -1
  96. package/node_modules/@allyhub-next/formats/dist/items.d.ts +21 -0
  97. package/node_modules/@allyhub-next/formats/dist/items.js +1 -1
  98. package/node_modules/@allyhub-next/formats/dist/note-shape.d.ts +39 -0
  99. package/node_modules/@allyhub-next/formats/dist/note-shape.js +2 -0
  100. package/node_modules/@allyhub-next/formats/dist/schemas.d.ts +418 -0
  101. package/node_modules/@allyhub-next/formats/dist/schemas.js +1 -1
  102. package/node_modules/@allyhub-next/formats/package.json +1 -1
  103. package/node_modules/@allyhub-next/measure/dist/index.d.ts +1 -1
  104. package/node_modules/@allyhub-next/measure/dist/index.js +1 -1
  105. package/node_modules/@allyhub-next/measure/dist/overlay.d.ts +14 -1
  106. package/node_modules/@allyhub-next/measure/dist/overlay.js +1 -1
  107. package/node_modules/@allyhub-next/measure/package.json +1 -1
  108. package/node_modules/@allyhub-next/media/dist/asr/parakeet.d.ts +1 -4
  109. package/node_modules/@allyhub-next/media/dist/asr/parakeet.js +4 -4
  110. package/node_modules/@allyhub-next/media/dist/asr/transcribe.d.ts +1 -1
  111. package/node_modules/@allyhub-next/media/dist/asr/transcribe.js +1 -1
  112. package/node_modules/@allyhub-next/media/dist/grid.d.ts +3 -3
  113. package/node_modules/@allyhub-next/media/dist/grid.js +5 -5
  114. package/node_modules/@allyhub-next/media/dist/local.d.ts +3 -0
  115. package/node_modules/@allyhub-next/media/dist/local.js +1 -1
  116. package/node_modules/@allyhub-next/media/dist/ocr/tesseract.d.ts +8 -2
  117. package/node_modules/@allyhub-next/media/dist/ocr/tesseract.js +1 -1
  118. package/node_modules/@allyhub-next/media/dist/ocr/text.js +3 -3
  119. package/node_modules/@allyhub-next/media/dist/ocr/worker.js +1 -1
  120. package/node_modules/@allyhub-next/media/dist/sheet.js +3 -3
  121. package/node_modules/@allyhub-next/media/dist/tools.d.ts +11 -1
  122. package/node_modules/@allyhub-next/media/dist/tools.js +1 -1
  123. package/node_modules/@allyhub-next/media/dist/vision/faces.js +1 -1
  124. package/node_modules/@allyhub-next/media/dist/vision/matte.js +1 -1
  125. package/node_modules/@allyhub-next/media/dist/vision/runtime.d.ts +1 -1
  126. package/node_modules/@allyhub-next/media/dist/vision/runtime.js +2 -2
  127. package/node_modules/@allyhub-next/media/dist/worker-process.d.ts +1 -1
  128. package/node_modules/@allyhub-next/media/dist/worker-process.js +1 -1
  129. package/node_modules/@allyhub-next/media/package.json +1 -1
  130. package/node_modules/@allyhub-next/model/dist/build-job.d.ts +2 -0
  131. package/node_modules/@allyhub-next/model/dist/build-worker.js +1 -1
  132. package/node_modules/@allyhub-next/model/dist/build.d.ts +10 -0
  133. package/node_modules/@allyhub-next/model/dist/build.js +2 -1
  134. package/node_modules/@allyhub-next/model/package.json +1 -1
  135. package/node_modules/@allyhub-next/project/dist/digest.d.ts +1 -3
  136. package/node_modules/@allyhub-next/project/dist/digest.js +1 -1
  137. package/node_modules/@allyhub-next/project/dist/page.d.ts +0 -5
  138. package/node_modules/@allyhub-next/project/dist/page.js +2 -2
  139. package/node_modules/@allyhub-next/project/dist/session.js +1 -1
  140. package/node_modules/@allyhub-next/project/package.json +1 -1
  141. package/node_modules/@allyhub-next/protocol/dist/app.d.ts +0 -64
  142. package/node_modules/@allyhub-next/protocol/dist/app.js +1 -1
  143. package/node_modules/@allyhub-next/protocol/dist/auth.d.ts +0 -17
  144. package/node_modules/@allyhub-next/protocol/dist/auth.js +1 -1
  145. package/node_modules/@allyhub-next/protocol/dist/cli.d.ts +0 -4
  146. package/node_modules/@allyhub-next/protocol/dist/cli.js +1 -1
  147. package/node_modules/@allyhub-next/protocol/dist/editor.d.ts +9 -26
  148. package/node_modules/@allyhub-next/protocol/dist/editor.js +1 -1
  149. package/node_modules/@allyhub-next/protocol/dist/index.d.ts +1 -0
  150. package/node_modules/@allyhub-next/protocol/dist/index.js +1 -1
  151. package/node_modules/@allyhub-next/protocol/dist/notes.d.ts +163 -0
  152. package/node_modules/@allyhub-next/protocol/dist/notes.js +2 -0
  153. package/node_modules/@allyhub-next/protocol/dist/registry.d.ts +1 -1
  154. package/node_modules/@allyhub-next/protocol/dist/runtimes.d.ts +3 -0
  155. package/node_modules/@allyhub-next/protocol/dist/runtimes.js +1 -1
  156. package/node_modules/@allyhub-next/protocol/dist/tools.d.ts +37 -0
  157. package/node_modules/@allyhub-next/protocol/dist/tools.js +1 -1
  158. package/node_modules/@allyhub-next/protocol/package.json +1 -1
  159. package/node_modules/@allyhub-next/registry/dist/registry.js +1 -1
  160. package/node_modules/@allyhub-next/registry/package.json +1 -1
  161. package/node_modules/@allyhub-next/render/dist/doc/index.d.ts +1 -1
  162. package/node_modules/@allyhub-next/render/dist/doc/index.js +1 -1
  163. package/node_modules/@allyhub-next/render/dist/doc/print.d.ts +11 -0
  164. package/node_modules/@allyhub-next/render/dist/doc/print.js +17 -1
  165. package/node_modules/@allyhub-next/render/dist/exports.d.ts +29 -4
  166. package/node_modules/@allyhub-next/render/dist/exports.js +2 -2
  167. package/node_modules/@allyhub-next/render/dist/page.d.ts +11 -1
  168. package/node_modules/@allyhub-next/render/dist/render.d.ts +2 -0
  169. package/node_modules/@allyhub-next/render/dist/render.js +2 -2
  170. package/node_modules/@allyhub-next/render/package.json +1 -1
  171. package/node_modules/@allyhub-next/runtime/LICENSE +241 -0
  172. package/node_modules/@allyhub-next/runtime/dist/bridge.d.ts +13 -3
  173. package/node_modules/@allyhub-next/runtime/dist/clock.js +1 -1
  174. package/node_modules/@allyhub-next/runtime/dist/env.js +1 -1
  175. package/node_modules/@allyhub-next/runtime/dist/facade.js +1 -1
  176. package/node_modules/@allyhub-next/runtime/dist/footage.js +1 -1
  177. package/node_modules/@allyhub-next/runtime/dist/frame.js +1 -1
  178. package/node_modules/@allyhub-next/runtime/dist/index.d.ts +2 -0
  179. package/node_modules/@allyhub-next/runtime/dist/index.js +1 -1
  180. package/node_modules/@allyhub-next/runtime/dist/locate.d.ts +11 -0
  181. package/node_modules/@allyhub-next/runtime/dist/locate.js +2 -0
  182. package/node_modules/@allyhub-next/runtime/dist/measure.d.ts +2 -1
  183. package/node_modules/@allyhub-next/runtime/dist/measure.js +1 -1
  184. package/node_modules/@allyhub-next/runtime/dist/music.js +1 -1
  185. package/node_modules/@allyhub-next/runtime/dist/output.js +1 -1
  186. package/node_modules/@allyhub-next/runtime/dist/piece.d.ts +5 -9
  187. package/node_modules/@allyhub-next/runtime/dist/piece.js +2 -2
  188. package/node_modules/@allyhub-next/runtime/dist/player/player.js +1 -1
  189. package/node_modules/@allyhub-next/runtime/dist/reads.d.ts +2 -0
  190. package/node_modules/@allyhub-next/runtime/dist/reads.js +1 -1
  191. package/node_modules/@allyhub-next/runtime/dist/sound.js +1 -1
  192. package/node_modules/@allyhub-next/runtime/dist/stage-kit.d.ts +12 -0
  193. package/node_modules/@allyhub-next/runtime/dist/stage-kit.js +2 -0
  194. package/node_modules/@allyhub-next/runtime/package.json +5 -6
  195. package/node_modules/@allyhub-next/runtimes/dist/errors.d.ts +5 -1
  196. package/node_modules/@allyhub-next/runtimes/dist/index.d.ts +1 -0
  197. package/node_modules/@allyhub-next/runtimes/dist/index.js +1 -1
  198. package/node_modules/@allyhub-next/runtimes/dist/node-program.d.ts +3 -0
  199. package/node_modules/@allyhub-next/runtimes/dist/node-program.js +2 -0
  200. package/node_modules/@allyhub-next/runtimes/dist/packages.d.ts +65 -0
  201. package/node_modules/@allyhub-next/runtimes/dist/packages.js +4 -0
  202. package/node_modules/@allyhub-next/runtimes/dist/runtimes.js +2 -2
  203. package/node_modules/@allyhub-next/runtimes/dist/unpack.d.ts +7 -0
  204. package/node_modules/@allyhub-next/runtimes/dist/unpack.js +1 -1
  205. package/node_modules/@allyhub-next/runtimes/package.json +5 -1
  206. package/node_modules/@allyhub-next/runtimes/pins/docx/package-lock.json +67 -0
  207. package/node_modules/@allyhub-next/runtimes/pins/docx/package.json +9 -0
  208. package/node_modules/@allyhub-next/runtimes/pins/exceljs/package-lock.json +2533 -0
  209. package/node_modules/@allyhub-next/runtimes/pins/exceljs/package.json +8 -0
  210. package/node_modules/@allyhub-next/runtimes/pins/gltf-tools/package-lock.json +753 -0
  211. package/node_modules/@allyhub-next/runtimes/pins/gltf-tools/package.json +14 -0
  212. package/node_modules/@allyhub-next/runtimes/pins/manifold-3d/package-lock.json +950 -0
  213. package/node_modules/@allyhub-next/runtimes/pins/manifold-3d/package.json +8 -0
  214. package/node_modules/@allyhub-next/runtimes/pins/onnxruntime-node/package-lock.json +227 -0
  215. package/node_modules/@allyhub-next/runtimes/pins/onnxruntime-node/package.json +8 -0
  216. package/node_modules/@allyhub-next/runtimes/pins/sherpa-onnx-node/package-lock.json +105 -0
  217. package/node_modules/@allyhub-next/runtimes/pins/sherpa-onnx-node/package.json +8 -0
  218. package/node_modules/@allyhub-next/runtimes/pins/tesseract.js/package-lock.json +128 -0
  219. package/node_modules/@allyhub-next/runtimes/pins/tesseract.js/package.json +9 -0
  220. package/node_modules/@allyhub-next/runtimes/schemas/runtimes.schema.json +5 -24
  221. package/node_modules/@allyhub-next/scaffold/dist/index.js +3 -3
  222. package/node_modules/@allyhub-next/scaffold/package.json +1 -1
  223. package/node_modules/@allyhub-next/scenery/package.json +1 -1
  224. package/node_modules/@allyhub-next/scenery-host/dist/bundle.d.ts +2 -2
  225. package/node_modules/@allyhub-next/scenery-host/dist/bundle.js +3 -3
  226. package/node_modules/@allyhub-next/scenery-host/dist/viewer.d.ts +11 -0
  227. package/node_modules/@allyhub-next/scenery-host/dist/viewer.js +1 -1
  228. package/node_modules/@allyhub-next/scenery-host/package.json +1 -1
  229. package/node_modules/@allyhub-next/sheet/package.json +1 -1
  230. package/node_modules/@allyhub-next/site/dist/media.js +2 -2
  231. package/node_modules/@allyhub-next/site/package.json +1 -1
  232. package/node_modules/@allyhub-next/slides-core/LICENSE +241 -0
  233. package/node_modules/@allyhub-next/slides-core/dist/animation.d.ts +129 -0
  234. package/node_modules/@allyhub-next/slides-core/dist/animation.js +2 -0
  235. package/node_modules/@allyhub-next/slides-core/dist/api.d.ts +649 -0
  236. package/node_modules/@allyhub-next/slides-core/dist/api.js +4 -0
  237. package/node_modules/@allyhub-next/slides-core/dist/capabilities.d.ts +18 -0
  238. package/node_modules/@allyhub-next/slides-core/dist/capabilities.js +2 -0
  239. package/node_modules/@allyhub-next/slides-core/dist/chart-api.d.ts +165 -0
  240. package/node_modules/@allyhub-next/slides-core/dist/chart-api.js +2 -0
  241. package/node_modules/@allyhub-next/slides-core/dist/chart-file.d.ts +11 -0
  242. package/node_modules/@allyhub-next/slides-core/dist/chart-file.js +2 -0
  243. package/node_modules/@allyhub-next/slides-core/dist/chart.d.ts +184 -0
  244. package/node_modules/@allyhub-next/slides-core/dist/chart.js +2 -0
  245. package/node_modules/@allyhub-next/slides-core/dist/check.d.ts +7 -0
  246. package/node_modules/@allyhub-next/slides-core/dist/check.js +2 -0
  247. package/node_modules/@allyhub-next/slides-core/dist/enums.d.ts +146 -0
  248. package/node_modules/@allyhub-next/slides-core/dist/enums.js +2 -0
  249. package/node_modules/@allyhub-next/slides-core/dist/file.d.ts +109 -0
  250. package/node_modules/@allyhub-next/slides-core/dist/file.js +4 -0
  251. package/node_modules/@allyhub-next/slides-core/dist/index.d.ts +21 -0
  252. package/node_modules/@allyhub-next/slides-core/dist/index.js +2 -0
  253. package/node_modules/@allyhub-next/slides-core/dist/measure.d.ts +34 -0
  254. package/node_modules/@allyhub-next/slides-core/dist/measure.js +2 -0
  255. package/node_modules/@allyhub-next/slides-core/dist/model.d.ts +278 -0
  256. package/node_modules/@allyhub-next/slides-core/dist/model.js +2 -0
  257. package/node_modules/@allyhub-next/slides-core/dist/office.d.ts +58 -0
  258. package/node_modules/@allyhub-next/slides-core/dist/office.js +2 -0
  259. package/node_modules/@allyhub-next/slides-core/dist/path.d.ts +6 -0
  260. package/node_modules/@allyhub-next/slides-core/dist/path.js +2 -0
  261. package/node_modules/@allyhub-next/slides-core/dist/placeholders.d.ts +7 -0
  262. package/node_modules/@allyhub-next/slides-core/dist/placeholders.js +2 -0
  263. package/node_modules/@allyhub-next/slides-core/dist/resolve.d.ts +181 -0
  264. package/node_modules/@allyhub-next/slides-core/dist/resolve.js +2 -0
  265. package/node_modules/@allyhub-next/slides-core/dist/script.d.ts +43 -0
  266. package/node_modules/@allyhub-next/slides-core/dist/script.js +3 -0
  267. package/node_modules/@allyhub-next/slides-core/dist/stage.d.ts +63 -0
  268. package/node_modules/@allyhub-next/slides-core/dist/stage.js +2 -0
  269. package/node_modules/@allyhub-next/slides-core/dist/strict.d.ts +23 -0
  270. package/node_modules/@allyhub-next/slides-core/dist/strict.js +2 -0
  271. package/node_modules/@allyhub-next/slides-core/dist/theme.d.ts +72 -0
  272. package/node_modules/@allyhub-next/slides-core/dist/theme.js +2 -0
  273. package/node_modules/@allyhub-next/slides-core/dist/units.d.ts +35 -0
  274. package/node_modules/@allyhub-next/slides-core/dist/units.js +2 -0
  275. package/node_modules/@allyhub-next/slides-core/package.json +14 -0
  276. package/node_modules/@allyhub-next/slides-pptx/LICENSE +241 -0
  277. package/node_modules/@allyhub-next/slides-pptx/dist/charts.d.ts +6 -0
  278. package/node_modules/@allyhub-next/slides-pptx/dist/charts.js +2 -0
  279. package/node_modules/@allyhub-next/slides-pptx/dist/fonts.d.ts +45 -0
  280. package/node_modules/@allyhub-next/slides-pptx/dist/fonts.js +2 -0
  281. package/node_modules/@allyhub-next/slides-pptx/dist/import.d.ts +18 -0
  282. package/node_modules/@allyhub-next/slides-pptx/dist/import.js +3 -0
  283. package/node_modules/@allyhub-next/slides-pptx/dist/index.d.ts +5 -0
  284. package/node_modules/@allyhub-next/slides-pptx/dist/index.js +2 -0
  285. package/node_modules/@allyhub-next/slides-pptx/dist/read.d.ts +55 -0
  286. package/node_modules/@allyhub-next/slides-pptx/dist/read.js +4 -0
  287. package/node_modules/@allyhub-next/slides-pptx/dist/shapes.d.ts +67 -0
  288. package/node_modules/@allyhub-next/slides-pptx/dist/shapes.js +2 -0
  289. package/node_modules/@allyhub-next/slides-pptx/dist/text.d.ts +21 -0
  290. package/node_modules/@allyhub-next/slides-pptx/dist/text.js +2 -0
  291. package/node_modules/@allyhub-next/slides-pptx/dist/theme.d.ts +4 -0
  292. package/node_modules/@allyhub-next/slides-pptx/dist/theme.js +2 -0
  293. package/node_modules/@allyhub-next/slides-pptx/dist/timing.d.ts +32 -0
  294. package/node_modules/@allyhub-next/slides-pptx/dist/timing.js +2 -0
  295. package/node_modules/@allyhub-next/slides-pptx/dist/write.d.ts +32 -0
  296. package/node_modules/@allyhub-next/slides-pptx/dist/write.js +3 -0
  297. package/node_modules/@allyhub-next/slides-pptx/dist/xml.d.ts +26 -0
  298. package/node_modules/@allyhub-next/slides-pptx/dist/xml.js +3 -0
  299. package/node_modules/@allyhub-next/slides-pptx/package.json +14 -0
  300. package/node_modules/@allyhub-next/slides-runtime/LICENSE +241 -0
  301. package/node_modules/@allyhub-next/slides-runtime/dist/draw.d.ts +40 -0
  302. package/node_modules/@allyhub-next/slides-runtime/dist/draw.js +3 -0
  303. package/node_modules/@allyhub-next/slides-runtime/dist/edit.d.ts +4 -0
  304. package/node_modules/@allyhub-next/slides-runtime/dist/edit.js +2 -0
  305. package/node_modules/@allyhub-next/slides-runtime/dist/index.d.ts +4 -0
  306. package/node_modules/@allyhub-next/slides-runtime/dist/index.js +2 -0
  307. package/node_modules/@allyhub-next/slides-runtime/dist/ink.d.ts +10 -0
  308. package/node_modules/@allyhub-next/slides-runtime/dist/ink.js +2 -0
  309. package/node_modules/@allyhub-next/slides-runtime/dist/load.d.ts +6 -0
  310. package/node_modules/@allyhub-next/slides-runtime/dist/load.js +6 -0
  311. package/node_modules/@allyhub-next/slides-runtime/package.json +14 -0
  312. package/node_modules/@allyhub-next/stage/dist/graphics.js +1 -1
  313. package/node_modules/@allyhub-next/stage/dist/identity.js +1 -1
  314. package/node_modules/@allyhub-next/stage/dist/page.d.ts +9 -0
  315. package/node_modules/@allyhub-next/stage/dist/page.js +12 -2
  316. package/node_modules/@allyhub-next/stage/dist/server.js +1 -1
  317. package/node_modules/@allyhub-next/stage/package.json +1 -1
  318. package/node_modules/@allyhub-next/stage-page/dist/fonts/arimo/400-italic.css +79 -0
  319. package/node_modules/@allyhub-next/stage-page/dist/fonts/arimo/400.css +79 -0
  320. package/node_modules/@allyhub-next/stage-page/dist/fonts/arimo/700-italic.css +79 -0
  321. package/node_modules/@allyhub-next/stage-page/dist/fonts/arimo/700.css +79 -0
  322. package/node_modules/@allyhub-next/stage-page/dist/fonts/arimo/LICENSE +93 -0
  323. package/node_modules/@allyhub-next/stage-page/dist/fonts/arimo/arial.css +316 -0
  324. package/node_modules/@allyhub-next/stage-page/dist/fonts/arimo/files/arimo-cyrillic-400-italic.woff2 +0 -0
  325. package/node_modules/@allyhub-next/stage-page/dist/fonts/arimo/files/arimo-cyrillic-400-normal.woff2 +0 -0
  326. package/node_modules/@allyhub-next/stage-page/dist/fonts/arimo/files/arimo-cyrillic-700-italic.woff2 +0 -0
  327. package/node_modules/@allyhub-next/stage-page/dist/fonts/arimo/files/arimo-cyrillic-700-normal.woff2 +0 -0
  328. package/node_modules/@allyhub-next/stage-page/dist/fonts/arimo/files/arimo-cyrillic-ext-400-italic.woff2 +0 -0
  329. package/node_modules/@allyhub-next/stage-page/dist/fonts/arimo/files/arimo-cyrillic-ext-400-normal.woff2 +0 -0
  330. package/node_modules/@allyhub-next/stage-page/dist/fonts/arimo/files/arimo-cyrillic-ext-700-italic.woff2 +0 -0
  331. package/node_modules/@allyhub-next/stage-page/dist/fonts/arimo/files/arimo-cyrillic-ext-700-normal.woff2 +0 -0
  332. package/node_modules/@allyhub-next/stage-page/dist/fonts/arimo/files/arimo-greek-400-italic.woff2 +0 -0
  333. package/node_modules/@allyhub-next/stage-page/dist/fonts/arimo/files/arimo-greek-400-normal.woff2 +0 -0
  334. package/node_modules/@allyhub-next/stage-page/dist/fonts/arimo/files/arimo-greek-700-italic.woff2 +0 -0
  335. package/node_modules/@allyhub-next/stage-page/dist/fonts/arimo/files/arimo-greek-700-normal.woff2 +0 -0
  336. package/node_modules/@allyhub-next/stage-page/dist/fonts/arimo/files/arimo-greek-ext-400-italic.woff2 +0 -0
  337. package/node_modules/@allyhub-next/stage-page/dist/fonts/arimo/files/arimo-greek-ext-400-normal.woff2 +0 -0
  338. package/node_modules/@allyhub-next/stage-page/dist/fonts/arimo/files/arimo-greek-ext-700-italic.woff2 +0 -0
  339. package/node_modules/@allyhub-next/stage-page/dist/fonts/arimo/files/arimo-greek-ext-700-normal.woff2 +0 -0
  340. package/node_modules/@allyhub-next/stage-page/dist/fonts/arimo/files/arimo-hebrew-400-italic.woff2 +0 -0
  341. package/node_modules/@allyhub-next/stage-page/dist/fonts/arimo/files/arimo-hebrew-400-normal.woff2 +0 -0
  342. package/node_modules/@allyhub-next/stage-page/dist/fonts/arimo/files/arimo-hebrew-700-italic.woff2 +0 -0
  343. package/node_modules/@allyhub-next/stage-page/dist/fonts/arimo/files/arimo-hebrew-700-normal.woff2 +0 -0
  344. package/node_modules/@allyhub-next/stage-page/dist/fonts/arimo/files/arimo-latin-400-italic.woff2 +0 -0
  345. package/node_modules/@allyhub-next/stage-page/dist/fonts/arimo/files/arimo-latin-400-normal.woff2 +0 -0
  346. package/node_modules/@allyhub-next/stage-page/dist/fonts/arimo/files/arimo-latin-700-italic.woff2 +0 -0
  347. package/node_modules/@allyhub-next/stage-page/dist/fonts/arimo/files/arimo-latin-700-normal.woff2 +0 -0
  348. package/node_modules/@allyhub-next/stage-page/dist/fonts/arimo/files/arimo-latin-ext-400-italic.woff2 +0 -0
  349. package/node_modules/@allyhub-next/stage-page/dist/fonts/arimo/files/arimo-latin-ext-400-normal.woff2 +0 -0
  350. package/node_modules/@allyhub-next/stage-page/dist/fonts/arimo/files/arimo-latin-ext-700-italic.woff2 +0 -0
  351. package/node_modules/@allyhub-next/stage-page/dist/fonts/arimo/files/arimo-latin-ext-700-normal.woff2 +0 -0
  352. package/node_modules/@allyhub-next/stage-page/dist/fonts/arimo/files/arimo-vietnamese-400-italic.woff2 +0 -0
  353. package/node_modules/@allyhub-next/stage-page/dist/fonts/arimo/files/arimo-vietnamese-400-normal.woff2 +0 -0
  354. package/node_modules/@allyhub-next/stage-page/dist/fonts/arimo/files/arimo-vietnamese-700-italic.woff2 +0 -0
  355. package/node_modules/@allyhub-next/stage-page/dist/fonts/arimo/files/arimo-vietnamese-700-normal.woff2 +0 -0
  356. package/node_modules/@allyhub-next/stage-page/dist/fonts/carlito/400-italic.css +69 -0
  357. package/node_modules/@allyhub-next/stage-page/dist/fonts/carlito/400.css +69 -0
  358. package/node_modules/@allyhub-next/stage-page/dist/fonts/carlito/700-italic.css +69 -0
  359. package/node_modules/@allyhub-next/stage-page/dist/fonts/carlito/700.css +69 -0
  360. package/node_modules/@allyhub-next/stage-page/dist/fonts/carlito/LICENSE +93 -0
  361. package/node_modules/@allyhub-next/stage-page/dist/fonts/carlito/calibri.css +276 -0
  362. package/node_modules/@allyhub-next/stage-page/dist/fonts/carlito/files/carlito-cyrillic-400-italic.woff2 +0 -0
  363. package/node_modules/@allyhub-next/stage-page/dist/fonts/carlito/files/carlito-cyrillic-400-normal.woff2 +0 -0
  364. package/node_modules/@allyhub-next/stage-page/dist/fonts/carlito/files/carlito-cyrillic-700-italic.woff2 +0 -0
  365. package/node_modules/@allyhub-next/stage-page/dist/fonts/carlito/files/carlito-cyrillic-700-normal.woff2 +0 -0
  366. package/node_modules/@allyhub-next/stage-page/dist/fonts/carlito/files/carlito-cyrillic-ext-400-italic.woff2 +0 -0
  367. package/node_modules/@allyhub-next/stage-page/dist/fonts/carlito/files/carlito-cyrillic-ext-400-normal.woff2 +0 -0
  368. package/node_modules/@allyhub-next/stage-page/dist/fonts/carlito/files/carlito-cyrillic-ext-700-italic.woff2 +0 -0
  369. package/node_modules/@allyhub-next/stage-page/dist/fonts/carlito/files/carlito-cyrillic-ext-700-normal.woff2 +0 -0
  370. package/node_modules/@allyhub-next/stage-page/dist/fonts/carlito/files/carlito-greek-400-italic.woff2 +0 -0
  371. package/node_modules/@allyhub-next/stage-page/dist/fonts/carlito/files/carlito-greek-400-normal.woff2 +0 -0
  372. package/node_modules/@allyhub-next/stage-page/dist/fonts/carlito/files/carlito-greek-700-italic.woff2 +0 -0
  373. package/node_modules/@allyhub-next/stage-page/dist/fonts/carlito/files/carlito-greek-700-normal.woff2 +0 -0
  374. package/node_modules/@allyhub-next/stage-page/dist/fonts/carlito/files/carlito-greek-ext-400-italic.woff2 +0 -0
  375. package/node_modules/@allyhub-next/stage-page/dist/fonts/carlito/files/carlito-greek-ext-400-normal.woff2 +0 -0
  376. package/node_modules/@allyhub-next/stage-page/dist/fonts/carlito/files/carlito-greek-ext-700-italic.woff2 +0 -0
  377. package/node_modules/@allyhub-next/stage-page/dist/fonts/carlito/files/carlito-greek-ext-700-normal.woff2 +0 -0
  378. package/node_modules/@allyhub-next/stage-page/dist/fonts/carlito/files/carlito-latin-400-italic.woff2 +0 -0
  379. package/node_modules/@allyhub-next/stage-page/dist/fonts/carlito/files/carlito-latin-400-normal.woff2 +0 -0
  380. package/node_modules/@allyhub-next/stage-page/dist/fonts/carlito/files/carlito-latin-700-italic.woff2 +0 -0
  381. package/node_modules/@allyhub-next/stage-page/dist/fonts/carlito/files/carlito-latin-700-normal.woff2 +0 -0
  382. package/node_modules/@allyhub-next/stage-page/dist/fonts/carlito/files/carlito-latin-ext-400-italic.woff2 +0 -0
  383. package/node_modules/@allyhub-next/stage-page/dist/fonts/carlito/files/carlito-latin-ext-400-normal.woff2 +0 -0
  384. package/node_modules/@allyhub-next/stage-page/dist/fonts/carlito/files/carlito-latin-ext-700-italic.woff2 +0 -0
  385. package/node_modules/@allyhub-next/stage-page/dist/fonts/carlito/files/carlito-latin-ext-700-normal.woff2 +0 -0
  386. package/node_modules/@allyhub-next/stage-page/dist/fonts/carlito/files/carlito-vietnamese-400-italic.woff2 +0 -0
  387. package/node_modules/@allyhub-next/stage-page/dist/fonts/carlito/files/carlito-vietnamese-400-normal.woff2 +0 -0
  388. package/node_modules/@allyhub-next/stage-page/dist/fonts/carlito/files/carlito-vietnamese-700-italic.woff2 +0 -0
  389. package/node_modules/@allyhub-next/stage-page/dist/fonts/carlito/files/carlito-vietnamese-700-normal.woff2 +0 -0
  390. package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/400.css +1 -1
  391. package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/700.css +1 -1
  392. package/node_modules/@allyhub-next/stage-page/dist/fonts/noto-sans-sc/microsoft-yahei.css +2018 -0
  393. package/node_modules/@allyhub-next/stage-page/dist/host.js +21 -0
  394. package/node_modules/@allyhub-next/stage-page/dist/page.js +79 -0
  395. package/node_modules/@allyhub-next/stage-page/package.json +14 -0
  396. package/node_modules/@allyhub-next/video-core/dist/export.d.ts +6 -5
  397. package/node_modules/@allyhub-next/video-core/dist/export.js +1 -1
  398. package/node_modules/@allyhub-next/video-core/dist/fact.d.ts +173 -4
  399. package/node_modules/@allyhub-next/video-core/dist/fact.js +1 -1
  400. package/node_modules/@allyhub-next/video-core/dist/formats.d.ts +6 -13
  401. package/node_modules/@allyhub-next/video-core/dist/formats.js +1 -1
  402. package/node_modules/@allyhub-next/video-core/dist/index.d.ts +0 -1
  403. package/node_modules/@allyhub-next/video-core/dist/index.js +1 -1
  404. package/node_modules/@allyhub-next/video-core/dist/measure.d.ts +83 -0
  405. package/node_modules/@allyhub-next/video-core/dist/piece.d.ts +8 -9
  406. package/node_modules/@allyhub-next/video-core/dist/piece.js +1 -1
  407. package/node_modules/@allyhub-next/video-core/dist/problem.d.ts +5 -1
  408. package/node_modules/@allyhub-next/video-core/dist/problem.js +1 -1
  409. package/node_modules/@allyhub-next/video-core/dist/schema.d.ts +0 -2
  410. package/node_modules/@allyhub-next/video-core/dist/script-edit.d.ts +4 -0
  411. package/node_modules/@allyhub-next/video-core/dist/script.d.ts +8 -0
  412. package/node_modules/@allyhub-next/video-core/dist/script.js +1 -1
  413. package/node_modules/@allyhub-next/video-core/dist/timeline.d.ts +34 -1
  414. package/node_modules/@allyhub-next/video-core/package.json +1 -1
  415. package/package.json +48 -41
  416. package/dist/commands/mcp-app.js +0 -3
  417. package/dist/commands/mcp-docs.js +0 -2
  418. package/dist/commands/mcp.js +0 -2
  419. package/editor-app/view.html +0 -128
  420. package/editor-web/assets/chevron-left-W6sP7nB1.js +0 -1
  421. package/editor-web/assets/chevron-up-566GQpAm.js +0 -1
  422. package/editor-web/assets/dist-BKDr73BR.js +0 -136
  423. package/editor-web/assets/dist-CPCNTYVu.js +0 -8
  424. package/editor-web/assets/dist-C_NajYp0.js +0 -1
  425. package/editor-web/assets/dist-mA6NrAKh.js +0 -232
  426. package/editor-web/assets/floating-ui.react-dom-BUxFRF6t.js +0 -1
  427. package/editor-web/assets/index-CFZhjTQW.js +0 -56
  428. package/editor-web/assets/index-DgU-lyX6.css +0 -2
  429. package/editor-web/assets/react-Ff_buMj8.js +0 -61
  430. package/editor-web/assets/undo-2-BKFItM3X.js +0 -1
  431. package/node_modules/@allyhub-next/runtime/dist/host.js +0 -21
  432. package/node_modules/@allyhub-next/runtime/dist/page.js +0 -72
  433. package/node_modules/@allyhub-next/runtime/dist/paged.d.ts +0 -16
  434. package/node_modules/@allyhub-next/runtime/dist/paged.js +0 -2
  435. package/node_modules/@allyhub-next/video-core/dist/slides.d.ts +0 -37
  436. package/node_modules/@allyhub-next/video-core/dist/slides.js +0 -2
  437. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-color-emoji/LICENSE +0 -0
  438. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-color-emoji/emoji.css +0 -0
  439. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-color-emoji/files/noto-color-emoji-emoji-400-normal.woff2 +0 -0
  440. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/LICENSE +0 -0
  441. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-100-400-normal.woff2 +0 -0
  442. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-100-700-normal.woff2 +0 -0
  443. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-101-400-normal.woff2 +0 -0
  444. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-101-700-normal.woff2 +0 -0
  445. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-102-400-normal.woff2 +0 -0
  446. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-102-700-normal.woff2 +0 -0
  447. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-103-400-normal.woff2 +0 -0
  448. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-103-700-normal.woff2 +0 -0
  449. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-104-400-normal.woff2 +0 -0
  450. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-104-700-normal.woff2 +0 -0
  451. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-105-400-normal.woff2 +0 -0
  452. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-105-700-normal.woff2 +0 -0
  453. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-106-400-normal.woff2 +0 -0
  454. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-106-700-normal.woff2 +0 -0
  455. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-107-400-normal.woff2 +0 -0
  456. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-107-700-normal.woff2 +0 -0
  457. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-108-400-normal.woff2 +0 -0
  458. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-108-700-normal.woff2 +0 -0
  459. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-109-400-normal.woff2 +0 -0
  460. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-109-700-normal.woff2 +0 -0
  461. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-110-400-normal.woff2 +0 -0
  462. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-110-700-normal.woff2 +0 -0
  463. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-111-400-normal.woff2 +0 -0
  464. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-111-700-normal.woff2 +0 -0
  465. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-112-400-normal.woff2 +0 -0
  466. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-112-700-normal.woff2 +0 -0
  467. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-113-400-normal.woff2 +0 -0
  468. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-113-700-normal.woff2 +0 -0
  469. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-114-400-normal.woff2 +0 -0
  470. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-114-700-normal.woff2 +0 -0
  471. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-115-400-normal.woff2 +0 -0
  472. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-115-700-normal.woff2 +0 -0
  473. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-116-400-normal.woff2 +0 -0
  474. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-116-700-normal.woff2 +0 -0
  475. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-117-400-normal.woff2 +0 -0
  476. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-117-700-normal.woff2 +0 -0
  477. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-118-400-normal.woff2 +0 -0
  478. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-118-700-normal.woff2 +0 -0
  479. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-119-400-normal.woff2 +0 -0
  480. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-119-700-normal.woff2 +0 -0
  481. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-21-400-normal.woff2 +0 -0
  482. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-21-700-normal.woff2 +0 -0
  483. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-22-400-normal.woff2 +0 -0
  484. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-22-700-normal.woff2 +0 -0
  485. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-23-400-normal.woff2 +0 -0
  486. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-23-700-normal.woff2 +0 -0
  487. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-24-400-normal.woff2 +0 -0
  488. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-24-700-normal.woff2 +0 -0
  489. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-25-400-normal.woff2 +0 -0
  490. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-25-700-normal.woff2 +0 -0
  491. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-26-400-normal.woff2 +0 -0
  492. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-26-700-normal.woff2 +0 -0
  493. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-27-400-normal.woff2 +0 -0
  494. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-27-700-normal.woff2 +0 -0
  495. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-28-400-normal.woff2 +0 -0
  496. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-28-700-normal.woff2 +0 -0
  497. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-29-400-normal.woff2 +0 -0
  498. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-29-700-normal.woff2 +0 -0
  499. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-30-400-normal.woff2 +0 -0
  500. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-30-700-normal.woff2 +0 -0
  501. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-31-400-normal.woff2 +0 -0
  502. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-31-700-normal.woff2 +0 -0
  503. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-32-400-normal.woff2 +0 -0
  504. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-32-700-normal.woff2 +0 -0
  505. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-33-400-normal.woff2 +0 -0
  506. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-33-700-normal.woff2 +0 -0
  507. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-34-400-normal.woff2 +0 -0
  508. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-34-700-normal.woff2 +0 -0
  509. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-35-400-normal.woff2 +0 -0
  510. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-35-700-normal.woff2 +0 -0
  511. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-36-400-normal.woff2 +0 -0
  512. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-36-700-normal.woff2 +0 -0
  513. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-37-400-normal.woff2 +0 -0
  514. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-37-700-normal.woff2 +0 -0
  515. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-38-400-normal.woff2 +0 -0
  516. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-38-700-normal.woff2 +0 -0
  517. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-39-400-normal.woff2 +0 -0
  518. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-39-700-normal.woff2 +0 -0
  519. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-4-400-normal.woff2 +0 -0
  520. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-4-700-normal.woff2 +0 -0
  521. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-40-400-normal.woff2 +0 -0
  522. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-40-700-normal.woff2 +0 -0
  523. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-41-400-normal.woff2 +0 -0
  524. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-41-700-normal.woff2 +0 -0
  525. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-42-400-normal.woff2 +0 -0
  526. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-42-700-normal.woff2 +0 -0
  527. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-43-400-normal.woff2 +0 -0
  528. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-43-700-normal.woff2 +0 -0
  529. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-44-400-normal.woff2 +0 -0
  530. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-44-700-normal.woff2 +0 -0
  531. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-45-400-normal.woff2 +0 -0
  532. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-45-700-normal.woff2 +0 -0
  533. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-46-400-normal.woff2 +0 -0
  534. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-46-700-normal.woff2 +0 -0
  535. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-47-400-normal.woff2 +0 -0
  536. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-47-700-normal.woff2 +0 -0
  537. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-48-400-normal.woff2 +0 -0
  538. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-48-700-normal.woff2 +0 -0
  539. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-49-400-normal.woff2 +0 -0
  540. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-49-700-normal.woff2 +0 -0
  541. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-5-400-normal.woff2 +0 -0
  542. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-5-700-normal.woff2 +0 -0
  543. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-50-400-normal.woff2 +0 -0
  544. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-50-700-normal.woff2 +0 -0
  545. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-51-400-normal.woff2 +0 -0
  546. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-51-700-normal.woff2 +0 -0
  547. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-52-400-normal.woff2 +0 -0
  548. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-52-700-normal.woff2 +0 -0
  549. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-53-400-normal.woff2 +0 -0
  550. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-53-700-normal.woff2 +0 -0
  551. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-54-400-normal.woff2 +0 -0
  552. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-54-700-normal.woff2 +0 -0
  553. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-55-400-normal.woff2 +0 -0
  554. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-55-700-normal.woff2 +0 -0
  555. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-56-400-normal.woff2 +0 -0
  556. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-56-700-normal.woff2 +0 -0
  557. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-57-400-normal.woff2 +0 -0
  558. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-57-700-normal.woff2 +0 -0
  559. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-58-400-normal.woff2 +0 -0
  560. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-58-700-normal.woff2 +0 -0
  561. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-59-400-normal.woff2 +0 -0
  562. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-59-700-normal.woff2 +0 -0
  563. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-6-400-normal.woff2 +0 -0
  564. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-6-700-normal.woff2 +0 -0
  565. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-60-400-normal.woff2 +0 -0
  566. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-60-700-normal.woff2 +0 -0
  567. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-61-400-normal.woff2 +0 -0
  568. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-61-700-normal.woff2 +0 -0
  569. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-62-400-normal.woff2 +0 -0
  570. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-62-700-normal.woff2 +0 -0
  571. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-63-400-normal.woff2 +0 -0
  572. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-63-700-normal.woff2 +0 -0
  573. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-64-400-normal.woff2 +0 -0
  574. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-64-700-normal.woff2 +0 -0
  575. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-65-400-normal.woff2 +0 -0
  576. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-65-700-normal.woff2 +0 -0
  577. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-66-400-normal.woff2 +0 -0
  578. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-66-700-normal.woff2 +0 -0
  579. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-67-400-normal.woff2 +0 -0
  580. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-67-700-normal.woff2 +0 -0
  581. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-68-400-normal.woff2 +0 -0
  582. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-68-700-normal.woff2 +0 -0
  583. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-69-400-normal.woff2 +0 -0
  584. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-69-700-normal.woff2 +0 -0
  585. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-70-400-normal.woff2 +0 -0
  586. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-70-700-normal.woff2 +0 -0
  587. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-71-400-normal.woff2 +0 -0
  588. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-71-700-normal.woff2 +0 -0
  589. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-72-400-normal.woff2 +0 -0
  590. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-72-700-normal.woff2 +0 -0
  591. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-73-400-normal.woff2 +0 -0
  592. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-73-700-normal.woff2 +0 -0
  593. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-74-400-normal.woff2 +0 -0
  594. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-74-700-normal.woff2 +0 -0
  595. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-75-400-normal.woff2 +0 -0
  596. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-75-700-normal.woff2 +0 -0
  597. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-76-400-normal.woff2 +0 -0
  598. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-76-700-normal.woff2 +0 -0
  599. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-77-400-normal.woff2 +0 -0
  600. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-77-700-normal.woff2 +0 -0
  601. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-78-400-normal.woff2 +0 -0
  602. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-78-700-normal.woff2 +0 -0
  603. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-79-400-normal.woff2 +0 -0
  604. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-79-700-normal.woff2 +0 -0
  605. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-80-400-normal.woff2 +0 -0
  606. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-80-700-normal.woff2 +0 -0
  607. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-81-400-normal.woff2 +0 -0
  608. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-81-700-normal.woff2 +0 -0
  609. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-82-400-normal.woff2 +0 -0
  610. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-82-700-normal.woff2 +0 -0
  611. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-83-400-normal.woff2 +0 -0
  612. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-83-700-normal.woff2 +0 -0
  613. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-84-400-normal.woff2 +0 -0
  614. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-84-700-normal.woff2 +0 -0
  615. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-85-400-normal.woff2 +0 -0
  616. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-85-700-normal.woff2 +0 -0
  617. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-86-400-normal.woff2 +0 -0
  618. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-86-700-normal.woff2 +0 -0
  619. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-87-400-normal.woff2 +0 -0
  620. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-87-700-normal.woff2 +0 -0
  621. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-88-400-normal.woff2 +0 -0
  622. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-88-700-normal.woff2 +0 -0
  623. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-89-400-normal.woff2 +0 -0
  624. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-89-700-normal.woff2 +0 -0
  625. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-90-400-normal.woff2 +0 -0
  626. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-90-700-normal.woff2 +0 -0
  627. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-91-400-normal.woff2 +0 -0
  628. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-91-700-normal.woff2 +0 -0
  629. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-97-400-normal.woff2 +0 -0
  630. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-97-700-normal.woff2 +0 -0
  631. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-98-400-normal.woff2 +0 -0
  632. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-98-700-normal.woff2 +0 -0
  633. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-99-400-normal.woff2 +0 -0
  634. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-99-700-normal.woff2 +0 -0
  635. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-cyrillic-400-normal.woff2 +0 -0
  636. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-cyrillic-700-normal.woff2 +0 -0
  637. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-latin-400-normal.woff2 +0 -0
  638. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-latin-700-normal.woff2 +0 -0
  639. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-latin-ext-400-normal.woff2 +0 -0
  640. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-latin-ext-700-normal.woff2 +0 -0
  641. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-vietnamese-400-normal.woff2 +0 -0
  642. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/fonts/noto-sans-sc/files/noto-sans-sc-vietnamese-700-normal.woff2 +0 -0
  643. /package/node_modules/@allyhub-next/{runtime → stage-page}/dist/host.d.ts +0 -0
@@ -1,6 +1,6 @@
1
1
  /*! AllyHub. Copyright (c) 2026 AllyHub, Inc. All rights reserved. Use is subject to LICENSE.md. */
2
- import{readFile as Y}from"node:fs/promises";import{join as A,posix as B,relative as V}from"node:path";import{fileURLToPath as W}from"node:url";import{z as h}from"zod";import{modelInfo as q}from"@allyhub-next/build";import{COMPONENTS_DIR as I}from"@allyhub-next/formats";import{EXIT as f}from"@allyhub-next/protocol";import{ASSET_DEFAULTS as G,ASSET_TYPES as K,PolyHaven as X,PolyHavenError as Z,RegistryError as J,applyAdd as T,fetchBakes as Q,folderRegistry as D,planAdd as L,searchIndex as O}from"@allyhub-next/registry";import{cacheHome as ee}from"@allyhub-next/runtimes";import{CLI_VERSION as te}from"../cli-version.js";import{CommandError as j,defineCommand as C}from"../command.js";import{projectRoot as ne}from"../project.js";import{dir as oe}from"../fields.js";import{resourcesIndex as P}from"../resources.js";const _=W(new URL(".",import.meta.resolve("@allyhub-next/components/registry.json"))),se=Object.keys(K),x=["component","3d-model","scenery","skill","template","lib","@polyhaven"],ae={"allyhub:component":"component","allyhub:model":"3d-model","allyhub:scenery":"scenery","allyhub:skill":"skill","allyhub:template":"template","allyhub:lib":"lib"},H=e=>ae[e]??e.replace(/^allyhub:/u,""),E=e=>`${H(e.type)}/${e.name}`;function ie(e){const n=/^(@?[a-z0-9-]+)\/(.+)$/u.exec(e),a=x.find(d=>d===n?.[1]);if(a===void 0||n?.[2]===void 0)throw new j("usage",n===null?`Name what to add as <type>/<name>: ${e} has no type.`:`${n[1]??""} is not a type: name what to add as <type>/<name>.`,{exit:f.usage,hint:`Types: ${x.join(", ")} (3d-model/monitor, scenery/home-desk-day, skill/product-demos, component/caption-line, @polyhaven/<id>). allyhub add lists every one.`});return{type:a,name:n[2]}}const le={"allyhub:model":"3D models","allyhub:scenery":"3D sceneries","allyhub:skill":"Skills","allyhub:template":"Templates","allyhub:component":"Components","allyhub:lib":"Libs (added with what uses them)"};function F(e,n){if(e.from==="none")return["AllyHub's resources (models, sceneries) could not be read: check the connection."];const a=n??e.index?.items??[],d=Math.max(0,...a.map(o=>E(o).length)),r=[`AllyHub's resources (allyhub add <type>/<name> copies one with what it needs, its Poly Haven assets and its baked light)${e.from==="stale"?", as last read (the registry cannot be read now)":""}:`];for(const[o,p]of Object.entries(le)){const c=a.filter(u=>u.type===o);c.length!==0&&r.push(` ${p}:`,...c.map(u=>` ${E(u).padEnd(d)} ${u.description}`))}return r}const N=20,z=e=>e.replace(/\.(?:ts|js)$/u,"").replaceAll(/[A-Z]/gu,n=>`-${n.toLowerCase()}`).replace(/^-/u,"");function M(e){return e instanceof J?new j(e.code,e.message,{exit:e.code==="conflict"?f.conflict:e.code==="no-item"?f.notFound:f.failed,...e.hint===void 0?{}:{hint:e.hint}}):e instanceof Z?new j(e.code,e.message,{exit:e.code==="network"?f.platform:e.code==="not-found"?f.notFound:e.code==="bad-choice"?f.usage:f.failed,...e.hint===void 0?{}:{hint:e.hint}}):e}const R=e=>new X({userAgent:`AllyHub/${te} (+https://allyhub.com)`,cacheDir:A(ee(e.env),"polyhaven"),...e.env.ALLYHUB_POLYHAVEN_API?{api:e.env.ALLYHUB_POLYHAVEN_API}:{}}),k=e=>`${e.toFixed(3)} m`;function de(e){const n=[e.type,e.category,e.size?`${k(e.size.width)} wide, ${k(e.size.depth)} deep, ${k(e.size.height)} tall`:void 0,e.covers?`one tile covers ${e.covers.map(k).join(" × ")}`:void 0,e.polycount!==void 0?`${e.polycount.toLocaleString("en")} polygons`:void 0,e.maxResolution?`up to ${String(e.maxResolution[0])} px`:void 0,e.authors.length>0?`by ${e.authors.join(", ")}`:void 0].filter(a=>a!==void 0);return` @polyhaven/${e.id}: ${e.name} (${n.join("; ")})
3
- found in ${e.matchedIn.join(", ")||"everything"}; tags ${e.tags.join(", ")}`}async function U(e,n){const a=[`${n.name} from Poly Haven (CC0, by ${n.source.authors.join(", ")||"its authors"}): ${String(n.files.length)} files in ${n.dir}/, ${n.fetched>0?`${String(n.fetched)} fetched`:"all already there"}. Records: ${n.records.join(", ")}.`];if(n.type==="model"){const r=n.main[0]??"",o=await q(e,r,await Y(A(e,r))),p=o.bounds;return a.push(p?`Measured: ${p.size.map(c=>c.toFixed(3)).join(" × ")} m along x, y (up), z; from ${p.min.map(c=>c.toFixed(3)).join(", ")} to ${p.max.map(c=>c.toFixed(3)).join(", ")}.`:`Not measured: ${o.contentsMissing??"no contents"}.`,...o.missing.length>0?[`Missing: ${o.missing.join(", ")}.`]:[],`In a scenery: const m = await w.load("${r}");`),{lines:a,model:o}}if(n.type==="hdri")return a.push(`In a scenery: await w.environment("${n.main[0]??""}", { background: true });`),{lines:a};const d=n.covers;return a.push(d&&d.length>=2?`One tile covers ${k(d[0]??0)} × ${k(d[1]??0)} (Poly Haven's dimensions): a surface's repeat is its size over that.`:"Poly Haven gives no size for one tile.",...n.main.map((r,o)=>{const p=n.maps?.[o]??"";return` ${p}: await w.texture("${r}"${p==="diffuse"?"":', { colorSpace: "linear" }'})`})),{lines:a}}export const add=C({name:"add",summary:"Adds to the project what AllyHub and Poly Haven have, each named <type>/<name>: a starter component, a 3D model, a 3D scenery, a skill or a template from AllyHub's registry, or a CC0 model, HDRI or texture from Poly Haven; alone it lists everything AllyHub has, by type",input:h.strictObject({name:h.array(h.string()).optional().describe("What to add, each <type>/<name>: component/caption-line, 3d-model/monitor, scenery/home-desk-demo-day, skill/product-demos (a skill goes in .agents/skills, linked from .claude/skills), template/<name>, lib/<name>, or @polyhaven/<id> (as allyhub add search prints it)"),to:h.string().optional().describe(`The folder the files go in, from the project (default ${I} for a component; for an asset, its kind's folder under assets/media/ and its id)`),force:h.boolean().default(!1).describe("Replace a component's copy the project changed (its changes are lost)"),res:h.string().optional().describe(`An asset's resolution, of its textures or of the HDRI (default ${G.resolution})`),dir:oe}),positional:["name"],output:h.looseObject({}),examples:["allyhub add","allyhub add component/caption-line","allyhub add 3d-model/monitor scenery/home-desk-day","allyhub add @polyhaven/metal_office_desk --res 2k"]},async(e,n)=>{const a=D(_);try{const d=await a.index();if(!e.name||e.name.length===0){const t=Math.max(...d.items.map(y=>`component/${y.name}`.length)),l=await P(n);return{value:{components:d.items,resources:l.index?.items??[]},text:["Starter components (allyhub add component/<name> copies one into components/; allyhub add search <words> finds among everything, Poly Haven's models, HDRIs and textures too):",...d.items.map(y=>` ${`component/${y.name}`.padEnd(t)} ${y.description}`),"",...F(l,void 0)].join(`
2
+ import{readFile as Y}from"node:fs/promises";import{join as A,posix as B,relative as V}from"node:path";import{fileURLToPath as W}from"node:url";import{z as h}from"zod";import{modelInfo as q}from"@allyhub-next/build";import{COMPONENTS_DIR as I}from"@allyhub-next/formats";import{EXIT as f}from"@allyhub-next/protocol";import{ASSET_DEFAULTS as G,ASSET_TYPES as K,PolyHaven as X,PolyHavenError as Z,RegistryError as J,applyAdd as T,fetchBakes as Q,folderRegistry as D,planAdd as L,searchIndex as O}from"@allyhub-next/registry";import{cacheHome as ee}from"@allyhub-next/runtimes";import{CLI_VERSION as te}from"../cli-version.js";import{CommandError as j,defineCommand as C}from"../command.js";import{projectRoot as ne}from"../project.js";import{dir as oe}from"../fields.js";import{resourcesIndex as P}from"../resources.js";const _=W(new URL(".",import.meta.resolve("@allyhub-next/components/registry.json"))),se=Object.keys(K),x=["component","3d-model","scenery","skill","template","lib","@polyhaven"],ae={"allyhub:component":"component","allyhub:model":"3d-model","allyhub:scenery":"scenery","allyhub:skill":"skill","allyhub:template":"template","allyhub:lib":"lib"},H=e=>ae[e]??e.replace(/^allyhub:/u,""),E=e=>`${H(e.type)}/${e.name}`;function ie(e){const n=/^(@?[a-z0-9-]+)\/(.+)$/u.exec(e),a=x.find(d=>d===n?.[1]);if(a===void 0||n?.[2]===void 0)throw new j("usage",n===null?`Name what to add as <type>/<name>: ${e} has no type.`:`${n[1]??""} is not a type: name what to add as <type>/<name>.`,{exit:f.usage,hint:`Types: ${x.join(", ")} (3d-model/monitor, scenery/home-desk-demo-day, skill/product-demos, component/caption-line, @polyhaven/<id>). allyhub add lists every one.`});return{type:a,name:n[2]}}const le={"allyhub:model":"3D models","allyhub:scenery":"3D sceneries","allyhub:skill":"Skills","allyhub:template":"Templates","allyhub:component":"Components","allyhub:lib":"Libs (added with what uses them)"};function F(e,n){if(e.from==="none")return["AllyHub's resources (models, sceneries) could not be read: check the connection."];const a=n??e.index?.items??[],d=Math.max(0,...a.map(o=>E(o).length)),r=[`AllyHub's resources (allyhub add <type>/<name> copies one with what it needs, its Poly Haven assets and its baked light)${e.from==="stale"?", as last read (the registry cannot be read now)":""}:`];for(const[o,p]of Object.entries(le)){const c=a.filter(u=>u.type===o);c.length!==0&&r.push(` ${p}:`,...c.map(u=>` ${E(u).padEnd(d)} ${u.description}`))}return r}const N=20,z=e=>e.replace(/\.(?:ts|js)$/u,"").replaceAll(/[A-Z]/gu,n=>`-${n.toLowerCase()}`).replace(/^-/u,"");function M(e){return e instanceof J?new j(e.code,e.message,{exit:e.code==="conflict"?f.conflict:e.code==="no-item"?f.notFound:f.failed,...e.hint===void 0?{}:{hint:e.hint}}):e instanceof Z?new j(e.code,e.message,{exit:e.code==="network"?f.platform:e.code==="not-found"?f.notFound:e.code==="bad-choice"?f.usage:f.failed,...e.hint===void 0?{}:{hint:e.hint}}):e}const R=e=>new X({userAgent:`AllyHub/${te} (+https://allyhub.com)`,cacheDir:A(ee(e.env),"polyhaven"),...e.env.ALLYHUB_POLYHAVEN_API?{api:e.env.ALLYHUB_POLYHAVEN_API}:{}}),k=e=>`${e.toFixed(3)} m`;function de(e){const n=[e.type,e.category,e.size?`${k(e.size.width)} wide, ${k(e.size.depth)} deep, ${k(e.size.height)} tall`:void 0,e.covers?`one tile covers ${e.covers.map(k).join(" × ")}`:void 0,e.polycount!==void 0?`${e.polycount.toLocaleString("en")} polygons`:void 0,e.maxResolution?`up to ${String(e.maxResolution[0])} px`:void 0,e.authors.length>0?`by ${e.authors.join(", ")}`:void 0].filter(a=>a!==void 0);return` @polyhaven/${e.id}: ${e.name} (${n.join("; ")})
3
+ found in ${e.matchedIn.join(", ")||"everything"}; tags ${e.tags.join(", ")}`}async function U(e,n){const a=[`${n.name} from Poly Haven (CC0, by ${n.source.authors.join(", ")||"its authors"}): ${String(n.files.length)} files in ${n.dir}/, ${n.fetched>0?`${String(n.fetched)} fetched`:"all already there"}. Records: ${n.records.join(", ")}.`];if(n.type==="model"){const r=n.main[0]??"",o=await q(e,r,await Y(A(e,r))),p=o.bounds;return a.push(p?`Measured: ${p.size.map(c=>c.toFixed(3)).join(" × ")} m along x, y (up), z; from ${p.min.map(c=>c.toFixed(3)).join(", ")} to ${p.max.map(c=>c.toFixed(3)).join(", ")}.`:`Not measured: ${o.contentsMissing??"no contents"}.`,...o.missing.length>0?[`Missing: ${o.missing.join(", ")}.`]:[],`In a scenery: const m = await w.load("${r}");`),{lines:a,model:o}}if(n.type==="hdri")return a.push(`In a scenery: await w.environment("${n.main[0]??""}", { background: true });`),{lines:a};const d=n.covers;return a.push(d&&d.length>=2?`One tile covers ${k(d[0]??0)} × ${k(d[1]??0)} (Poly Haven's dimensions): a surface's repeat is its size over that.`:"Poly Haven gives no size for one tile.",...n.main.map((r,o)=>{const p=n.maps?.[o]??"";return` ${p}: await w.texture("${r}"${p==="diffuse"?"":', { colorSpace: "linear" }'})`})),{lines:a}}export const add=C({name:"add",summary:"Adds to the project what AllyHub and Poly Haven have, each named <type>/<name>: a starter component, a 3D model, a 3D scenery, a skill or a template from AllyHub's registry, or a CC0 model, HDRI or texture from Poly Haven; alone it lists everything AllyHub has, by type",input:h.strictObject({name:h.array(h.string()).optional().describe("What to add, each <type>/<name>: component/caption-line, 3d-model/monitor, scenery/home-desk-demo-day, skill/product-demos (a skill goes in .agents/skills, linked from .claude/skills), template/<name>, lib/<name>, or @polyhaven/<id> (as allyhub add search prints it)"),to:h.string().optional().describe(`The folder the files go in, from the project (default ${I} for a component; for an asset, its kind's folder under assets/media/ and its id)`),force:h.boolean().default(!1).describe("Replace a component's copy the project changed (its changes are lost)"),res:h.string().optional().describe(`An asset's resolution, of its textures or of the HDRI (default ${G.resolution})`),dir:oe}),positional:["name"],output:h.looseObject({}),examples:["allyhub add","allyhub add component/caption-line","allyhub add 3d-model/monitor scenery/home-desk-demo-day","allyhub add @polyhaven/metal_office_desk --res 2k"]},async(e,n)=>{const a=D(_);try{const d=await a.index();if(!e.name||e.name.length===0){const t=Math.max(...d.items.map(y=>`component/${y.name}`.length)),l=await P(n);return{value:{components:d.items,resources:l.index?.items??[]},text:["Starter components (allyhub add component/<name> copies one into components/; allyhub add search <words> finds among everything, Poly Haven's models, HDRIs and textures too):",...d.items.map(y=>` ${`component/${y.name}`.padEnd(t)} ${y.description}`),"",...F(l,void 0)].join(`
4
4
  `)}}const r=e.name.map(ie),o=await ne(n.cwd,e.dir),p=new Set(d.items.map(t=>t.name)),c=t=>t.type==="component"&&p.has(z(t.name)),u=r.filter(c).map(t=>z(t.name)),v=r.filter(t=>t.type==="@polyhaven").map(t=>t.name),g=r.filter(t=>t.type!=="@polyhaven"&&!c(t)),b=g.length>0?await P(n):void 0;for(const t of g){const l=b?.index?.items.find(y=>y.name===t.name);if(!l)throw new j("no-item",`There is no ${t.type}/${t.name}.`,{exit:f.notFound,hint:b?.from==="none"?"AllyHub's registry could not be read: check the connection.":`allyhub add search --type ${t.type} lists them.`});if(H(l.type)!==t.type)throw new j("usage",`${t.name} is a ${H(l.type)}, not a ${t.type}.`,{exit:f.usage,hint:`allyhub add ${E(l)}`})}const w=g.map(t=>t.name),i=[],S={};if(u.length>0){const t=e.to??I,l=await L(a,u,{root:o,dir:t,force:e.force});await T(o,l);const y=m=>m==="up to date"?"Up to date":m==="added"?"Added":"Replaced";i.push(...l.files.map(m=>`${y(m.status)} ${m.path}`));const s=l.items.find(m=>m.name===u[0]),$=s?.files[0]?.target.replaceAll("{dir}",t);if(s&&$){const m=V(A(o,"name"),A(o,$)).split("\\").join("/").replace(/\.ts$/u,".js");i.push(`Import it from an item's entry file (<name>/video.ts): import { ${s.title} } from "${m.startsWith(".")?m:`./${m}`}"; one "../" more for each folder the item is deeper.`,"The file is the project's: change it as you like. allyhub add component/<name> --force puts the registry's back.")}l.missing.length>0&&i.push(`It needs packages the project does not declare: ${l.missing.join(", ")}.`),S.components=l.files.map(m=>({item:m.item,path:m.path,status:m.status})),S.missing=l.missing}if(b&&w.length>0){const t=await L(b.source,w,{root:o,dir:".",force:e.force});await T(o,t),i.length>0&&i.push(""),i.push(...t.files.map(s=>`${s.status==="up to date"?"Up to date":s.status==="added"?"Added":"Replaced"} ${s.path}`));const l=R(n);for(const s of t.assets){const $=await l.add(s.id,{root:o,...s.resolution===void 0?{}:{resolution:s.resolution},...s.maps===void 0?{}:{maps:s.maps}});i.push(...(await U(o,$)).lines)}const y=await Q(o,t.bakes);i.push(...y.map(s=>`${s.status==="added"?"Downloaded":"Up to date"} the baked light for ${s.bake.scenery}: ${s.path}`),"The files are the project's: change them as you like (a changed scenery is drawn unbaked until allyhub scenery bake bakes it again). allyhub add <type>/<name> --force puts the registry's back."),S.resources={files:t.files.map(s=>({item:s.item,path:s.path,status:s.status})),assets:t.assets,bakes:y.map(s=>({path:s.path,status:s.status}))}}if(v.length>0){const t=R(n),l=[];for(const y of v){const s=await t.add(y,{root:o,...e.to===void 0||u.length>0?{}:{to:B.normalize(e.to)},...e.res===void 0?{}:{resolution:e.res}}),$=await U(o,s);i.length>0&&i.push(""),i.push(...$.lines),l.push({...s,...$.model===void 0?{}:{model:$.model}})}S.assets=l}return{value:S,text:i.join(`
5
5
  `)}}catch(d){throw M(d)}}),addSearch=C({name:"add search",summary:"Finds the starter components, AllyHub's resources (models, sceneries) and Poly Haven's CC0 models, HDRIs and textures whose names, tags, categories or descriptions hold every word, each with where its words were found; with no words, lists every one",input:h.strictObject({words:h.array(h.string()).default([]).describe("The words to find (a word may start one of theirs); none lists every one"),type:h.array(h.enum(x)).optional().describe(`Only these types (default all): ${x.join(", ")} (@polyhaven: Poly Haven's models, HDRIs and textures)`),all:h.boolean().default(!1).describe(`Every match, not only the first ${String(N)} Poly Haven assets`)}),positional:["words"],output:h.looseObject({}),examples:["allyhub add search --type 3d-model",'allyhub add search "office desk" --type @polyhaven',"allyhub add search caption --type component"]},async(e,n)=>{const a=e.words.join(" ").trim(),d=a===""?"":` hold "${a}"`;try{const r=e.type??x,o=r.includes("component")?O(await D(_).index(),a):[],p=r.filter(i=>i!=="@polyhaven"),c=p.length>0?await P(n):void 0,u=c?.index?O(c.index,a).filter(i=>p.includes(H(i.type))):[],v=r.includes("@polyhaven")?se:[],{found:g,total:b}=v.length>0?await R(n).search(a,v):{found:[],total:0},w=e.all?g:g.slice(0,N);return{value:{query:a,components:o,resources:u,assets:{total:b,matches:g.length,found:w}},text:[...r.includes("component")?[`Starter components: ${String(o.length)}${d}.`,...o.map(i=>` component/${i.name} (${i.title}): ${i.description}`)]:[],...c?c.from==="none"?F(c,[]):[`AllyHub's resources: ${String(u.length)}${d}${c.from==="stale"?" (as last read)":""}.`,...u.map(i=>` ${E(i)} (${i.title}): ${i.description}`)]:[],...v.length>0?[`From Poly Haven (CC0): ${String(g.length)} of ${String(b)} assets${d}${w.length<g.length?`; the first ${String(w.length)} (--all for every one)`:""}.`,...w.map(de)]:[],"","Add one: allyhub add <type>/<name>"].join(`
6
6
  `)}}catch(r){throw M(r)}});
@@ -1,6 +1,6 @@
1
1
  /*! AllyHub. Copyright (c) 2026 AllyHub, Inc. All rights reserved. Use is subject to LICENSE.md. */
2
- import{z as e}from"zod";import{billingSummary as f,accessToken as w,hostsText as y,openBrowser as v,readCredentials as m,signIn as $,signInDevice as S,signInInBackground as I,signedInAs as k,signOut as A,SIGN_IN_WAIT_MS as p}from"@allyhub-next/cloud";import{API_KEY_ENV as b,DEVICES_PAGE_PATH as O,EXIT as _}from"@allyhub-next/protocol";import{defineCommand as d}from"../command.js";import{cloudOf as g,cloudWork as h}from"./cloud.js";const x=e.looseObject({url:e.string()});export const authLogin=d({name:"auth login",summary:"Sign this computer in to AllyHub, for the cloud tools; once per computer, shared with AllyHub Studio",input:e.strictObject({wait:e.boolean().optional().describe(`Wait here for the browser (default in a terminal); --no-wait waits ${String(p/6e4)} minutes in the background and returns at once (default for an agent), then allyhub auth status says when it is done`),browser:e.boolean().default(!0).describe("Open the browser; --no-browser only prints the address"),device:e.boolean().default(!1).describe("Sign in with a code entered in a browser elsewhere (RFC 8628's device flow), for a computer with no browser of its own")}),output:e.looseObject({status:e.enum(["signed-in","waiting"]),email:e.string().optional(),url:e.string().optional(),hosts:x}),mcp:!1,examples:["allyhub auth login","allyhub auth login --no-wait --no-browser","allyhub auth login --device"]},(u,i)=>h(async()=>{const t=g(i),n={url:t.url,from:t.config.from},s=`Signing in to AllyHub: ${y(t.config)}.`,o=await k(t);if(o)return{value:{status:"signed-in",email:o.email,hosts:n},text:`This computer is signed in to AllyHub as ${o.email}.`};if(u.device){const a=await S(t,c=>{i.progress(`${s}
3
- On any computer, open ${c.verification_uri} and enter ${c.user_code}${c.verification_uri_complete===void 0?"":` (or open ${c.verification_uri_complete})`}.`)});return{value:{status:"signed-in",email:a.email,hosts:n},text:`Signed in as ${a.email}.`}}const r=a=>{u.browser&&v(a,i.env)};if(u.wait===!1||u.wait===void 0&&!process.stdout.isTTY){const a=await I(t,i.env);return r(a),{value:{status:"waiting",url:a,hosts:n},text:[s,"Sign in in the browser (opened, or open this address):",` ${a}`,`It waits ${String(p/6e4)} minutes in the background; allyhub auth status says when it is done.`].join(`
4
- `)}}const l=await $(t,a=>{i.progress(`${s}
2
+ import{z as e}from"zod";import{billingSummary as w,hostsText as p,openBrowser as b,readCredentials as f,signIn as y,signInDevice as $,signInInBackground as v,signedInAs as S,SIGN_IN_WAIT_MS as d}from"@allyhub-next/cloud";import{API_KEY_ENV as I,EXIT as _}from"@allyhub-next/protocol";import{defineCommand as h}from"../command.js";import{cloudOf as g,cloudWork as m}from"./cloud.js";const x=e.looseObject({url:e.string()});export const authLogin=h({name:"auth login",summary:"Sign this computer in to AllyHub, for the cloud tools; once per computer, shared with AllyHub Studio",input:e.strictObject({wait:e.boolean().optional().describe(`Wait here for the browser (default in a terminal); --no-wait waits ${String(d/6e4)} minutes in the background and returns at once (default for an agent), then allyhub auth status says when it is done`),browser:e.boolean().default(!0).describe("Open the browser; --no-browser only prints the address"),device:e.boolean().default(!1).describe("Sign in with a code entered in a browser elsewhere (RFC 8628's device flow), for a computer with no browser of its own")}),output:e.looseObject({status:e.enum(["signed-in","waiting"]),email:e.string().optional(),url:e.string().optional(),hosts:x}),examples:["allyhub auth login","allyhub auth login --no-wait --no-browser","allyhub auth login --device"]},(u,s)=>m(async()=>{const t=g(s),i={url:t.url,from:t.config.from},r=`Signing in to AllyHub: ${p(t.config)}.`,o=await S(t);if(o)return{value:{status:"signed-in",email:o.email,hosts:i},text:`This computer is signed in to AllyHub as ${o.email}.`};if(u.device){const n=await $(t,c=>{s.progress(`${r}
3
+ On any computer, open ${c.verification_uri} and enter ${c.user_code}${c.verification_uri_complete===void 0?"":` (or open ${c.verification_uri_complete})`}.`)});return{value:{status:"signed-in",email:n.email,hosts:i},text:`Signed in as ${n.email}.`}}const a=n=>{u.browser&&b(n,s.env)};if(u.wait===!1||u.wait===void 0&&!process.stdout.isTTY){const n=await v(t,s.env);return a(n),{value:{status:"waiting",url:n,hosts:i},text:[r,"Sign in in the browser (opened, or open this address):",` ${n}`,`It waits ${String(d/6e4)} minutes in the background; allyhub auth status says when it is done.`].join(`
4
+ `)}}const l=await y(t,n=>{s.progress(`${r}
5
5
  Sign in in your browser. If it did not open:
6
- ${a}`),r(a)});return{value:{status:"signed-in",email:l.email,hosts:n},text:`Signed in as ${l.email}. AllyHub Studio on this computer is signed in too.`}})),authStatus=d({name:"auth status",summary:"Whether this computer is signed in to AllyHub, as whom, and the account's credits; exits 4 when it is not",input:e.strictObject({}),output:e.looseObject({signedIn:e.boolean(),source:e.enum(["env","oauth"]).optional(),organization:e.string().optional(),email:e.string().optional(),url:e.string(),credits:e.number().optional()})},(u,i)=>h(async()=>{const t=g(i),n=await t.key();if(!n)return{value:{signedIn:!1,url:t.url},text:"Not signed in. Run allyhub auth login.",exit:_.auth};const s=await f(t),o=n.source==="oauth"?await m(t.config):void 0,r=o?.account.organization,l=n.source==="env"?`with the key in ${b}`:`as ${o?.account.email??"this computer's account"}${r===void 0?"":` in ${r.name||"their own organization"}`}`;return{value:{signedIn:!0,source:n.source,...o?{email:o.account.email}:{},...r===void 0?{}:{organization:r.id},url:t.url,credits:s.credits},text:`Signed in ${l} at ${t.url}. Credits: ${String(s.credits)}.`}})),authLogout=d({name:"auth logout",summary:"Sign this computer out of AllyHub: the CLI and AllyHub Studio here, which share the sign-in",input:e.strictObject({}),output:e.looseObject({signedOut:e.boolean(),revoked:e.boolean().optional(),apiKeyEnv:e.boolean()})},(u,i)=>h(async()=>{const t=g(i),n=await m(t.config),s=t.config.apiKey!==void 0,o=s?` ${b} is still set, and allyhub uses it.`:"";if(!n)return{value:{signedOut:!1,apiKeyEnv:s},text:`This computer was not signed in.${o}`};try{await A(t.config,n)}catch(r){const l=`${t.url}${O}`;return{value:{signedOut:!0,revoked:!1,devices:l,apiKeyEnv:s},text:`Signed out here, but AllyHub could not be told (${r.message}). Sign this computer out at ${l}.${o}`}}return{value:{signedOut:!0,revoked:!0,apiKeyEnv:s},text:`Signed out of AllyHub: the CLI and AllyHub Studio on this computer.${o}`}})),authToken=d({name:"auth token",summary:"An access token for another program on this computer (Studio, an MCP server, a script), from the computer's sign-in and made anew before it ends, as gh auth token gives one",input:e.strictObject({}),output:e.looseObject({accessToken:e.string(),source:e.enum(["env","oauth"]),expiresAt:e.string().optional(),account:e.looseObject({id:e.string(),email:e.string(),name:e.string().optional()}).optional()}),examples:['curl -H "Authorization: Bearer $(allyhub auth token)" …']},(u,i)=>h(async()=>{const t=await w(g(i));return{value:{...t},text:t.accessToken}}));
6
+ ${n}`),a(n)});return{value:{status:"signed-in",email:l.email,hosts:i},text:`Signed in as ${l.email}. AllyHub Studio on this computer is signed in too.`}})),authStatus=h({name:"auth status",summary:"Whether this computer is signed in to AllyHub, as whom, and the account's credits; exits 4 when it is not",input:e.strictObject({}),output:e.looseObject({signedIn:e.boolean(),source:e.enum(["env","oauth"]).optional(),organization:e.string().optional(),email:e.string().optional(),url:e.string(),credits:e.number().optional()})},(u,s)=>m(async()=>{const t=g(s),i=await t.key();if(!i)return{value:{signedIn:!1,url:t.url},text:"Not signed in. Run allyhub auth login.",exit:_.auth};const r=await w(t),o=i.source==="oauth"?await f(t.config):void 0,a=o?.account.organization,l=i.source==="env"?`with the key in ${I}`:`as ${o?.account.email??"this computer's account"}${a===void 0?"":` in ${a.name||"their own organization"}`}`;return{value:{signedIn:!0,source:i.source,...o?{email:o.account.email}:{},...a===void 0?{}:{organization:a.id},url:t.url,credits:r.credits},text:`Signed in ${l} at ${t.url}. Credits: ${String(r.credits)}.`}}));
@@ -1,11 +1,10 @@
1
1
  /*! AllyHub. Copyright (c) 2026 AllyHub, Inc. All rights reserved. Use is subject to LICENSE.md. */
2
- import{readFile as I}from"node:fs/promises";import{join as D,resolve as x}from"node:path";import{z as n}from"zod";import{callTool as F,findTool as N,loadCatalog as p,resumeJob as L,uploadFiles as M}from"@allyhub-next/cloud";import{WORK_DIR as E}from"@allyhub-next/formats";import{EXIT as h}from"@allyhub-next/protocol";import{CommandError as w,defineCommand as m}from"../command.js";import{optionName as H}from"../args.js";import{commandHelp as U}from"../help.js";import{requiredMissing as B,toolInput as K,toolOptions as _}from"../tool-options.js";import{cloudOf as u,cloudWork as f,placeFrom as q,plural as g}from"./cloud.js";const G=8e3,c={input:n.string().optional().describe("The input as JSON, or a file of it: the whole of it, or the fields no option gives; an option given beside it wins"),file:n.string().optional().describe("The path of the file it makes (without an extension it takes the result's); the same call with the same input then keeps it, calling nothing, and while its call works waits for that call; default a folder under .allyhub/work/"),force:n.boolean().default(!1).describe("With --file: call even when the file was made from this input, and replace a file that has no record"),wait:n.boolean().default(!0).describe("Wait for a long tool (an audit, a video model); --no-wait returns its call at once"),resume:n.string().optional().describe("Wait for a call of this tool this computer made (from --no-wait, or a call that stopped waiting), and download its file")},$=(t,a)=>new w("usage",t,{exit:h.usage,...a===void 0?{}:{hint:a}}),R=t=>{const a=t.reduce((e,r)=>r.map((s,i)=>Math.max(e[i]??0,s.length)),[]);return t.map(e=>` ${e.map((r,s)=>s===e.length-1?r:r.padEnd(a[s]??0)).join(" ")}`.trimEnd())};function T(t){return m({name:t.id,summary:`${t.title}: ${t.description} Lists the tools, each a command`,input:n.strictObject({fresh:n.boolean().default(!1).describe("Read the catalog from AllyHub again, not the copy kept an hour")}),output:n.looseObject({work:n.string(),tools:n.array(n.looseObject({name:n.string()}))}),examples:[`allyhub ${t.id}`,`allyhub ${t.id} --json`]},(a,e)=>f(async()=>{const s=(await p(u(e),{refresh:a.fresh})).tools.filter(i=>i.work===t.id).sort((i,o)=>i.name.localeCompare(o.name));return{value:{work:t.id,title:t.title,tools:s.map(i=>({name:i.name,title:i.title,description:i.description,long:i.long}))},text:[`${t.title} (${g(s.length,"tool")}):`,...R(s.map(i=>[i.name,i.title])),"",`Each costs credits when it worked; a failed call is free. allyhub help ${t.id} <tool> shows a tool's options and how its credits are counted.`].join(`
3
- `)}}))}function z(t,a=5,e=160){const r=i=>{const o=i===void 0?"undefined":JSON.stringify(i);return o.length>e?`${o.slice(0,e-1)}…`:o},s=(i,o)=>[`${i?`${i}: `:""}${g(o.length,"item")}${o.length>a?`, the first ${String(a)}:`:":"}`,...o.slice(0,a).map((l,b)=>` [${String(b)}] ${r(l)}`)];return Array.isArray(t)?s("",t):typeof t!="object"||t===null?[r(t)]:Object.entries(t).flatMap(([i,o])=>Array.isArray(o)?s(i,o):[`${i}: ${r(o)}`])}function W(t,a){if("jobId"in t)return[`${t.tool} is still working (call ${t.jobId}).`,`Wait for it: allyhub ${a} --resume ${t.jobId}${t.file===void 0?"":" (or the same command again: it waits for this call)"}`].join(`
4
- `);if(t.kept)return[`Kept ${t.file??""}: ${t.tool} made it from this same input on ${t.kept.at} (${t.gen??""}).`,"Nothing was called or charged. --force makes it again."].join(`
5
- `);const e=JSON.stringify(t.output,null,2);return[e.length<=G?e:[`Output: ${String(Math.round(Buffer.byteLength(e)/1024))} KB of JSON, in short (--json prints it whole):`,...z(t.output)].join(`
6
- `),...t.file?[`File: ${t.file}${t.replaced?" (replaced: it was made from another input)":""}`]:[],...t.words?[`Words: ${t.words} (when each word is said: a part can say a stretch of the file)`]:[],...t.gen?[`Record: ${t.gen} (move it with the file)`]:[],`Credits used: ${t.credits===void 0?"not reported":String(t.credits)}`].join(`
7
- `)}const P=t=>{const a=Math.max(0,Math.round(t));return`${String(Math.floor(a/60))}:${String(a%60).padStart(2,"0")}`},X=t=>t!==null&&typeof t=="object"&&!Array.isArray(t);async function Q(t,a){const e=t.trim().startsWith("{"),r=e?t:await I(x(a.cwd,t),"utf8").catch(i=>{throw new w("not-found",`--input: cannot read ${t}: ${i.message}`,{exit:h.notFound,hint:"Give a JSON object, or a file of one."})});let s;try{s=JSON.parse(r)}catch{s=void 0}if(!X(s))throw $(`--input: ${e?"the text":t} is not a JSON object.`,`Give '{"field": …}', or a file of it.`);return s}export function toolCommand(t){const a=`${t.work} ${t.name}`,e=_(t.input,Object.keys(c)),r=n.strictObject({...e.shape,...c,input:c.input.describe(e.inputOnly.length?`${c.input.description??""}. Fields only it gives: ${e.inputOnly.join(", ")}`:c.input.description??"")}),s=[...e.fields].filter(([,i])=>e.required.includes(i)).map(([i,o])=>`--${H(i)} <${o}>`);return{spec:{name:a,summary:t.description,input:r,output:n.looseObject({tool:n.string(),output:n.record(n.string(),n.unknown()).optional(),credits:n.number().optional(),file:n.string().optional(),gen:n.string().optional(),words:n.string().optional(),jobId:n.string().optional()}),examples:[`allyhub ${[a,...s].join(" ")}`]},about:{lines:[t.title,"","A call is charged once, when it worked, as the description says; a failed call is free.",...t.long?["A long tool: the command waits for it (--no-wait returns its call, --resume waits again)."]:[]],value:{work:t.work,title:t.title,long:t.long,inputSchema:t.input,outputSchema:t.output}},run:(i,o)=>f(async()=>{const l=i,b=i,k=u(o),j=await q(o),y=K(e,b,l.input===void 0?{}:await Q(l.input,o));let O=0;const S={base:j,signal:o.signal,onRunning:d=>{Date.now()-O<3e4||(O=Date.now(),o.progress(`${t.name}: working · ${P((Date.now()-Date.parse(d.createdAt))/1e3)} (call ${d.id})`))},onRetry:(d,C,J)=>{o.progress(`${t.name}: ${C.message}; reading call ${d} again in ${String(J)} s`)}};if(l.resume!==void 0){if(Object.keys(y).length>0||l.file!==void 0)throw $("--resume waits for a call as it was made: give it no input or --file.");const d=await L(k,l.resume,{...S,tool:t.name});return{value:{...d},text:W(d,a)}}const v=B(e,y);if(v.length>0)throw $(`${t.name} needs ${v.join(", ")}.`,`allyhub help ${a} shows its options.`);const A=await F(k,t.name,y,{...S,outDir:D(j,E,t.work,t.name),...l.file===void 0?{}:{file:x(o.cwd,l.file)},force:l.force,wait:l.wait});return{value:{...A},text:W(A,a)}})}}const V=t=>p(u(t)).catch(()=>{});export const CLOUD_SOURCE={entries:[{name:"<work>",summary:"List a work's cloud tools (AllyHub's catalog), a line each; allyhub help lists the works"},{name:"<work> <tool>",summary:"Run a cloud tool with the account's credits, its input as options (allyhub help <work> <tool>, which says how its credits are counted)"}],async nouns(t){return(await p(u(t))).works.map(e=>({name:e.id,summary:`${e.title}: ${e.description}`}))},resolve:(t,a)=>f(async()=>{const[e,r]=t;if(e===void 0||e.startsWith("-"))return;let s=await V(a),i=s?.works.find(l=>l.id===e);if(i||(s=await p(u(a),{refresh:!0}).catch(()=>s),i=s?.works.find(l=>l.id===e)),!s||!i)return;if(r===void 0||r.startsWith("-"))return{command:T(i),rest:t.slice(1),list:!0};const o=s.tools.find(l=>l.name===r);if(o?.work!==i.id)throw new w("unknown-tool",o?`${r} is not a ${i.id} tool: it is in allyhub ${o.work}.`:`No ${i.id} tool ${r}.`,{exit:h.notFound,hint:o?`allyhub ${o.work} ${r}`:`allyhub ${i.id} lists its tools.`});return{command:toolCommand(o),rest:t.slice(2),list:!1}})},upload=m({name:"upload",summary:"Upload files from this computer for a cloud tool whose input takes a URL (a presenter photo, speech audio, a reference clip), and print a signed URL for each, which works for a few hours",input:n.strictObject({files:n.array(n.string()).min(1).describe("The files: images (.jpg, .png, .webp, .gif), sound (.mp3, .wav, .m4a, .aac, .ogg, .flac) or video (.mp4, .mov, .webm), 50 MB at most")}),positional:["files"],output:n.looseObject({files:n.array(n.looseObject({file:n.string(),ok:n.boolean(),url:n.string().optional()}))}),examples:["allyhub upload assets/media/presenter.jpg"]},(t,a)=>f(async()=>{const e=await M(u(a),t.files,{base:a.cwd}),r=e.filter(o=>!o.ok),s=e.map(o=>o.ok?`${o.file}
8
- ${o.url}${o.expiresAt===void 0?"":` (works until ${o.expiresAt})`}`:`${o.file}
9
- failed: ${o.error.message}${o.error.hint?` ${o.error.hint}`:""}`);e.length>1&&s.push(r.length===0?`${g(e.length,"file")} uploaded.`:`${String(e.length-r.length)} of ${g(e.length,"file")} uploaded; ${String(r.length)} failed.`);const i=r[0];return{value:{files:e.map(o=>o.ok?{...o}:{file:o.file,ok:!1,error:{code:o.error.code,message:o.error.message,...o.error.hint?{hint:o.error.hint}:{}}})},text:s.join(`
10
- `),...i?{exit:i.error.exit}:{}}})),cloudList=m({name:"cloud list",summary:"List AllyHub's cloud works, or one work's tools, a line each",input:n.strictObject({work:n.string().optional().describe("The work whose tools to list; none lists the works")}),output:n.looseObject({})},(t,a)=>f(async()=>{const e=await p(u(a));if(t.work===void 0)return{value:{works:e.works},text:["AllyHub's cloud works:",...R(e.works.map(i=>[i.id,i.description]))].join(`
11
- `)};const r=e.works.find(i=>i.id===t.work);if(!r)throw new w("unknown-work",`No work ${t.work}.`,{exit:h.notFound,hint:`The works are ${e.works.map(i=>i.id).join(", ")}.`});const s=await T(r).run({fresh:!1},a);return{value:s.value,text:s.text}})),cloudTool=m({name:"cloud tool",summary:"Show a cloud tool: what it does and how its credits are counted, and its input (as cloud call's input takes it)",input:n.strictObject({tool:n.string().describe("The tool's name, as cloud list lists it")}),output:n.looseObject({name:n.string()})},(t,a)=>f(async()=>{const e=toolCommand(await N(u(a),t.tool));return{value:{name:t.tool,summary:e.spec.summary,about:e.about?.lines??[],...e.about?.value},text:U(e.spec,e.about?.lines)}})),cloudCall=m({name:"cloud call",summary:"Run a cloud tool with the account's credits: its output, the credits used, and the file it makes with its record; waits for a long one",input:n.strictObject({tool:n.string().describe("The tool's name, as cloud list lists it"),input:n.record(n.string(),n.unknown()).default({}).describe("Its input, by its input schema (cloud tool)"),file:c.file,force:c.force,wait:c.wait,resume:c.resume}),output:n.looseObject({tool:n.string()})},(t,a)=>f(async()=>{const{tool:e,input:r,...s}=t,i=toolCommand(await N(u(a),e)),o=i.spec.input.safeParse({...s,...Object.keys(r).length?{input:JSON.stringify(r)}:{}});if(!o.success)throw $(o.error.message);const l=await i.run(o.data,a);return{...l,value:{tool:e,...l.value}}}));
2
+ import{readFile as C}from"node:fs/promises";import{join as J,resolve as v}from"node:path";import{z as o}from"zod";import{callTool as D,loadCatalog as m,resumeJob as E,uploadFiles as I}from"@allyhub-next/cloud";import{WORK_DIR as M}from"@allyhub-next/formats";import{EXIT as g}from"@allyhub-next/protocol";import{CommandError as w,defineCommand as N}from"../command.js";import{optionName as F}from"../args.js";import{requiredMissing as T,toolInput as L,toolOptions as U}from"../tool-options.js";import{cloudOf as f,cloudWork as $,placeFrom as H,plural as b}from"./cloud.js";const B=8e3,p={input:o.string().optional().describe("The input as JSON, or a file of it: the whole of it, or the fields no option gives; an option given beside it wins"),file:o.string().optional().describe("The path of the file it makes (without an extension it takes the result's); the same call with the same input then keeps it, calling nothing, and while its call works waits for that call; default a folder under .allyhub/work/"),force:o.boolean().default(!1).describe("With --file: call even when the file was made from this input, and replace a file that has no record"),wait:o.boolean().default(!0).describe("Wait for a long tool (an audit, a video model); --no-wait returns its call at once"),resume:o.string().optional().describe("Wait for a call of this tool this computer made (from --no-wait, or a call that stopped waiting), and download its file")},k=(e,a)=>new w("usage",e,{exit:g.usage,...a===void 0?{}:{hint:a}}),K=e=>{const a=e.reduce((i,r)=>r.map((s,n)=>Math.max(i[n]??0,s.length)),[]);return e.map(i=>` ${i.map((r,s)=>s===i.length-1?r:r.padEnd(a[s]??0)).join(" ")}`.trimEnd())};function _(e){return N({name:e.id,summary:`${e.title}: ${e.description} Lists the tools, each a command`,input:o.strictObject({fresh:o.boolean().default(!1).describe("Read the catalog from AllyHub again, not the copy kept an hour")}),output:o.looseObject({work:o.string(),tools:o.array(o.looseObject({name:o.string()}))}),examples:[`allyhub ${e.id}`,`allyhub ${e.id} --json`]},(a,i)=>$(async()=>{const s=(await m(f(i),{refresh:a.fresh})).tools.filter(n=>n.work===e.id).sort((n,t)=>n.name.localeCompare(t.name));return{value:{work:e.id,title:e.title,tools:s.map(n=>({name:n.name,title:n.title,description:n.description,long:n.long}))},text:[`${e.title} (${b(s.length,"tool")}):`,...K(s.map(n=>[n.name,n.title])),"",`Each costs credits when it worked; a failed call is free. allyhub help ${e.id} <tool> shows a tool's options and how its credits are counted.`].join(`
3
+ `)}}))}function q(e,a=5,i=160){const r=n=>{const t=n===void 0?"undefined":JSON.stringify(n);return t.length>i?`${t.slice(0,i-1)}…`:t},s=(n,t)=>[`${n?`${n}: `:""}${b(t.length,"item")}${t.length>a?`, the first ${String(a)}:`:":"}`,...t.slice(0,a).map((l,d)=>` [${String(d)}] ${r(l)}`)];return Array.isArray(e)?s("",e):typeof e!="object"||e===null?[r(e)]:Object.entries(e).flatMap(([n,t])=>Array.isArray(t)?s(n,t):[`${n}: ${r(t)}`])}function R(e,a){if("jobId"in e)return[`${e.tool} is still working (call ${e.jobId}).`,`Wait for it: allyhub ${a} --resume ${e.jobId}${e.file===void 0?"":" (or the same command again: it waits for this call)"}`].join(`
4
+ `);if(e.kept)return[`Kept ${e.file??""}: ${e.tool} made it from this same input on ${e.kept.at} (${e.gen??""}).`,"Nothing was called or charged. --force makes it again."].join(`
5
+ `);const i=JSON.stringify(e.output,null,2);return[i.length<=B?i:[`Output: ${String(Math.round(Buffer.byteLength(i)/1024))} KB of JSON, in short (--json prints it whole):`,...q(e.output)].join(`
6
+ `),...e.file?[`File: ${e.file}${e.replaced?" (replaced: it was made from another input)":""}`]:[],...e.words?[`Words: ${e.words} (when each word is said: a part can say a stretch of the file)`]:[],...e.gen?[`Record: ${e.gen} (move it with the file)`]:[],`Credits used: ${e.credits===void 0?"not reported":String(e.credits)}`].join(`
7
+ `)}const G=e=>{const a=Math.max(0,Math.round(e));return`${String(Math.floor(a/60))}:${String(a%60).padStart(2,"0")}`},z=e=>e!==null&&typeof e=="object"&&!Array.isArray(e);async function X(e,a){const i=e.trim().startsWith("{"),r=i?e:await C(v(a.cwd,e),"utf8").catch(n=>{throw new w("not-found",`--input: cannot read ${e}: ${n.message}`,{exit:g.notFound,hint:"Give a JSON object, or a file of one."})});let s;try{s=JSON.parse(r)}catch{s=void 0}if(!z(s))throw k(`--input: ${i?"the text":e} is not a JSON object.`,`Give '{"field": …}', or a file of it.`);return s}export function toolCommand(e){const a=`${e.work} ${e.name}`,i=U(e.input,Object.keys(p)),r=o.strictObject({...i.shape,...p,input:p.input.describe(i.inputOnly.length?`${p.input.description??""}. Fields only it gives: ${i.inputOnly.join(", ")}`:p.input.description??"")}),s=[...i.fields].filter(([,n])=>i.required.includes(n)).map(([n,t])=>`--${F(n)} <${t}>`);return{spec:{name:a,summary:e.description,input:r,output:o.looseObject({tool:o.string(),output:o.record(o.string(),o.unknown()).optional(),credits:o.number().optional(),file:o.string().optional(),gen:o.string().optional(),words:o.string().optional(),jobId:o.string().optional()}),examples:[`allyhub ${[a,...s].join(" ")}`]},about:{lines:[e.title,"","A call is charged once, when it worked, as the description says; a failed call is free.",...e.long?["A long tool: the command waits for it (--no-wait returns its call, --resume waits again)."]:[]],value:{work:e.work,title:e.title,long:e.long,inputSchema:e.input,outputSchema:e.output}},run:(n,t)=>$(async()=>{const l=n,d=n,u=f(t),h=await H(t),y=L(i,d,l.input===void 0?{}:await X(l.input,t));let j=0;const O={base:h,signal:t.signal,onRunning:c=>{Date.now()-j<3e4||(j=Date.now(),t.progress(`${e.name}: working · ${G((Date.now()-Date.parse(c.createdAt))/1e3)} (call ${c.id})`))},onRetry:(c,W,x)=>{t.progress(`${e.name}: ${W.message}; reading call ${c} again in ${String(x)} s`)}};if(l.resume!==void 0){if(Object.keys(y).length>0||l.file!==void 0)throw k("--resume waits for a call as it was made: give it no input or --file.");const c=await E(u,l.resume,{...O,tool:e.name});return{value:{...c},text:R(c,a)}}const S=T(i,y);if(S.length>0)throw k(`${e.name} needs ${S.join(", ")}.`,`allyhub help ${a} shows its options.`);const A=await D(u,e.name,y,{...O,outDir:J(h,M,e.work,e.name),...l.file===void 0?{}:{file:v(t.cwd,l.file)},force:l.force,wait:l.wait});return{value:{...A},text:R(A,a)}})}}export const CLOUD_SOURCE={entries:[{name:"<work>",summary:"List a work's cloud tools (AllyHub's catalog), a line each; allyhub help lists the works"},{name:"<work> <tool>",summary:"Run a cloud tool with the account's credits, its input as options (allyhub help <work> <tool>, which says how its credits are counted)"}],async nouns(e){return(await m(f(e))).works.map(i=>({name:i.id,summary:`${i.title}: ${i.description}`}))},resolve:(e,a)=>$(async()=>{const[i,r]=e;if(i===void 0||i.startsWith("-"))return;let s;const n=(u,h)=>(s=u,h);let t=await m(f(a)).catch(n),l=t?.works.find(u=>u.id===i);if(l||(t=await m(f(a),{refresh:!0}).catch(u=>n(u,t)),l=t?.works.find(u=>u.id===i)),!t)throw new w("catalog-unreachable",`"${i}" is none of allyhub's own commands, and its cloud tools could not be read: ${s instanceof Error?s.message:String(s)}.`,{exit:g.failed,hint:"They need the network: run allyhub outside a sandbox that blocks it."});if(!l)return;if(r===void 0||r.startsWith("-"))return{command:_(l),rest:e.slice(1),list:!0};const d=t.tools.find(u=>u.name===r);if(d?.work!==l.id)throw new w("unknown-tool",d?`${r} is not a ${l.id} tool: it is in allyhub ${d.work}.`:`No ${l.id} tool ${r}.`,{exit:g.notFound,hint:d?`allyhub ${d.work} ${r}`:`allyhub ${l.id} lists its tools.`});return{command:toolCommand(d),rest:e.slice(2),list:!1}})},upload=N({name:"upload",summary:"Upload files from this computer for a cloud tool whose input takes a URL (a presenter photo, speech audio, a reference clip), and print a signed URL for each, which works for a few hours",input:o.strictObject({files:o.array(o.string()).min(1).describe("The files: images (.jpg, .png, .webp, .gif), sound (.mp3, .wav, .m4a, .aac, .ogg, .flac) or video (.mp4, .mov, .webm), 50 MB at most")}),positional:["files"],output:o.looseObject({files:o.array(o.looseObject({file:o.string(),ok:o.boolean(),url:o.string().optional()}))}),examples:["allyhub upload assets/media/presenter.jpg"]},(e,a)=>$(async()=>{const i=await I(f(a),e.files,{base:a.cwd}),r=i.filter(t=>!t.ok),s=i.map(t=>t.ok?`${t.file}
8
+ ${t.url}${t.expiresAt===void 0?"":` (works until ${t.expiresAt})`}`:`${t.file}
9
+ failed: ${t.error.message}${t.error.hint?` ${t.error.hint}`:""}`);i.length>1&&s.push(r.length===0?`${b(i.length,"file")} uploaded.`:`${String(i.length-r.length)} of ${b(i.length,"file")} uploaded; ${String(r.length)} failed.`);const n=r[0];return{value:{files:i.map(t=>t.ok?{...t}:{file:t.file,ok:!1,error:{code:t.error.code,message:t.error.message,...t.error.hint?{hint:t.error.hint}:{}}})},text:s.join(`
10
+ `),...n?{exit:n.error.exit}:{}}}));
@@ -1,3 +1,3 @@
1
1
  /*! AllyHub. Copyright (c) 2026 AllyHub, Inc. All rights reserved. Use is subject to LICENSE.md. */
2
- import{mkdir as y,readFile as f,rm as b,writeFile as S}from"node:fs/promises";import{dirname as m,join as p}from"node:path";import{fileURLToPath as E}from"node:url";import{z as a}from"zod";import{listFiles as R}from"@allyhub-next/build";import{openBrowser as h}from"@allyhub-next/cloud";import{startDevServer as u}from"@allyhub-next/dev-server";import{DEV_FILE as w,scanItems as T}from"@allyhub-next/formats";import{EXIT as I}from"@allyhub-next/protocol";import{CommandError as g,defineCommand as $}from"../command.js";import{dir as O,indexing as D}from"../fields.js";import{projectRoot as P}from"../project.js";export const PAGE=p(m(E(import.meta.url)),"../../editor-web");const l=4340,j=20;export async function start(r,e,n){const s={root:r,ui:PAGE,index:n};if(e!==void 0)return u({...s,port:e}).catch(t=>{throw t.code==="EADDRINUSE"?new g("port-in-use",`Port ${String(e)} is in use.`,{hint:"Choose another with --port, or leave it out."}):t});for(let t=l;t<l+j;t++)try{return await u({...s,port:t})}catch(o){if(o.code!=="EADDRINUSE")throw o}return u(s)}async function F(r){try{const e=JSON.parse(await f(p(r,w),"utf8"));return typeof e.url!="string"||typeof e.pid!="number"?void 0:(process.kill(e.pid,0),(await fetch(e.url,{signal:AbortSignal.timeout(2e3)})).ok?e.url:void 0)}catch{return}}async function v(r,e,n){if(n===void 0)return e;const{items:s}=T(await R(r)),t=n.replace(/^\.\//u,"").replace(/\/+$/u,""),o=s.find(i=>i.dir===t||i.entry===t);if(!o)throw new g("not-found",`There is no item ${n} in the project.`,{exit:I.notFound,hint:`Its items: ${s.map(i=>i.dir).join(", ")||"none"}.`});return`${e}?${new URLSearchParams({item:o.dir}).toString()}`}export const dev=$({name:"dev",summary:"The project's items in the browser, each in its editor (docs, sheets, videos, 3D sceneries), as their files change; runs until stopped, and run again while it runs, opens its page and ends",input:a.strictObject({item:a.string().optional().describe("Open the page on this item: its folder or its entry file"),dir:O,port:a.number().int().min(1).max(65535).optional().describe(`The port; default the first free one from ${String(l)}`),open:a.boolean().default(!0).describe("Open the page in the browser; --no-open only prints it")}),positional:["item"],output:a.strictObject({url:a.string()}),mcp:!1,examples:["allyhub dev","allyhub dev launch/plan","allyhub dev --port 4400 --no-open"]},async(r,e)=>{const n=await P(e.cwd,r.dir),s=r.port===void 0?await F(n):void 0;if(s!==void 0){const i=await v(n,s,r.item);return e.progress(`allyhub dev is already running at ${i}`),r.open&&h(i,e.env),{value:{url:i},text:""}}const t=await start(n,r.port,D(e.env)),o=p(n,w);try{const i=await v(n,t.url,r.item);return await y(m(o),{recursive:!0}),await S(o,JSON.stringify({url:t.url,pid:process.pid})),e.progress(`allyhub dev is at ${i}
2
+ import{mkdir as y,readFile as f,rm as b,writeFile as S}from"node:fs/promises";import{dirname as m,join as p}from"node:path";import{fileURLToPath as E}from"node:url";import{z as a}from"zod";import{listFiles as R}from"@allyhub-next/build";import{openBrowser as h}from"@allyhub-next/cloud";import{startDevServer as u}from"@allyhub-next/dev-server";import{DEV_FILE as w,scanItems as T}from"@allyhub-next/formats";import{EXIT as I}from"@allyhub-next/protocol";import{CommandError as g,defineCommand as $}from"../command.js";import{dir as O,indexing as D}from"../fields.js";import{projectRoot as P}from"../project.js";export const PAGE=p(m(E(import.meta.url)),"../../editor-web");const l=4340,j=20;export async function start(r,e,n){const s={root:r,ui:PAGE,index:n};if(e!==void 0)return u({...s,port:e}).catch(t=>{throw t.code==="EADDRINUSE"?new g("port-in-use",`Port ${String(e)} is in use.`,{hint:"Choose another with --port, or leave it out."}):t});for(let t=l;t<l+j;t++)try{return await u({...s,port:t})}catch(o){if(o.code!=="EADDRINUSE")throw o}return u(s)}async function F(r){try{const e=JSON.parse(await f(p(r,w),"utf8"));return typeof e.url!="string"||typeof e.pid!="number"?void 0:(process.kill(e.pid,0),(await fetch(e.url,{signal:AbortSignal.timeout(2e3)})).ok?e.url:void 0)}catch{return}}async function v(r,e,n){if(n===void 0)return e;const{items:s}=T(await R(r)),t=n.replace(/^\.\//u,"").replace(/\/+$/u,""),o=s.find(i=>i.dir===t||i.entry===t);if(!o)throw new g("not-found",`There is no item ${n} in the project.`,{exit:I.notFound,hint:`Its items: ${s.map(i=>i.dir).join(", ")||"none"}.`});return`${e}?${new URLSearchParams({item:o.dir}).toString()}`}export const dev=$({name:"dev",summary:"The project's items in the browser, each in its editor (docs, sheets, videos, 3D sceneries), as their files change; runs until stopped, and run again while it runs, opens its page and ends",input:a.strictObject({item:a.string().optional().describe("Open the page on this item: its folder or its entry file"),dir:O,port:a.number().int().min(1).max(65535).optional().describe(`The port; default the first free one from ${String(l)}`),open:a.boolean().default(!0).describe("Open the page in the browser; --no-open only prints it")}),positional:["item"],output:a.strictObject({url:a.string()}),examples:["allyhub dev","allyhub dev launch/plan","allyhub dev --port 4400 --no-open"]},async(r,e)=>{const n=await P(e.cwd,r.dir),s=r.port===void 0?await F(n):void 0;if(s!==void 0){const i=await v(n,s,r.item);return e.progress(`allyhub dev is already running at ${i}`),r.open&&h(i,e.env),{value:{url:i},text:""}}const t=await start(n,r.port,D(e.env)),o=p(n,w);try{const i=await v(n,t.url,r.item);return await y(m(o),{recursive:!0}),await S(o,JSON.stringify({url:t.url,pid:process.pid})),e.progress(`allyhub dev is at ${i}
3
3
  Press Ctrl+C to stop.`),r.open&&h(i,e.env),await new Promise(c=>{const d=()=>{process.off("SIGTERM",d),e.signal.removeEventListener("abort",d),c()};e.signal.aborted&&c(),e.signal.addEventListener("abort",d),process.once("SIGTERM",d)}),{value:{url:i},text:""}}finally{(await f(o,"utf8").catch(()=>"")).includes(`"pid":${String(process.pid)}`)&&await b(o,{force:!0}),await t.close()}});
@@ -1,5 +1,5 @@
1
1
  /*! AllyHub. Copyright (c) 2026 AllyHub, Inc. All rights reserved. Use is subject to LICENSE.md. */
2
- import{z as i}from"zod";import{startBrowser as y}from"@allyhub-next/browser";import{LOCAL_PACKS as v,formatBytes as h,installPack as j,localPacks as N,removePack as A}from"@allyhub-next/media";import{EXIT as g}from"@allyhub-next/protocol";import{ENCODERS as C,FFMPEG_MINIMUM as E,FFMPEG_PINNED as $,ffmpegEncoders as L,ffmpegHint as u,findFfmpeg as P}from"@allyhub-next/render";import{createRuntimes as c}from"@allyhub-next/runtimes";import{defineCommand as F}from"../command.js";import{media as p,progressLines as H}from"../media.js";const d=[22,19],w=[...v,"ffmpeg","chrome"];function I(){const[e=0,o=0]=process.versions.node.split(".").map(Number),t=e>d[0]||e===d[0]&&o>=d[1];return{name:"node",ok:t,detail:`Node.js ${process.versions.node}`,...t?{}:{hint:`AllyHub needs Node.js ${d.join(".")} or newer: install it from nodejs.org or with a version manager.`}}}const k=(e,o)=>({name:o,ok:e?.available??!1,detail:e?.available?`not downloaded yet (${h(e.size)} the first time a command needs it, into ${e.dir})`:`AllyHub has no ${o} build for this computer`,...e?.available?{}:{hint:`Set ALLYHUB_${o.toUpperCase()} to one installed here.`}});async function M(e){const o=await c().locate("ffmpeg"),t=o?.bins.ffmpeg;if(t===void 0)return k(e,"ffmpeg");const s=await P(t);if(!s)return{name:"ffmpeg",ok:!1,detail:`${t} does not run`,hint:u(!0)};const n=`AllyHub needs ${E} or newer and is made with ${$}`;if(s.old)return{name:"ffmpeg",ok:!1,detail:`ffmpeg ${s.version} (${t}) is too old: ${n}`,hint:u(!0)};const r=await L(t),l=Object.entries(C).filter(([,a])=>!r.has(a)),m=[...s.pinned?[]:[`Not ${$}: its frames may differ from another computer's. ${u(!1)}`],...l.length>0?[`It cannot render ${l.map(([a,f])=>`${a} (no ${f})`).join(", ")}.`]:[]];return{name:"ffmpeg",ok:r.has("libx264"),detail:`ffmpeg ${s.version} (${t}${o?.from==="env"?", named by ALLYHUB_FFMPEG":""})`,...m.length>0?{hint:m.join(" ")}:{}}}async function O(e){if(!await c().locate("chrome"))return k(e,"chrome");try{const o=await y({gpu:!1}),t=o.product;return await o.close(),{name:"chrome",ok:!0,detail:t}}catch(o){return{name:"chrome",ok:!1,detail:`headless Chrome does not start: ${o.message.split(`
3
- `)[0]??""}`,hint:"Run allyhub outside the agent's sandbox, or set ALLYHUB_CHROME to another Chrome."}}}const R=e=>`${e.id}: ${e.unsupported??(e.installed?`installed (${h(e.bytes)})`:`not installed (${h(e.download)} to download, on first use or with --install ${e.id})`)}`;async function b(e,o,t){const s=[];for(const n of e){if(n==="ffmpeg"||n==="chrome"){const r=c();o?await r.remove(n):(t.progress(`Getting ${n}…`),await r.ensure(n,{signal:t.signal}))}else o?await p(()=>A(n)):await p(()=>j(n,{signal:t.signal,onProgress:H(t)}));s.push(`${o?"Removed":"Installed"} ${n}.`)}return s}export const doctor=F({name:"doctor",summary:"What this computer has for AllyHub: Node.js, ffmpeg, headless Chrome, the local models; --install and --remove",input:i.strictObject({install:i.array(i.enum(w)).default([]).describe("Download ahead what a command would on first use: a local pack (speech: speech recognition; people: face tracks and person mattes; reference: OCR and yt-dlp), ffmpeg or chrome"),remove:i.array(i.enum(w)).default([]).describe("Take them off this computer; a command downloads them again when it needs them")}),output:i.looseObject({ok:i.boolean(),checks:i.array(i.unknown())}),examples:["allyhub doctor","allyhub doctor --install speech"]},async(e,o)=>{const t=[...await b(e.remove,!0,o),...await b(e.install,!1,o)],s=await c().status(),n=a=>s.find(f=>f.name===a),r=[I(),await M(n("ffmpeg")),await O(n("chrome"))],l=await p(()=>N()),m=r.every(a=>a.ok);return{value:{ok:m,checks:r,packs:l,runtimes:s,changed:t},text:[...t,...r.map(a=>`${a.ok?"ok ":"FAIL"} ${a.name}: ${a.detail}${a.hint===void 0?"":`
4
- ${a.hint}`}`),...l.map(a=>` ${R(a)}`)].join(`
5
- `),exit:m?g.ok:g.failed}});
2
+ import{z as l}from"zod";import{startBrowser as j}from"@allyhub-next/browser";import{LOCAL_PACKS as A,formatBytes as d,installPack as C,localPacks as N,removePack as P}from"@allyhub-next/media";import{EXIT as g}from"@allyhub-next/protocol";import{ENCODERS as E,FFMPEG_MINIMUM as L,FFMPEG_PINNED as $,ffmpegEncoders as x,ffmpegHint as h,findFfmpeg as F}from"@allyhub-next/render";import{createPackages as w,createRuntimes as m}from"@allyhub-next/runtimes";import{defineCommand as H}from"../command.js";import{media as p,progressLines as I}from"../media.js";const f=[22,19],k=[...A,"excel","word","3d","ffmpeg","chrome"],b={excel:["exceljs"],word:["docx"],"3d":["manifold-3d","gltf-tools"]};function M(){const[e=0,o=0]=process.versions.node.split(".").map(Number),t=e>f[0]||e===f[0]&&o>=f[1];return{name:"node",ok:t,detail:`Node.js ${process.versions.node}`,...t?{}:{hint:`AllyHub needs Node.js ${f.join(".")} or newer: install it from nodejs.org or with a version manager.`}}}const y=(e,o)=>({name:o,ok:e?.available??!1,detail:e?.available?`not downloaded yet (${d(e.size)} the first time a command needs it, into ${e.dir})`:`AllyHub has no ${o} build for this computer`,...e?.available?{}:{hint:`Set ALLYHUB_${o.toUpperCase()} to one installed here.`}});async function O(e){const o=await m().locate("ffmpeg"),t=o?.bins.ffmpeg;if(t===void 0)return y(e,"ffmpeg");const s=await F(t);if(!s)return{name:"ffmpeg",ok:!1,detail:`${t} does not run`,hint:h(!0)};const a=`AllyHub needs ${L} or newer and is made with ${$}`;if(s.old)return{name:"ffmpeg",ok:!1,detail:`ffmpeg ${s.version} (${t}) is too old: ${a}`,hint:h(!0)};const r=await x(t),i=Object.entries(E).filter(([,n])=>!r.has(n)),c=[...s.pinned?[]:[`Not ${$}: its frames may differ from another computer's. ${h(!1)}`],...i.length>0?[`It cannot render ${i.map(([n,u])=>`${n} (no ${u})`).join(", ")}.`]:[]];return{name:"ffmpeg",ok:r.has("libx264"),detail:`ffmpeg ${s.version} (${t}${o?.from==="env"?", named by ALLYHUB_FFMPEG":""})`,...c.length>0?{hint:c.join(" ")}:{}}}async function R(e){if(!await m().locate("chrome"))return y(e,"chrome");try{const o=await j({gpu:!1}),t=o.product;return await o.close(),{name:"chrome",ok:!0,detail:t}}catch(o){return{name:"chrome",ok:!1,detail:`headless Chrome does not start: ${o.message.split(`
3
+ `)[0]??""}`,hint:"Run allyhub outside the agent's sandbox, or set ALLYHUB_CHROME to another Chrome."}}}function _(e){const o=w(),t=b[e],s=t.reduce((a,r)=>a+o.size(r),0);return t.every(a=>o.locate(a)!==void 0)?`${e}: installed (${d(s)})`:`${e}: not installed (${d(s)} to download, on first use or with --install ${e})`}const G=e=>`${e.id}: ${e.unsupported??(e.installed?`installed (${d(e.bytes)})`:`not installed (${d(e.download)} to download, on first use or with --install ${e.id})`)}`;async function v(e,o,t){const s=[];for(const a of e){if(a==="ffmpeg"||a==="chrome"){const r=m();o?await r.remove(a):(t.progress(`Getting ${a}…`),await r.ensure(a,{signal:t.signal}))}else if(a==="excel"||a==="word"||a==="3d"){const r=w();for(const i of b[a])o?await r.remove(i):(t.progress(`Getting ${i}…`),await r.ensure(i,{signal:t.signal}))}else o?await p(()=>P(a)):await p(()=>C(a,{signal:t.signal,onProgress:I(t)}));s.push(`${o?"Removed":"Installed"} ${a}.`)}return s}export const doctor=H({name:"doctor",summary:"What this computer has for AllyHub: Node.js, ffmpeg, headless Chrome, the local models; --install and --remove",input:l.strictObject({install:l.array(l.enum(k)).default([]).describe("Download ahead what a command would on first use: a local pack (speech: speech recognition; people: face tracks and person mattes; reference: OCR and yt-dlp), a package (excel: workbooks; word: Word documents; 3d: building and reading models), ffmpeg or chrome"),remove:l.array(l.enum(k)).default([]).describe("Take them off this computer; a command downloads them again when it needs them")}),output:l.looseObject({ok:l.boolean(),checks:l.array(l.unknown())}),examples:["allyhub doctor","allyhub doctor --install speech"]},async(e,o)=>{const t=[...await v(e.remove,!0,o),...await v(e.install,!1,o)],s=await m().status(),a=n=>s.find(u=>u.name===n),r=[M(),await O(a("ffmpeg")),await R(a("chrome"))],i=await p(()=>N()),c=r.every(n=>n.ok);return{value:{ok:c,checks:r,packs:i,runtimes:s,changed:t},text:[...t,...r.map(n=>`${n.ok?"ok ":"FAIL"} ${n.name}: ${n.detail}${n.hint===void 0?"":`
4
+ ${n.hint}`}`),...i.map(n=>` ${G(n)}`),...["excel","word","3d"].map(n=>` ${_(n)}`)].join(`
5
+ `),exit:c?g.ok:g.failed}});
@@ -1,2 +1,2 @@
1
1
  /*! AllyHub. Copyright (c) 2026 AllyHub, Inc. All rights reserved. Use is subject to LICENSE.md. */
2
- import{basename as q,resolve as b}from"node:path";import{Mattes as J,OVERLAY_KEY as Q,frameOverlay as Z,overlaySvg as v}from"@allyhub-next/measure";import{filmTimes as tt,partOf as et}from"@allyhub-next/project";import{GRID_WIDTH as it,MAX_TILES as D,defaultCols as nt,gridHtml as ot,gridLayout as st,labelSize as rt,probeVideo as at,sheetHtml as dt,stretchFrames as ct}from"@allyhub-next/media";import{clipTypeOf as ft,ffmpegOf as pt,hasFinalLook as lt,videoFrame as mt,writeClip as ht}from"@allyhub-next/render";import{EXIT as ut}from"@allyhub-next/protocol";import{CommandError as wt}from"../../command.js";import{drawPage as G,gridError as K,isFile as gt,looks as yt,momentOf as bt,pictureUrl as R,picturePath as E,save as C,secondsName as A,usage as $,withCombo as I,workPath as $t}from"./common.js";const M=e=>Math.round(e*1e3)/1e3,V=e=>({source:"piece",piece:e.target.piece,combo:e.target.combo,...e.target.id===void 0?{}:{id:e.target.id},format:e.target.format}),L=(e,t)=>$t(t,"frames",e.target.piece);function P(e,t){const i=e.at(-1);return e.find(o=>t>=o.start&&t<o.end)??(i&&t>=i.end?i:void 0)}export async function stillsSheet(e,t){const i=e.timeline,o=e.version.summary?.text??[],h=[];for(const d of i.parts)h.push(await e.still(d.still));const p=i.width/i.height,l=p<1?4:3,g=p<1?1320:1600,r=[];for(let d=0;d<i.parts.length;d+=l)r.push({cells:i.parts.slice(d,d+l).map((u,H)=>{const w=o.find(x=>x.key===u.key);return{image:h[d+H]??Buffer.alloc(0),label:`${u.key} · ${u.still.toFixed(2)} s`,text:w?.notes??w?.spoken??w?.onScreen.join(" · ")??""}})});const k=await G(e.session.browser,{html:dt({title:`${e.target.piece} · ${i.parts.length===1?"1 part":`${String(i.parts.length)} parts`} · ${i.duration.toFixed(2)} s`,rows:r,cols:l,width:g,aspect:p}),width:g}),s=await C(E(t.cwd,t.out,b(L(e,t.root),`${I("sheet",e.target)}.png`)),k);return{mode:"sheet",...V(e),out:s,parts:i.parts.map(d=>({key:d.key,t:M(d.still)}))}}export function clipKind(e){const t=ft(e);if(!t)throw $("bad-clip",`Cannot tell what kind of video ${e} is.`,"End --clip with .gif, .mp4 or .webm.");return t}async function xt(e,t){if(!await gt(e))throw new wt("not-found",`There is no file ${e} (--beside).`,{exit:ut.notFound});const i=await at(e),o=Math.max(1,Math.round(i.duration*i.fps)),h=[];for(const p of t){const l=Math.round(p*i.fps);h.push(p<0||l>o-1?void 0:await mt(e,l,i.fps))}return{info:i,shots:h}}export async function pieceMoments(e,t){const i=e.timeline,o=t.part===void 0?void 0:et(i,t.part),h=o?.start??0,p=t.from!==void 0||t.to!==void 0;if(p&&t.at!==void 0)throw $("bad-option","Give --at or --from and --to, not both.");if(p&&(t.from===void 0||t.to===void 0))throw $("bad-option","A stretch needs --from and --to.");if(t.clip!==void 0&&!p)throw $("bad-option","--clip needs --from and --to.","For example --from 3.2 --to 4.4 --clip move.gif.");const l=t.clip===void 0?void 0:clipKind(t.clip),g=t.clip===void 0||t.out!==void 0;let r;try{r=t.from!==void 0&&t.to!==void 0?ct({from:h+t.from,to:h+t.to},{fps:i.fps,duration:i.duration,grid:g}):void 0}catch(n){throw K(n)}const k=(t.at??[]).map(bt),s=r?r.times:k.length===0&&o?[o.still]:tt(k,i.parts,o);if(s.length>D&&g)throw $("bad-time",`${String(s.length)} moments; one picture holds at most ${String(D)}.`);for(const n of s)if(n<0||n>i.duration+1/i.fps)throw $("bad-time",`${n.toFixed(2)} s is outside ${e.target.piece}, which is ${i.duration.toFixed(2)} s long.`,o?`With --part, --at counts from the part's start; ${o.key} runs ${o.start.toFixed(2)}–${o.end.toFixed(2)} s.`:`Parts: ${i.parts.map(a=>`${a.key} ${a.start.toFixed(2)}–${a.end.toFixed(2)}`).join(", ")}.`);const d=n=>Math.min(n,i.duration),u={...V(e),final:lt(e.look,i),...r?{stretch:{from:r.from,to:r.to,every:r.every,frames:r.times.length}}:{}};if(s.length===1&&!r&&!t.overlay&&t.beside===void 0){const n=s[0]??0,a=o?.key??P(i.parts,n)?.key??"",c=await C(E(t.cwd,t.out,b(L(e,t.root),`${I(t.at===void 0&&o?o.key:A(n),e.target)}.png`)),await e.still(d(n),{format:yt()}));return{mode:"frame",...u,out:c,t:M(n),part:a,width:i.width,height:i.height}}const w=[];for(const n of s)w.push(await e.still(d(n)));const x=t.clip!==void 0&&l?await ht(w,{file:b(t.cwd,t.clip),type:l,fps:i.fps/(r?.every??1)}):void 0;if(!g)return{mode:"clip",...u,clip:x};const O=[];if(t.overlay){const n=i.duration-1/i.fps,a=await e.version.measure(s.map(m=>Math.min(m,n))),c=new J({root:e.prepared.root,media:e.prepared.media,ffmpeg:await pt()});for(const m of s)O.push(await Z(Math.min(m,n),i,a,e.prepared.media,c))}const f=t.beside===void 0?void 0:await xt(b(t.cwd,t.beside),s),S=f?2:1,W=i.width/i.height;let y;try{y=st({count:s.length,cols:nt(s.length,W*S),width:it,aspect:W*S})}catch(n){throw K(n)}const _=(y.tiles[0]?.width??i.width)/S,X=Math.max(11,rt(_)-4),T=[...w],Y=f?q(t.beside??""):"",z=s.map((n,a)=>{const c=O[a],m={src:R(a),label:`${n.toFixed(r?3:2)} s · ${P(i.parts,n)?.key??""}`,...c?{over:v(c,i.width,i.height,_/i.width,X)}:{}};if(!f)return{pictures:[m]};const F=f.shots[a];return F&&T.push(F),{pictures:[{src:F?R(T.length-1):void 0,label:`${Y} · ${n.toFixed(2)} s${F?"":" · past its end"}`},m]}}),B=await G(e.session.browser,{html:ot({layout:y,cells:z,...t.overlay?{legend:Q}:{}}),width:y.width,pictures:T}),j=s[0]??0,N=s.at(-1)??j,U=await C(E(t.cwd,t.out,b(L(e,t.root),`${I(`${r?"stretch":"moments"}-${A(j)}-${A(N)}`,e.target)}.png`)),B);return{mode:"grid",...u,out:U,cols:y.cols,tiles:s.map((n,a)=>{const c=y.tiles[a],m=O[a];return{t:M(n),part:P(i.parts,n)?.key??"",...c?{box:[c.x,c.y,c.width,c.height]}:{},...m?{overlay:m}:{},...f?{beside:{t:M(n),shown:f.shots[a]!==void 0}}:{}}}),...f?{beside:{file:b(t.cwd,t.beside??""),video:{duration:f.info.duration,width:f.info.width,height:f.info.height,fps:f.info.fps}}}:{},...x?{clip:x}:{}}}
2
+ import{basename as q,resolve as x}from"node:path";import{Mattes as J,DECK_OVERLAY_KEY as Q,OVERLAY_KEY as Z,frameOverlay as v,overlaySvg as tt}from"@allyhub-next/measure";import{filmTimes as et,partOf as it}from"@allyhub-next/project";import{GRID_WIDTH as nt,MAX_TILES as H,defaultCols as st,gridHtml as ot,gridLayout as rt,labelSize as at,probeVideo as dt,sheetHtml as ct,stretchFrames as ft}from"@allyhub-next/media";import{clipTypeOf as lt,ffmpegOf as pt,hasFinalLook as ht,videoFrame as mt,writeClip as ut}from"@allyhub-next/render";import{EXIT as wt}from"@allyhub-next/protocol";import{CommandError as gt}from"../../command.js";import{drawPage as R,gridError as V,isFile as $t,looks as yt,momentOf as bt,pictureUrl as W,picturePath as L,save as _,secondsName as I,usage as F,withCombo as K,workPath as kt}from"./common.js";const T=e=>Math.round(e*1e3)/1e3,j=e=>({source:"piece",piece:e.target.piece,combo:e.target.combo,...e.target.id===void 0?{}:{id:e.target.id},format:e.target.format}),P=(e,t)=>kt(t,"frames",e.target.piece);function C(e,t){const i=e.at(-1);return e.find(s=>t>=s.start&&t<s.end)??(i&&t>=i.end?i:void 0)}export async function stillsSheet(e,t){const i=e.timeline,s=e.version.summary?.text??[],p=i.parts.flatMap((a,l)=>{const w=a.steps??[a.still];return w.map((y,d)=>({p:a,t:y,slide:l,step:d,of:w.length}))}),h=[];for(const a of p)h.push(await e.still(a.t));const m=i.width/i.height,$=m<1?4:3,r=m<1?1320:1600,b=e.piece.kind==="slides",o=[];for(let a=0;a<p.length;a+=$)o.push({cells:p.slice(a,a+$).map(({p:l,slide:w,step:y,of:d},S)=>{const k=s.find(g=>g.key===l.key);return{image:h[a+S]??Buffer.alloc(0),label:b?`${String(w+1)}${d>1?`.${String(y)}`:""} · ${l.key}${l.hidden?" · hidden":""}`:`${l.key} · ${l.still.toFixed(2)} s`,text:k?.notes??k?.spoken??k?.onScreen.join(" · ")??""}})});const E=await R(e.session.browser,{html:ct({title:b?`${e.target.piece} · ${i.parts.length===1?"1 slide":`${String(i.parts.length)} slides`}`:`${e.target.piece} · ${i.parts.length===1?"1 part":`${String(i.parts.length)} parts`} · ${i.duration.toFixed(2)} s`,rows:o,cols:$,width:r,aspect:m}),width:r}),M=await _(L(t.cwd,t.out,x(P(e,t.root),`${K("sheet",e.target)}.png`)),E);return{mode:"sheet",...b?{slides:!0}:{},...j(e),out:M,parts:i.parts.map(a=>({key:a.key,t:T(a.still)}))}}export function clipKind(e){const t=lt(e);if(!t)throw F("bad-clip",`Cannot tell what kind of video ${e} is.`,"End --clip with .gif, .mp4 or .webm.");return t}async function xt(e,t){if(!await $t(e))throw new gt("not-found",`There is no file ${e} (--beside).`,{exit:wt.notFound});const i=await dt(e),s=Math.max(1,Math.round(i.duration*i.fps)),p=[];for(const h of t){const m=Math.round(h*i.fps);p.push(h<0||m>s-1?void 0:await mt(e,m,i.fps))}return{info:i,shots:p}}export async function pieceMoments(e,t){const i=e.timeline,s=t.part===void 0?void 0:it(i,t.part),p=s?.start??0,h=t.from!==void 0||t.to!==void 0;if(h&&t.at!==void 0)throw F("bad-option","Give --at or --from and --to, not both.");if(h&&(t.from===void 0||t.to===void 0))throw F("bad-option","A stretch needs --from and --to.");if(t.clip!==void 0&&!h)throw F("bad-option","--clip needs --from and --to.","For example --from 3.2 --to 4.4 --clip move.gif.");const m=t.clip===void 0?void 0:clipKind(t.clip),$=t.clip===void 0||t.out!==void 0;let r;try{r=t.from!==void 0&&t.to!==void 0?ft({from:p+t.from,to:p+t.to},{fps:i.fps,duration:i.duration,grid:$}):void 0}catch(n){throw V(n)}const b=(t.at??[]).map(bt),o=r?r.times:b.length===0&&s?[s.still]:et(b,i.parts,s);if(o.length>H&&$)throw F("bad-time",`${String(o.length)} moments; one picture holds at most ${String(H)}.`);for(const n of o)if(n<0||n>i.duration+1/i.fps)throw F("bad-time",`${n.toFixed(2)} s is outside ${e.target.piece}, which is ${i.duration.toFixed(2)} s long.`,s?`With --part, --at counts from the part's start; ${s.key} runs ${s.start.toFixed(2)}–${s.end.toFixed(2)} s.`:`Parts: ${i.parts.map(c=>`${c.key} ${c.start.toFixed(2)}–${c.end.toFixed(2)}`).join(", ")}.`);const E=n=>Math.min(n,i.duration),M={...j(e),final:ht(e.look,i),...r?{stretch:{from:r.from,to:r.to,every:r.every,frames:r.times.length}}:{}};if(o.length===1&&!r&&!t.overlay&&t.beside===void 0){const n=o[0]??0,c=s?.key??C(i.parts,n)?.key??"",f=await _(L(t.cwd,t.out,x(P(e,t.root),`${K(t.at===void 0&&s?s.key:I(n),e.target)}.png`)),await e.still(E(n),{format:yt()}));return{mode:"frame",...M,out:f,t:T(n),part:c,width:i.width,height:i.height}}const l=[];for(const n of o)l.push(await e.still(E(n)));const w=t.clip!==void 0&&m?await ut(l,{file:x(t.cwd,t.clip),type:m,fps:i.fps/(r?.every??1)}):void 0;if(!$)return{mode:"clip",...M,clip:w};const y=[];if(t.overlay){const n=i.duration-1/i.fps,c=await e.version.measure(o.map(u=>Math.min(u,n))),f=new J({root:e.prepared.root,media:e.prepared.media,ffmpeg:await pt()});for(const u of o)y.push(await v(Math.min(u,n),i,c,e.prepared.media,f))}const d=t.beside===void 0?void 0:await xt(x(t.cwd,t.beside),o),S=d?2:1,k=i.width/i.height;let g;try{g=rt({count:o.length,cols:st(o.length,k*S),width:nt,aspect:k*S})}catch(n){throw V(n)}const Y=(g.tiles[0]?.width??i.width)/S,G=Math.max(11,at(Y)-4),A=[...l],X=d?q(t.beside??""):"",z=o.map((n,c)=>{const f=y[c],u={src:W(c),label:e.piece.kind==="slides"?C(i.parts,n)?.key??"":`${n.toFixed(r?3:2)} s · ${C(i.parts,n)?.key??""}`,...f?{over:tt(f,i.width,i.height,Y/i.width,G)}:{}};if(!d)return{pictures:[u]};const O=d.shots[c];return O&&A.push(O),{pictures:[{src:O?W(A.length-1):void 0,label:`${X} · ${n.toFixed(2)} s${O?"":" · past its end"}`},u]}}),B=await R(e.session.browser,{html:ot({layout:g,cells:z,...t.overlay?{legend:e.piece.kind==="slides"?Q:Z}:{}}),width:g.width,pictures:A}),D=o[0]??0,N=o.at(-1)??D,U=await _(L(t.cwd,t.out,x(P(e,t.root),`${K(`${r?"stretch":"moments"}-${I(D)}-${I(N)}`,e.target)}.png`)),B);return{mode:"grid",...M,out:U,cols:g.cols,tiles:o.map((n,c)=>{const f=g.tiles[c],u=y[c];return{t:T(n),part:C(i.parts,n)?.key??"",...f?{box:[f.x,f.y,f.width,f.height]}:{},...u?{overlay:u}:{},...d?{beside:{t:T(n),shown:d.shots[c]!==void 0}}:{}}}),...d?{beside:{file:x(t.cwd,t.beside??""),video:{duration:d.info.duration,width:d.info.width,height:d.info.height,fps:d.info.fps}}}:{},...w?{clip:w}:{}}}
@@ -1,8 +1,8 @@
1
1
  /*! AllyHub. Copyright (c) 2026 AllyHub, Inc. All rights reserved. Use is subject to LICENSE.md. */
2
- import{z as t}from"zod";import{formatConsole as z,formatProblem as P}from"../text/index.js";import{COMPARE_DEFAULTS as W,CUT_REVIEW_DEFAULTS as M,cutLine as I,dbText as w,silenceText as L}from"@allyhub-next/measure";import{consoleJson as x}from"@allyhub-next/project";import{PAGE_CAPTURE_DEFAULTS as $}from"@allyhub-next/browser";import{EXIT as j}from"@allyhub-next/protocol";import{defineCommand as p}from"../command.js";import{dir as k}from"../fields.js";import{parameters as T}from"../parameters.js";import{projectRoot as f}from"../project.js";import{VERSION_FIELDS as v,commandError as F,withVersion as u}from"../version.js";import{compareText as O,comparePictures as C}from"./frames/compare.js";import{isPicture as _,isVideo as E,usage as h}from"./frames/common.js";import{cutSheets as R}from"./frames/cuts.js";import{fileFrames as H}from"./frames/file.js";import{pageShot as N}from"./frames/page.js";import{pieceMoments as U,stillsSheet as G}from"./frames/piece.js";import{sizeOf as V}from"./scenery-input.js";function g(e){return[...e.problems.filter(s=>s.level==="error").map(P),...z(x(e.console))]}const b=e=>({problems:e.problems,...x(e.console)}),y=(e,i)=>f(e,i),B=t.strictObject({...v,item:t.string().optional().describe("The piece (its id, or a path into it; default the project's only one), or a video file: a path ending in .mp4, .mov, .webm, .m4v, .qt, .mkv or .avi is a file, anything else a piece"),at:t.array(t.string()).optional().describe("Moments: seconds (from the start of --part when given) or anchors (@press, @/map a stretch's end, @press+0.2); a video file's are seconds. One is written as the frame itself, several are tiled. Without it, --part's still, or every part's still on one sheet"),part:t.string().optional().describe("The part --at, --from and --to count from; alone, its still"),from:t.number().optional().describe("A stretch of consecutive frames from this second (with --to), instead of --at"),to:t.number().optional().describe("The stretch's last second"),clip:t.string().optional().describe("Write the stretch as a small silent video, .gif, .mp4 or .webm by its extension; with --out, the grid too"),overlay:t.boolean().default(!1).describe("Draw over each tile the face boxes with ids, the person matte's outline, the covered areas and the text boxes; places nothing"),beside:t.string().optional().describe("Another video file (a reference) whose frame at the same time goes on each tile's left"),grid:t.number().int().min(4).optional().describe("A video file at one --at: the frame at its own size with numbered lines every this many pixels"),out:t.string().optional().describe("Where the picture goes (a WebP); default under .allyhub/work/frames/")});function J(e){const i=[["--combo",e.combo!==void 0],["--part",e.part!==void 0],["--beside",e.beside!==void 0],["--overlay",e.overlay]].filter(([,s])=>s).map(([s])=>s);if(i.length>0)throw h("bad-option",`${i.join(" and ")} ${i.length===1?"is":"are"} a piece's: a video file has no combos or parts.`)}export const frames=p({name:"frames",summary:"Pictures of a piece over time, drawn as the render draws them: every part's still on a sheet (default), a moment, a stretch tiled or as a clip, overlays; or any video file's frames",input:B,positional:["item"],output:t.looseObject({mode:t.enum(["sheet","frame","grid","clip"])}),examples:["allyhub frames launch/film","allyhub frames launch/film --at 2.5","allyhub frames launch/film --part hook --from 0 --to 1 --clip hook.gif","allyhub frames launch/film --at 1,2,3 --overlay","allyhub frames reference.mp4 --at 0,1,2","allyhub frames reference.mp4 --at 3 --grid 50"]},async(e,i)=>{const s=i.cwd;if(e.item!==void 0&&E(e.item)){J(e);const r=await H({cwd:s,root:await y(s,e.dir),file:e.item,at:e.at,from:e.from,to:e.to,clip:e.clip,out:e.out,grid:e.grid}).catch(D=>{throw F(D)}),a=r.video,m=`${r.file} · ${a.duration.toFixed(2)} s · ${String(a.width)}×${String(a.height)} · ${String(a.fps)} fps`,S="clip"in r&&r.clip?`${r.clip.out} (${r.clip.type}, ${String(r.clip.frames)} frames at ${String(r.clip.fps)} fps, no sound)`:void 0;return{value:r,text:[m,..."out"in r?[`${r.out}${"tiles"in r?` (${String(r.tiles.length)} moments in ${String(r.cols)} columns)`:""}`]:[],...S?[S]:[]].join(`
3
- `)}}if(e.grid!==void 0)throw h("bad-option","--grid draws a video file's frame at its own size: give the file.");const l=await f(s,e.dir);if(!(e.at!==void 0||e.part!==void 0||e.from!==void 0||e.to!==void 0)){if(e.clip!==void 0||e.beside!==void 0||e.overlay)throw h("bad-option","--clip, --beside and --overlay draw moments: give --at, --part, or --from and --to.");const{result:r,...a}=await u(e,i,"render",m=>G(m,{cwd:s,root:l,out:e.out}));return{value:{...r,...b(a)},text:[`${r.out} (${r.piece} · ${r.format} · ${String(r.parts.length)} part${r.parts.length===1?"":"s"})`,...g(a)].join(`
4
- `)}}const{result:o,...d}=await u(e,i,"render",r=>U(r,{cwd:s,root:l,at:e.at,part:e.part,from:e.from,to:e.to,clip:e.clip,out:e.out,overlay:e.overlay,beside:e.beside})),c=[];if(o.mode==="frame"&&c.push(`${o.out} (${o.piece} · ${o.format} · ${o.part} · ${o.t.toFixed(2)} s)`),o.mode==="grid"){c.push(`${o.out} (${o.piece} · ${String(o.tiles.length)} moments in ${String(o.cols)} columns)`,` ${o.tiles.map(a=>`${a.t.toFixed(o.stretch?3:2)} ${a.part}`).join(" · ")}`);const r=[...new Set(o.tiles.flatMap(a=>a.overlay?.missing??[]))];r.length>0&&c.push(` Not measured: ${r.join(", ")}.`)}return o.stretch&&c.push(` Stretch ${o.stretch.from.toFixed(3)}–${o.stretch.to.toFixed(3)} s, one frame in ${String(o.stretch.every)}: ${String(o.stretch.frames)} frames.`),"clip"in o&&o.clip&&c.push(`${o.clip.out} (${o.clip.type}, ${String(o.clip.frames)} frames at ${String(o.clip.fps)} fps, no sound)`),{value:{...o,...b(d)},text:[...c,...g(d)].join(`
5
- `)}}),framesCuts=p({name:"frames cuts",summary:"A review sheet per cut of a video (a cut take's jumps, part joins, a scenery camera's cuts): frames around it, waveform and level, the words each side, the sound at it",input:t.strictObject({...v,part:t.string().optional().describe("Only this part's cuts and its joins"),out:t.string().optional().describe("The folder the sheets go in; default .allyhub/work/cuts/"),params:T({span:t.number().positive().max(10).default(M.span).describe("Seconds shown on each side of a cut")})}),positional:["item"],output:t.looseObject({out:t.string(),cuts:t.array(t.looseObject({sheet:t.string()}))}),examples:["allyhub frames cuts launch/film","allyhub frames cuts launch/film --part hook"]},async(e,i)=>{const s=i.cwd,l=await f(s,e.dir),{result:n,...o}=await u(e,i,"render",r=>R(r,{cwd:s,root:l,part:e.part,out:e.out,review:{span:e.params.span}})),d=n.part===void 0?`${String(n.cuts.length)} cut${n.cuts.length===1?"":"s"}`:`${String(n.cuts.length)} of ${String(n.total)} cuts (part ${n.part} and its joins)`,c=[`${n.piece} · ${n.format} · ${d}; silence is sound under ${String(n.threshold)} dBFS`];for(const r of n.cuts){const a=r.sound?`level ${w(r.sound.levelDb)} / around ${w(r.sound.aroundDb)} dBFS, peak ${w(r.sound.peakDb)}, step ${r.sound.jumpDb<0?"−":"+"}${Math.abs(r.sound.jumpDb).toFixed(1)} dB`:"no sound";c.push(`${String(r.index).padStart(3)} ${r.t.toFixed(3).padStart(7)} s ${r.kind.padEnd(6)} ${I(r)}`,` silence at the cut: ${L(r.silence)} · ${a}`,` “${r.said.before}” | “${r.said.after}”${r.across?` · across the cut: “${r.across}”`:""}`,` ${r.sheet}`)}return{value:{...n,...b(o)},text:[...c,...g(o)].join(`
6
- `)}});const A=W;export const framesCompare=p({name:"frames compare",summary:"How a candidate picture differs from a reference, as numbers (ΔE, channels, SSIM, levels, grain, edges, regions) with a heatmap and a side-by-side: a piece's moment, a picture file or a video file's frame",input:t.strictObject({reference:t.string().describe("The reference picture (PNG, WebP, JPEG…)"),candidate:t.string().optional().describe("A piece (its id, or a path into it; default the project's only one) at --at or --part's still; or a file by its extension: a picture (.png, .jpg, .webp…), or a video file's frame at --at (.mp4, .mov, .webm…)"),combo:v.combo,dir:k,at:t.string().optional().describe("The moment: seconds (from the start of --part when given) or an anchor of the piece; a video file's are seconds (default 0)"),part:t.string().optional().describe("The piece's part --at counts from; alone, its still"),refCrop:t.string().optional().describe("Cut the reference to x,y,width,height, or to an element of the elements.json beside it (frames web writes one)"),crop:t.string().optional().describe("Cut the candidate to x,y,width,height before any resize"),encode:t.string().optional().describe("Draw the candidate through this encode first, as a platform serves it: codec:kbps, h264 or hevc (hevc:618)"),out:t.string().optional().describe("Where its files go, a path without extension; default under .allyhub/work/compare/"),params:T({resize:t.enum(["stretch","width","none"]).default(A.resize).describe("When sizes differ: stretch the candidate to the reference, scale it to its width, or compare the common area"),shift:t.number().int().min(0).max(32).default(A.shift).describe("Search the best offset within this many pixels each way")})}),positional:["reference","candidate"],output:t.looseObject({reference:t.string(),files:t.looseObject({side:t.string(),heatmap:t.string()})}),examples:["allyhub frames compare reference.png launch/film --at 2.5 --encode hevc:618","allyhub frames compare reference.png shot.webp --ref-crop cta","allyhub frames compare reference.png theirs.mp4 --at 3"]},async(e,i)=>{const s=i.cwd,l=e.params,n=e.candidate!==void 0&&(_(e.candidate)||E(e.candidate))?e.candidate:void 0,o=a=>({cwd:s,root:a,reference:e.reference,file:n,at:e.at===void 0?void 0:[e.at],part:e.part,refCrop:e.refCrop,crop:e.crop,encode:e.encode,out:e.out,options:{shift:l.shift,resize:l.resize}});if(n!==void 0){if(e.combo!==void 0||e.part!==void 0)throw h("bad-option","--combo and --part are a piece's: the candidate is a file.");const a=await C(o(await y(s,e.dir)),void 0).catch(m=>{throw F(m)});return{value:a,text:O(a)}}const d=await f(s,e.dir),{result:c,...r}=await u({...e,item:e.candidate},i,"render",a=>C(o(d),a));return{value:{...c,...b(r)},text:[O(c),...g(r)].join(`
7
- `)}}),framesWeb=p({name:"frames web",summary:"A web page's screenshot with its named elements' boxes in the image's pixels, for a screen demo",input:t.strictObject({url:t.string().describe("The page: an address, or an HTML file on this computer"),el:t.array(t.string()).optional().describe("An element to locate, name=selector (CSS, or text=<words>); [data-el] elements are found too"),click:t.array(t.string()).optional().describe("Selectors clicked in order before the shot (close a banner, open a dialog)"),full:t.boolean().default(!1).describe("The whole page, not one viewport"),out:t.string().optional().describe("Where the picture goes (a WebP), its boxes in <out>.elements.json beside it; default under .allyhub/work/pages/"),dir:k,size:t.string().default(`${String($.width)}x${String($.height)}`).describe("The viewport, WIDTHxHEIGHT in CSS pixels"),scale:t.number().min(1).max(4).default($.scale).describe("Image pixels per CSS pixel; 2 draws a high-density screen, sharp when a camera goes in"),wait:t.number().int().min(0).optional().describe("Milliseconds to wait after loading and clicking")}),positional:["url"],output:t.looseObject({out:t.string(),elementsFile:t.string()}),examples:["allyhub frames web https://example.com --el cta=text=Sign\\ up --scale 2 --out assets/media/home","allyhub frames web page.html --click '#accept' --full"]},async(e,i)=>{const s=i.cwd,[l,n]=V(e.size),o=await N({cwd:s,root:await y(s,e.dir),url:e.url,out:e.out,el:e.el,click:e.click,width:l,height:n,scale:e.scale,full:e.full,wait:e.wait});return{value:o,text:[`${o.out}: ${String(o.width)}×${String(o.height)}${o.scale===1?"":` (${String(o.scale)} image pixels per CSS pixel)`}, ${String(Object.keys(o.elements).length)} elements (${Object.keys(o.elements).join(", ")||"none"}) in ${o.elementsFile}`,...o.missing.length>0?[`Not found: ${o.missing.join(", ")} (the selector is wrong, or something must be opened with --click first).`]:[]].join(`
2
+ import{z as t}from"zod";import{formatConsole as z,formatProblem as P}from"../text/index.js";import{COMPARE_DEFAULTS as W,CUT_REVIEW_DEFAULTS as M,cutLine as I,dbText as w,silenceText as L}from"@allyhub-next/measure";import{consoleJson as x}from"@allyhub-next/project";import{PAGE_CAPTURE_DEFAULTS as $}from"@allyhub-next/browser";import{EXIT as j}from"@allyhub-next/protocol";import{defineCommand as p}from"../command.js";import{dir as k}from"../fields.js";import{parameters as T}from"../parameters.js";import{projectRoot as f}from"../project.js";import{VERSION_FIELDS as v,commandError as F,withVersion as u}from"../version.js";import{compareText as O,comparePictures as C}from"./frames/compare.js";import{isPicture as _,isVideo as E,usage as h}from"./frames/common.js";import{cutSheets as R}from"./frames/cuts.js";import{fileFrames as H}from"./frames/file.js";import{pageShot as N}from"./frames/page.js";import{pieceMoments as U,stillsSheet as G}from"./frames/piece.js";import{sizeOf as V}from"./scenery-input.js";function g(e){return[...e.problems.filter(s=>s.level==="error").map(P),...z(x(e.console))]}const b=e=>({problems:e.problems,...x(e.console)}),y=(e,a)=>f(e,a),B=t.strictObject({...v,item:t.string().optional().describe("The piece (its id, or a path into it; default the project's only one), or a video file: a path ending in .mp4, .mov, .webm, .m4v, .qt, .mkv or .avi is a file, anything else a piece"),at:t.array(t.string()).optional().describe("Moments: seconds (from the start of --part when given) or anchors (@press, @/map a stretch's end, @press+0.2); a video file's are seconds. One is written as the frame itself, several are tiled. Without it, --part's still, or every part's still on one sheet"),part:t.string().optional().describe("The part --at, --from and --to count from; alone, its still"),from:t.number().optional().describe("A stretch of consecutive frames from this second (with --to), instead of --at"),to:t.number().optional().describe("The stretch's last second"),clip:t.string().optional().describe("Write the stretch as a small silent video, .gif, .mp4 or .webm by its extension; with --out, the grid too"),overlay:t.boolean().default(!1).describe("Draw over each tile the face boxes with ids, the person matte's outline, the covered areas and the text boxes; places nothing"),beside:t.string().optional().describe("Another video file (a reference) whose frame at the same time goes on each tile's left"),grid:t.number().int().min(4).optional().describe("A video file at one --at: the frame at its own size with numbered lines every this many pixels"),out:t.string().optional().describe("Where the picture goes (a WebP); default under .allyhub/work/frames/")});function J(e){const a=[["--combo",e.combo!==void 0],["--part",e.part!==void 0],["--beside",e.beside!==void 0],["--overlay",e.overlay]].filter(([,s])=>s).map(([s])=>s);if(a.length>0)throw h("bad-option",`${a.join(" and ")} ${a.length===1?"is":"are"} a piece's: a video file has no combos or parts.`)}export const frames=p({name:"frames",summary:"Pictures of a piece over time, drawn as the render draws them: every part's still on a sheet (default), a moment, a stretch tiled or as a clip, overlays; or any video file's frames",input:B,positional:["item"],output:t.looseObject({mode:t.enum(["sheet","frame","grid","clip"])}),examples:["allyhub frames launch/film","allyhub frames launch/film --at 2.5","allyhub frames launch/film --part hook --from 0 --to 1 --clip hook.gif","allyhub frames launch/film --at 1,2,3 --overlay","allyhub frames reference.mp4 --at 0,1,2","allyhub frames reference.mp4 --at 3 --grid 50"]},async(e,a)=>{const s=a.cwd;if(e.item!==void 0&&E(e.item)){J(e);const r=await H({cwd:s,root:await y(s,e.dir),file:e.item,at:e.at,from:e.from,to:e.to,clip:e.clip,out:e.out,grid:e.grid}).catch(D=>{throw F(D)}),i=r.video,m=`${r.file} · ${i.duration.toFixed(2)} s · ${String(i.width)}×${String(i.height)} · ${String(i.fps)} fps`,S="clip"in r&&r.clip?`${r.clip.out} (${r.clip.type}, ${String(r.clip.frames)} frames at ${String(r.clip.fps)} fps, no sound)`:void 0;return{value:r,text:[m,..."out"in r?[`${r.out}${"tiles"in r?` (${String(r.tiles.length)} moments in ${String(r.cols)} columns)`:""}`]:[],...S?[S]:[]].join(`
3
+ `)}}if(e.grid!==void 0)throw h("bad-option","--grid draws a video file's frame at its own size: give the file.");const l=await f(s,e.dir);if(!(e.at!==void 0||e.part!==void 0||e.from!==void 0||e.to!==void 0)){if(e.clip!==void 0||e.beside!==void 0||e.overlay)throw h("bad-option","--clip, --beside and --overlay draw moments: give --at, --part, or --from and --to.");const{result:r,...i}=await u(e,a,"render",m=>G(m,{cwd:s,root:l,out:e.out}));return{value:{...r,...b(i)},text:[`${r.out} (${r.piece} · ${r.format} · ${String(r.parts.length)} ${"slides"in r?"slide":"part"}${r.parts.length===1?"":"s"})`,...g(i)].join(`
4
+ `)}}const{result:o,...d}=await u(e,a,"render",r=>U(r,{cwd:s,root:l,at:e.at,part:e.part,from:e.from,to:e.to,clip:e.clip,out:e.out,overlay:e.overlay,beside:e.beside})),c=[];if(o.mode==="frame"&&c.push(`${o.out} (${o.piece} · ${o.format} · ${o.part} · ${o.t.toFixed(2)} s)`),o.mode==="grid"){c.push(`${o.out} (${o.piece} · ${String(o.tiles.length)} moments in ${String(o.cols)} columns)`,` ${o.tiles.map(i=>`${i.t.toFixed(o.stretch?3:2)} ${i.part}`).join(" · ")}`);const r=[...new Set(o.tiles.flatMap(i=>i.overlay?.missing??[]))];r.length>0&&c.push(` Not measured: ${r.join(", ")}.`)}return o.stretch&&c.push(` Stretch ${o.stretch.from.toFixed(3)}–${o.stretch.to.toFixed(3)} s, one frame in ${String(o.stretch.every)}: ${String(o.stretch.frames)} frames.`),"clip"in o&&o.clip&&c.push(`${o.clip.out} (${o.clip.type}, ${String(o.clip.frames)} frames at ${String(o.clip.fps)} fps, no sound)`),{value:{...o,...b(d)},text:[...c,...g(d)].join(`
5
+ `)}}),framesCuts=p({name:"frames cuts",summary:"A review sheet per cut of a video (a cut take's jumps, part joins, a scenery camera's cuts): frames around it, waveform and level, the words each side, the sound at it",input:t.strictObject({...v,part:t.string().optional().describe("Only this part's cuts and its joins"),out:t.string().optional().describe("The folder the sheets go in; default .allyhub/work/cuts/"),params:T({span:t.number().positive().max(10).default(M.span).describe("Seconds shown on each side of a cut")})}),positional:["item"],output:t.looseObject({out:t.string(),cuts:t.array(t.looseObject({sheet:t.string()}))}),examples:["allyhub frames cuts launch/film","allyhub frames cuts launch/film --part hook"]},async(e,a)=>{const s=a.cwd,l=await f(s,e.dir),{result:n,...o}=await u(e,a,"render",r=>R(r,{cwd:s,root:l,part:e.part,out:e.out,review:{span:e.params.span}})),d=n.part===void 0?`${String(n.cuts.length)} cut${n.cuts.length===1?"":"s"}`:`${String(n.cuts.length)} of ${String(n.total)} cuts (part ${n.part} and its joins)`,c=[`${n.piece} · ${n.format} · ${d}; silence is sound under ${String(n.threshold)} dBFS`];for(const r of n.cuts){const i=r.sound?`level ${w(r.sound.levelDb)} / around ${w(r.sound.aroundDb)} dBFS, peak ${w(r.sound.peakDb)}, step ${r.sound.jumpDb<0?"−":"+"}${Math.abs(r.sound.jumpDb).toFixed(1)} dB`:"no sound";c.push(`${String(r.index).padStart(3)} ${r.t.toFixed(3).padStart(7)} s ${r.kind.padEnd(6)} ${I(r)}`,` silence at the cut: ${L(r.silence)} · ${i}`,` “${r.said.before}” | “${r.said.after}”${r.across?` · across the cut: “${r.across}”`:""}`,` ${r.sheet}`)}return{value:{...n,...b(o)},text:[...c,...g(o)].join(`
6
+ `)}});const A=W;export const framesCompare=p({name:"frames compare",summary:"How a candidate picture differs from a reference, as numbers (ΔE, channels, SSIM, levels, grain, edges, regions) with a heatmap and a side-by-side: a piece's moment, a picture file or a video file's frame",input:t.strictObject({reference:t.string().describe("The reference picture (PNG, WebP, JPEG…)"),candidate:t.string().optional().describe("A piece (its id, or a path into it; default the project's only one) at --at or --part's still; or a file by its extension: a picture (.png, .jpg, .webp…), or a video file's frame at --at (.mp4, .mov, .webm…)"),combo:v.combo,dir:k,at:t.string().optional().describe("The moment: seconds (from the start of --part when given) or an anchor of the piece; a video file's are seconds (default 0)"),part:t.string().optional().describe("The piece's part --at counts from; alone, its still"),refCrop:t.string().optional().describe("Cut the reference to x,y,width,height, or to an element of the elements.json beside it (frames web writes one)"),crop:t.string().optional().describe("Cut the candidate to x,y,width,height before any resize"),encode:t.string().optional().describe("Draw the candidate through this encode first, as a platform serves it: codec:kbps, h264 or hevc (hevc:618)"),out:t.string().optional().describe("Where its files go, a path without extension; default under .allyhub/work/compare/"),params:T({resize:t.enum(["stretch","width","none"]).default(A.resize).describe("When sizes differ: stretch the candidate to the reference, scale it to its width, or compare the common area"),shift:t.number().int().min(0).max(32).default(A.shift).describe("Search the best offset within this many pixels each way")})}),positional:["reference","candidate"],output:t.looseObject({reference:t.string(),files:t.looseObject({side:t.string(),heatmap:t.string()})}),examples:["allyhub frames compare reference.png launch/film --at 2.5 --encode hevc:618","allyhub frames compare reference.png shot.webp --ref-crop cta","allyhub frames compare reference.png theirs.mp4 --at 3"]},async(e,a)=>{const s=a.cwd,l=e.params,n=e.candidate!==void 0&&(_(e.candidate)||E(e.candidate))?e.candidate:void 0,o=i=>({cwd:s,root:i,reference:e.reference,file:n,at:e.at===void 0?void 0:[e.at],part:e.part,refCrop:e.refCrop,crop:e.crop,encode:e.encode,out:e.out,options:{shift:l.shift,resize:l.resize}});if(n!==void 0){if(e.combo!==void 0||e.part!==void 0)throw h("bad-option","--combo and --part are a piece's: the candidate is a file.");const i=await C(o(await y(s,e.dir)),void 0).catch(m=>{throw F(m)});return{value:i,text:O(i)}}const d=await f(s,e.dir),{result:c,...r}=await u({...e,item:e.candidate},a,"render",i=>C(o(d),i));return{value:{...c,...b(r)},text:[O(c),...g(r)].join(`
7
+ `)}}),framesWeb=p({name:"frames web",summary:"A web page's screenshot with its named elements' boxes in the image's pixels, for a screen demo",input:t.strictObject({url:t.string().describe("The page: an address, or an HTML file on this computer"),el:t.array(t.string()).optional().describe("An element to locate, name=selector (CSS, or text=<words>); [data-el] elements are found too"),click:t.array(t.string()).optional().describe("Selectors clicked in order before the shot (close a banner, open a dialog)"),full:t.boolean().default(!1).describe("The whole page, not one viewport"),out:t.string().optional().describe("Where the picture goes (a WebP), its boxes in <out>.elements.json beside it; default under .allyhub/work/pages/"),dir:k,size:t.string().default(`${String($.width)}x${String($.height)}`).describe("The viewport, WIDTHxHEIGHT in CSS pixels"),scale:t.number().min(1).max(4).default($.scale).describe("Image pixels per CSS pixel; 2 draws a high-density screen, sharp when a camera goes in"),wait:t.number().int().min(0).optional().describe("Milliseconds to wait after loading and clicking")}),positional:["url"],output:t.looseObject({out:t.string(),elementsFile:t.string()}),examples:["allyhub frames web https://example.com --el cta=text=Sign\\ up --scale 2 --out assets/media/home","allyhub frames web page.html --click '#accept' --full"]},async(e,a)=>{const s=a.cwd,[l,n]=V(e.size),o=await N({cwd:s,root:await y(s,e.dir),url:e.url,out:e.out,el:e.el,click:e.click,width:l,height:n,scale:e.scale,full:e.full,wait:e.wait});return{value:o,text:[`${o.out}: ${String(o.width)}×${String(o.height)}${o.scale===1?"":` (${String(o.scale)} image pixels per CSS pixel)`}, ${String(Object.keys(o.elements).length)} elements (${Object.keys(o.elements).join(", ")||"none"}) in ${o.elementsFile}`,...o.missing.length>0?[`Not found: ${o.missing.join(", ")} (the selector is wrong, or something must be opened with --click first).`]:[]].join(`
8
8
  `),exit:o.missing.length>0?j.failed:j.ok}}),FRAMES_COMMANDS=[frames,framesCuts,framesCompare,framesWeb];
@@ -1,2 +1,2 @@
1
1
  /*! AllyHub. Copyright (c) 2026 AllyHub, Inc. All rights reserved. Use is subject to LICENSE.md. */
2
- import{add as o,addSearch as r}from"./add.js";import{align as m}from"./align.js";import{audio as t,audioRecording as e}from"./audio.js";import{authLogin as i,authLogout as p,authStatus as f,authToken as d}from"./auth.js";import{orgsList as a,orgsSwitch as s}from"./orgs.js";import{check as c}from"./check.js";import{dev as C}from"./dev.js";import{doctor as S}from"./doctor.js";import{FRAMES_COMMANDS as l}from"./frames.js";import{INSPECT_COMMANDS as M}from"./inspect/index.js";import{mcp as n}from"./mcp.js";import{model as u,modelCapabilities as h}from"./model.js";import{reference as O,referenceCompare as N,referenceServed as A,referenceSetCommand as D}from"./reference.js";import{render as E}from"./render.js";import{SCENERY_COMMANDS as g}from"./scenery.js";import{sheet as _,sheetImport as L}from"./sheet.js";import{siteMediaCommand as R}from"./site.js";import{skills as k,skillsShow as w}from"./skills.js";import{CLOUD_SOURCE as v,cloudCall as x,cloudList as T,cloudTool as U,upload as I}from"./cloud-tools.js";import{voice as P}from"./voice.js";import{words as b,wordsEdits as F}from"./words.js";export const COMMANDS=[c,...M,E,...l,t,e,_,L,C,o,r,k,w,R,b,F,m,O,N,A,D,...g,u,h,i,p,f,d,a,s,I,P,S,n],COMMAND_SOURCES=[v],MCP_COMMANDS=[T,U,x];
2
+ import{add as o,addSearch as r}from"./add.js";import{align as m}from"./align.js";import{audio as e,audioRecording as i}from"./audio.js";import{authLogin as t,authStatus as p}from"./auth.js";import{orgsList as f}from"./orgs.js";import{check as d}from"./check.js";import{dev as s}from"./dev.js";import{doctor as a}from"./doctor.js";import{FRAMES_COMMANDS as C}from"./frames.js";import{INSPECT_COMMANDS as S}from"./inspect/index.js";import{model as c,modelCapabilities as l}from"./model.js";import{slidesCapabilities as n,slidesImport as M}from"./slides.js";import{reference as O,referenceCompare as h,referenceServed as E,referenceSetCommand as N}from"./reference.js";import{render as u}from"./render.js";import{SCENERY_COMMANDS as A}from"./scenery.js";import{sheet as D,sheetImport as R}from"./sheet.js";import{siteMediaCommand as _}from"./site.js";import{skills as g,skillsShow as k}from"./skills.js";import{CLOUD_SOURCE as v,upload as w}from"./cloud-tools.js";import{voice as I}from"./voice.js";import{words as L,wordsEdits as U}from"./words.js";export const COMMANDS=[d,...S,u,...C,e,i,D,R,s,o,r,g,k,_,L,U,m,O,h,E,N,...A,c,l,n,M,t,p,f,w,I,a],COMMAND_SOURCES=[v];
@@ -1,2 +1,2 @@
1
1
  /*! AllyHub. Copyright (c) 2026 AllyHub, Inc. All rights reserved. Use is subject to LICENSE.md. */
2
- import{z as i}from"zod";import{textContrast as c}from"@allyhub-next/measure";import{stretchOf as m}from"@allyhub-next/project";import{CONTRAST_DEFAULTS as p}from"@allyhub-next/video-core";import{defineCommand as f}from"../../command.js";import{VERSION_FIELDS as h,known as u,withVersion as d}from"../../version.js";import{MOMENTS as y,STRETCH as w,all as b,factsResult as O,momentsOf as S}from"./common.js";export const inspectContrast=f({name:"inspect contrast",summary:"The text against the pixels behind its glyphs now, as WCAG contrast ratios (the check does not measure it)",input:i.strictObject({...h,...y,...w,final:i.boolean().default(!1).describe("Over the final picture, footage composited (slower), not the check's graphics"),all:b(`every block, however faint (without it, those at ${String(p.opacity*100)} % opacity or more)`)}),positional:["item"],output:i.looseObject({}),examples:["allyhub inspect contrast launch/film --part hook","allyhub inspect contrast launch/film --at 1.5 --final"]},async(t,n)=>{const r=await d(t,n,t.final?"render":"check",async o=>{const{from:s,to:a}=u(()=>m(o.timeline,t)),l=S(t,o)??(await o.version.measure()).moments.map(e=>e.t).filter(e=>e>=s-1e-6&&e<=a+1e-6);return c(o.version,l,t.all?{opacity:0}:{},t.final?{still:e=>o.still(e,{raw:!0})}:void 0)});return O(r.result,r,{all:t.all})});
2
+ import{z as i}from"zod";import{textContrast as p}from"@allyhub-next/measure";import{stretchOf as u}from"@allyhub-next/project";import{CONTRAST_DEFAULTS as f}from"@allyhub-next/video-core";import{defineCommand as h}from"../../command.js";import{VERSION_FIELDS as d,known as b,withVersion as w}from"../../version.js";import{MOMENTS as y,STRETCH as x,all as O,factsResult as k,momentsOf as g}from"./common.js";export const inspectContrast=h({name:"inspect contrast",summary:"The text against the pixels behind its glyphs now, as WCAG contrast ratios (the check does not measure it)",input:i.strictObject({...d,...y,...x,final:i.boolean().default(!1).describe("Over the final picture, footage composited (slower), not the check's graphics"),below:i.number().min(1).max(21).optional().describe("Only texts whose lowest ratio is under this one, and those not measured (default every text)"),all:O(`every block, however faint (without it, those at ${String(f.opacity*100)} % opacity or more)`)}),positional:["item"],output:i.looseObject({}),examples:["allyhub inspect contrast launch/film --part hook","allyhub inspect contrast launch/film --at 1.5 --final","allyhub inspect contrast launch/deck --below 4.5"]},async(e,r)=>{const n=await w(e,r,e.final?"render":"check",async t=>{const{from:l,to:c}=b(()=>u(t.timeline,e)),m=g(e,t)??(await t.version.measure()).moments.map(o=>o.t).filter(o=>o>=l-1e-6&&o<=c+1e-6);return p(t.version,m,e.all?{opacity:0}:{},e.final?{still:o=>t.still(o,{raw:!0})}:void 0)}),{below:s}=e,a=s===void 0?n.result:n.result.filter(t=>t.kind!=="text-contrast"||"missing"in t.data||t.data.ratio.min<s);return k(a,n,{all:e.all,total:n.result.length})});
@@ -1,2 +1,2 @@
1
1
  /*! AllyHub. Copyright (c) 2026 AllyHub, Inc. All rights reserved. Use is subject to LICENSE.md. */
2
- import{z as s}from"zod";import{measuredFacts as u}from"@allyhub-next/measure";import{stretchOf as d}from"@allyhub-next/project";import{ffmpegOf as y}from"@allyhub-next/render";import{filterFacts as b}from"@allyhub-next/video-core";import{defineCommand as h}from"../../command.js";import{textOnScreen as O}from"../../text/index.js";import{VERSION_FIELDS as k,known as w,withVersion as x}from"../../version.js";import{MOMENTS as S,STRETCH as $,all as g,boxText as E,factsResult as T,kind as j,kindsOf as F,momentsOf as L,sec as R}from"./common.js";export const inspectLayout=h({name:"inspect layout",summary:"One version's layout measured now, at its measured moments or at --at / --every; --texts lists every text block with its fonts",input:s.strictObject({...k,...S,...$,texts:s.boolean().default(!1).describe("List every text block at every moment, with its box and fonts"),kind:j,all:g()}),positional:["item"],output:s.looseObject({}),examples:["allyhub inspect layout launch/film --at 1.5,@press --texts","allyhub inspect layout launch/film --every 0.5 --part hook"]},async(e,f)=>{const n=await x(e,f,"render",async t=>{const a=t.timeline,{part:m}=w(()=>d(a,e)),i=await t.version.measure(L(e,t)),l=[...t.version.summary?.facts??[],...await u(i,a,t.target,{root:t.prepared.root,media:t.prepared.media,ffmpeg:await y()},a.profile?.label)];return{facts:b(l,{kinds:F(e.kind),part:e.part}),total:l.length,moments:e.texts?i.moments.filter(o=>!m||o.part===m.key).map(o=>({t:o.t,part:o.part,...o.face?{face:o.face}:{},texts:o.texts})):void 0}}),{facts:p,total:c,moments:r}=n.result;return T(p,n,{all:e.all,total:c,...r?{extra:{moments:r}}:{}},(r??[]).map(t=>` ${R(t.t)} ${t.part}${t.face?` face ${E(t.face)}`:""}: ${t.texts.map(O).join("; ")||"(no text)"}`))});
2
+ import{z as r}from"zod";import{measuredFacts as u}from"@allyhub-next/measure";import{DECK_FACT_DEFAULTS as c,deckFacts as h}from"@allyhub-next/slides-core";import{stretchOf as y}from"@allyhub-next/project";import{ffmpegOf as b}from"@allyhub-next/render";import{filterFacts as k}from"@allyhub-next/video-core";import{defineCommand as w}from"../../command.js";import{textOnScreen as g}from"../../text/index.js";import{VERSION_FIELDS as x,known as v,withVersion as O}from"../../version.js";import{MOMENTS as S,STRETCH as $,all as A,boxText as E,factsResult as F,kind as T,kindsOf as C,momentsOf as L,sec as N}from"./common.js";export const inspectLayout=w({name:"inspect layout",summary:"One version's layout measured now, at its measured moments or at --at / --every; --texts lists every text block with its fonts",input:r.strictObject({...x,...S,...$,texts:r.boolean().default(!1).describe("List every text block at every moment, with its box and fonts"),within:r.number().positive().optional().describe(`A deck: lines up to this many points apart and not in line are near-alignment (default ${String(c.within)})`),drift:r.number().nonnegative().optional().describe(`A deck: places further apart than this, in points, are placement-drift (default ${String(c.drift)})`),level:r.array(r.enum(["master","layout","slide"])).optional().describe("A deck: measure only shapes of these levels (default every one): slide leaves out what a master or a layout draws on every slide"),except:r.array(r.string()).optional().describe("A deck: leave shapes of these names out of every fact, * for any letters (tick-*)"),room:r.string().regex(/^[\d.]+,[\d.]+$/u).optional().describe("A deck's read-size: a room as its screen's width and its farthest seat, in metres (3,12); without it no room is measured"),kind:T,all:A()}),positional:["item"],output:r.looseObject({}),examples:["allyhub inspect layout launch/film --at 1.5,@press --texts","allyhub inspect layout launch/film --every 0.5 --part hook","allyhub inspect layout launch/deck --kind near-alignment --within 10","allyhub inspect layout launch/deck --level slide --except 'tick-*'"]},async(e,d)=>{const s=await O(e,d,"render",async t=>{const n=t.timeline,{part:l}=v(()=>y(n,e)),o=await t.version.measure(L(e,t)),m=[...t.version.summary?.facts??[],...await u(o,n,t.target,{root:t.prepared.root,media:t.prepared.media,ffmpeg:await b()},n.profile?.label),...o.deck?h(o.deck,{width:o.width,height:o.height},{piece:t.target.piece,output:t.target.output,combo:t.target.combo,format:t.target.format},{...e.within===void 0?{}:{within:e.within},...e.drift===void 0?{}:{drift:e.drift},...e.level===void 0?{}:{levels:e.level},...e.except===void 0?{}:{except:e.except},...e.room===void 0?{}:{room:{screen:Number(e.room.split(",")[0]),distance:Number(e.room.split(",")[1])}}}):[]];return{facts:k(m,{kinds:C(e.kind),part:e.part}),total:m.length,moments:e.texts?o.moments.filter(i=>!l||i.part===l.key).map(i=>({t:i.t,part:i.part,...i.face?{face:i.face}:{},texts:i.texts})):void 0}}),{facts:p,total:f,moments:a}=s.result;return F(p,s,{all:e.all,total:f,...a?{extra:{moments:a}}:{}},(a??[]).map(t=>` ${N(t.t)} ${t.part}${t.face?` face ${E(t.face)}`:""}: ${t.texts.map(g).join("; ")||"(no text)"}`))});
@@ -1,3 +1,3 @@
1
1
  /*! AllyHub. Copyright (c) 2026 AllyHub, Inc. All rights reserved. Use is subject to LICENSE.md. */
2
- import{z as o}from"zod";import{chooseOrganization as f,organizations as l,readCredentials as p}from"@allyhub-next/cloud";import{API_KEY_ENV as h,EXIT as u}from"@allyhub-next/protocol";import{defineCommand as c}from"../command.js";import{cloudOf as g,cloudWork as d}from"./cloud.js";const y=o.looseObject({id:o.string(),name:o.string(),slug:o.string(),role:o.string(),current:o.boolean()});export const orgsList=c({name:"orgs list",summary:"The organizations you are in, with your role; the one this computer acts in and pays from is marked",input:o.strictObject({}),output:o.looseObject({organizations:o.array(y)})},(r,a)=>d(async()=>{const e=g(a),s=await l(e),i=(await p(e.config))?.account.organization?.id,n=s.filter(t=>t.dissolvedAt===null).map((t,m)=>({id:t.id,name:t.name,slug:t.slug,role:t.role,current:i===void 0?m===0:t.id===i}));return{value:{organizations:n},text:n.map(t=>`${t.current?"*":" "} ${t.slug} ${t.name} ${t.role}`).join(`
3
- `)}})),orgsSwitch=c({name:"orgs switch",summary:"Act in and pay from another organization on this computer (Studio too), by its slug or id",input:o.strictObject({org:o.string().min(1).describe("The organization: its slug or id")}),positional:["org"],output:o.looseObject({id:o.string(),name:o.string()}),examples:["allyhub orgs switch apollo"]},(r,a)=>d(async()=>{const e=g(a);if(e.config.apiKey!==void 0)return{value:{id:"",name:""},text:`A key in ${h} acts in the organization it was made for; unset it to choose one here.`,exit:u.usage};const i=(await l(e)).filter(n=>n.dissolvedAt===null).find(n=>n.slug===r.org||n.id===r.org);return i===void 0?{value:{id:"",name:""},text:`You are in no organization ${r.org}. allyhub orgs list says which you are in.`,exit:u.usage}:(await f(e.config,{id:i.id,name:i.name}),{value:{id:i.id,name:i.name},text:`This computer acts in ${i.name} now.`})}));
2
+ import{z as n}from"zod";import{organizations as l,readCredentials as c}from"@allyhub-next/cloud";import{defineCommand as u}from"../command.js";import{cloudOf as m,cloudWork as d}from"./cloud.js";const g=n.looseObject({id:n.string(),name:n.string(),slug:n.string(),role:n.string(),current:n.boolean()});export const orgsList=u({name:"orgs list",summary:"The organizations you are in, with your role; the one this computer acts in and pays from is marked",input:n.strictObject({}),output:n.looseObject({organizations:n.array(g)})},(p,e)=>d(async()=>{const o=m(e),a=await l(o),r=(await c(o.config))?.account.organization?.id,i=a.filter(t=>t.dissolvedAt===null).map((t,s)=>({id:t.id,name:t.name,slug:t.slug,role:t.role,current:r===void 0?s===0:t.id===r}));return{value:{organizations:i},text:i.map(t=>`${t.current?"*":" "} ${t.slug} ${t.name} ${t.role}`).join(`
3
+ `)}}));
@@ -1,3 +1,3 @@
1
1
  /*! AllyHub. Copyright (c) 2026 AllyHub, Inc. All rights reserved. Use is subject to LICENSE.md. */
2
- import{join as u,resolve as b}from"node:path";import{z as a}from"zod";import{formatConsole as g,formatProblem as y}from"../text/index.js";import{exportProject as x}from"@allyhub-next/export";import{SHARE_ENCODE as s}from"@allyhub-next/render";import{consoleJson as m}from"@allyhub-next/project";import{OUT_DIR as v}from"@allyhub-next/formats";import{EXIT as d}from"@allyhub-next/protocol";import{defineCommand as w}from"../command.js";import{parameters as $}from"../parameters.js";import{projectRoot as k}from"../project.js";import{combosOf as P,commandError as O}from"../version.js";import{dir as j,indexing as B}from"../fields.js";const S={codec:a.enum(["h264","h265"]).default("h264").describe("The mp4's video codec; h265 is smaller"),crf:a.number().int().min(0).max(63).optional().describe(`Quality, lower is better: default ${String(s.crf)} for an mp4, ready to share (a platform profile's format its own), 30 for a webm`),maxBitrate:a.number().int().min(0).max(5e5).optional().describe(`An mp4's most video bitrate, kbit/s, 0 for none: default ${String(s.maxKbps)} at 1080p ${String(s.fps)} fps, scaled by the frame's pixels and the frames a second (16000 at 1080p 60, 32000 at 4K 30), so the file is ready to share; a platform profile's format its own`),audioBitrate:a.number().int().min(32).max(512).optional().describe("The sound's bitrate, kbit/s: default 192 (AAC in an mp4), 160 (Opus in a webm); a mov keeps PCM")},T=(o,r)=>`${String(o)} ${r}${o===1?"":"s"}`;export const render=w({name:"render",summary:"The files: a video, its frames, subtitles, cover and mastered mix; a batch's table of ads; a deck's PDF, PPTX and PNGs; a doc's PDF and Markdown; a sheet's xlsx, CSV, Markdown and JSON; a 3D model's GLB",input:a.strictObject({items:a.array(a.string()).optional().describe("Only these items: an id, a path into one, or a folder of items; default every one"),combo:a.array(a.string()).optional().describe("Only the combos matching name=value pairs joined with commas (lang=zh-cn,hook=b), or a combo's id (c03)"),type:a.array(a.string()).optional().describe("File types: mp4, mov, webm, gif, png, srt, vtt (cues cut as the piece's captions layer cuts them, else by default), cover, wav (the mix, mastered as the render masters it: 48 kHz, 16 bits, the film's length), pdf, pptx; csv for a piece with slots, its table of ads (<piece>/ads.csv: a row per ad with its combo, picks, length, file, name and generated media); a doc's pdf, png, md; a sheet's xlsx, csv, md, json; a 3D model's glb. Default mp4 for a video, pdf for a deck and a doc, xlsx for a sheet, glb for a model; a type an item does not have is skipped"),out:a.string().optional().describe("The folder the files go in; default .allyhub/out"),name:a.string().optional().describe("Name a video's or deck's files <name>.<ext> in its folder of the output, with what tells its versions apart before the extension when there are several (<name>.zh-cn.mp4, <name>.c03.mp4); default <output>.<combo>.<ext>"),params:$(S),dir:j}),positional:["items"],output:a.looseObject({out:a.string(),files:a.array(a.looseObject({name:a.string(),path:a.string(),type:a.string()})),failed:a.array(a.looseObject({name:a.string(),code:a.string()}))}),examples:["allyhub render","allyhub render launch/film --type mp4,srt","allyhub render launch/film --type wav","allyhub render ads/tidyform --type csv","allyhub render launch/plan --type pdf,md","allyhub render --combo lang=zh-cn --param crf=16","allyhub render launch/film --name launch-film --param max-bitrate=0"]},async(o,r)=>{const n=await k(r.cwd,o.dir),l=b(r.cwd,o.out??u(n,v)),i=o.params,f={codec:i.codec,...i.crf===void 0?{}:{crf:i.crf},...i.maxBitrate===void 0?{}:{maxBitrate:i.maxBitrate},...i.audioBitrate===void 0?{}:{audioBitrate:i.audioBitrate}};let t;try{t=await x({root:n,out:l,...o.items===void 0?{}:{items:o.items},combos:P(o),...o.type===void 0?{}:{types:o.type},...o.name===void 0?{}:{name:o.name},encode:f,index:B(r.env),log:e=>{r.progress(e)},signal:r.signal})}catch(e){throw O(e)}const p=e=>e?` (${e.integrated.toFixed(1)} LUFS, true peak ${e.truePeak===void 0?"–":e.truePeak.toFixed(1)} dBTP)`:"",c=t.problems.filter(e=>e.level==="error"),h=[`${T(t.files.length,"file")} in ${t.out}:`,...t.files.map(e=>` ${e.path}${p(e.loudness)}`),...t.failed.length>0?["Not made:",...t.failed.map(e=>` ${e.name}: ${e.message}${e.hint?` ${e.hint}`:""}`)]:[],...t.unindexed.map(e=>`Not indexed, drawn the fallback way: ${e.file} (${e.error})`),...c.map(y),...g(m(t.console))];return{value:{out:t.out,files:t.files.map(e=>({...e})),failed:t.failed.map(e=>({...e})),problems:t.problems,...t.unindexed.length>0?{unindexed:t.unindexed}:{},...m(t.console)},text:h.join(`
3
- `),exit:t.failed.length>0?d.failed:d.ok}});
2
+ import{join as x,resolve as g}from"node:path";import{z as t}from"zod";import{formatConsole as y,formatProblem as w}from"../text/index.js";import{exportProject as v}from"@allyhub-next/export";import{SHARE_ENCODE as n}from"@allyhub-next/render";import{consoleJson as m}from"@allyhub-next/project";import{OUT_DIR as k}from"@allyhub-next/formats";import{EXIT as p}from"@allyhub-next/protocol";import{defineCommand as $}from"../command.js";import{parameters as P}from"../parameters.js";import{projectRoot as O}from"../project.js";import{combosOf as j,commandError as B}from"../version.js";import{dir as S,indexing as A}from"../fields.js";const T={codec:t.enum(["h264","h265"]).default("h264").describe("The mp4's video codec; h265 is smaller"),crf:t.number().int().min(0).max(63).optional().describe(`Quality, lower is better: default ${String(n.crf)} for an mp4, ready to share (a platform profile's format its own), 30 for a webm`),maxBitrate:t.number().int().min(0).max(5e5).optional().describe(`An mp4's most video bitrate, kbit/s, 0 for none: default ${String(n.maxKbps)} at 1080p ${String(n.fps)} fps, scaled by the frame's pixels and the frames a second (16000 at 1080p 60, 32000 at 4K 30), so the file is ready to share; a platform profile's format its own`),audioBitrate:t.number().int().min(32).max(512).optional().describe("The sound's bitrate, kbit/s: default 192 (AAC in an mp4), 160 (Opus in a webm); a mov keeps PCM"),steps:t.boolean().default(!1).describe("A deck's pdf, png and pptx: a page, a file or a slide per step of each page, not only its last"),pptx:t.enum(["native","picture","editable"]).default("native").describe("A deck's pptx: native, PowerPoint's own model (the deck's masters, layouts, placeholders, shapes, text, pictures, videos and notes, a component as its picture); picture, each slide a picture of the page; or editable, the page's picture without its text under a text box per block of text")},D=(o,s)=>`${String(o)} ${s}${o===1?"":"s"}`;export const render=$({name:"render",summary:"The files: a video, its frames, subtitles, cover and mastered mix; a batch's table of ads; a deck's PDF, PPTX and PNGs; a doc's PDF and Markdown; a sheet's xlsx, CSV, Markdown and JSON; a 3D model's GLB",input:t.strictObject({items:t.array(t.string()).optional().describe("Only these items: an id, a path into one, or a folder of items; default every one"),combo:t.array(t.string()).optional().describe("Only the combos matching name=value pairs joined with commas (lang=zh-cn,hook=b), or a combo's id (c03)"),type:t.array(t.string()).optional().describe("File types: mp4, mov, webm, gif, png, srt, vtt (cues cut as the piece's captions layer cuts them, else by default), cover, wav (the mix, mastered as the render masters it: 48 kHz, 16 bits, the film's length), pdf, pptx; csv for a piece with slots, its table of ads (<piece>/ads.csv: a row per ad with its combo, picks, length, file, name and generated media); a doc's pdf, docx, png, md; a sheet's xlsx, csv, md, json; a 3D model's glb. Default mp4 for a video, pdf for a deck and a doc, xlsx for a sheet, glb for a model; a type an item does not have is skipped"),out:t.string().optional().describe("The folder the files go in; default .allyhub/out"),name:t.string().optional().describe("Name a video's or deck's files <name>.<ext> in its folder of the output, with what tells its versions apart before the extension when there are several (<name>.zh-cn.mp4, <name>.c03.mp4); default <output>.<combo>.<ext>"),params:P(T),dir:S}),positional:["items"],output:t.looseObject({out:t.string(),files:t.array(t.looseObject({name:t.string(),path:t.string(),type:t.string()})),failed:t.array(t.looseObject({name:t.string(),code:t.string()}))}),examples:["allyhub render","allyhub render launch/film --type mp4,srt","allyhub render launch/film --type wav","allyhub render ads/tidyform --type csv","allyhub render launch/plan --type pdf,md","allyhub render launch/deck --type pptx --param pptx=editable","allyhub render --combo lang=zh-cn --param crf=16","allyhub render launch/film --name launch-film --param max-bitrate=0"]},async(o,s)=>{const d=await O(s.cwd,o.dir),c=g(s.cwd,o.out??x(d,k)),r=o.params,f={codec:r.codec,...r.crf===void 0?{}:{crf:r.crf},...r.maxBitrate===void 0?{}:{maxBitrate:r.maxBitrate},...r.audioBitrate===void 0?{}:{audioBitrate:r.audioBitrate}};let a;try{a=await v({root:d,out:c,...o.items===void 0?{}:{items:o.items},combos:j(o),...o.type===void 0?{}:{types:o.type},...o.name===void 0?{}:{name:o.name},encode:f,...r.steps?{steps:!0}:{},...r.pptx==="native"?{}:{pptx:r.pptx},index:A(s.env),log:e=>{s.progress(e)},signal:s.signal})}catch(e){throw B(e)}const h=e=>e?` (${e.integrated.toFixed(1)} LUFS, true peak ${e.truePeak===void 0?"–":e.truePeak.toFixed(1)} dBTP)`:"",u=a.problems.filter(e=>e.level==="error"),l=a.files.flatMap(e=>e.files.length>1?e.files.map(i=>` ${i}`):[` ${e.path}${h(e.loudness)}`]),b=[`${D(l.length,"file")} in ${a.out}:`,...l,...a.failed.length>0?["Not made:",...a.failed.map(e=>` ${e.name}: ${e.message}${e.hint?` ${e.hint}`:""}`)]:[],...a.unindexed.map(e=>`Not indexed, drawn the fallback way: ${e.file} (${e.error})`),...new Set(a.files.flatMap(e=>(e.fontsLeft??[]).map(i=>`Not in the file: ${i.font} (${i.why}); PowerPoint shows another font where it is not installed.`))),...u.map(w),...y(m(a.console))];return{value:{out:a.out,files:a.files.map(e=>({...e})),failed:a.failed.map(e=>({...e})),problems:a.problems,...a.unindexed.length>0?{unindexed:a.unindexed}:{},...m(a.console)},text:b.join(`
3
+ `),exit:a.failed.length>0?p.failed:p.ok}});
@@ -1,4 +1,4 @@
1
1
  /*! AllyHub. Copyright (c) 2026 AllyHub, Inc. All rights reserved. Use is subject to LICENSE.md. */
2
- import{mkdir as M,readFile as b,stat as S,writeFile as k}from"node:fs/promises";import{basename as x,dirname as v,join as l,relative as I,resolve as T}from"node:path";import{z as m}from"zod";import{ITEM_KINDS as N,SHEET_SPEC as E}from"@allyhub-next/formats";import{EXIT as w}from"@allyhub-next/protocol";import{importSheets as V,PROFILE_TOP as L,profileSheet as _,readSheet as j,readSpec as A}from"@allyhub-next/sheet";import{CommandError as p,defineCommand as F}from"../command.js";import{projectRoot as O}from"../project.js";import{dir as C}from"../fields.js";const u=N.sheet.entries[0];async function D(e,n,o){const s=T(n,o);for(const t of[x(s)===u?s:l(s,u),l(e,o,u)])if((await S(t).catch(()=>{}))?.isFile())return t;throw new p("not-found",`There is no sheet ${o}.`,{exit:w.notFound,hint:"Name it by its folder (research/leads) or its sheet.csv."})}const d=e=>e.toLocaleString("en-US"),y=e=>e.toLocaleString("en-US",{maximumFractionDigits:4});function P(e,n){const o=[`${d(e.empty)} empty`,`${d(e.distinct)} distinct`];if(e.unreadable>0&&o.push(`${d(e.unreadable)} unreadable`),e.min!==void 0&&e.max!==void 0){const t=r=>typeof r=="number"?y(r):r;o.push(`${t(e.min)} to ${t(e.max)}`)}e.sum!==void 0&&o.push(`sum ${y(e.sum)}`),e.mean!==void 0&&o.push(`mean ${y(e.mean)}`),e.shortest!==void 0&&e.longest!==void 0&&o.push(`${String(e.shortest)} to ${String(e.longest)} characters`);const s=[`${e.name.padEnd(n)} ${e.type.padEnd(12)} ${o.join(", ")}`];return e.values?.some(t=>t.count>1)&&s.push(`${"".padEnd(n+14)} most: ${e.values.map(t=>`${JSON.stringify(t.value.length>40?`${t.value.slice(0,39)}…`:t.value)} ${d(t.count)}`).join(", ")}`),s}const R=m.string().transform(e=>e.replace(/^\/+|\/+$/gu,"")).refine(e=>e!==""&&!e.split("/").some(n=>n===""||n==="."||n===".."),{message:"a folder from the project's root, such as research/leads"});async function U(){return(await import("exceljs")).default}export const sheet=F({name:"sheet",summary:"A sheet's columns measured: counts, empty, distinct, ranges, frequent values",input:m.strictObject({sheet:m.string().describe("The sheet, by its folder or its sheet.csv"),dir:C}),positional:["sheet"],output:m.looseObject({}),examples:["allyhub sheet research/leads"]},async(e,n)=>{const o=await O(n.cwd,e.dir),s=await D(o,n.cwd,e.sheet),t=j(await b(s,"utf8")),r=await b(l(v(s),E),"utf8").catch(()=>{}),f=r===void 0?{columns:{}}:A(r).spec,c=_(t.data,f),h=I(o,s),a=Math.min(24,Math.max(4,...c.map(i=>i.name.length)));return{value:{file:h,rows:t.data.rows.length,columns:c,problems:t.problems.length},text:[`${h}: ${d(t.data.rows.length)} rows, ${String(c.length)} columns; each column's ${String(L)} most frequent values`,"",...c.flatMap(i=>P(i,a)),...t.problems.length>0?["",`The file has ${String(t.problems.length)} problems: allyhub check lists them.`]:[]].join(`
3
- `)}}),sheetImport=F({name:"sheet import",summary:"Makes a sheet of a CSV, TSV or workbook: a CSV as it is, a TSV as CSV, a workbook a sheet per worksheet; never over a place that is taken",input:m.strictObject({file:m.string().describe("The file to make a sheet of; a workbook's columns are typed only where it types a whole column"),to:R.optional().describe("The sheet's folder, from the project's root (default the file's name); a workbook's worksheets go at <folder>-<worksheet>"),dir:C}),positional:["file"],output:m.looseObject({}),examples:["allyhub sheet import ~/Downloads/leads.xlsx --to research/leads"]},async(e,n)=>{const o=await O(n.cwd,e.dir),s=T(n.cwd,e.file),t=await b(s).catch(()=>{throw new p("not-found",`There is no file ${s}.`,{exit:w.notFound})}),r=e.to?.includes("/")?v(e.to):"";let f;try{f=await V(s,new Uint8Array(t),{...e.to===void 0?{}:{base:x(e.to)},.../\.xlsx$/iu.test(s)?{excel:await U()}:{}})}catch(a){throw new p("bad-file",a.message,{exit:w.usage})}const c=f.map(a=>r===""?a.name:`${r}/${a.name}`);for(const a of c)if(await S(l(o,a)).catch(()=>{}))throw new p("place-taken",`${a} is already there.`,{exit:w.conflict,hint:"Name another place with --to."});const h=[];for(const[a,i]of f.entries()){const $=c[a]??i.name,g=l(o,$);await M(g,{recursive:!0}),await k(l(g,u),i.csv,{flag:"wx"}),await k(l(g,E),i.spec,{flag:"wx"}),h.push({place:$,file:`${$}/${u}`,title:i.title,rows:j(i.csv).data.rows.length})}return{value:{made:h},text:h.map(a=>`Made ${a.file}: ${d(a.rows)} row${a.rows===1?"":"s"}`).join(`
2
+ import{mkdir as M,readFile as b,stat as S,writeFile as k}from"node:fs/promises";import{basename as x,dirname as v,join as l,relative as I,resolve as T}from"node:path";import{z as m}from"zod";import{ITEM_KINDS as N,SHEET_SPEC as j}from"@allyhub-next/formats";import{EXIT as w}from"@allyhub-next/protocol";import{createPackages as V}from"@allyhub-next/runtimes";import{importSheets as L,PROFILE_TOP as P,profileSheet as _,readSheet as E,readSpec as A}from"@allyhub-next/sheet";import{CommandError as p,defineCommand as F}from"../command.js";import{projectRoot as O}from"../project.js";import{dir as C}from"../fields.js";const u=N.sheet.entries[0];async function D(e,n,o){const s=T(n,o);for(const t of[x(s)===u?s:l(s,u),l(e,o,u)])if((await S(t).catch(()=>{}))?.isFile())return t;throw new p("not-found",`There is no sheet ${o}.`,{exit:w.notFound,hint:"Name it by its folder (research/leads) or its sheet.csv."})}const d=e=>e.toLocaleString("en-US"),y=e=>e.toLocaleString("en-US",{maximumFractionDigits:4});function R(e,n){const o=[`${d(e.empty)} empty`,`${d(e.distinct)} distinct`];if(e.unreadable>0&&o.push(`${d(e.unreadable)} unreadable`),e.min!==void 0&&e.max!==void 0){const t=r=>typeof r=="number"?y(r):r;o.push(`${t(e.min)} to ${t(e.max)}`)}e.sum!==void 0&&o.push(`sum ${y(e.sum)}`),e.mean!==void 0&&o.push(`mean ${y(e.mean)}`),e.shortest!==void 0&&e.longest!==void 0&&o.push(`${String(e.shortest)} to ${String(e.longest)} characters`);const s=[`${e.name.padEnd(n)} ${e.type.padEnd(12)} ${o.join(", ")}`];return e.values?.some(t=>t.count>1)&&s.push(`${"".padEnd(n+14)} most: ${e.values.map(t=>`${JSON.stringify(t.value.length>40?`${t.value.slice(0,39)}…`:t.value)} ${d(t.count)}`).join(", ")}`),s}const U=m.string().transform(e=>e.replace(/^\/+|\/+$/gu,"")).refine(e=>e!==""&&!e.split("/").some(n=>n===""||n==="."||n===".."),{message:"a folder from the project's root, such as research/leads"});async function q(){const{default:e}=await V().load("exceljs");return e}export const sheet=F({name:"sheet",summary:"A sheet's columns measured: counts, empty, distinct, ranges, frequent values",input:m.strictObject({sheet:m.string().describe("The sheet, by its folder or its sheet.csv"),dir:C}),positional:["sheet"],output:m.looseObject({}),examples:["allyhub sheet research/leads"]},async(e,n)=>{const o=await O(n.cwd,e.dir),s=await D(o,n.cwd,e.sheet),t=E(await b(s,"utf8")),r=await b(l(v(s),j),"utf8").catch(()=>{}),f=r===void 0?{columns:{}}:A(r).spec,c=_(t.data,f),h=I(o,s),a=Math.min(24,Math.max(4,...c.map(i=>i.name.length)));return{value:{file:h,rows:t.data.rows.length,columns:c,problems:t.problems.length},text:[`${h}: ${d(t.data.rows.length)} rows, ${String(c.length)} columns; each column's ${String(P)} most frequent values`,"",...c.flatMap(i=>R(i,a)),...t.problems.length>0?["",`The file has ${String(t.problems.length)} problems: allyhub check lists them.`]:[]].join(`
3
+ `)}}),sheetImport=F({name:"sheet import",summary:"Makes a sheet of a CSV, TSV or workbook: a CSV as it is, a TSV as CSV, a workbook a sheet per worksheet; never over a place that is taken",input:m.strictObject({file:m.string().describe("The file to make a sheet of; a workbook's columns are typed only where it types a whole column"),to:U.optional().describe("The sheet's folder, from the project's root (default the file's name); a workbook's worksheets go at <folder>-<worksheet>"),dir:C}),positional:["file"],output:m.looseObject({}),examples:["allyhub sheet import ~/Downloads/leads.xlsx --to research/leads"]},async(e,n)=>{const o=await O(n.cwd,e.dir),s=T(n.cwd,e.file),t=await b(s).catch(()=>{throw new p("not-found",`There is no file ${s}.`,{exit:w.notFound})}),r=e.to?.includes("/")?v(e.to):"";let f;try{f=await L(s,new Uint8Array(t),{...e.to===void 0?{}:{base:x(e.to)},.../\.xlsx$/iu.test(s)?{excel:await q()}:{}})}catch(a){throw new p("bad-file",a.message,{exit:w.usage})}const c=f.map(a=>r===""?a.name:`${r}/${a.name}`);for(const a of c)if(await S(l(o,a)).catch(()=>{}))throw new p("place-taken",`${a} is already there.`,{exit:w.conflict,hint:"Name another place with --to."});const h=[];for(const[a,i]of f.entries()){const $=c[a]??i.name,g=l(o,$);await M(g,{recursive:!0}),await k(l(g,u),i.csv,{flag:"wx"}),await k(l(g,j),i.spec,{flag:"wx"}),h.push({place:$,file:`${$}/${u}`,title:i.title,rows:E(i.csv).data.rows.length})}return{value:{made:h},text:h.map(a=>`Made ${a.file}: ${d(a.rows)} row${a.rows===1?"":"s"}`).join(`
4
4
  `)}});
@@ -0,0 +1,3 @@
1
+ /*! AllyHub. Copyright (c) 2026 AllyHub, Inc. All rights reserved. Use is subject to LICENSE.md. */
2
+ import{mkdir as y,readFile as b,stat as k,writeFile as x}from"node:fs/promises";import{basename as p,dirname as $,join as f,resolve as v}from"node:path";import{z as o}from"zod";import{EXIT as l}from"@allyhub-next/protocol";import{CAPABILITIES as h}from"@allyhub-next/slides-core";import{importDeck as j,nameOf as P,readPptx as O}from"@allyhub-next/slides-pptx";import{CommandError as n,defineCommand as u}from"../command.js";import{dir as I}from"../fields.js";import{projectRoot as T}from"../project.js";export const slidesCapabilities=u({name:"slides capabilities",summary:"What a deck's API holds of python-pptx's (its classes and enums), how it differs and what it adds, as JSON",input:o.strictObject({}),output:o.looseObject({}),examples:["allyhub slides capabilities"]},()=>Promise.resolve({value:{...h},text:JSON.stringify(h,null,2)}));const z=o.string().transform(e=>e.replace(/^\/+|\/+$/gu,"")).refine(e=>e!==""&&!e.split("/").some(a=>a===""||a==="."||a===".."),{message:"a folder from the project's root, such as launch/deck"});export const slidesImport=u({name:"slides import",summary:"Makes a deck of a PowerPoint file: its masters and layouts as slides.ts, its slides as slides.yaml, its words and notes as the script, its pictures and videos in media/; says what it could not hold; never over a place that is taken",input:o.strictObject({file:o.string().describe("The .pptx to make a deck of"),to:z.optional().describe("The deck's folder, from the project's root (default the file's name)"),lang:o.string().regex(/^[a-z]{2,3}(-[a-z0-9]+)*$/u).default("en").describe("The language of its words: the script is script.<lang>.yaml"),dir:I}),positional:["file"],output:o.looseObject({}),examples:["allyhub slides import ~/Downloads/q3-review.pptx --to reviews/q3","allyhub slides import 培训.pptx --to training --lang zh-cn"]},async(e,a)=>{const c=await T(a.cwd,e.dir),r=v(a.cwd,e.file),w=await b(r).catch(()=>{throw new n("not-found",`There is no file ${r}.`,{exit:l.notFound})}),t=e.to??P(p(r).replace(/\.pptx$/iu,""),new Set,"deck");if(await k(f(c,t)).catch(()=>{}))throw new n("place-taken",`${t} is already there.`,{exit:l.conflict,hint:"Name another place with --to."});let i;try{i=j(O(new Uint8Array(w)),{lang:e.lang,source:p(r)})}catch(s){throw new n("bad-file",`${r} is not a PowerPoint file this can read: ${s.message}`,{exit:l.usage})}for(const[s,g]of i.files){const m=f(c,t,s);await y($(m),{recursive:!0}),await x(m,g,{flag:"wx"})}const d=[...i.files.keys()];return{value:{place:t,files:d.map(s=>`${t}/${s}`),lost:i.lost},text:[`Made ${t}/: ${d.join(", ")}`,...i.lost.length>0?["Not carried over:",...i.lost.map(s=>` ${s}`)]:[],`allyhub check, then allyhub frames ${t}, to see it.`].join(`
3
+ `)}});
package/dist/main.js CHANGED
@@ -1,8 +1,8 @@
1
1
  /*! AllyHub. Copyright (c) 2026 AllyHub, Inc. All rights reserved. Use is subject to LICENSE.md. */
2
- import{EXIT as m,describeCommand as O}from"@allyhub-next/protocol";import{readArgs as D}from"./args.js";import{CLI_VERSION as S}from"./cli-version.js";import{CommandError as h}from"./command.js";import{COMMAND_SOURCES as M,COMMANDS as N}from"./commands/index.js";import{commandHelp as E,listHelp as T,workHelp as H}from"./help.js";import{sdkDocs as R}from"./sdk-docs.js";import{WORKS as G,cloudNouns as J,workNamed as W,workTitle as j}from"./works.js";const _={stdout:e=>process.stdout.write(e),stderr:e=>process.stderr.write(e),cwd:process.cwd(),env:process.env};export function findCommand(e,s=N){let i;for(const c of s){const l=c.spec.name.split(" ");l.every((o,a)=>e[a]===o)&&l.length>(i?.length??0)&&(i={command:c,length:l.length})}return i?{command:i.command,rest:e.slice(i.length)}:{rest:[...e]}}export async function resolveCommand(e,s,i=N,c=M){const l=findCommand(e,i);if(l.command)return l;for(const o of c){const a=await o.resolve(e,s);if(a)return a}return l}const A=e=>({...O(e.spec),...e.about?.value});export async function main(e,s=_,i=N,c=M){const l=e.includes("--json"),o=e.filter(n=>n!=="--json"),a=(n,t)=>{s.stdout(l?`${JSON.stringify(n,null,2)}
2
+ import{EXIT as m,describeCommand as M}from"@allyhub-next/protocol";import{readArgs as T}from"./args.js";import{CLI_VERSION as N}from"./cli-version.js";import{CommandError as w}from"./command.js";import{COMMAND_SOURCES as E,COMMANDS as C}from"./commands/index.js";import{commandHelp as j,listHelp as H,workHelp as R}from"./help.js";import{sdkDocs as W}from"./sdk-docs.js";import{WORKS as G,cloudNouns as J,workNamed as _,workTitle as A}from"./works.js";const K={stdout:e=>process.stdout.write(e),stderr:e=>process.stderr.write(e),cwd:process.cwd(),env:process.env};export function findCommand(e,s=C){let i;for(const c of s){const l=c.spec.name.split(" ");l.every((o,a)=>e[a]===o)&&l.length>(i?.length??0)&&(i={command:c,length:l.length})}return i?{command:i.command,rest:e.slice(i.length)}:{rest:[...e]}}export async function resolveCommand(e,s,i=C,c=E){const l=findCommand(e,i);if(l.command)return l;for(const o of c){const a=await o.resolve(e,s);if(a)return a}return l}const D=e=>({...M(e.spec),...e.about?.value});export async function main(e,s=K,i=C,c=E){const l=e.includes("--json"),o=e.filter(n=>n!=="--json"),a=(n,t)=>{s.stdout(l?`${JSON.stringify(n,null,2)}
3
3
  `:`${t}
4
- `)},b=i.map(n=>n.spec),v=new AbortController,y={cwd:s.cwd,env:s.env,progress:n=>{s.stderr(`${n}
5
- `)},signal:v.signal};if(o[0]==="--version"||o[0]==="-v")return a({version:S},S),m.ok;if(o.length===0||o[0]==="help"||o[0]==="--help"||o[0]==="-h"){const n=o.slice(1),t=await R(s.cwd).catch(()=>{}),k=async()=>{const r=await Promise.all(c.map(u=>u.nouns(y).catch(()=>{})));return r.some(u=>u===void 0)?void 0:r.flatMap(u=>u??[])};if(n.length===0){const r=await k();return a({version:S,docs:t?.dir,works:G.map(u=>({...u,title:j(u,r)})),commands:b.map(O),made:[...c.flatMap(u=>u.entries),...r??[]]},T(b,c,r,t?.dir)),m.ok}const d=n.length===1?W(n[0]??""):void 0;if(d){const r=d.cloud===void 0?[]:await k();return a({...d,title:j(d,r),...d.cloud===void 0?{}:{cloudWorks:r&&J(d,r)},docsDir:t?.dir},H(d,b,c,t?.dir,r)),m.ok}let p;try{p=await resolveCommand(n,y,i,c)}catch(r){return g(r)}const{command:f,rest:I}=p;return f&&p.list===!0?await $(f,I):!f||I.length>0?g(new h("unknown-command",`allyhub has no command "${n.join(" ")}".`,{exit:m.usage,hint:"allyhub help lists them and the works."})):(a(A(f),E(f.spec,f.about?.lines)),m.ok)}let C;try{C=await resolveCommand(o,y,i,c)}catch(n){return g(n)}const{command:w,rest:x}=C;if(!w)return g(new h("unknown-command",`allyhub has no command "${o[0]??""}".`,{exit:m.usage,hint:"allyhub help lists them."}));if(x.includes("--help")||x.includes("-h"))return a(A(w),E(w.spec,w.about?.lines)),m.ok;return await $(w,x);async function $(n,t){const k=()=>{v.abort(new h("interrupted","Stopped.",{exit:m.interrupted}))};process.once("SIGINT",k);try{const d=D(n.spec,t),p=await n.run(d,y);return a(p.value,p.text),p.exit??m.ok}catch(d){return g(d)}finally{process.off("SIGINT",k)}}function g(n){const t=n instanceof h?n:v.signal.aborted?new h("interrupted","Stopped.",{exit:m.interrupted}):new h("failed",n instanceof Error?n.message:String(n));return l?s.stdout(`${JSON.stringify({error:{code:t.code,message:t.message,...t.hint?{hint:t.hint}:{}}},null,2)}
4
+ `)},b=i.map(n=>n.spec),x=new AbortController,y={cwd:s.cwd,env:s.env,progress:n=>{s.stderr(`${n}
5
+ `)},signal:x.signal};if(o[0]==="--version"||o[0]==="-v")return a({version:N},N),m.ok;if(o.length===0||o[0]==="help"||o[0]==="--help"||o[0]==="-h"){const n=o.slice(1).findIndex(r=>r.startsWith("-")),t=n<0?o.slice(1):o.slice(1,n+1),f=await W(s.cwd).catch(()=>{}),p=async()=>{const r=await Promise.all(c.map(u=>u.nouns(y).catch(()=>{})));return r.some(u=>u===void 0)?void 0:r.flatMap(u=>u??[])};if(t.length===0){const r=await p();return a({version:N,docs:f?.dir,works:G.map(u=>({...u,title:A(u,r)})),commands:b.map(M),made:[...c.flatMap(u=>u.entries),...r??[]]},H(b,c,r,f?.dir)),m.ok}const d=t.length===1?_(t[0]??""):void 0;if(d){const r=d.cloud===void 0?[]:await p();return a({...d,title:A(d,r),...d.cloud===void 0?{}:{cloudWorks:r&&J(d,r)},docsDir:f?.dir},R(d,b,c,f?.dir,r)),m.ok}let S;try{S=await resolveCommand(t,y,i,c)}catch(r){return k(r)}const{command:h,rest:O}=S;return h&&S.list===!0?await $(h,O):!h||O.length>0?k(new w("unknown-command",`allyhub has no command "${t.join(" ")}".`,{exit:m.usage,hint:"allyhub help lists them and the works."})):(a(D(h),j(h.spec,h.about?.lines)),m.ok)}let I;try{I=await resolveCommand(o,y,i,c)}catch(n){return k(n)}const{command:g,rest:v}=I;if(!g)return k(new w("unknown-command",`allyhub has no command "${o[0]??""}".`,{exit:m.usage,hint:"allyhub help lists them."}));if(v.includes("--help")||v.includes("-h"))return a(D(g),j(g.spec,g.about?.lines)),m.ok;return await $(g,v);async function $(n,t){const f=()=>{x.abort(new w("interrupted","Stopped.",{exit:m.interrupted}))};process.once("SIGINT",f);try{const p=T(n.spec,t),d=await n.run(p,y);return a(d.value,d.text),d.exit??m.ok}catch(p){return k(p)}finally{process.off("SIGINT",f)}}function k(n){const t=n instanceof w?n:x.signal.aborted?new w("interrupted","Stopped.",{exit:m.interrupted}):new w("failed",n instanceof Error?n.message:String(n));return l?s.stdout(`${JSON.stringify({error:{code:t.code,message:t.message,...t.hint?{hint:t.hint}:{}}},null,2)}
6
6
  `):s.stderr(`${t.message}${t.hint?`
7
7
  ${t.hint}`:""}
8
8
  `),t.exit}}