zilmate 1.9.9 → 1.10.2

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 (287) hide show
  1. package/.agents/skills/ad-creative/SKILL.md +362 -0
  2. package/.agents/skills/ad-creative/evals/evals.json +90 -0
  3. package/.agents/skills/ad-creative/references/generative-tools.md +637 -0
  4. package/.agents/skills/ad-creative/references/platform-specs.md +213 -0
  5. package/.agents/skills/ai-seo/SKILL.md +489 -0
  6. package/.agents/skills/ai-seo/evals/evals.json +90 -0
  7. package/.agents/skills/ai-seo/references/content-patterns.md +285 -0
  8. package/.agents/skills/ai-seo/references/content-types.md +71 -0
  9. package/.agents/skills/ai-seo/references/okf.md +104 -0
  10. package/.agents/skills/ai-seo/references/platform-ranking-factors.md +154 -0
  11. package/.agents/skills/clerk-backend-api/SKILL.md +426 -0
  12. package/.agents/skills/clerk-backend-api/evals/evals.json +87 -0
  13. package/.agents/skills/clerk-backend-api/scripts/api-specs-context.sh +30 -0
  14. package/.agents/skills/clerk-backend-api/scripts/execute-request.sh +88 -0
  15. package/.agents/skills/clerk-backend-api/scripts/extract-endpoint-detail.sh +165 -0
  16. package/.agents/skills/clerk-backend-api/scripts/extract-tag-endpoints.sh +208 -0
  17. package/.agents/skills/clerk-backend-api/scripts/extract-tags.js +14 -0
  18. package/.agents/skills/copy-editing/SKILL.md +457 -0
  19. package/.agents/skills/copy-editing/evals/evals.json +89 -0
  20. package/.agents/skills/copy-editing/references/checklist.md +66 -0
  21. package/.agents/skills/copy-editing/references/content-refresh.md +38 -0
  22. package/.agents/skills/copy-editing/references/plain-english-alternatives.md +394 -0
  23. package/.agents/skills/hyperframes/SKILL.md +163 -0
  24. package/.agents/skills/hyperframes-cli/SKILL.md +109 -0
  25. package/.agents/skills/hyperframes-cli/references/doctor-browser.md +45 -0
  26. package/.agents/skills/hyperframes-cli/references/init-and-scaffold.md +51 -0
  27. package/.agents/skills/hyperframes-cli/references/lambda.md +132 -0
  28. package/.agents/skills/hyperframes-cli/references/lint-validate-inspect.md +121 -0
  29. package/.agents/skills/hyperframes-cli/references/preview-render.md +109 -0
  30. package/.agents/skills/hyperframes-cli/references/upgrade-info-misc.md +75 -0
  31. package/.agents/skills/hyperframes-media/SKILL.md +97 -0
  32. package/.agents/skills/hyperframes-media/assets/sfx/CREDITS.md +35 -0
  33. package/.agents/skills/hyperframes-media/assets/sfx/manifest.json +97 -0
  34. package/.agents/skills/hyperframes-media/references/bgm.md +72 -0
  35. package/.agents/skills/hyperframes-media/references/captions/authoring.md +159 -0
  36. package/.agents/skills/hyperframes-media/references/captions/motion.md +87 -0
  37. package/.agents/skills/hyperframes-media/references/captions/transcript-handling.md +97 -0
  38. package/.agents/skills/hyperframes-media/references/remove-background.md +143 -0
  39. package/.agents/skills/hyperframes-media/references/requirements.md +29 -0
  40. package/.agents/skills/hyperframes-media/references/sfx.md +42 -0
  41. package/.agents/skills/hyperframes-media/references/transcribe.md +52 -0
  42. package/.agents/skills/hyperframes-media/references/tts-to-captions.md +24 -0
  43. package/.agents/skills/hyperframes-media/references/tts.md +135 -0
  44. package/.agents/skills/hyperframes-media/scripts/audio.mjs +282 -0
  45. package/.agents/skills/hyperframes-media/scripts/heygen-tts.mjs +121 -0
  46. package/.agents/skills/hyperframes-media/scripts/lib/bgm.mjs +235 -0
  47. package/.agents/skills/hyperframes-media/scripts/lib/heygen.mjs +131 -0
  48. package/.agents/skills/hyperframes-media/scripts/lib/sfx.mjs +128 -0
  49. package/.agents/skills/hyperframes-media/scripts/lib/tts.mjs +220 -0
  50. package/.agents/skills/hyperframes-media/scripts/lyria-recipe.py +128 -0
  51. package/.agents/skills/hyperframes-media/scripts/wait-bgm.mjs +167 -0
  52. package/.agents/skills/hyperframes-registry/SKILL.md +101 -0
  53. package/.agents/skills/hyperframes-registry/examples/add-block.md +51 -0
  54. package/.agents/skills/hyperframes-registry/examples/add-component.md +73 -0
  55. package/.agents/skills/hyperframes-registry/references/contributing.md +166 -0
  56. package/.agents/skills/hyperframes-registry/references/demo-html-pattern.md +54 -0
  57. package/.agents/skills/hyperframes-registry/references/discovery.md +215 -0
  58. package/.agents/skills/hyperframes-registry/references/install-locations.md +45 -0
  59. package/.agents/skills/hyperframes-registry/references/templates.md +417 -0
  60. package/.agents/skills/hyperframes-registry/references/wiring-blocks.md +61 -0
  61. package/.agents/skills/hyperframes-registry/references/wiring-components.md +39 -0
  62. package/.agents/skills/marketing-psychology/SKILL.md +455 -0
  63. package/.agents/skills/marketing-psychology/evals/evals.json +88 -0
  64. package/.agents/skills/mintlify/SKILL.md +328 -0
  65. package/.agents/skills/product-launch-video/SKILL.md +206 -0
  66. package/.agents/skills/product-launch-video/references/cut-catalog.md +220 -0
  67. package/.agents/skills/product-launch-video/references/motion-language.md +156 -0
  68. package/.agents/skills/product-launch-video/references/story-design.md +373 -0
  69. package/.agents/skills/product-launch-video/references/visual-design.md +126 -0
  70. package/.agents/skills/product-launch-video/scripts/assemble-index.mjs +570 -0
  71. package/.agents/skills/product-launch-video/scripts/audio.mjs +253 -0
  72. package/.agents/skills/product-launch-video/scripts/build-frame.mjs +536 -0
  73. package/.agents/skills/product-launch-video/scripts/captions.mjs +508 -0
  74. package/.agents/skills/product-launch-video/scripts/lib/assets.mjs +55 -0
  75. package/.agents/skills/product-launch-video/scripts/lib/dimensions.mjs +45 -0
  76. package/.agents/skills/product-launch-video/scripts/lib/storyboard.mjs +249 -0
  77. package/.agents/skills/product-launch-video/scripts/lib/tokens.mjs +204 -0
  78. package/.agents/skills/product-launch-video/scripts/lib/transition-registry.mjs +38 -0
  79. package/.agents/skills/product-launch-video/scripts/lib/transitions.json +71 -0
  80. package/.agents/skills/product-launch-video/scripts/stage-assets.mjs +39 -0
  81. package/.agents/skills/product-launch-video/scripts/transitions.mjs +320 -0
  82. package/.agents/skills/product-launch-video/sub-agents/frame-worker.md +74 -0
  83. package/.agents/skills/prompt-engineering-patterns/SKILL.md +144 -0
  84. package/.agents/skills/prompt-engineering-patterns/assets/few-shot-examples.json +106 -0
  85. package/.agents/skills/prompt-engineering-patterns/assets/prompt-template-library.md +264 -0
  86. package/.agents/skills/prompt-engineering-patterns/references/chain-of-thought.md +412 -0
  87. package/.agents/skills/prompt-engineering-patterns/references/details.md +338 -0
  88. package/.agents/skills/prompt-engineering-patterns/references/few-shot-learning.md +386 -0
  89. package/.agents/skills/prompt-engineering-patterns/references/prompt-optimization.md +428 -0
  90. package/.agents/skills/prompt-engineering-patterns/references/prompt-templates.md +484 -0
  91. package/.agents/skills/prompt-engineering-patterns/references/system-prompts.md +195 -0
  92. package/.agents/skills/prompt-engineering-patterns/scripts/optimize-prompt.py +279 -0
  93. package/.agents/skills/remotion-to-hyperframes/SKILL.md +127 -0
  94. package/.agents/skills/remotion-to-hyperframes/assets/.gitkeep +0 -0
  95. package/.agents/skills/remotion-to-hyperframes/assets/test-corpus/run.sh +249 -0
  96. package/.agents/skills/remotion-to-hyperframes/assets/test-corpus/tier-1-title-card/README.md +41 -0
  97. package/.agents/skills/remotion-to-hyperframes/assets/test-corpus/tier-1-title-card/expected.json +26 -0
  98. package/.agents/skills/remotion-to-hyperframes/assets/test-corpus/tier-1-title-card/hf-src/index.html +61 -0
  99. package/.agents/skills/remotion-to-hyperframes/assets/test-corpus/tier-1-title-card/remotion-src/package.json +14 -0
  100. package/.agents/skills/remotion-to-hyperframes/assets/test-corpus/tier-1-title-card/remotion-src/remotion.config.ts +13 -0
  101. package/.agents/skills/remotion-to-hyperframes/assets/test-corpus/tier-1-title-card/remotion-src/src/Root.tsx +13 -0
  102. package/.agents/skills/remotion-to-hyperframes/assets/test-corpus/tier-1-title-card/remotion-src/src/TitleCard.tsx +34 -0
  103. package/.agents/skills/remotion-to-hyperframes/assets/test-corpus/tier-1-title-card/remotion-src/src/index.ts +4 -0
  104. package/.agents/skills/remotion-to-hyperframes/assets/test-corpus/tier-1-title-card/remotion-src/tsconfig.json +15 -0
  105. package/.agents/skills/remotion-to-hyperframes/assets/test-corpus/tier-2-multi-scene/README.md +54 -0
  106. package/.agents/skills/remotion-to-hyperframes/assets/test-corpus/tier-2-multi-scene/expected.json +29 -0
  107. package/.agents/skills/remotion-to-hyperframes/assets/test-corpus/tier-2-multi-scene/hf-src/index.html +118 -0
  108. package/.agents/skills/remotion-to-hyperframes/assets/test-corpus/tier-2-multi-scene/remotion-src/package.json +14 -0
  109. package/.agents/skills/remotion-to-hyperframes/assets/test-corpus/tier-2-multi-scene/remotion-src/remotion.config.ts +13 -0
  110. package/.agents/skills/remotion-to-hyperframes/assets/test-corpus/tier-2-multi-scene/remotion-src/src/MultiScene.tsx +105 -0
  111. package/.agents/skills/remotion-to-hyperframes/assets/test-corpus/tier-2-multi-scene/remotion-src/src/Root.tsx +13 -0
  112. package/.agents/skills/remotion-to-hyperframes/assets/test-corpus/tier-2-multi-scene/remotion-src/src/index.ts +4 -0
  113. package/.agents/skills/remotion-to-hyperframes/assets/test-corpus/tier-2-multi-scene/remotion-src/tsconfig.json +15 -0
  114. package/.agents/skills/remotion-to-hyperframes/assets/test-corpus/tier-2-multi-scene/setup.sh +34 -0
  115. package/.agents/skills/remotion-to-hyperframes/assets/test-corpus/tier-3-data-driven/README.md +85 -0
  116. package/.agents/skills/remotion-to-hyperframes/assets/test-corpus/tier-3-data-driven/expected.json +41 -0
  117. package/.agents/skills/remotion-to-hyperframes/assets/test-corpus/tier-3-data-driven/hf-src/index.html +269 -0
  118. package/.agents/skills/remotion-to-hyperframes/assets/test-corpus/tier-3-data-driven/remotion-src/package.json +15 -0
  119. package/.agents/skills/remotion-to-hyperframes/assets/test-corpus/tier-3-data-driven/remotion-src/remotion.config.ts +13 -0
  120. package/.agents/skills/remotion-to-hyperframes/assets/test-corpus/tier-3-data-driven/remotion-src/src/Root.tsx +27 -0
  121. package/.agents/skills/remotion-to-hyperframes/assets/test-corpus/tier-3-data-driven/remotion-src/src/Stargazed.tsx +37 -0
  122. package/.agents/skills/remotion-to-hyperframes/assets/test-corpus/tier-3-data-driven/remotion-src/src/components/AnimatedNumber.tsx +23 -0
  123. package/.agents/skills/remotion-to-hyperframes/assets/test-corpus/tier-3-data-driven/remotion-src/src/components/StatCard.tsx +59 -0
  124. package/.agents/skills/remotion-to-hyperframes/assets/test-corpus/tier-3-data-driven/remotion-src/src/components/UnderlinedText.tsx +47 -0
  125. package/.agents/skills/remotion-to-hyperframes/assets/test-corpus/tier-3-data-driven/remotion-src/src/index.ts +4 -0
  126. package/.agents/skills/remotion-to-hyperframes/assets/test-corpus/tier-3-data-driven/remotion-src/src/scenes/OutroScene.tsx +18 -0
  127. package/.agents/skills/remotion-to-hyperframes/assets/test-corpus/tier-3-data-driven/remotion-src/src/scenes/StatsScene.tsx +34 -0
  128. package/.agents/skills/remotion-to-hyperframes/assets/test-corpus/tier-3-data-driven/remotion-src/src/scenes/TitleScene.tsx +55 -0
  129. package/.agents/skills/remotion-to-hyperframes/assets/test-corpus/tier-3-data-driven/remotion-src/tsconfig.json +15 -0
  130. package/.agents/skills/remotion-to-hyperframes/assets/test-corpus/tier-4-escape-hatch/README.md +51 -0
  131. package/.agents/skills/remotion-to-hyperframes/assets/test-corpus/tier-4-escape-hatch/cases/01-use-state.tsx +29 -0
  132. package/.agents/skills/remotion-to-hyperframes/assets/test-corpus/tier-4-escape-hatch/cases/02-use-effect-deps.tsx +29 -0
  133. package/.agents/skills/remotion-to-hyperframes/assets/test-corpus/tier-4-escape-hatch/cases/03-async-metadata.tsx +39 -0
  134. package/.agents/skills/remotion-to-hyperframes/assets/test-corpus/tier-4-escape-hatch/cases/04-third-party-react.tsx +30 -0
  135. package/.agents/skills/remotion-to-hyperframes/assets/test-corpus/tier-4-escape-hatch/cases/05-lambda-config.tsx +38 -0
  136. package/.agents/skills/remotion-to-hyperframes/assets/test-corpus/tier-4-escape-hatch/cases/06-warnings-only.tsx +36 -0
  137. package/.agents/skills/remotion-to-hyperframes/assets/test-corpus/tier-4-escape-hatch/cases/07-custom-hook.tsx +28 -0
  138. package/.agents/skills/remotion-to-hyperframes/assets/test-corpus/tier-4-escape-hatch/cases/08-mixed.tsx +41 -0
  139. package/.agents/skills/remotion-to-hyperframes/assets/test-corpus/tier-4-escape-hatch/expected.json +85 -0
  140. package/.agents/skills/remotion-to-hyperframes/assets/test-corpus/tier-4-escape-hatch/validate.sh +110 -0
  141. package/.agents/skills/remotion-to-hyperframes/references/api-map.md +142 -0
  142. package/.agents/skills/remotion-to-hyperframes/references/escape-hatch.md +115 -0
  143. package/.agents/skills/remotion-to-hyperframes/references/eval.md +140 -0
  144. package/.agents/skills/remotion-to-hyperframes/references/fonts.md +112 -0
  145. package/.agents/skills/remotion-to-hyperframes/references/limitations.md +136 -0
  146. package/.agents/skills/remotion-to-hyperframes/references/lottie.md +121 -0
  147. package/.agents/skills/remotion-to-hyperframes/references/media.md +149 -0
  148. package/.agents/skills/remotion-to-hyperframes/references/parameters.md +167 -0
  149. package/.agents/skills/remotion-to-hyperframes/references/sequencing.md +195 -0
  150. package/.agents/skills/remotion-to-hyperframes/references/timing.md +165 -0
  151. package/.agents/skills/remotion-to-hyperframes/references/transitions.md +114 -0
  152. package/.agents/skills/remotion-to-hyperframes/scripts/.gitkeep +0 -0
  153. package/.agents/skills/remotion-to-hyperframes/scripts/frame_strip.sh +107 -0
  154. package/.agents/skills/remotion-to-hyperframes/scripts/lint_source.py +358 -0
  155. package/.agents/skills/remotion-to-hyperframes/scripts/render_diff.sh +103 -0
  156. package/.agents/skills/remotion-to-hyperframes/scripts/tests/fixtures/blocker.tsx +50 -0
  157. package/.agents/skills/remotion-to-hyperframes/scripts/tests/fixtures/clean.tsx +46 -0
  158. package/.agents/skills/remotion-to-hyperframes/scripts/tests/smoke.sh +90 -0
  159. package/.agents/skills/seo-audit/SKILL.md +497 -0
  160. package/.agents/skills/seo-audit/evals/evals.json +136 -0
  161. package/.agents/skills/seo-audit/references/ai-writing-detection.md +200 -0
  162. package/.agents/skills/seo-audit/references/international-seo.md +230 -0
  163. package/README.md +4 -2
  164. package/SDK.md +64 -1
  165. package/dist/agents/coding.agent.d.ts +558 -0
  166. package/dist/agents/coding.agent.d.ts.map +1 -1
  167. package/dist/agents/coding.agent.js +8 -0
  168. package/dist/agents/coding.agent.js.map +1 -1
  169. package/dist/agents/developer-helper.agent.d.ts +712 -0
  170. package/dist/agents/developer-helper.agent.d.ts.map +1 -1
  171. package/dist/agents/developer-helper.agent.js +6 -0
  172. package/dist/agents/developer-helper.agent.js.map +1 -1
  173. package/dist/agents/docs-research.agent.d.ts +8 -0
  174. package/dist/agents/docs-research.agent.d.ts.map +1 -1
  175. package/dist/agents/finance.agent.d.ts +8 -0
  176. package/dist/agents/finance.agent.d.ts.map +1 -1
  177. package/dist/agents/manager.d.ts +837 -2
  178. package/dist/agents/manager.d.ts.map +1 -1
  179. package/dist/agents/manager.js +28 -0
  180. package/dist/agents/manager.js.map +1 -1
  181. package/dist/agents/security.agent.d.ts +165 -3
  182. package/dist/agents/security.agent.d.ts.map +1 -1
  183. package/dist/agents/security.agent.js +3 -0
  184. package/dist/agents/security.agent.js.map +1 -1
  185. package/dist/agents/swarm/main.js +1 -1
  186. package/dist/agents/swarm/main.js.map +1 -1
  187. package/dist/agents/swarm/registry.d.ts.map +1 -1
  188. package/dist/agents/swarm/registry.js +232 -26
  189. package/dist/agents/swarm/registry.js.map +1 -1
  190. package/dist/cli/doctor.d.ts +14 -0
  191. package/dist/cli/doctor.d.ts.map +1 -1
  192. package/dist/cli/doctor.js +91 -0
  193. package/dist/cli/doctor.js.map +1 -1
  194. package/dist/cli/menu.d.ts.map +1 -1
  195. package/dist/cli/menu.js +102 -0
  196. package/dist/cli/menu.js.map +1 -1
  197. package/dist/cli/setup.d.ts +10 -0
  198. package/dist/cli/setup.d.ts.map +1 -1
  199. package/dist/cli/setup.js +178 -0
  200. package/dist/cli/setup.js.map +1 -1
  201. package/dist/cli/swarm.d.ts +1 -0
  202. package/dist/cli/swarm.d.ts.map +1 -1
  203. package/dist/cli/swarm.js +47 -8
  204. package/dist/cli/swarm.js.map +1 -1
  205. package/dist/cli/theme.d.ts +0 -24
  206. package/dist/cli/theme.d.ts.map +1 -1
  207. package/dist/cli/theme.js +6 -2
  208. package/dist/cli/theme.js.map +1 -1
  209. package/dist/config/env.d.ts +10 -0
  210. package/dist/config/env.d.ts.map +1 -1
  211. package/dist/config/env.js +38 -17
  212. package/dist/config/env.js.map +1 -1
  213. package/dist/index.js +96 -5
  214. package/dist/index.js.map +1 -1
  215. package/dist/jobs/trigger-orchestrator.d.ts +5 -1
  216. package/dist/jobs/trigger-orchestrator.d.ts.map +1 -1
  217. package/dist/jobs/trigger-orchestrator.js +29 -9
  218. package/dist/jobs/trigger-orchestrator.js.map +1 -1
  219. package/dist/jobs/trigger-router.d.ts.map +1 -1
  220. package/dist/jobs/trigger-router.js +3 -2
  221. package/dist/jobs/trigger-router.js.map +1 -1
  222. package/dist/memory/corporate-wiki.d.ts +15 -0
  223. package/dist/memory/corporate-wiki.d.ts.map +1 -0
  224. package/dist/memory/corporate-wiki.js +152 -0
  225. package/dist/memory/corporate-wiki.js.map +1 -0
  226. package/dist/memory/scratchpad.d.ts +2 -0
  227. package/dist/memory/scratchpad.d.ts.map +1 -1
  228. package/dist/memory/scratchpad.js +27 -0
  229. package/dist/memory/scratchpad.js.map +1 -1
  230. package/dist/observability/doctor.d.ts.map +1 -1
  231. package/dist/observability/doctor.js +12 -4
  232. package/dist/observability/doctor.js.map +1 -1
  233. package/dist/observability/traces.d.ts +72 -0
  234. package/dist/observability/traces.d.ts.map +1 -0
  235. package/dist/observability/traces.js +1134 -0
  236. package/dist/observability/traces.js.map +1 -0
  237. package/dist/runtime/swarm.d.ts +1 -1
  238. package/dist/runtime/swarm.d.ts.map +1 -1
  239. package/dist/runtime/swarm.js +54 -25
  240. package/dist/runtime/swarm.js.map +1 -1
  241. package/dist/safety/approvals.d.ts +2 -2
  242. package/dist/safety/approvals.d.ts.map +1 -1
  243. package/dist/safety/approvals.js +47 -1
  244. package/dist/safety/approvals.js.map +1 -1
  245. package/dist/safety/redaction.d.ts.map +1 -1
  246. package/dist/safety/redaction.js +10 -0
  247. package/dist/safety/redaction.js.map +1 -1
  248. package/dist/tools/cloud.tool.d.ts +394 -0
  249. package/dist/tools/cloud.tool.d.ts.map +1 -0
  250. package/dist/tools/cloud.tool.js +784 -0
  251. package/dist/tools/cloud.tool.js.map +1 -0
  252. package/dist/tools/computer-use.tool.d.ts +2 -2
  253. package/dist/tools/corporate-wiki.tool.d.ts +22 -0
  254. package/dist/tools/corporate-wiki.tool.d.ts.map +1 -0
  255. package/dist/tools/corporate-wiki.tool.js +43 -0
  256. package/dist/tools/corporate-wiki.tool.js.map +1 -0
  257. package/dist/tools/devops.tool.d.ts +162 -0
  258. package/dist/tools/devops.tool.d.ts.map +1 -0
  259. package/dist/tools/devops.tool.js +377 -0
  260. package/dist/tools/devops.tool.js.map +1 -0
  261. package/dist/tools/multimedia.tool.d.ts +126 -0
  262. package/dist/tools/multimedia.tool.d.ts.map +1 -0
  263. package/dist/tools/multimedia.tool.js +533 -0
  264. package/dist/tools/multimedia.tool.js.map +1 -0
  265. package/dist/tools/osint.tool.d.ts +6 -6
  266. package/dist/tools/sandbox-dev.tool.d.ts +15 -0
  267. package/dist/tools/sandbox-dev.tool.d.ts.map +1 -0
  268. package/dist/tools/sandbox-dev.tool.js +146 -0
  269. package/dist/tools/sandbox-dev.tool.js.map +1 -0
  270. package/dist/tools/scratchpad.tool.d.ts +8 -0
  271. package/dist/tools/scratchpad.tool.d.ts.map +1 -1
  272. package/dist/tools/scratchpad.tool.js +40 -1
  273. package/dist/tools/scratchpad.tool.js.map +1 -1
  274. package/dist/tools/setup-assistant.tool.d.ts +1 -1
  275. package/dist/tools/swarm-ops.tool.d.ts +14 -0
  276. package/dist/tools/swarm-ops.tool.d.ts.map +1 -1
  277. package/dist/tools/swarm-ops.tool.js +47 -0
  278. package/dist/tools/swarm-ops.tool.js.map +1 -1
  279. package/dist/tools/sysops.tool.d.ts +157 -0
  280. package/dist/tools/sysops.tool.d.ts.map +1 -0
  281. package/dist/tools/sysops.tool.js +643 -0
  282. package/dist/tools/sysops.tool.js.map +1 -0
  283. package/dist/voice/deepgram.d.ts.map +1 -1
  284. package/dist/voice/deepgram.js +30 -2
  285. package/dist/voice/deepgram.js.map +1 -1
  286. package/package.json +8 -1
  287. package/scripts/release-github.mjs +23 -16
@@ -0,0 +1,97 @@
1
+ # Transcript Guide
2
+
3
+ For the `transcribe` CLI invocation, the `.en`-translates-non-English rule, and whisper model selection, see [`../transcribe.md`](../transcribe.md). This file covers what to do with the resulting transcript when authoring captions: input formats, mandatory quality checks, cleaning code, external-API fallbacks.
4
+
5
+ ## Supported Input Formats
6
+
7
+ The CLI auto-detects and normalizes these formats:
8
+
9
+ | Format | Extension | Source | Word-level? |
10
+ | --------------------- | --------- | --------------------------------------------------------------------------- | ----------------- |
11
+ | whisper.cpp JSON | `.json` | `hyperframes init --video`, `hyperframes transcribe` | Yes |
12
+ | OpenAI Whisper API | `.json` | `openai.audio.transcriptions.create({ timestamp_granularities: ["word"] })` | Yes |
13
+ | SRT subtitles | `.srt` | Video editors, subtitle tools, YouTube | No (phrase-level) |
14
+ | VTT subtitles | `.vtt` | Web players, YouTube, transcription services | No (phrase-level) |
15
+ | Normalized word array | `.json` | Pre-processed by any tool | Yes |
16
+
17
+ **Word-level timestamps produce better captions.** SRT/VTT give phrase-level timing, which works but can't do per-word animation effects.
18
+
19
+ ## Transcript Quality Check (Mandatory)
20
+
21
+ After every transcription, **read the transcript and check for quality issues before proceeding.** Bad transcripts produce nonsensical captions. Never skip this step.
22
+
23
+ ### What to look for
24
+
25
+ | Signal | Example | Cause |
26
+ | ---------------------------- | -------------------------------------- | ---------------------------------------------------------------------------- |
27
+ | Music note tokens (`♪`, `�`) | `{ "text": "♪" }` or `{ "text": "�" }` | Whisper detected music, not speech |
28
+ | Garbled / nonsense words | "Do a chin", "Get so gay", "huh" | Model misheard lyrics or background noise |
29
+ | Long gaps with no words | 20+ seconds of only `♪` tokens | Instrumental section — expected, but high ratio means speech is being missed |
30
+ | Repeated filler | Many "huh", "uh", "oh" entries | Model is hallucinating on music |
31
+ | Very short word spans | Words with `end - start < 0.05` | Unreliable timestamp alignment |
32
+
33
+ ### Automatic retry rules
34
+
35
+ **If more than 20% of entries are `♪`/`�` tokens, or the transcript contains obvious nonsense words, the transcription failed.** Do not proceed with the bad transcript. Instead:
36
+
37
+ 1. **Retry with `medium.en`** if the original used `small.en` or smaller:
38
+ ```bash
39
+ npx hyperframes transcribe audio.mp3 --model medium.en
40
+ ```
41
+ 2. **If `medium.en` also fails** (still >20% music tokens or garbled), tell the user the audio is too noisy for local transcription and suggest:
42
+ - Providing lyrics manually as an SRT/VTT file
43
+ - Using an external API (OpenAI or Groq Whisper — see below)
44
+ 3. **Always clean the transcript** before building captions — filter out `♪`/`�` tokens and entries where `text` is a single non-word character. Only real words should reach the caption composition.
45
+
46
+ ### Cleaning a transcript
47
+
48
+ After transcription (even with a good model), strip non-word entries:
49
+
50
+ ```js
51
+ var raw = JSON.parse(transcriptJson);
52
+ var words = raw.filter(function (w) {
53
+ if (!w.text || w.text.trim().length === 0) return false;
54
+ if (/^[♪�\u266a\u266b\u266c\u266d\u266e\u266f]+$/.test(w.text)) return false;
55
+ if (/^(huh|uh|um|ah|oh)$/i.test(w.text) && w.end - w.start < 0.1) return false;
56
+ return true;
57
+ });
58
+ ```
59
+
60
+ For model-selection guidance by content type, see [`../transcribe.md`](../transcribe.md) → "Picking a model by content type".
61
+
62
+ ## Using External Transcription APIs
63
+
64
+ For the best accuracy, use an external API and import the result:
65
+
66
+ **OpenAI Whisper API** (recommended for quality):
67
+
68
+ ```bash
69
+ # Generate with word timestamps, then import
70
+ curl https://api.openai.com/v1/audio/transcriptions \
71
+ -H "Authorization: Bearer $OPENAI_API_KEY" \
72
+ -F file=@audio.mp3 -F model=whisper-1 \
73
+ -F response_format=verbose_json \
74
+ -F "timestamp_granularities[]=word" \
75
+ -o transcript-openai.json
76
+
77
+ npx hyperframes transcribe transcript-openai.json
78
+ ```
79
+
80
+ **Groq Whisper API** (fast, free tier available):
81
+
82
+ ```bash
83
+ curl https://api.groq.com/openai/v1/audio/transcriptions \
84
+ -H "Authorization: Bearer $GROQ_API_KEY" \
85
+ -F file=@audio.mp3 -F model=whisper-large-v3 \
86
+ -F response_format=verbose_json \
87
+ -F "timestamp_granularities[]=word" \
88
+ -o transcript-groq.json
89
+
90
+ npx hyperframes transcribe transcript-groq.json
91
+ ```
92
+
93
+ ## If No Transcript Exists
94
+
95
+ 1. Check the project root for `transcript.json`, `.srt`, or `.vtt` files.
96
+ 2. If none found, run [`../transcribe.md`](../transcribe.md) — pick the starting model from "Picking a model by content type" there.
97
+ 3. Run the quality check above. If it fails, retry with a larger model or fall back to manual lyrics / external API.
@@ -0,0 +1,143 @@
1
+ # Background Removal
2
+
3
+ Make a transparent overlay (typical: a talking head over an arbitrary scene). Uses `u2net_human_seg` (MIT).
4
+
5
+ ```bash
6
+ npx hyperframes remove-background subject.mp4 -o transparent.webm # default: VP9 + alpha
7
+ npx hyperframes remove-background subject.mp4 -o transparent.mov # ProRes 4444 (editing)
8
+ npx hyperframes remove-background portrait.jpg -o cutout.png # single-image cutout
9
+ npx hyperframes remove-background subject.mp4 -o subject.webm \
10
+ --background-output plate.webm # both layers, one pass
11
+ npx hyperframes remove-background subject.mp4 -o transparent.webm --device cpu
12
+ npx hyperframes remove-background --info # detected providers
13
+ ```
14
+
15
+ ## Output Format
16
+
17
+ - **`.webm` (VP9 alpha)** — default. Plug straight into `<video>` for Chrome-native transparent playback (~1 MB / 4s @ 1080p).
18
+ - **`.mov` (ProRes 4444)** — round-trip in editors (Premiere / Resolve / DaVinci). ~50 MB / 4s.
19
+ - **`.png`** — single-image cutout.
20
+
21
+ ## Quality (`--quality`)
22
+
23
+ Controls VP9 encoder CRF only — segmentation quality is fixed. Higher quality keeps the cutout's RGB closer to the source MP4 (important when overlaying the cutout on its own source).
24
+
25
+ | Preset | CRF | When |
26
+ | ---------- | --- | --------------------------------------------- |
27
+ | `fast` | 30 | Iterating, smaller files, looser color match |
28
+ | `balanced` | 18 | **Default**; visually identical for most uses |
29
+ | `best` | 12 | Master / final delivery, tightest color match |
30
+
31
+ ## Device (`--device`)
32
+
33
+ `auto` (default) picks CoreML on Apple Silicon, CUDA when available, otherwise CPU. Force with `--device cpu | coreml | cuda`. CUDA requires `HYPERFRAMES_CUDA=1` plus a GPU-enabled `onnxruntime-node` build. Use `--info` to inspect detected providers without rendering.
34
+
35
+ ## Compositing patterns — pick the right one
36
+
37
+ The cutout WebM is a **re-encoded copy** of the source MP4's RGB. What sits behind it matters.
38
+
39
+ | Pattern | Behind the cutout | Result |
40
+ | -------------------------------------------------------- | --------------------------------------- | --------------------------------------------------------------------------------------------------------------- |
41
+ | **Cutout over a different scene** (most common) | Static image, gradient, unrelated video | Looks great. Single RGB source for the subject. |
42
+ | **Cutout over its own source mp4** (text-behind-subject) | Same mp4 the cutout came from | At `balanced` doubling is barely visible; at `fast` you'll see color shift / edge halo. Use `best` for masters. |
43
+ | **Cutout over a different take of the same person** | Footage of the same subject | **Two overlapping people. Don't do this.** |
44
+
45
+ ## Text-behind-subject pattern (two non-obvious rules)
46
+
47
+ Putting a headline behind a presenter cutout:
48
+
49
+ ```html
50
+ <video
51
+ src="presenter.mp4"
52
+ id="bg"
53
+ data-start="0"
54
+ data-duration="6"
55
+ data-track-index="0"
56
+ muted
57
+ playsinline
58
+ ></video>
59
+
60
+ <h1 id="headline" style="z-index:2; ...">MAKE IT IN HYPERFRAMES</h1>
61
+
62
+ <div class="cutout-wrap" style="position:absolute; inset:0; z-index:3; opacity:0">
63
+ <video
64
+ src="presenter.webm"
65
+ data-start="0"
66
+ data-duration="6"
67
+ data-track-index="1"
68
+ muted
69
+ playsinline
70
+ ></video>
71
+ </div>
72
+ ```
73
+
74
+ ```js
75
+ // Flip the wrapper's opacity at the cut, NOT the video's
76
+ tl.set(".cutout-wrap", { opacity: 1 }, 3.3);
77
+ ```
78
+
79
+ Two rules that are easy to miss:
80
+
81
+ 1. **Wrap the cutout `<video>` in a non-timed `<div>` and animate the wrapper's opacity, not the video element's.** The framework forces `opacity: 1` on active clips (any element with `data-start` / `data-duration`), so animating the video's opacity directly is silently overridden. The wrapper has no `data-*` attributes, so it's owned by your CSS / GSAP.
82
+ 2. **Both videos use `data-start="0"` and `data-media-start="0"`** so the framework decodes them in sync from t=0. Late-mounting the cutout (`data-start=3.3`) introduces a seek + warm-up that lands a frame off the base mp4 — visible as one frame of misalignment at the cut.
83
+
84
+ ## Layer separation (`--background-output`)
85
+
86
+ Emits a **second** transparent video alongside the cutout: same source RGB, alpha is `255 - mask` instead of `mask`. The cutout has the subject opaque; the plate has the surroundings opaque (with a transparent hole where the subject was). Use it when text / graphics need to live **between** the two layers.
87
+
88
+ | File | Alpha is… | Use it for |
89
+ | -------------------------------- | ------------------------------------------------------- | ---------------------------------------------------------------- |
90
+ | `-o subject.webm` | mask — subject opaque, background transparent | Foreground layer (top) |
91
+ | `--background-output plate.webm` | inverse mask — surroundings opaque, subject transparent | Bottom layer; place text / graphics between this and the subject |
92
+
93
+ Both share the same `--quality` and run from a single inference pass — only encode cost roughly doubles. Only valid for video inputs with `.webm` / `.mov` outputs.
94
+
95
+ **Hole-cut, not inpainted.** The subject region in `plate.webm` is fully transparent — composite something opaque under it to fill the hole.
96
+
97
+ **Single test for whether `--background-output` is the right tool:** _will anything ever be visible through the subject's silhouette where the subject used to be?_ If no, you don't need the plate — `subject.webm` alone over a different background is enough.
98
+
99
+ ### Use case → right tool
100
+
101
+ | Use case | Right tool |
102
+ | ----------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------- |
103
+ | Text/graphics between the cutout and the plate (this command's reason for existing) | **Hole-cut** (`--background-output`) |
104
+ | Subject onto an unrelated scene | Just `subject.webm`; ignore the plate |
105
+ | Show the room _without_ the person, alone over no other content | **Clean plate** — needs an inpainter (LaMa, ProPainter, E2FGVI). Not this command. |
106
+ | Replace the subject with a different subject | **Clean plate** — same as above |
107
+
108
+ ### Canonical 3-layer template (plate + content + cutout)
109
+
110
+ Ship just the two transparent layers and let arbitrary content live between them — no original mp4 needed:
111
+
112
+ ```html
113
+ <!-- z=1 plate: surroundings opaque, subject silhouette transparent -->
114
+ <video
115
+ src="plate.webm"
116
+ data-start="0"
117
+ data-duration="6"
118
+ data-track-index="0"
119
+ muted
120
+ playsinline
121
+ ></video>
122
+
123
+ <!-- z=2 your content lives between the layers -->
124
+ <h1 id="headline" style="z-index:2; ...">MAKE IT IN HYPERFRAMES</h1>
125
+
126
+ <!-- z=3 cutout floats the subject back on top -->
127
+ <div class="cutout-wrap" style="position:absolute; inset:0; z-index:3">
128
+ <video
129
+ src="subject.webm"
130
+ data-start="0"
131
+ data-duration="6"
132
+ data-track-index="1"
133
+ muted
134
+ playsinline
135
+ ></video>
136
+ </div>
137
+ ```
138
+
139
+ Functionally equivalent to the text-behind-subject pattern above, but doesn't require shipping the original mp4 — the plate replaces it. Use this when delivering just the two transparent layers as a reusable asset.
140
+
141
+ ## When `remove-background` is NOT the right tool
142
+
143
+ If a user asks for "the room **without** the person, displayed standalone" (no subject anywhere, no compositing on top), `--background-output` is wrong — its plate has a transparent hole, not a filled-in clean plate. They need an **inpainter**: LaMa, ProPainter, or E2FGVI. Tell them this command can't do it.
@@ -0,0 +1,29 @@
1
+ # Requirements & Caches
2
+
3
+ ## Credential & key priority
4
+
5
+ Run `npx hyperframes auth status` to see what's configured and which engines a workflow will use (see the skill's **Preflight** section). Keys resolve in this order — **first match wins**:
6
+
7
+ | Provider | Resolution order (first non-empty wins) | Local deps when used |
8
+ | ------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------ |
9
+ | **HeyGen** (TTS + BGM/SFX retrieval) | `$HEYGEN_API_KEY` → `$HYPERFRAMES_API_KEY` → `~/.heygen/credentials` (shared with heygen-cli; `$HEYGEN_CONFIG_DIR` overrides the dir; written by `hyperframes auth login`) | none (REST) |
10
+ | **ElevenLabs** (TTS fallback) | `$ELEVENLABS_API_KEY` | `pip install elevenlabs` |
11
+ | **Lyria** (BGM fallback) | `$GEMINI_API_KEY` → `$GOOGLE_API_KEY` | `pip install google-genai` |
12
+ | **Kokoro** (TTS, no key) | always — final voice fallback | `pip install kokoro-onnx soundfile` |
13
+ | **MusicGen** (BGM, no key) | always — final music fallback | `pip install transformers torch soundfile numpy` |
14
+
15
+ `hyperframes auth login` (browser OAuth) is the recommended setup: one sign-in, every project, no per-repo `.env`. An OAuth login is sent as `Authorization: Bearer`; an API key as `X-Api-Key`. With no HeyGen credential, voice/BGM run fully locally (Kokoro / MusicGen) — `hyperframes auth status` and `hyperframes doctor` both report whether those local deps are installed.
16
+
17
+ ## Model caches & system dependencies
18
+
19
+ Each command downloads its own model on first run and caches it under `~/.cache/hyperframes/`:
20
+
21
+ - **TTS (HeyGen)** — no local deps; needs a HeyGen credential + `ffmpeg` on PATH (to transcode the mp3 response to `.wav`). Credential resolves like the CLI: `$HEYGEN_API_KEY` → `$HYPERFRAMES_API_KEY` → `~/.heygen/credentials` (shared with heygen-cli; run `npx hyperframes auth login`). An OAuth login is sent as `Authorization: Bearer`; an API key as `X-Api-Key`.
22
+ - **TTS (ElevenLabs)** — same as HeyGen: API key + `ffmpeg`.
23
+ - **TTS (Kokoro)** — Kokoro-82M (~311 MB) + voices (~27 MB) in `tts/`. Requires Python 3.8+ with `kokoro-onnx` and `soundfile` (`pip install kokoro-onnx soundfile`). Non-English text also needs `espeak-ng` system-wide.
24
+ - **BGM (Lyria)** — needs `$GEMINI_API_KEY` or `$GOOGLE_API_KEY` + `pip install google-genai`. No local model cache.
25
+ - **BGM (MusicGen)** — `pip install transformers torch soundfile`. `facebook/musicgen-small` (~300 MB) cached under `~/.cache/huggingface/` on first run.
26
+ - **Transcribe** — Whisper model size depending on choice (75 MB – 3.1 GB) in `whisper/`. Bundles `whisper.cpp`.
27
+ - **Remove-background** — `u2net_human_seg` (~168 MB ONNX) in `background-removal/models/`. Peak inference RAM ~1.5 GB.
28
+
29
+ Run `npx hyperframes doctor` if a command fails because of a missing dependency.
@@ -0,0 +1,42 @@
1
+ # Sound effects (SFX)
2
+
3
+ Named sound effects, produced by the shared audio engine (`scripts/audio.mjs` → `scripts/lib/sfx.mjs`). **Provider-gated** by the engine's one switch — whether a HeyGen credential is present, decided once (not per cue):
4
+
5
+ - **HeyGen credential present → retrieve every cue** from HeyGen's audio library (`/v3/audio/sounds`, `type=sound_effects`, `min_score=0.4`). Search-and-download, **not** generation. The bundled library is NOT consulted.
6
+ - **No credential → the bundled 21-file library** (`assets/sfx/` + `manifest.json`): match each cue name, copy the matched file into the project. Offline, deterministic, free.
7
+
8
+ There is no `npx hyperframes sfx` command. SFX is never generated — it is retrieved (online) or taken from the bundled library (offline).
9
+
10
+ ## Cues — request → meta
11
+
12
+ Each line names the effects it wants: `lines[].sfx: ["whoosh", "ui click"]`. The engine flattens these into cues, resolves them per the switch, dedupes identical `(id, name)` pairs (the same effect named twice downloads/copies once), and writes `audio_meta.sfx[]`:
13
+
14
+ ```jsonc
15
+ {
16
+ "id": "3", // joins the cue to the caller's model (frame / scene / segment)
17
+ "name": "whoosh",
18
+ "file": "assets/sfx/whoosh.mp3", // downloaded or copied, relative to project root
19
+ "source": "heygen" | "local", // which route resolved it
20
+ "offset_s": 0, // delay from the line's start
21
+ "duration_s": 0.57,
22
+ "volume": 0.35 // SFX sit UNDER voice + BGM
23
+ }
24
+ ```
25
+
26
+ A cue that matches nothing is **skipped** (recorded as an anomaly); SFX never blocks a render.
27
+
28
+ ## HeyGen retrieval (credentialed)
29
+
30
+ `searchSounds(name, "sound_effects", { limit: 3, minScore: 0.4 })` → top hit → `assets/sfx/<slug>.mp3`. Results are ranked by `score` (each carries a presigned `audio_url`, `duration`, `description`). The floor is **0.4** because good SFX hits score ~0.5–0.67 — below the API's default `0.7`, which would silently drop most named cues (only whoosh/swoosh-family clears 0.7). `duration_s` comes from the result (else 1.0). Name effects concretely (`glass shatter`, not `dramatic sound`); a vague query returns a poor match.
31
+
32
+ ## Bundled library (no credential)
33
+
34
+ 21 curated files in `assets/sfx/`, indexed by `manifest.json` — `{ file, duration, description }` per key (e.g. `whoosh`, `pop`, `click`, `chime`, `riser`, `impact-bass-1`, `glitch-1`, `typing`, …). A cue name resolves by **manifest key, file basename, or slug**, so `whoosh`, `whoosh.mp3`, or `"ui click"` (→ slug) all match. Matched files are copied into the project's `assets/sfx/`; `duration_s` comes from the manifest, so timing is known **offline** — e.g. `riser` is 10.03s, so trigger it at `climax − 10.03s`. The manifest's `description` field carries placement hints per effect; read `assets/sfx/manifest.json` for the full set and usage.
35
+
36
+ ## Rules
37
+
38
+ - **Volume ~0.35.** SFX must sit under narration and BGM, not fight them.
39
+ - **No match → skip, don't fail.** A missing effect logs an anomaly and moves on; never a render blocker.
40
+ - **Retrieval (credentialed) or bundled library (offline) — never generation.** You search HeyGen by text, or match a name against the 21-file manifest.
41
+ - **One asset per distinct name.** Reuse across lines is deduped to a single download/copy, many cues.
42
+ - **The switch is global, not per cue.** With a credential, retrieval handles even the long tail (effects not in the 21); without one, only the 21 bundled names resolve.
@@ -0,0 +1,52 @@
1
+ # Transcription
2
+
3
+ Create normalized word-level timestamps. **Always specify `--model` explicitly** — the CLI default is `small.en`, which silently translates non-English audio into English.
4
+
5
+ ```bash
6
+ npx hyperframes transcribe audio.mp3 --model small.en # known English
7
+ npx hyperframes transcribe video.mp4 --model small --language es # known Spanish
8
+ npx hyperframes transcribe audio.mp3 --model small # unknown language (auto-detect)
9
+ npx hyperframes transcribe subtitles.srt # import existing
10
+ npx hyperframes transcribe subtitles.vtt
11
+ npx hyperframes transcribe openai-response.json
12
+ ```
13
+
14
+ ## Language Rule (Non-Negotiable)
15
+
16
+ `.en` models (`tiny.en` / `base.en` / `small.en` / `medium.en`) **translate** non-English audio into English. This silently destroys the original language.
17
+
18
+ 1. **Known English** → `--model small.en` (or `medium.en` for music / noisy audio)
19
+ 2. **Known non-English** → `--model small --language <iso-code>` (no `.en` suffix)
20
+ 3. **Unknown language** → `--model small` (whisper auto-detects)
21
+
22
+ **CLI default is `small.en`** — do not rely on it; always pass `--model` to make the choice explicit. `--language` also filters out non-target-language segments from mixed-language audio.
23
+
24
+ ## Model Sizes
25
+
26
+ | Model | Size | Speed | When |
27
+ | ---------- | ------ | -------- | ------------------------------------- |
28
+ | `tiny` | 75 MB | Fastest | Quick previews, smoke tests |
29
+ | `base` | 142 MB | Fast | Short clips, clear audio |
30
+ | `small` | 466 MB | Moderate | Default for most multilingual content |
31
+ | `medium` | 1.5 GB | Slow | Music with vocals, noisy audio |
32
+ | `large-v3` | 3.1 GB | Slowest | Production quality |
33
+
34
+ ### Picking a model by content type
35
+
36
+ 1. Speech over silence / light background → `small.en`
37
+ 2. Speech over music, or music with vocals → start with `medium.en`
38
+ 3. Produced music track (vocals + full instrumentation) → start with `medium.en`; expect to need manual lyrics or an external API ([`captions/transcript-handling.md`](captions/transcript-handling.md) → "Using External Transcription APIs")
39
+ 4. Multilingual → `medium` or `large-v3` (no `.en` suffix), pair with `--language`
40
+
41
+ ## Output Shape
42
+
43
+ Compositions consume a flat array of word objects. The `id` (`w0`, `w1`, …) is added during normalization for stable references in caption overrides; optional for backwards compatibility.
44
+
45
+ ```json
46
+ [
47
+ { "id": "w0", "text": "Hello", "start": 0.0, "end": 0.5 },
48
+ { "id": "w1", "text": "world.", "start": 0.6, "end": 1.2 }
49
+ ]
50
+ ```
51
+
52
+ For mandatory caption-quality checks, retry rules, and the OpenAI/Groq Whisper API import path, see `captions/transcript-handling.md`.
@@ -0,0 +1,24 @@
1
+ # TTS → Captions
2
+
3
+ When no recorded voiceover exists, generate one and obtain word-level caption timing. Two paths depending on which TTS provider is in use:
4
+
5
+ ## Path A — HeyGen (single call, no Whisper)
6
+
7
+ HeyGen returns word timestamps in the same response as the audio. Pass `--words` and you're done:
8
+
9
+ ```bash
10
+ npx hyperframes tts script.txt --provider heygen --output narration.wav --words narration.words.json
11
+ ```
12
+
13
+ `narration.words.json` is already in the `[{ id, text, start, end }]` shape the captions pipeline consumes — no separate transcribe pass.
14
+
15
+ ## Path B — ElevenLabs / Kokoro (TTS → Whisper)
16
+
17
+ These providers don't return word data. Generate the audio, then transcribe:
18
+
19
+ ```bash
20
+ npx hyperframes tts script.txt --voice af_heart --output narration.wav
21
+ npx hyperframes transcribe narration.wav --model small.en # voice af_heart is American English
22
+ ```
23
+
24
+ Whisper extracts precise word boundaries from the generated audio, so caption timing matches delivery without hand-tuning. Match `--model` to the voice's language (use `small.en` for `a`/`b` prefixes, `small --language <code>` otherwise). Then consume `transcript.json` via the caption references in `captions/`.
@@ -0,0 +1,135 @@
1
+ # Text To Speech
2
+
3
+ `npx hyperframes tts` auto-detects a provider from env vars; explicit override via `--provider`.
4
+
5
+ > **Run the Preflight first — no credential is not a green light to silently use the local voice.** Before generating a voiceover, complete the sign-in **Preflight** (see `../SKILL.md` → Preflight): run `npx hyperframes auth status`, recommend signing in, and **STOP for the user's choice** (sign in for HeyGen voices, or continue offline with local Kokoro). This applies to a one-off "generate a voiceover" request just as much as inside a full workflow.
6
+
7
+ ## Provider chain
8
+
9
+ | Order | Provider | Env trigger | Voice IDs | Word timestamps | Audio format |
10
+ | ----- | ----------------- | ------------------------------------------- | ------------------------------------------- | ----------------------------------------- | -------------------- |
11
+ | 1 | HeyGen (Starfish) | `$HEYGEN_API_KEY` / `~/.heygen/credentials` | UUIDs from `GET /v3/voices?engine=starfish` | **Yes** (`word_timestamps[]` in response) | mp3 → wav via ffmpeg |
12
+ | 2 | ElevenLabs | `$ELEVENLABS_API_KEY` | UUIDs from elevenlabs.io dashboard | No | mp3 → wav via ffmpeg |
13
+ | 3 | Kokoro-82M | always (local fallback) | `am_michael`, `af_heart`, … (54 voices) | No | wav direct |
14
+
15
+ ```bash
16
+ # Auto-detect (HeyGen if key set, else ElevenLabs, else Kokoro)
17
+ npx hyperframes tts "Welcome to HyperFrames" -o narration.wav
18
+
19
+ # Pin the provider explicitly
20
+ npx hyperframes tts "Hello" --provider kokoro
21
+ npx hyperframes tts "Hello" --provider heygen --voice <heygen-uuid>
22
+ npx hyperframes tts "Hello" --provider elevenlabs --voice 21m00Tcm4TlvDq8ikWAM
23
+
24
+ # HeyGen path: capture word timestamps in one call (skips a Whisper pass)
25
+ npx hyperframes tts "Hi there" --words narration.words.json
26
+ ```
27
+
28
+ ## Self-contained HeyGen (no CLI) — `scripts/heygen-tts.mjs`
29
+
30
+ The published `hyperframes tts` CLI synthesizes locally with Kokoro only. When you
31
+ want HeyGen specifically — best quality **plus** word timestamps in one call — use
32
+ the skill's bundled script, which calls the HeyGen v3 REST API directly and needs
33
+ no CLI provider plumbing:
34
+
35
+ The script resolves a HeyGen credential the same way the CLI does — first source
36
+ wins: `$HEYGEN_API_KEY` → `$HYPERFRAMES_API_KEY` → a project `.env` (auto-loaded,
37
+ walks up ≤5 dirs) → `~/.heygen/credentials` (shared with heygen-cli;
38
+ `$HEYGEN_CONFIG_DIR` overrides the dir). An OAuth login is sent as
39
+ `Authorization: Bearer`; an API key as `X-Api-Key`. If the only credential is an
40
+ expired OAuth token it stops with a hint to run `npx hyperframes auth refresh`.
41
+
42
+ ```bash
43
+ # Only needed if you haven't run `npx hyperframes auth login`:
44
+ export HEYGEN_API_KEY=... # or put it in a project .env
45
+
46
+ # Synthesize + capture word timestamps in one call (skips a Whisper pass)
47
+ node skills/hyperframes-media/scripts/heygen-tts.mjs \
48
+ "Welcome to HyperFrames." -o narration.wav --words narration.words.json
49
+
50
+ node skills/hyperframes-media/scripts/heygen-tts.mjs ./script.txt -o narration.wav
51
+ node skills/hyperframes-media/scripts/heygen-tts.mjs --list # public starfish voices
52
+ ```
53
+
54
+ - **Voice:** `--voice <id>` must be a **starfish** voice_id (`--list`, or `GET /v3/voices?engine=starfish`). v2-catalog ids are rejected with HTTP 400. Omit `--voice` (English) and it defaults to **Marcia** (`05f19352e8f74b0392a8f411eba40de1`, a fixed default so the choice is deterministic). Non-English with no `--voice` falls back to the first matching catalog voice.
55
+ - **Output:** `.wav` → transcoded to 44.1k mono via ffmpeg; `.mp3` → raw bytes (no ffmpeg needed).
56
+ - **Words:** `--words <path>` writes the flat `[{id,text,start,end}]` shape below, drop-in for the captions pipeline. HeyGen's `<start>`/`<end>` boundary sentinels are filtered out and ids are re-contiguous.
57
+ - **Non-English:** `--lang <code>` (anything but `en`) is sent as the request `language`.
58
+
59
+ ## When to use which provider
60
+
61
+ | Goal | Use |
62
+ | --------------------------------------------------------- | --------------------------------------------------- |
63
+ | Best voice quality + word timestamps in one call | **HeyGen** |
64
+ | Drop-in cloud TTS, big voice catalog | **ElevenLabs** |
65
+ | Offline, no API key, fast iteration | **Kokoro** |
66
+ | Non-English multilingual with deterministic phonemization | **Kokoro** (`ef_dora`, `jf_alpha`, `zf_xiaobei`, …) |
67
+
68
+ ## ffmpeg requirement
69
+
70
+ HeyGen + ElevenLabs return mp3. The CLI transcodes to wav when `--output` ends in `.wav` (the default and what downstream `ffprobe` + Whisper expect). If you'd rather skip the transcode, pass `-o file.mp3`. Without `ffmpeg` on PATH, `.wav` output from the cloud providers fails — install ffmpeg or use `.mp3`.
71
+
72
+ ## Voice selection (Kokoro)
73
+
74
+ Default `af_heart`. Curated picks:
75
+
76
+ | Content type | Voice |
77
+ | ----------------- | ---------------------- |
78
+ | Product demo | `af_heart`, `af_nova` |
79
+ | Tutorial / how-to | `am_adam`, `bf_emma` |
80
+ | Marketing / promo | `af_sky`, `am_michael` |
81
+ | Documentation | `bf_emma`, `bm_george` |
82
+ | Casual / social | `af_heart`, `af_sky` |
83
+
84
+ Run `npx hyperframes tts --list` for the bundled set.
85
+
86
+ ## Multilingual (Kokoro voice prefix → language)
87
+
88
+ The first letter of a Kokoro voice ID picks the phonemizer language; `--lang` overrides auto-detection.
89
+
90
+ | Prefix | Language |
91
+ | ------ | -------------------- |
92
+ | `a` | American English |
93
+ | `b` | British English |
94
+ | `e` | Spanish |
95
+ | `f` | French |
96
+ | `h` | Hindi |
97
+ | `i` | Italian |
98
+ | `j` | Japanese |
99
+ | `p` | Brazilian Portuguese |
100
+ | `z` | Mandarin |
101
+
102
+ ```bash
103
+ npx hyperframes tts "La reunión empieza a las nueve" --voice ef_dora --provider kokoro
104
+ npx hyperframes tts "Today is a nice day" --voice af_heart --provider kokoro
105
+ ```
106
+
107
+ Valid `--lang` codes (only needed to override the voice's auto-detected language): `en-us`, `en-gb`, `es`, `fr-fr`, `hi`, `it`, `pt-br`, `ja`, `zh`.
108
+
109
+ Non-English phonemization requires `espeak-ng` system-wide (`brew install espeak-ng` / `apt-get install espeak-ng`).
110
+
111
+ ## Speed
112
+
113
+ - `0.7-0.8` — tutorial, complex content, accessibility
114
+ - `1.0` — natural pace (default)
115
+ - `1.1-1.2` — intros, transitions, upbeat content
116
+ - `1.5+` — rarely appropriate, test carefully
117
+
118
+ Honored by Kokoro + HeyGen; ElevenLabs ignores `--speed` (use voice settings on their dashboard).
119
+
120
+ ## Long scripts
121
+
122
+ Past a few paragraphs, write the text to a `.txt` file and pass the path. Inputs over ~5 minutes of speech may benefit from splitting into segments.
123
+
124
+ ## HeyGen word-timestamp shape
125
+
126
+ When `--words <path>` is passed to a HeyGen call, the file is written in the same flat shape `transcribe` produces — drop-in compatible with the captions pipeline:
127
+
128
+ ```json
129
+ [
130
+ { "id": "w0", "text": "Hi", "start": 0.0, "end": 0.21 },
131
+ { "id": "w1", "text": "there", "start": 0.22, "end": 0.55 }
132
+ ]
133
+ ```
134
+
135
+ For ElevenLabs / Kokoro, run `npx hyperframes transcribe narration.wav --model small.en` to get the same shape.