akari-video 0.1.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 (492) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +81 -0
  3. package/bin/akari.mjs +14 -0
  4. package/package.json +42 -0
  5. package/src/cli.mjs +140 -0
  6. package/src/messages.mjs +100 -0
  7. package/src/path-lookup.mjs +47 -0
  8. package/src/project-state.mjs +25 -0
  9. package/src/repo-assets.mjs +59 -0
  10. package/src/task-labels.mjs +30 -0
  11. package/src/update-check.mjs +189 -0
  12. package/vendor/packages/project-scaffold/package.json +11 -0
  13. package/vendor/packages/project-scaffold/src/index.mjs +523 -0
  14. package/vendor/packages/project-scaffold/test/create-project.test.mjs +81 -0
  15. package/vendor/packages/project-scaffold/test/skill-adapter-link.test.mjs +204 -0
  16. package/vendor/packages/schemas/analysis.schema.json +475 -0
  17. package/vendor/packages/schemas/asset-meta.schema.json +225 -0
  18. package/vendor/packages/schemas/avatar-rendition.schema.json +65 -0
  19. package/vendor/packages/schemas/avatar.schema.json +178 -0
  20. package/vendor/packages/schemas/bin/validate-asset.mjs +597 -0
  21. package/vendor/packages/schemas/bin/validate-avatar.mjs +486 -0
  22. package/vendor/packages/schemas/bin/validate-captions.mjs +316 -0
  23. package/vendor/packages/schemas/bin/validate-connections.mjs +295 -0
  24. package/vendor/packages/schemas/bin/validate-edit.mjs +766 -0
  25. package/vendor/packages/schemas/bin/validate-intake.mjs +185 -0
  26. package/vendor/packages/schemas/bin/validate-interpretation.mjs +515 -0
  27. package/vendor/packages/schemas/bin/validate-plan-comments.mjs +170 -0
  28. package/vendor/packages/schemas/bin/validate-plan.mjs +365 -0
  29. package/vendor/packages/schemas/bin/validate-recipe.mjs +267 -0
  30. package/vendor/packages/schemas/bin/validate-research-plan.mjs +510 -0
  31. package/vendor/packages/schemas/bin/validate-review.mjs +427 -0
  32. package/vendor/packages/schemas/captions.schema.json +141 -0
  33. package/vendor/packages/schemas/connections.schema.json +153 -0
  34. package/vendor/packages/schemas/edit.schema.json +437 -0
  35. package/vendor/packages/schemas/examples/analysis-person-matte-valid/analysis.json +18 -0
  36. package/vendor/packages/schemas/examples/captions-text-style-background-mode-invalid/captions.json +18 -0
  37. package/vendor/packages/schemas/examples/captions-text-style-color-non-hex-invalid/captions.json +14 -0
  38. package/vendor/packages/schemas/examples/captions-text-style-default-only-valid/captions.json +27 -0
  39. package/vendor/packages/schemas/examples/captions-text-style-omitted-valid/captions.json +11 -0
  40. package/vendor/packages/schemas/examples/captions-text-style-opacity-out-of-range-invalid/captions.json +8 -0
  41. package/vendor/packages/schemas/examples/captions-text-style-record-override-valid/captions.json +27 -0
  42. package/vendor/packages/schemas/examples/captions-text-style-size-non-positive-invalid/captions.json +14 -0
  43. package/vendor/packages/schemas/examples/captions-text-style-zone-invalid/captions.json +16 -0
  44. package/vendor/packages/schemas/examples/connections-v0-invalid-auth/connections.json +32 -0
  45. package/vendor/packages/schemas/examples/connections-v0-memory-valid/connections.json +42 -0
  46. package/vendor/packages/schemas/examples/edit-beats-duplicate-id/edit.json +11 -0
  47. package/vendor/packages/schemas/examples/edit-beats-invalid-id/edit.json +10 -0
  48. package/vendor/packages/schemas/examples/edit-beats-missing-kind/edit.json +10 -0
  49. package/vendor/packages/schemas/examples/edit-beats-strength-out-of-range/edit.json +11 -0
  50. package/vendor/packages/schemas/examples/edit-beats-v0-src-present/edit.json +10 -0
  51. package/vendor/packages/schemas/examples/edit-beats-v0-valid/edit.json +29 -0
  52. package/vendor/packages/schemas/examples/edit-beats-v1-src-missing-reference/edit.json +14 -0
  53. package/vendor/packages/schemas/examples/edit-beats-v1-valid/edit.json +37 -0
  54. package/vendor/packages/schemas/examples/edit-bgm-ducking-invalid/edit.json +10 -0
  55. package/vendor/packages/schemas/examples/edit-bgm-fade-invalid/edit.json +10 -0
  56. package/vendor/packages/schemas/examples/edit-bgm-fade-valid/edit.json +10 -0
  57. package/vendor/packages/schemas/examples/edit-bgm-in-invalid/edit.json +10 -0
  58. package/vendor/packages/schemas/examples/edit-bgm-in-valid/edit.json +10 -0
  59. package/vendor/packages/schemas/examples/edit-bgm-missing-path/edit.json +10 -0
  60. package/vendor/packages/schemas/examples/edit-bgm-null-valid/edit.json +11 -0
  61. package/vendor/packages/schemas/examples/edit-bgm-sfx-gain-out-of-range/edit.json +11 -0
  62. package/vendor/packages/schemas/examples/edit-bgm-sfx-valid/edit.json +23 -0
  63. package/vendor/packages/schemas/examples/edit-chroma-key-invalid/edit.json +7 -0
  64. package/vendor/packages/schemas/examples/edit-cuts-at-negative-invalid/edit.json +7 -0
  65. package/vendor/packages/schemas/examples/edit-cuts-at-track-valid/edit.json +20 -0
  66. package/vendor/packages/schemas/examples/edit-cuts-opacity-out-of-range-invalid/edit.json +16 -0
  67. package/vendor/packages/schemas/examples/edit-cuts-track-invalid/edit.json +7 -0
  68. package/vendor/packages/schemas/examples/edit-cuts-transform-full-valid/edit.json +17 -0
  69. package/vendor/packages/schemas/examples/edit-cuts-transform-omitted-valid/edit.json +9 -0
  70. package/vendor/packages/schemas/examples/edit-cuts-transform-partial-valid/edit.json +16 -0
  71. package/vendor/packages/schemas/examples/edit-cuts-transform-rotate-invalid/edit.json +16 -0
  72. package/vendor/packages/schemas/examples/edit-cuts-transform-scale-invalid/edit.json +16 -0
  73. package/vendor/packages/schemas/examples/edit-cuts-transform-unknown-key-invalid/edit.json +16 -0
  74. package/vendor/packages/schemas/examples/edit-direction-intensity-negative/edit.json +8 -0
  75. package/vendor/packages/schemas/examples/edit-direction-intensity-not-integer/edit.json +8 -0
  76. package/vendor/packages/schemas/examples/edit-direction-intensity-out-of-range/edit.json +8 -0
  77. package/vendor/packages/schemas/examples/edit-direction-missing-preset/edit.json +8 -0
  78. package/vendor/packages/schemas/examples/edit-direction-overrides-array/edit.json +8 -0
  79. package/vendor/packages/schemas/examples/edit-direction-preset-only/edit.json +8 -0
  80. package/vendor/packages/schemas/examples/edit-direction-valid/edit.json +8 -0
  81. package/vendor/packages/schemas/examples/edit-emphasis-words-empty-word/edit.json +10 -0
  82. package/vendor/packages/schemas/examples/edit-emphasis-words-invalid-id/edit.json +10 -0
  83. package/vendor/packages/schemas/examples/edit-emphasis-words-missing-emotion/edit.json +10 -0
  84. package/vendor/packages/schemas/examples/edit-emphasis-words-range-invalid/edit.json +11 -0
  85. package/vendor/packages/schemas/examples/edit-emphasis-words-v0-src-present/edit.json +10 -0
  86. package/vendor/packages/schemas/examples/edit-emphasis-words-v0-valid/edit.json +32 -0
  87. package/vendor/packages/schemas/examples/edit-emphasis-words-v1-valid/edit.json +39 -0
  88. package/vendor/packages/schemas/examples/edit-layers-invalid-bad-blend/edit.json +17 -0
  89. package/vendor/packages/schemas/examples/edit-layers-invalid-chroma-key-on-baked/edit.json +17 -0
  90. package/vendor/packages/schemas/examples/edit-layers-invalid-duplicate-id/edit.json +11 -0
  91. package/vendor/packages/schemas/examples/edit-layers-track-invalid/edit.json +8 -0
  92. package/vendor/packages/schemas/examples/edit-layers-valid/edit.json +31 -0
  93. package/vendor/packages/schemas/examples/edit-look-invalid/edit.json +7 -0
  94. package/vendor/packages/schemas/examples/edit-master-invalid/edit.json +8 -0
  95. package/vendor/packages/schemas/examples/edit-narration-gain-out-of-range/edit.json +18 -0
  96. package/vendor/packages/schemas/examples/edit-narration-invalid-id/edit.json +17 -0
  97. package/vendor/packages/schemas/examples/edit-narration-missing-provenance/edit.json +16 -0
  98. package/vendor/packages/schemas/examples/edit-narration-valid/edit.json +36 -0
  99. package/vendor/packages/schemas/examples/edit-narration-voicevox-missing-credit/edit.json +20 -0
  100. package/vendor/packages/schemas/examples/edit-render-basics-valid/edit.json +22 -0
  101. package/vendor/packages/schemas/examples/edit-sfx-in-invalid/edit.json +10 -0
  102. package/vendor/packages/schemas/examples/edit-sfx-in-out-valid/edit.json +10 -0
  103. package/vendor/packages/schemas/examples/edit-sfx-out-invalid/edit.json +10 -0
  104. package/vendor/packages/schemas/examples/edit-sfx-out-type-invalid/edit.json +10 -0
  105. package/vendor/packages/schemas/examples/edit-sfx-t-invalid/edit.json +10 -0
  106. package/vendor/packages/schemas/examples/edit-sfx-track-invalid/edit.json +8 -0
  107. package/vendor/packages/schemas/examples/edit-speed-invalid/edit.json +7 -0
  108. package/vendor/packages/schemas/examples/edit-timeline-declared-valid/edit.json +14 -0
  109. package/vendor/packages/schemas/examples/edit-timeline-duplicate-id-invalid/edit.json +13 -0
  110. package/vendor/packages/schemas/examples/edit-timeline-interleaved-valid/edit.json +22 -0
  111. package/vendor/packages/schemas/examples/edit-timeline-omitted-valid/edit.json +7 -0
  112. package/vendor/packages/schemas/examples/edit-timeline-ref-invalid/edit.json +13 -0
  113. package/vendor/packages/schemas/examples/edit-tracks-section-invalid/edit.json +8 -0
  114. package/vendor/packages/schemas/examples/edit-tracks-section-valid/edit.json +13 -0
  115. package/vendor/packages/schemas/examples/edit-transition-invalid/edit.json +10 -0
  116. package/vendor/packages/schemas/examples/edit-v0-sample/edit.json +27 -0
  117. package/vendor/packages/schemas/examples/edit-v0-sample/overlays/cap-a.html +17 -0
  118. package/vendor/packages/schemas/examples/edit-v0-sample/overlays/cap-b.html +17 -0
  119. package/vendor/packages/schemas/examples/edit-v1-bgm-sfx-valid/edit.json +13 -0
  120. package/vendor/packages/schemas/examples/edit-v1-sample/edit.json +14 -0
  121. package/vendor/packages/schemas/examples/plan-comments-v0-sample/plan-comments.json +19 -0
  122. package/vendor/packages/schemas/examples/plan-v0-sample/plan.json +39 -0
  123. package/vendor/packages/schemas/examples/recipe-v0-sample/product-demo-quick-cuts.json +23 -0
  124. package/vendor/packages/schemas/examples/review-v1-sample/review.json +11 -0
  125. package/vendor/packages/schemas/fixtures/avatar/invalid-avatar-md-136-lines/AVATAR.md +159 -0
  126. package/vendor/packages/schemas/fixtures/avatar/invalid-avatar-md-136-lines/avatar.json +22 -0
  127. package/vendor/packages/schemas/fixtures/avatar/invalid-avatar-md-136-lines/renditions/2d-bustup/happy.png +0 -0
  128. package/vendor/packages/schemas/fixtures/avatar/invalid-avatar-md-136-lines/renditions/2d-bustup/neutral-half.png +0 -0
  129. package/vendor/packages/schemas/fixtures/avatar/invalid-avatar-md-136-lines/renditions/2d-bustup/neutral-open.png +0 -0
  130. package/vendor/packages/schemas/fixtures/avatar/invalid-avatar-md-136-lines/renditions/2d-bustup/neutral.png +0 -0
  131. package/vendor/packages/schemas/fixtures/avatar/invalid-avatar-md-136-lines/renditions/2d-bustup/rendition.json +18 -0
  132. package/vendor/packages/schemas/fixtures/avatar/invalid-avatar-md-136-lines/renditions/2d-fullbody/happy.png +0 -0
  133. package/vendor/packages/schemas/fixtures/avatar/invalid-avatar-md-136-lines/renditions/2d-fullbody/neutral-half.png +0 -0
  134. package/vendor/packages/schemas/fixtures/avatar/invalid-avatar-md-136-lines/renditions/2d-fullbody/neutral-open.png +0 -0
  135. package/vendor/packages/schemas/fixtures/avatar/invalid-avatar-md-136-lines/renditions/2d-fullbody/neutral.png +0 -0
  136. package/vendor/packages/schemas/fixtures/avatar/invalid-avatar-md-136-lines/renditions/2d-fullbody/rendition.json +18 -0
  137. package/vendor/packages/schemas/fixtures/avatar/invalid-default-role/AVATAR.md +30 -0
  138. package/vendor/packages/schemas/fixtures/avatar/invalid-default-role/avatar.json +22 -0
  139. package/vendor/packages/schemas/fixtures/avatar/invalid-default-role/renditions/2d-bustup/happy.png +0 -0
  140. package/vendor/packages/schemas/fixtures/avatar/invalid-default-role/renditions/2d-bustup/neutral-half.png +0 -0
  141. package/vendor/packages/schemas/fixtures/avatar/invalid-default-role/renditions/2d-bustup/neutral-open.png +0 -0
  142. package/vendor/packages/schemas/fixtures/avatar/invalid-default-role/renditions/2d-bustup/neutral.png +0 -0
  143. package/vendor/packages/schemas/fixtures/avatar/invalid-default-role/renditions/2d-bustup/rendition.json +18 -0
  144. package/vendor/packages/schemas/fixtures/avatar/invalid-default-role/renditions/2d-fullbody/happy.png +0 -0
  145. package/vendor/packages/schemas/fixtures/avatar/invalid-default-role/renditions/2d-fullbody/neutral-half.png +0 -0
  146. package/vendor/packages/schemas/fixtures/avatar/invalid-default-role/renditions/2d-fullbody/neutral-open.png +0 -0
  147. package/vendor/packages/schemas/fixtures/avatar/invalid-default-role/renditions/2d-fullbody/neutral.png +0 -0
  148. package/vendor/packages/schemas/fixtures/avatar/invalid-default-role/renditions/2d-fullbody/rendition.json +18 -0
  149. package/vendor/packages/schemas/fixtures/avatar/invalid-energy-out-of-range/AVATAR.md +30 -0
  150. package/vendor/packages/schemas/fixtures/avatar/invalid-energy-out-of-range/avatar.json +22 -0
  151. package/vendor/packages/schemas/fixtures/avatar/invalid-energy-out-of-range/renditions/2d-bustup/happy.png +0 -0
  152. package/vendor/packages/schemas/fixtures/avatar/invalid-energy-out-of-range/renditions/2d-bustup/neutral-half.png +0 -0
  153. package/vendor/packages/schemas/fixtures/avatar/invalid-energy-out-of-range/renditions/2d-bustup/neutral-open.png +0 -0
  154. package/vendor/packages/schemas/fixtures/avatar/invalid-energy-out-of-range/renditions/2d-bustup/neutral.png +0 -0
  155. package/vendor/packages/schemas/fixtures/avatar/invalid-energy-out-of-range/renditions/2d-bustup/rendition.json +18 -0
  156. package/vendor/packages/schemas/fixtures/avatar/invalid-energy-out-of-range/renditions/2d-fullbody/happy.png +0 -0
  157. package/vendor/packages/schemas/fixtures/avatar/invalid-energy-out-of-range/renditions/2d-fullbody/neutral-half.png +0 -0
  158. package/vendor/packages/schemas/fixtures/avatar/invalid-energy-out-of-range/renditions/2d-fullbody/neutral-open.png +0 -0
  159. package/vendor/packages/schemas/fixtures/avatar/invalid-energy-out-of-range/renditions/2d-fullbody/neutral.png +0 -0
  160. package/vendor/packages/schemas/fixtures/avatar/invalid-energy-out-of-range/renditions/2d-fullbody/rendition.json +18 -0
  161. package/vendor/packages/schemas/fixtures/avatar/invalid-missing-asset/AVATAR.md +30 -0
  162. package/vendor/packages/schemas/fixtures/avatar/invalid-missing-asset/avatar.json +22 -0
  163. package/vendor/packages/schemas/fixtures/avatar/invalid-missing-asset/renditions/2d-bustup/neutral-half.png +0 -0
  164. package/vendor/packages/schemas/fixtures/avatar/invalid-missing-asset/renditions/2d-bustup/neutral-open.png +0 -0
  165. package/vendor/packages/schemas/fixtures/avatar/invalid-missing-asset/renditions/2d-bustup/neutral.png +0 -0
  166. package/vendor/packages/schemas/fixtures/avatar/invalid-missing-asset/renditions/2d-bustup/rendition.json +18 -0
  167. package/vendor/packages/schemas/fixtures/avatar/invalid-missing-asset/renditions/2d-fullbody/happy.png +0 -0
  168. package/vendor/packages/schemas/fixtures/avatar/invalid-missing-asset/renditions/2d-fullbody/neutral-half.png +0 -0
  169. package/vendor/packages/schemas/fixtures/avatar/invalid-missing-asset/renditions/2d-fullbody/neutral-open.png +0 -0
  170. package/vendor/packages/schemas/fixtures/avatar/invalid-missing-asset/renditions/2d-fullbody/neutral.png +0 -0
  171. package/vendor/packages/schemas/fixtures/avatar/invalid-missing-asset/renditions/2d-fullbody/rendition.json +18 -0
  172. package/vendor/packages/schemas/fixtures/avatar/invalid-missing-rights/AVATAR.md +30 -0
  173. package/vendor/packages/schemas/fixtures/avatar/invalid-missing-rights/avatar.json +21 -0
  174. package/vendor/packages/schemas/fixtures/avatar/invalid-missing-rights/renditions/2d-bustup/happy.png +0 -0
  175. package/vendor/packages/schemas/fixtures/avatar/invalid-missing-rights/renditions/2d-bustup/neutral-half.png +0 -0
  176. package/vendor/packages/schemas/fixtures/avatar/invalid-missing-rights/renditions/2d-bustup/neutral-open.png +0 -0
  177. package/vendor/packages/schemas/fixtures/avatar/invalid-missing-rights/renditions/2d-bustup/neutral.png +0 -0
  178. package/vendor/packages/schemas/fixtures/avatar/invalid-missing-rights/renditions/2d-bustup/rendition.json +18 -0
  179. package/vendor/packages/schemas/fixtures/avatar/invalid-missing-rights/renditions/2d-fullbody/happy.png +0 -0
  180. package/vendor/packages/schemas/fixtures/avatar/invalid-missing-rights/renditions/2d-fullbody/neutral-half.png +0 -0
  181. package/vendor/packages/schemas/fixtures/avatar/invalid-missing-rights/renditions/2d-fullbody/neutral-open.png +0 -0
  182. package/vendor/packages/schemas/fixtures/avatar/invalid-missing-rights/renditions/2d-fullbody/neutral.png +0 -0
  183. package/vendor/packages/schemas/fixtures/avatar/invalid-missing-rights/renditions/2d-fullbody/rendition.json +18 -0
  184. package/vendor/packages/schemas/fixtures/avatar/invalid-no-avatar-json/AVATAR.md +30 -0
  185. package/vendor/packages/schemas/fixtures/avatar/invalid-person-in-catalog/catalog/avatars/impostor/AVATAR.md +30 -0
  186. package/vendor/packages/schemas/fixtures/avatar/invalid-person-in-catalog/catalog/avatars/impostor/avatar.json +22 -0
  187. package/vendor/packages/schemas/fixtures/avatar/invalid-person-in-catalog/catalog/avatars/impostor/renditions/2d-bustup/happy.png +0 -0
  188. package/vendor/packages/schemas/fixtures/avatar/invalid-person-in-catalog/catalog/avatars/impostor/renditions/2d-bustup/neutral-half.png +0 -0
  189. package/vendor/packages/schemas/fixtures/avatar/invalid-person-in-catalog/catalog/avatars/impostor/renditions/2d-bustup/neutral-open.png +0 -0
  190. package/vendor/packages/schemas/fixtures/avatar/invalid-person-in-catalog/catalog/avatars/impostor/renditions/2d-bustup/neutral.png +0 -0
  191. package/vendor/packages/schemas/fixtures/avatar/invalid-person-in-catalog/catalog/avatars/impostor/renditions/2d-bustup/rendition.json +18 -0
  192. package/vendor/packages/schemas/fixtures/avatar/invalid-person-in-catalog/catalog/avatars/impostor/renditions/2d-fullbody/happy.png +0 -0
  193. package/vendor/packages/schemas/fixtures/avatar/invalid-person-in-catalog/catalog/avatars/impostor/renditions/2d-fullbody/neutral-half.png +0 -0
  194. package/vendor/packages/schemas/fixtures/avatar/invalid-person-in-catalog/catalog/avatars/impostor/renditions/2d-fullbody/neutral-open.png +0 -0
  195. package/vendor/packages/schemas/fixtures/avatar/invalid-person-in-catalog/catalog/avatars/impostor/renditions/2d-fullbody/neutral.png +0 -0
  196. package/vendor/packages/schemas/fixtures/avatar/invalid-person-in-catalog/catalog/avatars/impostor/renditions/2d-fullbody/rendition.json +18 -0
  197. package/vendor/packages/schemas/fixtures/avatar/invalid-person-sellable/AVATAR.md +30 -0
  198. package/vendor/packages/schemas/fixtures/avatar/invalid-person-sellable/avatar.json +22 -0
  199. package/vendor/packages/schemas/fixtures/avatar/invalid-person-sellable/renditions/2d-bustup/happy.png +0 -0
  200. package/vendor/packages/schemas/fixtures/avatar/invalid-person-sellable/renditions/2d-bustup/neutral-half.png +0 -0
  201. package/vendor/packages/schemas/fixtures/avatar/invalid-person-sellable/renditions/2d-bustup/neutral-open.png +0 -0
  202. package/vendor/packages/schemas/fixtures/avatar/invalid-person-sellable/renditions/2d-bustup/neutral.png +0 -0
  203. package/vendor/packages/schemas/fixtures/avatar/invalid-person-sellable/renditions/2d-bustup/rendition.json +18 -0
  204. package/vendor/packages/schemas/fixtures/avatar/invalid-person-sellable/renditions/2d-fullbody/happy.png +0 -0
  205. package/vendor/packages/schemas/fixtures/avatar/invalid-person-sellable/renditions/2d-fullbody/neutral-half.png +0 -0
  206. package/vendor/packages/schemas/fixtures/avatar/invalid-person-sellable/renditions/2d-fullbody/neutral-open.png +0 -0
  207. package/vendor/packages/schemas/fixtures/avatar/invalid-person-sellable/renditions/2d-fullbody/neutral.png +0 -0
  208. package/vendor/packages/schemas/fixtures/avatar/invalid-person-sellable/renditions/2d-fullbody/rendition.json +18 -0
  209. package/vendor/packages/schemas/fixtures/avatar/unsupported-version/AVATAR.md +30 -0
  210. package/vendor/packages/schemas/fixtures/avatar/unsupported-version/avatar.json +22 -0
  211. package/vendor/packages/schemas/fixtures/avatar/unsupported-version/renditions/2d-bustup/happy.png +0 -0
  212. package/vendor/packages/schemas/fixtures/avatar/unsupported-version/renditions/2d-bustup/neutral-half.png +0 -0
  213. package/vendor/packages/schemas/fixtures/avatar/unsupported-version/renditions/2d-bustup/neutral-open.png +0 -0
  214. package/vendor/packages/schemas/fixtures/avatar/unsupported-version/renditions/2d-bustup/neutral.png +0 -0
  215. package/vendor/packages/schemas/fixtures/avatar/unsupported-version/renditions/2d-bustup/rendition.json +18 -0
  216. package/vendor/packages/schemas/fixtures/avatar/unsupported-version/renditions/2d-fullbody/happy.png +0 -0
  217. package/vendor/packages/schemas/fixtures/avatar/unsupported-version/renditions/2d-fullbody/neutral-half.png +0 -0
  218. package/vendor/packages/schemas/fixtures/avatar/unsupported-version/renditions/2d-fullbody/neutral-open.png +0 -0
  219. package/vendor/packages/schemas/fixtures/avatar/unsupported-version/renditions/2d-fullbody/neutral.png +0 -0
  220. package/vendor/packages/schemas/fixtures/avatar/unsupported-version/renditions/2d-fullbody/rendition.json +18 -0
  221. package/vendor/packages/schemas/fixtures/avatar/valid/AVATAR.md +30 -0
  222. package/vendor/packages/schemas/fixtures/avatar/valid/avatar.json +22 -0
  223. package/vendor/packages/schemas/fixtures/avatar/valid/renditions/2d-bustup/happy.png +0 -0
  224. package/vendor/packages/schemas/fixtures/avatar/valid/renditions/2d-bustup/neutral-half.png +0 -0
  225. package/vendor/packages/schemas/fixtures/avatar/valid/renditions/2d-bustup/neutral-open.png +0 -0
  226. package/vendor/packages/schemas/fixtures/avatar/valid/renditions/2d-bustup/neutral.png +0 -0
  227. package/vendor/packages/schemas/fixtures/avatar/valid/renditions/2d-bustup/rendition.json +18 -0
  228. package/vendor/packages/schemas/fixtures/avatar/valid/renditions/2d-fullbody/happy.png +0 -0
  229. package/vendor/packages/schemas/fixtures/avatar/valid/renditions/2d-fullbody/neutral-half.png +0 -0
  230. package/vendor/packages/schemas/fixtures/avatar/valid/renditions/2d-fullbody/neutral-open.png +0 -0
  231. package/vendor/packages/schemas/fixtures/avatar/valid/renditions/2d-fullbody/neutral.png +0 -0
  232. package/vendor/packages/schemas/fixtures/avatar/valid/renditions/2d-fullbody/rendition.json +18 -0
  233. package/vendor/packages/schemas/fixtures/avatar/valid-unknown-fields/AVATAR.md +30 -0
  234. package/vendor/packages/schemas/fixtures/avatar/valid-unknown-fields/avatar.json +23 -0
  235. package/vendor/packages/schemas/fixtures/avatar/valid-unknown-fields/renditions/2d-bustup/happy.png +0 -0
  236. package/vendor/packages/schemas/fixtures/avatar/valid-unknown-fields/renditions/2d-bustup/neutral-half.png +0 -0
  237. package/vendor/packages/schemas/fixtures/avatar/valid-unknown-fields/renditions/2d-bustup/neutral-open.png +0 -0
  238. package/vendor/packages/schemas/fixtures/avatar/valid-unknown-fields/renditions/2d-bustup/neutral.png +0 -0
  239. package/vendor/packages/schemas/fixtures/avatar/valid-unknown-fields/renditions/2d-bustup/rendition.json +18 -0
  240. package/vendor/packages/schemas/fixtures/avatar/valid-unknown-fields/renditions/2d-fullbody/happy.png +0 -0
  241. package/vendor/packages/schemas/fixtures/avatar/valid-unknown-fields/renditions/2d-fullbody/neutral-half.png +0 -0
  242. package/vendor/packages/schemas/fixtures/avatar/valid-unknown-fields/renditions/2d-fullbody/neutral-open.png +0 -0
  243. package/vendor/packages/schemas/fixtures/avatar/valid-unknown-fields/renditions/2d-fullbody/neutral.png +0 -0
  244. package/vendor/packages/schemas/fixtures/avatar/valid-unknown-fields/renditions/2d-fullbody/rendition.json +18 -0
  245. package/vendor/packages/schemas/fixtures/avatar/valid-voice-only/AVATAR.md +28 -0
  246. package/vendor/packages/schemas/fixtures/avatar/valid-voice-only/avatar.json +19 -0
  247. package/vendor/packages/schemas/fixtures/intake/invalid-duplicate-task/intake.json +8 -0
  248. package/vendor/packages/schemas/fixtures/intake/invalid-missing-submitted-at/intake.json +8 -0
  249. package/vendor/packages/schemas/fixtures/intake/invalid-target-exclusive/intake.json +8 -0
  250. package/vendor/packages/schemas/fixtures/intake/invalid-unknown-task/intake.json +8 -0
  251. package/vendor/packages/schemas/fixtures/intake/valid-draft/intake.json +8 -0
  252. package/vendor/packages/schemas/fixtures/intake/valid-submitted/intake.json +8 -0
  253. package/vendor/packages/schemas/fixtures/plan/invalid-bad-confidence-enum/plan.json +15 -0
  254. package/vendor/packages/schemas/fixtures/plan/invalid-constraint-bad-applies-to/plan.json +18 -0
  255. package/vendor/packages/schemas/fixtures/plan/invalid-dangling-media-path/plan.json +15 -0
  256. package/vendor/packages/schemas/fixtures/plan/invalid-duplicate-slot-id/plan.json +25 -0
  257. package/vendor/packages/schemas/fixtures/plan/invalid-missing-required-field/plan.json +14 -0
  258. package/vendor/packages/schemas/fixtures/plan/unsupported-version/plan.json +4 -0
  259. package/vendor/packages/schemas/fixtures/plan/valid/plan.json +40 -0
  260. package/vendor/packages/schemas/fixtures/plan/valid/scaffold/beat-01.png +1 -0
  261. package/vendor/packages/schemas/fixtures/plan/valid/scaffold/beat-01.wav +1 -0
  262. package/vendor/packages/schemas/fixtures/plan/valid/scaffold/broll.mp4 +1 -0
  263. package/vendor/packages/schemas/fixtures/plan/warns-confidence-gap/plan.json +28 -0
  264. package/vendor/packages/schemas/fixtures/plan-comments/invalid-bad-pass/plan-comments.json +6 -0
  265. package/vendor/packages/schemas/fixtures/plan-comments/invalid-bad-target-id-for-index-kind/plan-comments.json +13 -0
  266. package/vendor/packages/schemas/fixtures/plan-comments/invalid-bad-target-kind/plan-comments.json +13 -0
  267. package/vendor/packages/schemas/fixtures/plan-comments/invalid-comments-not-array/plan-comments.json +6 -0
  268. package/vendor/packages/schemas/fixtures/plan-comments/invalid-missing-comment-field/plan-comments.json +12 -0
  269. package/vendor/packages/schemas/fixtures/plan-comments/invalid-missing-version/plan-comments.json +5 -0
  270. package/vendor/packages/schemas/fixtures/plan-comments/unsupported-version/plan-comments.json +6 -0
  271. package/vendor/packages/schemas/fixtures/plan-comments/valid/plan-comments.json +19 -0
  272. package/vendor/packages/schemas/fixtures/plan-comments/valid-unknown-fields/plan-comments.json +15 -0
  273. package/vendor/packages/schemas/fixtures/recipe/invalid-bad-aspect/recipe.json +13 -0
  274. package/vendor/packages/schemas/fixtures/recipe/invalid-bad-confirmed-by/recipe.json +13 -0
  275. package/vendor/packages/schemas/fixtures/recipe/invalid-bad-name-casing/recipe.json +13 -0
  276. package/vendor/packages/schemas/fixtures/recipe/invalid-bad-workflow/recipe.json +13 -0
  277. package/vendor/packages/schemas/fixtures/recipe/invalid-duplicate-overlay-kind/recipe.json +13 -0
  278. package/vendor/packages/schemas/fixtures/recipe/invalid-empty-confirmed/recipe.json +9 -0
  279. package/vendor/packages/schemas/fixtures/recipe/invalid-empty-narration/recipe.json +13 -0
  280. package/vendor/packages/schemas/fixtures/recipe/invalid-missing-version/recipe.json +12 -0
  281. package/vendor/packages/schemas/fixtures/recipe/invalid-provenance-mismatch/recipe.json +15 -0
  282. package/vendor/packages/schemas/fixtures/recipe/invalid-source-project-path/recipe.json +13 -0
  283. package/vendor/packages/schemas/fixtures/recipe/unsupported-version/recipe.json +13 -0
  284. package/vendor/packages/schemas/fixtures/recipe/valid/recipe.json +15 -0
  285. package/vendor/packages/schemas/fixtures/recipe/valid-unknown-fields/recipe.json +16 -0
  286. package/vendor/packages/schemas/fixtures/review/invalid-malformed-canvas-target/review.json +6 -0
  287. package/vendor/packages/schemas/fixtures/review/invalid-malformed-doc-target/review.json +6 -0
  288. package/vendor/packages/schemas/fixtures/review/invalid-malformed-image-target/review.json +6 -0
  289. package/vendor/packages/schemas/fixtures/review/invalid-strokes-bad-space/review.json +6 -0
  290. package/vendor/packages/schemas/fixtures/review/invalid-strokes-canvas-rect-with-frame/review.json +6 -0
  291. package/vendor/packages/schemas/fixtures/review/invalid-strokes-image-rect-with-frame/review.json +6 -0
  292. package/vendor/packages/schemas/fixtures/review/invalid-video-null-sourcet/review.json +6 -0
  293. package/vendor/packages/schemas/fixtures/review/valid/review.json +8 -0
  294. package/vendor/packages/schemas/fixtures/review/valid-canvas-target/review.json +7 -0
  295. package/vendor/packages/schemas/fixtures/review/valid-input-session/review.json +6 -0
  296. package/vendor/packages/schemas/fixtures/review/valid-strokes/review.json +8 -0
  297. package/vendor/packages/schemas/intake.schema.json +117 -0
  298. package/vendor/packages/schemas/interpretation.schema.json +419 -0
  299. package/vendor/packages/schemas/package.json +18 -0
  300. package/vendor/packages/schemas/plan-comments.schema.json +52 -0
  301. package/vendor/packages/schemas/plan.schema.json +129 -0
  302. package/vendor/packages/schemas/recipe.schema.json +106 -0
  303. package/vendor/packages/schemas/research-plan.schema.json +230 -0
  304. package/vendor/packages/schemas/review.schema.json +227 -0
  305. package/vendor/packages/schemas/test/fixtures/asset/invalid-matched-by/audio/whoosh-transition/meta.json +31 -0
  306. package/vendor/packages/schemas/test/fixtures/asset/valid-catalog/audio/whoosh-transition/meta.json +31 -0
  307. package/vendor/packages/schemas/test/fixtures/asset/valid-library/telop/lower-third-clean/fragment.html +139 -0
  308. package/vendor/packages/schemas/test/fixtures/asset/valid-library/telop/lower-third-clean/meta.json +32 -0
  309. package/vendor/packages/schemas/test/fixtures/asset/valid-library/telop/lower-third-clean/preview.png +0 -0
  310. package/vendor/packages/schemas/test/fixtures/interpretation/invalid-analyses-missing-ref/interpretation.json +131 -0
  311. package/vendor/packages/schemas/test/fixtures/interpretation/invalid-analyses-ref-mismatch/interpretation.json +132 -0
  312. package/vendor/packages/schemas/test/fixtures/interpretation/invalid-arc-empty-refs/interpretation.json +126 -0
  313. package/vendor/packages/schemas/test/fixtures/interpretation/invalid-context-missing-interview/interpretation.json +126 -0
  314. package/vendor/packages/schemas/test/fixtures/interpretation/invalid-context-null-intake/interpretation.json +133 -0
  315. package/vendor/packages/schemas/test/fixtures/interpretation/invalid-dangling-arc-ref/interpretation.json +132 -0
  316. package/vendor/packages/schemas/test/fixtures/interpretation/invalid-duplicate-asset-ref/interpretation.json +132 -0
  317. package/vendor/packages/schemas/test/fixtures/interpretation/invalid-flag-bad-type/interpretation.json +132 -0
  318. package/vendor/packages/schemas/test/fixtures/interpretation/invalid-flag-missing-evidence/interpretation.json +131 -0
  319. package/vendor/packages/schemas/test/fixtures/interpretation/invalid-missing-required-field/interpretation.json +131 -0
  320. package/vendor/packages/schemas/test/fixtures/interpretation/invalid-open-question-answer-present-when-open/interpretation.json +133 -0
  321. package/vendor/packages/schemas/test/fixtures/interpretation/invalid-open-question-answered-without-answer/interpretation.json +131 -0
  322. package/vendor/packages/schemas/test/fixtures/interpretation/invalid-relations-dangling-target/interpretation.json +132 -0
  323. package/vendor/packages/schemas/test/fixtures/interpretation/invalid-relations-self-reference/interpretation.json +132 -0
  324. package/vendor/packages/schemas/test/fixtures/interpretation/invalid-section-end-before-start/interpretation.json +132 -0
  325. package/vendor/packages/schemas/test/fixtures/interpretation/invalid-section-mismatched-start-end/interpretation.json +131 -0
  326. package/vendor/packages/schemas/test/fixtures/interpretation/invalid-unknown-root-field/interpretation.json +133 -0
  327. package/vendor/packages/schemas/test/fixtures/interpretation/unsupported-version/interpretation.json +132 -0
  328. package/vendor/packages/schemas/test/fixtures/interpretation/valid/interpretation.json +132 -0
  329. package/vendor/packages/schemas/test/fixtures/research-plan/invalid-bad-category-enum/research-plan.json +128 -0
  330. package/vendor/packages/schemas/test/fixtures/research-plan/invalid-dangling-chapter-ref/research-plan.json +128 -0
  331. package/vendor/packages/schemas/test/fixtures/research-plan/invalid-dangling-shot-list-ref/research-plan.json +128 -0
  332. package/vendor/packages/schemas/test/fixtures/research-plan/invalid-decided-at-mismatch/research-plan.json +128 -0
  333. package/vendor/packages/schemas/test/fixtures/research-plan/invalid-duplicate-candidate-id/research-plan.json +128 -0
  334. package/vendor/packages/schemas/test/fixtures/research-plan/invalid-japan-sns-notes-empty/research-plan.json +128 -0
  335. package/vendor/packages/schemas/test/fixtures/research-plan/invalid-missing-required-field/research-plan.json +127 -0
  336. package/vendor/packages/schemas/test/fixtures/research-plan/invalid-selected-missing-candidate/research-plan.json +128 -0
  337. package/vendor/packages/schemas/test/fixtures/research-plan/invalid-structure-confirmed-mismatch/research-plan.json +128 -0
  338. package/vendor/packages/schemas/test/fixtures/research-plan/unsupported-version/research-plan.json +128 -0
  339. package/vendor/packages/schemas/test/fixtures/research-plan/valid/research-plan.json +79 -0
  340. package/vendor/packages/schemas/test/fixtures/research-plan/warns-empty-sources/research-plan.json +120 -0
  341. package/vendor/packages/schemas/test/validate-asset.test.mjs +38 -0
  342. package/vendor/packages/schemas/test/validate-avatar.test.mjs +109 -0
  343. package/vendor/packages/schemas/test/validate-captions.test.mjs +59 -0
  344. package/vendor/packages/schemas/test/validate-connections.test.mjs +31 -0
  345. package/vendor/packages/schemas/test/validate-edit.test.mjs +490 -0
  346. package/vendor/packages/schemas/test/validate-intake.test.mjs +66 -0
  347. package/vendor/packages/schemas/test/validate-interpretation.test.mjs +167 -0
  348. package/vendor/packages/schemas/test/validate-plan-comments.test.mjs +70 -0
  349. package/vendor/packages/schemas/test/validate-plan.test.mjs +67 -0
  350. package/vendor/packages/schemas/test/validate-recipe.test.mjs +107 -0
  351. package/vendor/packages/schemas/test/validate-research-plan.test.mjs +98 -0
  352. package/vendor/packages/schemas/test/validate-review.test.mjs +102 -0
  353. package/vendor/skills/.gitkeep +0 -0
  354. package/vendor/skills/address-review/SKILL.md +84 -0
  355. package/vendor/skills/address-review/bin/core/review-store.mjs +210 -0
  356. package/vendor/skills/address-review/bin/list.mjs +198 -0
  357. package/vendor/skills/address-review/bin/respond.mjs +89 -0
  358. package/vendor/skills/address-review/dev-fixtures/fixture-project/captions.json +22 -0
  359. package/vendor/skills/address-review/dev-fixtures/fixture-project/edit.json +12 -0
  360. package/vendor/skills/address-review/dev-fixtures/fixture-project/review.json +100 -0
  361. package/vendor/skills/address-review/test/review-store.test.mjs +201 -0
  362. package/vendor/skills/analyze-footage/SKILL.md +35 -0
  363. package/vendor/skills/analyze-footage/analysis-json.md +185 -0
  364. package/vendor/skills/analyze-footage/bin/person-matte/person-matte-helper.swift +343 -0
  365. package/vendor/skills/analyze-footage/bin/person-matte/person-matte.mjs +415 -0
  366. package/vendor/skills/analyze-footage/bin/speechanalyzer-helper.swift +138 -0
  367. package/vendor/skills/analyze-footage/bin/transcribe-cloud.mjs +486 -0
  368. package/vendor/skills/analyze-footage/bin/transcribe-sa.mjs +189 -0
  369. package/vendor/skills/analyze-footage/events-and-hooks.md +93 -0
  370. package/vendor/skills/analyze-footage/keyframes-and-review.md +130 -0
  371. package/vendor/skills/analyze-footage/media-and-transcript.md +219 -0
  372. package/vendor/skills/analyze-footage/person-matte.md +121 -0
  373. package/vendor/skills/analyze-footage/references/akari-data-contract.md +18 -0
  374. package/vendor/skills/analyze-footage/references/asset.meta.example.json +23 -0
  375. package/vendor/skills/analyze-footage/test/fixtures/scribe-punctuation-inflation.json +17 -0
  376. package/vendor/skills/analyze-footage/test/normalize-scribe.test.mjs +76 -0
  377. package/vendor/skills/analyze-footage/workflow.md +95 -0
  378. package/vendor/skills/analyze-project/SKILL.md +58 -0
  379. package/vendor/skills/analyze-project/collect.md +51 -0
  380. package/vendor/skills/analyze-project/decision-record.md +55 -0
  381. package/vendor/skills/analyze-project/interpretation.md +128 -0
  382. package/vendor/skills/analyze-project/interview.md +66 -0
  383. package/vendor/skills/analyze-project/references/interpretation-shape.md +42 -0
  384. package/vendor/skills/analyze-project/references/open-questions-examples.md +35 -0
  385. package/vendor/skills/analyze-project/validate-and-render.md +66 -0
  386. package/vendor/skills/bake-3d/SKILL.md +78 -0
  387. package/vendor/skills/compile-review-session/SKILL.md +78 -0
  388. package/vendor/skills/compile-review-session/bin/compile-review-session.mjs +799 -0
  389. package/vendor/skills/compile-review-session/bin/core/canvas-compiler.mjs +105 -0
  390. package/vendor/skills/compile-review-session/bin/core/compiler.mjs +221 -0
  391. package/vendor/skills/compile-review-session/bin/core/review-store.mjs +74 -0
  392. package/vendor/skills/compile-review-session/bin/core/time-mapping.mjs +370 -0
  393. package/vendor/skills/compile-review-session/bin/core/transcription.mjs +721 -0
  394. package/vendor/skills/compile-review-session/compilation-rules.md +98 -0
  395. package/vendor/skills/compile-review-session/dev-fixtures/README.md +24 -0
  396. package/vendor/skills/compile-review-session/dev-fixtures/fixture-project/review/sessions/s-0001/audio.wav +0 -0
  397. package/vendor/skills/compile-review-session/dev-fixtures/fixture-project/review/sessions/s-0001/edit.snapshot.json +12 -0
  398. package/vendor/skills/compile-review-session/dev-fixtures/fixture-project/review/sessions/s-0001/events.jsonl +2 -0
  399. package/vendor/skills/compile-review-session/dev-fixtures/fixture-project/review/sessions/s-0001/session.json +11 -0
  400. package/vendor/skills/compile-review-session/dev-fixtures/fixture-project/review/sessions/s-0002/audio.wav +0 -0
  401. package/vendor/skills/compile-review-session/dev-fixtures/fixture-project/review/sessions/s-0002/edit.snapshot.json +12 -0
  402. package/vendor/skills/compile-review-session/dev-fixtures/fixture-project/review/sessions/s-0002/events.jsonl +5 -0
  403. package/vendor/skills/compile-review-session/dev-fixtures/fixture-project/review/sessions/s-0002/session.json +11 -0
  404. package/vendor/skills/compile-review-session/dev-fixtures/fixture-project/review/sessions/s-0003/audio.wav +0 -0
  405. package/vendor/skills/compile-review-session/dev-fixtures/fixture-project/review/sessions/s-0003/edit.snapshot.json +12 -0
  406. package/vendor/skills/compile-review-session/dev-fixtures/fixture-project/review/sessions/s-0003/events.jsonl +19 -0
  407. package/vendor/skills/compile-review-session/dev-fixtures/fixture-project/review/sessions/s-0003/session.json +11 -0
  408. package/vendor/skills/compile-review-session/dev-fixtures/fixture-project/review/sessions/s-0004/audio.wav +0 -0
  409. package/vendor/skills/compile-review-session/dev-fixtures/fixture-project/review/sessions/s-0004/edit.snapshot.json +12 -0
  410. package/vendor/skills/compile-review-session/dev-fixtures/fixture-project/review/sessions/s-0004/events.jsonl +2 -0
  411. package/vendor/skills/compile-review-session/dev-fixtures/fixture-project/review/sessions/s-0004/session.json +11 -0
  412. package/vendor/skills/compile-review-session/dev-fixtures/fixture-project/review/sessions/s-0005/session.json +1 -0
  413. package/vendor/skills/compile-review-session/dev-fixtures/fixture-project/review/sessions/s-0006/audio.wav +0 -0
  414. package/vendor/skills/compile-review-session/dev-fixtures/fixture-project/review/sessions/s-0006/events.jsonl +2 -0
  415. package/vendor/skills/compile-review-session/dev-fixtures/fixture-project/review/sessions/s-0006/session.json +11 -0
  416. package/vendor/skills/compile-review-session/dev-fixtures/fixture-project/review/sessions/s-0007/audio.wav +0 -0
  417. package/vendor/skills/compile-review-session/dev-fixtures/fixture-project/review/sessions/s-0007/edit.snapshot.json +13 -0
  418. package/vendor/skills/compile-review-session/dev-fixtures/fixture-project/review/sessions/s-0007/events.jsonl +9 -0
  419. package/vendor/skills/compile-review-session/dev-fixtures/fixture-project/review/sessions/s-0007/session.json +11 -0
  420. package/vendor/skills/compile-review-session/dev-fixtures/fixture-project/review/sessions/s-0008/audio.wav +0 -0
  421. package/vendor/skills/compile-review-session/dev-fixtures/fixture-project/review/sessions/s-0008/edit.snapshot.json +12 -0
  422. package/vendor/skills/compile-review-session/dev-fixtures/fixture-project/review/sessions/s-0008/events.jsonl +2 -0
  423. package/vendor/skills/compile-review-session/dev-fixtures/fixture-project/review/sessions/s-0008/session.json +11 -0
  424. package/vendor/skills/compile-review-session/dev-fixtures/fixture-project/review/sessions/s-0008/transcript.json +9 -0
  425. package/vendor/skills/compile-review-session/dev-fixtures/fixture-project/review.json +7 -0
  426. package/vendor/skills/compile-review-session/test/canvas-compiler.test.mjs +283 -0
  427. package/vendor/skills/compile-review-session/test/compiler.test.mjs +458 -0
  428. package/vendor/skills/create-project/SKILL.md +46 -0
  429. package/vendor/skills/create-project/bin/create-project.mjs +88 -0
  430. package/vendor/skills/edit-lint/SKILL.md +73 -0
  431. package/vendor/skills/edit-plan/SKILL.md +64 -0
  432. package/vendor/skills/edit-plan/approvals-and-generation.md +106 -0
  433. package/vendor/skills/edit-plan/avatar-resolution.md +241 -0
  434. package/vendor/skills/edit-plan/beat-sync.md +545 -0
  435. package/vendor/skills/edit-plan/beats.md +197 -0
  436. package/vendor/skills/edit-plan/emphasis-detection.md +366 -0
  437. package/vendor/skills/edit-plan/execution.md +157 -0
  438. package/vendor/skills/edit-plan/expression-selection.md +290 -0
  439. package/vendor/skills/edit-plan/plan-json.md +52 -0
  440. package/vendor/skills/edit-plan/recipe.md +74 -0
  441. package/vendor/skills/edit-plan/references/asset.decisions.example.json +12 -0
  442. package/vendor/skills/edit-plan/references/event.example.json +7 -0
  443. package/vendor/skills/edit-plan/report-guide.md +192 -0
  444. package/vendor/skills/edit-plan/workflow.md +108 -0
  445. package/vendor/skills/generate-narration/SKILL.md +40 -0
  446. package/vendor/skills/generate-narration/assets/reading-script-v1.md +18 -0
  447. package/vendor/skills/generate-narration/avatar-voice.md +54 -0
  448. package/vendor/skills/generate-narration/bin/generate-narration.mjs +572 -0
  449. package/vendor/skills/generate-narration/engines.md +78 -0
  450. package/vendor/skills/generate-narration/reading-text.md +36 -0
  451. package/vendor/skills/generate-narration/voice-profile-setup.md +77 -0
  452. package/vendor/skills/harvest-asset/SKILL.md +132 -0
  453. package/vendor/skills/manage-connections/SKILL.md +75 -0
  454. package/vendor/skills/manage-connections/bin/doctor.mjs +341 -0
  455. package/vendor/skills/overlay-authoring/3d.md +143 -0
  456. package/vendor/skills/overlay-authoring/SKILL.md +30 -0
  457. package/vendor/skills/overlay-authoring/motion.md +58 -0
  458. package/vendor/skills/overlay-authoring/table.md +41 -0
  459. package/vendor/skills/overlay-authoring/telop.md +69 -0
  460. package/vendor/skills/overlay-authoring/text-behind-person.md +224 -0
  461. package/vendor/skills/overlay-authoring/thumbnail.md +126 -0
  462. package/vendor/skills/render-cut/SKILL.md +66 -0
  463. package/vendor/skills/research-plan/SKILL.md +75 -0
  464. package/vendor/skills/research-plan/competitor.md +50 -0
  465. package/vendor/skills/research-plan/ideate.md +56 -0
  466. package/vendor/skills/research-plan/shotlist.md +46 -0
  467. package/vendor/skills/research-plan/storyboard.md +48 -0
  468. package/vendor/skills/research-plan/trends.md +33 -0
  469. package/vendor/skills/setup-audio-library/SKILL.md +93 -0
  470. package/vendor/skills/setup-audio-library/candidate-list.md +72 -0
  471. package/vendor/skills/setup-audio-library/drop-folder.md +72 -0
  472. package/vendor/skills/setup-audio-library/gallery.md +43 -0
  473. package/vendor/skills/setup-library/SKILL.md +33 -0
  474. package/vendor/skills/setup-library/fetch-and-validate.md +102 -0
  475. package/vendor/skills/setup-library/starter-pack.md +55 -0
  476. package/vendor/skills/setup-library/tools-check.md +83 -0
  477. package/vendor/skills/verify/SKILL.md +137 -0
  478. package/vendor/templates/project-default/.akari/cache/.gitkeep +0 -0
  479. package/vendor/templates/project-default/.akari/connections.json +233 -0
  480. package/vendor/templates/project-default/.akari/diffs/.gitkeep +1 -0
  481. package/vendor/templates/project-default/.akari/events/.gitkeep +1 -0
  482. package/vendor/templates/project-default/.akari/reports/.gitkeep +0 -0
  483. package/vendor/templates/project-default/.akari/sidecars/.gitkeep +1 -0
  484. package/vendor/templates/project-default/.akari/work/.gitkeep +0 -0
  485. package/vendor/templates/project-default/.akari/workflow.json +48 -0
  486. package/vendor/templates/project-default/.claude/settings.json +15 -0
  487. package/vendor/templates/project-default/.claude/skills/README.md +26 -0
  488. package/vendor/templates/project-default/AGENTS.md +49 -0
  489. package/vendor/templates/project-default/CLAUDE.md +35 -0
  490. package/vendor/templates/project-default/assets/.gitkeep +1 -0
  491. package/vendor/templates/project-default/exports/.gitkeep +1 -0
  492. package/vendor/templates/project-default/planning/.gitkeep +1 -0
@@ -0,0 +1,572 @@
1
+ #!/usr/bin/env node
2
+
3
+ // 原稿テキストから VOICEVOX(ローカル)または fal Qwen3-TTS(自声クローン)でナレーション音声を
4
+ // 生成し、docs/contract-2026-07-20-edit-json-v1-narration.md 準拠のエントリを組み立てる。
5
+
6
+ import fs from "node:fs";
7
+ import os from "node:os";
8
+ import path from "node:path";
9
+ import { spawn, spawnSync } from "node:child_process";
10
+ import { fileURLToPath } from "node:url";
11
+
12
+ const VOICEVOX_BASE_URL = "http://127.0.0.1:50021";
13
+ const VOICEVOX_RUN_ENV = "VOICEVOX_RUN";
14
+ const VOICEVOX_STARTUP_TIMEOUT_MS = 60_000;
15
+ const FAL_TTS_URL = "https://fal.run/fal-ai/qwen-3-tts/text-to-speech/1.7b";
16
+ const FAL_USD_PER_1000_CHARS = 0.09;
17
+
18
+ const usage = [
19
+ "使い方:",
20
+ " node generate-narration.mjs generate \\",
21
+ " --project <projectDir> --engine <voicevox|fal-qwen3> \\",
22
+ " --reading-file <読み原稿.txt> [--script-file <表示原稿.txt>] \\",
23
+ " --t <タイムライン秒> [--gain-db 0] [--id n-0001] \\",
24
+ " [--speaker 3] [--profile owner-ja] [--dry-run] [--yes] [--apply]",
25
+ ].join("\n");
26
+
27
+ class PublicError extends Error {
28
+ constructor(message, exitCode = 1) {
29
+ super(message);
30
+ this.exitCode = exitCode;
31
+ }
32
+ }
33
+
34
+ function printJson(value) {
35
+ process.stdout.write(`${JSON.stringify(value, null, 2)}\n`);
36
+ }
37
+
38
+ function sleep(ms) {
39
+ return new Promise((resolve) => setTimeout(resolve, ms));
40
+ }
41
+
42
+ function isPlainObject(value) {
43
+ return value !== null && typeof value === "object" && !Array.isArray(value);
44
+ }
45
+
46
+ function isFiniteNumber(value) {
47
+ return typeof value === "number" && Number.isFinite(value);
48
+ }
49
+
50
+ const VALUE_OPTIONS = new Set([
51
+ "--project", "--engine", "--reading-file", "--script-file",
52
+ "--t", "--gain-db", "--id", "--speaker", "--profile",
53
+ ]);
54
+ const FLAG_OPTIONS = new Set(["--dry-run", "--yes", "--apply"]);
55
+
56
+ function parseArguments(argv) {
57
+ if (argv[0] !== "generate") {
58
+ throw new PublicError(`不明なサブコマンドです。\n${usage}`, 2);
59
+ }
60
+ const options = {
61
+ project: null,
62
+ engine: null,
63
+ readingFile: null,
64
+ scriptFile: null,
65
+ t: null,
66
+ gainDb: 0,
67
+ id: null,
68
+ speaker: "3",
69
+ profile: null,
70
+ dryRun: false,
71
+ yes: false,
72
+ apply: false,
73
+ };
74
+ for (let index = 1; index < argv.length; index += 1) {
75
+ const argument = argv[index];
76
+ if (VALUE_OPTIONS.has(argument)) {
77
+ const value = argv[index + 1];
78
+ if (value === undefined || FLAG_OPTIONS.has(value) || VALUE_OPTIONS.has(value)) {
79
+ throw new PublicError(`${argument} の値がありません`);
80
+ }
81
+ index += 1;
82
+ switch (argument) {
83
+ case "--project": options.project = value; break;
84
+ case "--engine": options.engine = value; break;
85
+ case "--reading-file": options.readingFile = value; break;
86
+ case "--script-file": options.scriptFile = value; break;
87
+ case "--t": options.t = Number(value); break;
88
+ case "--gain-db": options.gainDb = Number(value); break;
89
+ case "--id": options.id = value; break;
90
+ case "--speaker": options.speaker = value; break;
91
+ case "--profile": options.profile = value; break;
92
+ default: break;
93
+ }
94
+ } else if (argument === "--dry-run") {
95
+ options.dryRun = true;
96
+ } else if (argument === "--yes") {
97
+ options.yes = true;
98
+ } else if (argument === "--apply") {
99
+ options.apply = true;
100
+ } else {
101
+ throw new PublicError(`不明な引数です: ${argument}\n${usage}`, 2);
102
+ }
103
+ }
104
+
105
+ if (!options.project) throw new PublicError("--project が必要です");
106
+ if (options.engine !== "voicevox" && options.engine !== "fal-qwen3") {
107
+ throw new PublicError("--engine には voicevox または fal-qwen3 を指定してください");
108
+ }
109
+ if (!options.readingFile) throw new PublicError("--reading-file が必要です");
110
+ if (!isFiniteNumber(options.t) || options.t < 0) {
111
+ throw new PublicError("--t には 0 以上の有限数を指定してください");
112
+ }
113
+ if (!isFiniteNumber(options.gainDb) || options.gainDb < -60 || options.gainDb > 12) {
114
+ throw new PublicError("--gain-db は -60 から 12 の範囲の有限数である必要があります");
115
+ }
116
+ if (options.id !== null && !/^n-\d{4}$/.test(options.id)) {
117
+ throw new PublicError("--id は n- に続く 4 桁の数字である必要があります(例: n-0001)");
118
+ }
119
+ if (options.engine === "fal-qwen3" && !options.profile) {
120
+ throw new PublicError("--engine fal-qwen3 には --profile が必要です");
121
+ }
122
+
123
+ options.project = path.resolve(options.project);
124
+ return options;
125
+ }
126
+
127
+ function readTextFile(filePath, label) {
128
+ let resolved;
129
+ try {
130
+ resolved = path.resolve(filePath);
131
+ const text = fs.readFileSync(resolved, "utf8").trim();
132
+ if (!text) throw new PublicError(`${label} が空です: ${resolved}`);
133
+ return text;
134
+ } catch (error) {
135
+ if (error instanceof PublicError) throw error;
136
+ throw new PublicError(`${label} を読めません: ${resolved ?? filePath}`);
137
+ }
138
+ }
139
+
140
+ function computeNextId(projectDir) {
141
+ const editPath = path.join(projectDir, "edit.json");
142
+ let ids = [];
143
+ try {
144
+ const edit = JSON.parse(fs.readFileSync(editPath, "utf8"));
145
+ const narration = edit?.audio?.narration;
146
+ if (Array.isArray(narration)) {
147
+ ids = narration
148
+ .map((item) => item?.id)
149
+ .filter((id) => typeof id === "string" && /^n-\d{4}$/.test(id));
150
+ }
151
+ } catch {
152
+ // edit.json が無い、または narration 配列が無い場合は n-0001 から開始する。
153
+ }
154
+ const max = ids.reduce((accumulator, id) => Math.max(accumulator, Number(id.slice(2))), 0);
155
+ return `n-${String(max + 1).padStart(4, "0")}`;
156
+ }
157
+
158
+ function extensionFor(engine) {
159
+ return engine === "voicevox" ? "wav" : "mp3";
160
+ }
161
+
162
+ function relativeOutputPath(id, engine) {
163
+ return `out/narration/${id}.${extensionFor(engine)}`;
164
+ }
165
+
166
+ // --- credentials.env(fal-qwen3 用。skills/analyze-footage/bin/transcribe-cloud.mjs と同型) ---
167
+
168
+ function credentialsPath() {
169
+ return path.resolve(
170
+ process.env.AKARI_CREDENTIALS_FILE
171
+ ?? path.join(os.homedir(), ".config", "akari-video", "credentials.env"),
172
+ );
173
+ }
174
+
175
+ function readCredentials() {
176
+ let source;
177
+ try {
178
+ source = fs.readFileSync(credentialsPath(), "utf8");
179
+ } catch (error) {
180
+ if (error?.code === "ENOENT") return new Map();
181
+ throw new PublicError("credentials.env を読めません");
182
+ }
183
+ const values = new Map();
184
+ for (const originalLine of source.split(/\r?\n/)) {
185
+ const line = originalLine.trim();
186
+ if (!line || line.startsWith("#")) continue;
187
+ const separator = line.indexOf("=");
188
+ if (separator < 1) continue;
189
+ const name = line.slice(0, separator).trim();
190
+ if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(name)) continue;
191
+ let value = line.slice(separator + 1).trim();
192
+ if (
193
+ value.length >= 2
194
+ && ((value.startsWith('"') && value.endsWith('"'))
195
+ || (value.startsWith("'") && value.endsWith("'")))
196
+ ) {
197
+ value = value.slice(1, -1);
198
+ }
199
+ values.set(name, value);
200
+ }
201
+ return values;
202
+ }
203
+
204
+ function resolveFalKey() {
205
+ const secret = readCredentials().get("FAL_KEY");
206
+ if (!secret) {
207
+ throw new PublicError(
208
+ `FAL_KEY が未設定です。${credentialsPath()} に FAL_KEY=... を 1 行追加してください`
209
+ + "(取得先: https://fal.ai/dashboard/keys)。",
210
+ );
211
+ }
212
+ return secret;
213
+ }
214
+
215
+ function profileMetaPath(profileName) {
216
+ return path.join(os.homedir(), ".config", "akari-video", "voice-profiles", profileName, "meta.json");
217
+ }
218
+
219
+ function readProfileMeta(profileName) {
220
+ const metaPath = profileMetaPath(profileName);
221
+ let raw;
222
+ try {
223
+ raw = fs.readFileSync(metaPath, "utf8");
224
+ } catch {
225
+ throw new PublicError(`声プロファイルが見つかりません: ${metaPath}`);
226
+ }
227
+ let meta;
228
+ try {
229
+ meta = JSON.parse(raw);
230
+ } catch {
231
+ throw new PublicError(`声プロファイルの meta.json が不正な JSON です: ${metaPath}`);
232
+ }
233
+ if (typeof meta.embedding_source_url !== "string" || !meta.embedding_source_url) {
234
+ throw new PublicError(`声プロファイルの meta.json に embedding_source_url がありません: ${metaPath}`);
235
+ }
236
+ if (typeof meta.reference_text !== "string" || !meta.reference_text) {
237
+ throw new PublicError(`声プロファイルの meta.json に reference_text がありません: ${metaPath}`);
238
+ }
239
+ return meta;
240
+ }
241
+
242
+ function buildFalPayload(readingText, meta) {
243
+ return {
244
+ text: readingText,
245
+ language: "Japanese",
246
+ speaker_voice_embedding_file_url: meta.embedding_source_url,
247
+ reference_text: meta.reference_text,
248
+ max_new_tokens: 2048,
249
+ };
250
+ }
251
+
252
+ function estimateFalCostUsd(readingText) {
253
+ return Number(((readingText.length / 1000) * FAL_USD_PER_1000_CHARS).toFixed(6));
254
+ }
255
+
256
+ async function synthesizeFal(readingText, meta, falKey) {
257
+ const payload = buildFalPayload(readingText, meta);
258
+ let response;
259
+ try {
260
+ response = await fetch(FAL_TTS_URL, {
261
+ method: "POST",
262
+ headers: { Authorization: `Key ${falKey}`, "Content-Type": "application/json" },
263
+ body: JSON.stringify(payload),
264
+ });
265
+ } catch {
266
+ throw new PublicError("fal API へのネットワーク接続に失敗しました");
267
+ }
268
+ if (!response.ok) throw new PublicError(`fal API が HTTP ${response.status} を返しました`);
269
+ const result = await response.json();
270
+ const audioUrl = result?.audio?.url;
271
+ if (typeof audioUrl !== "string" || !audioUrl) {
272
+ throw new PublicError("fal API の応答に audio.url がありません");
273
+ }
274
+ const audioResponse = await fetch(audioUrl);
275
+ if (!audioResponse.ok) {
276
+ throw new PublicError(`生成音声の取得に失敗しました(HTTP ${audioResponse.status})`);
277
+ }
278
+ return Buffer.from(await audioResponse.arrayBuffer());
279
+ }
280
+
281
+ // --- VOICEVOX ローカルエンジン ---
282
+
283
+ /**
284
+ * VOICEVOX エンジン(vv-engine の `run` 実行ファイル)のパスを解決する。
285
+ * 優先順位: 環境変数 `VOICEVOX_RUN`(絶対パス直指定)→ platform 別既定インストール先。
286
+ * 純粋関数にして `platform` / `env` を注入でき、実プラットフォームに依存せずテストできる
287
+ * ようにする(darwin 既定パスは不変。win32 既定パスの根拠は report.md 参照)。
288
+ */
289
+ export function resolveVoicevoxRunPath(platform = process.platform, env = process.env) {
290
+ const override = env[VOICEVOX_RUN_ENV];
291
+ if (override) return override;
292
+
293
+ if (platform === "darwin") {
294
+ return "/Applications/VOICEVOX.app/Contents/Resources/vv-engine/run";
295
+ }
296
+ if (platform === "win32") {
297
+ // VOICEVOX 0.16+ の既定インストーラ配置先(root repo 未検証・GitHub issue で確認済み。
298
+ // 根拠: report.md 参照)。`%LOCALAPPDATA%` が無い実行環境向けに homedir から組み立てる
299
+ // fallback も用意する。
300
+ const localAppData = env.LOCALAPPDATA || path.join(os.homedir(), "AppData", "Local");
301
+ return path.join(localAppData, "Programs", "VOICEVOX", "vv-engine", "run.exe");
302
+ }
303
+ throw new PublicError(
304
+ `VOICEVOX の既定インストール先を ${platform} 向けに解決できません。` +
305
+ `環境変数 ${VOICEVOX_RUN_ENV} に run 実行ファイルの絶対パスを指定してください。`,
306
+ );
307
+ }
308
+
309
+ async function isVoicevoxUp() {
310
+ const controller = new AbortController();
311
+ const timeout = setTimeout(() => controller.abort(), 1_500);
312
+ try {
313
+ const response = await fetch(`${VOICEVOX_BASE_URL}/version`, { signal: controller.signal });
314
+ return response.ok;
315
+ } catch {
316
+ return false;
317
+ } finally {
318
+ clearTimeout(timeout);
319
+ }
320
+ }
321
+
322
+ async function ensureVoicevoxEngine() {
323
+ if (await isVoicevoxUp()) return { startedByUs: false, child: null };
324
+ const runPath = resolveVoicevoxRunPath();
325
+ if (!fs.existsSync(runPath)) {
326
+ throw new PublicError(`VOICEVOX エンジンが見つかりません: ${runPath}`);
327
+ }
328
+ const child = spawn(runPath, [], { stdio: "ignore" });
329
+ const deadline = Date.now() + VOICEVOX_STARTUP_TIMEOUT_MS;
330
+ while (Date.now() < deadline) {
331
+ if (await isVoicevoxUp()) return { startedByUs: true, child };
332
+ await sleep(1_000);
333
+ }
334
+ try {
335
+ child.kill("SIGTERM");
336
+ } catch {
337
+ // 起動確認前にプロセスが落ちている場合は無視する。
338
+ }
339
+ throw new PublicError(
340
+ `VOICEVOX エンジンの起動が ${VOICEVOX_STARTUP_TIMEOUT_MS / 1000} 秒でタイムアウトしました。`,
341
+ );
342
+ }
343
+
344
+ async function stopVoicevoxEngine(child) {
345
+ if (!child) return;
346
+ try {
347
+ child.kill("SIGTERM");
348
+ } catch {
349
+ // 既に終了している場合は無視する。
350
+ }
351
+ }
352
+
353
+ async function getVoicevoxVersion() {
354
+ const response = await fetch(`${VOICEVOX_BASE_URL}/version`);
355
+ if (!response.ok) throw new PublicError(`VOICEVOX /version が HTTP ${response.status} を返しました`);
356
+ return String(await response.json()).trim();
357
+ }
358
+
359
+ async function resolveVoicevoxSpeakerName(speakerId) {
360
+ const response = await fetch(`${VOICEVOX_BASE_URL}/speakers`);
361
+ if (!response.ok) throw new PublicError(`VOICEVOX /speakers が HTTP ${response.status} を返しました`);
362
+ const speakers = await response.json();
363
+ for (const speaker of Array.isArray(speakers) ? speakers : []) {
364
+ const styles = Array.isArray(speaker?.styles) ? speaker.styles : [];
365
+ if (styles.some((style) => style.id === speakerId)) return String(speaker.name);
366
+ }
367
+ return "unknown";
368
+ }
369
+
370
+ async function synthesizeVoicevox(readingText, speakerId) {
371
+ const queryUrl = `${VOICEVOX_BASE_URL}/audio_query?speaker=${speakerId}&text=${encodeURIComponent(readingText)}`;
372
+ const queryResponse = await fetch(queryUrl, { method: "POST" });
373
+ if (!queryResponse.ok) {
374
+ throw new PublicError(`VOICEVOX /audio_query が HTTP ${queryResponse.status} を返しました`);
375
+ }
376
+ const query = await queryResponse.json();
377
+
378
+ const synthesisUrl = `${VOICEVOX_BASE_URL}/synthesis?speaker=${speakerId}`;
379
+ const synthesisResponse = await fetch(synthesisUrl, {
380
+ method: "POST",
381
+ headers: { "Content-Type": "application/json" },
382
+ body: JSON.stringify(query),
383
+ });
384
+ if (!synthesisResponse.ok) {
385
+ throw new PublicError(`VOICEVOX /synthesis が HTTP ${synthesisResponse.status} を返しました`);
386
+ }
387
+ return Buffer.from(await synthesisResponse.arrayBuffer());
388
+ }
389
+
390
+ // --- edit.json への --apply ---
391
+
392
+ function validateEditScriptPath() {
393
+ return fileURLToPath(new URL("../../../packages/schemas/bin/validate-edit.mjs", import.meta.url));
394
+ }
395
+
396
+ function applyToEditJson(projectDir, entry) {
397
+ const editPath = path.join(projectDir, "edit.json");
398
+ let originalText;
399
+ try {
400
+ originalText = fs.readFileSync(editPath, "utf8");
401
+ } catch {
402
+ throw new PublicError(`--apply には既存の edit.json が必要です: ${editPath}`);
403
+ }
404
+ let edit;
405
+ try {
406
+ edit = JSON.parse(originalText);
407
+ } catch {
408
+ throw new PublicError(`edit.json を JSON として読めません: ${editPath}`);
409
+ }
410
+
411
+ if (!isPlainObject(edit.audio)) edit.audio = {};
412
+ if (!Array.isArray(edit.audio.narration)) edit.audio.narration = [];
413
+ edit.audio.narration.push(entry);
414
+
415
+ fs.writeFileSync(editPath, `${JSON.stringify(edit, null, 2)}\n`, "utf8");
416
+
417
+ const validateResult = spawnSync("node", [validateEditScriptPath(), editPath], { encoding: "utf8" });
418
+ if (validateResult.status !== 0) {
419
+ fs.writeFileSync(editPath, originalText, "utf8");
420
+ const detail = `${validateResult.stdout ?? ""}${validateResult.stderr ?? ""}`.trim();
421
+ throw new PublicError(
422
+ `validate-edit が NG のため edit.json への書き込みをロールバックしました。\n${detail}`,
423
+ );
424
+ }
425
+ process.stderr.write(`edit.json に ${entry.id} を追加しました(validate-edit: PASS)。\n`);
426
+ }
427
+
428
+ // --- dry-run ---
429
+
430
+ function maskKey(secret) {
431
+ // 実際のキー文字は 1 文字も出力しない(manage-connections ハードルール「表示は常にマスク」)。
432
+ return secret ? "***configured***" : "***unconfigured***";
433
+ }
434
+
435
+ async function runDryRun(options, readingText) {
436
+ const outputPath = relativeOutputPath(options.id ?? computeNextId(options.project), options.engine);
437
+ if (options.engine === "voicevox") {
438
+ printJson({
439
+ dry_run: true,
440
+ engine: "voicevox",
441
+ output_path: outputPath,
442
+ estimated_cost_usd: 0,
443
+ request: {
444
+ base_url: VOICEVOX_BASE_URL,
445
+ steps: [
446
+ `POST /audio_query?speaker=${options.speaker}&text=<読み原稿>`,
447
+ `POST /synthesis?speaker=${options.speaker}`,
448
+ ],
449
+ speaker: Number(options.speaker),
450
+ text: readingText,
451
+ },
452
+ });
453
+ return;
454
+ }
455
+
456
+ const falKey = resolveFalKey();
457
+ const meta = readProfileMeta(options.profile);
458
+ const payload = buildFalPayload(readingText, meta);
459
+ const estimatedCostUsd = estimateFalCostUsd(readingText);
460
+ printJson({
461
+ dry_run: true,
462
+ engine: "fal-qwen3",
463
+ output_path: outputPath,
464
+ estimated_cost_usd: estimatedCostUsd,
465
+ request: {
466
+ endpoint: FAL_TTS_URL,
467
+ headers: { Authorization: `Key ${maskKey(falKey)}` },
468
+ body: payload,
469
+ },
470
+ });
471
+ }
472
+
473
+ // --- generate 本体 ---
474
+
475
+ async function runGenerate(options) {
476
+ const readingText = readTextFile(options.readingFile, "読み原稿");
477
+ const scriptText = options.scriptFile ? readTextFile(options.scriptFile, "表示原稿") : null;
478
+
479
+ if (options.dryRun) {
480
+ await runDryRun(options, readingText);
481
+ return;
482
+ }
483
+
484
+ const id = options.id ?? computeNextId(options.project);
485
+ const relativePath = relativeOutputPath(id, options.engine);
486
+ const outputPath = path.join(options.project, relativePath);
487
+
488
+ let audioBuffer;
489
+ let provenance;
490
+
491
+ if (options.engine === "voicevox") {
492
+ const speakerId = Number(options.speaker);
493
+ if (!Number.isInteger(speakerId) || speakerId < 0) {
494
+ throw new PublicError("--speaker には 0 以上の整数を指定してください");
495
+ }
496
+ const engineHandle = await ensureVoicevoxEngine();
497
+ try {
498
+ audioBuffer = await synthesizeVoicevox(readingText, speakerId);
499
+ const [version, speakerName] = await Promise.all([
500
+ getVoicevoxVersion(),
501
+ resolveVoicevoxSpeakerName(speakerId),
502
+ ]);
503
+ provenance = {
504
+ provider: "voicevox",
505
+ engine: `voicevox-${version}`,
506
+ voice: `speaker:${speakerId}(${speakerName})`,
507
+ credit: `VOICEVOX:${speakerName}`,
508
+ generated_at: new Date().toISOString(),
509
+ };
510
+ } finally {
511
+ if (engineHandle.startedByUs) await stopVoicevoxEngine(engineHandle.child);
512
+ }
513
+ } else {
514
+ const falKey = resolveFalKey();
515
+ const meta = readProfileMeta(options.profile);
516
+ const estimatedCostUsd = estimateFalCostUsd(readingText);
517
+ process.stderr.write(
518
+ `fal-qwen3 推定費用: 約 $${estimatedCostUsd}(${readingText.length} 文字 × $${FAL_USD_PER_1000_CHARS}/1000字)\n`,
519
+ );
520
+ if (!options.yes) {
521
+ printJson({
522
+ sent: false,
523
+ engine: "fal-qwen3",
524
+ estimated_cost_usd: estimatedCostUsd,
525
+ reason: "費用承認(--yes)がありません。実リクエストは送信していません。",
526
+ });
527
+ process.exitCode = 2;
528
+ return;
529
+ }
530
+ // --yes が明示された場合のみ、ここで初めて課金の発生する fal API を呼び出す。
531
+ audioBuffer = await synthesizeFal(readingText, meta, falKey);
532
+ provenance = {
533
+ provider: "fal",
534
+ engine: "qwen-3-tts-1.7b",
535
+ voice: `profile:${options.profile}`,
536
+ generated_at: new Date().toISOString(),
537
+ };
538
+ }
539
+
540
+ fs.mkdirSync(path.dirname(outputPath), { recursive: true });
541
+ fs.writeFileSync(outputPath, audioBuffer);
542
+
543
+ const entry = {
544
+ id,
545
+ path: relativePath,
546
+ t: options.t,
547
+ gain_db: options.gainDb,
548
+ ...(scriptText ? { script: scriptText } : {}),
549
+ reading: readingText,
550
+ provenance,
551
+ };
552
+
553
+ if (options.apply) applyToEditJson(options.project, entry);
554
+
555
+ printJson(entry);
556
+ }
557
+
558
+ async function main() {
559
+ let options;
560
+ try {
561
+ options = parseArguments(process.argv.slice(2));
562
+ await runGenerate(options);
563
+ } catch (error) {
564
+ const exitCode = error instanceof PublicError ? error.exitCode : 1;
565
+ const message = error instanceof PublicError ? error.message : `内部処理に失敗しました: ${error?.message ?? error}`;
566
+ process.stderr.write(`${message}\n`);
567
+ printJson({ error: message });
568
+ process.exitCode = exitCode;
569
+ }
570
+ }
571
+
572
+ await main();
@@ -0,0 +1,78 @@
1
+ # エンジンアダプタ
2
+
3
+ `bin/generate-narration.mjs` の `generate` サブコマンドで実際にナレーション音声を作る。
4
+
5
+ ```
6
+ node skills/generate-narration/bin/generate-narration.mjs generate \
7
+ --project <projectDir> --engine <voicevox|fal-qwen3> \
8
+ --reading-file <読み原稿.txt> [--script-file <表示原稿.txt>] \
9
+ --t <タイムライン秒> [--gain-db 0] [--id n-0001] \
10
+ [--speaker 3] # voicevox 用(既定 3 = ずんだもん/ノーマル)
11
+ [--profile owner-ja] # fal-qwen3 用
12
+ [--dry-run] [--yes] [--apply]
13
+ ```
14
+
15
+ - `--reading-file` は必須。原稿は [reading-text.md](reading-text.md) の規約でかな化した**読み原稿**を渡す
16
+ - `--script-file` は任意。渡した場合、表示原稿として `script` に記録される
17
+ - `--id` を省略すると、`<projectDir>/edit.json` の `audio.narration[]` にある既存 id の最大値 + 1
18
+ (無ければ `n-0001`)を自動採番する
19
+ - 出力音声は `<projectDir>/out/narration/<id>.<wav|mp3>` に保存される(voicevox は wav、fal-qwen3 は mp3)
20
+ - `--apply` を付けると `edit.json` の `audio.narration[]` にエントリを追加し(`audio` / `narration` が
21
+ 無ければ作る)、直後に `packages/schemas/bin/validate-edit.mjs` を実行する。NG なら書き込みを
22
+ ロールバックする
23
+ - `--apply` を付けない場合、音声ファイルの生成とエントリ JSON の標準出力のみ行い、`edit.json` は
24
+ 変更しない(手動で確認してから追記したい場合に使う)
25
+
26
+ ## voicevox アダプタ
27
+
28
+ - 完全ローカル・無償・API キー不要。既にエンジンが `http://127.0.0.1:50021` で起動していればそれを使い、
29
+ 未起動なら vv-engine の `run` をヘッドレスで自動起動する
30
+ (`/version` 応答まで最大 60 秒待機。自分が起動した場合のみ生成後に終了させる)
31
+ - run 実行ファイルの解決順: 環境変数 `VOICEVOX_RUN`(絶対パス直指定)→ platform 別既定インストール先
32
+ — darwin: `/Applications/VOICEVOX.app/Contents/Resources/vv-engine/run`、
33
+ win32: `%LOCALAPPDATA%\Programs\VOICEVOX\vv-engine\run.exe`(VOICEVOX 0.16+ の既定インストーラ配置先)。
34
+ それ以外の platform では `VOICEVOX_RUN` 指定が必須(既定パスなし)
35
+ - `/audio_query` → `/synthesis`(speaker id 指定)の順で呼び、wav を得る
36
+ - `--speaker` は VOICEVOX の style id(既定 3 = ずんだもん・ノーマル)。話者名は `/speakers` から解決し、
37
+ provenance に `voice: speaker:<id>(<話者名>)` / `credit: VOICEVOX:<話者名>` として記録する
38
+ (キャラクターごとのクレジット表記義務。ハードルール 6)
39
+ - 費用はゼロ。承認ゲートは不要(`--dry-run` 以外はそのまま実行される)
40
+
41
+ ## fal-qwen3 アダプタ(自声クローン)
42
+
43
+ - `~/.config/akari-video/voice-profiles/<profile>/meta.json` の `embedding_source_url` /
44
+ `reference_text` を使い、`https://fal.run/fal-ai/qwen-3-tts/text-to-speech/1.7b` へ
45
+ `text` / `language:"Japanese"` / `speaker_voice_embedding_file_url` / `reference_text` /
46
+ `max_new_tokens:2048` を POST する
47
+ - 声プロファイルが無ければ先に [voice-profile-setup.md](voice-profile-setup.md) を行う
48
+ - `FAL_KEY` は `~/.config/akari-video/credentials.env` から読む。無ければ KEY 名と置き場を案内して
49
+ exit 1(API キー直叩き禁止・manage-connections 経由のみ。ハードルール 5)
50
+ - 実行前に見積り(文字数 × $0.09 / 1000 字)を stderr に表示する。**`--yes` を明示しない限り送信せず
51
+ exit 2**(費用宣言 → 明示承認、ハードルール 4)
52
+ - provenance は `provider: fal` / `engine: qwen-3-tts-1.7b` / `voice: profile:<name>` を記録する
53
+
54
+ ## ElevenLabs(凍結中)
55
+
56
+ ElevenLabs は今回のスキルではアダプタを実装しない。凍結中のため、実行時にも選択肢として提示しない
57
+ (ハードルール 4)。`.akari/connections.json` の `elevenlabs` エントリ自体は既存のまま変更しない。
58
+
59
+ ## `--dry-run`
60
+
61
+ どちらのエンジンでも実リクエストを送らない。送るはずのペイロード JSON(fal の API キーはマスク表示)と、
62
+ 出力予定パス・見積り費用(voicevox は 0、fal-qwen3 は概算 USD)を標準出力に JSON で出して exit 0 で終わる。
63
+ 本番実行前の確認や、有償レーンの費用感を人間に見せる用途に使う。
64
+
65
+ ## エンジン選択基準・二段運用
66
+
67
+ | 状況 | 選ぶエンジン |
68
+ |---|---|
69
+ | 尺やテンポを素早く確定したい(仮ナレ・アニマティクス) | voicevox(無償・数秒・承認ゲート不要) |
70
+ | ずんだもん文化圏コンテンツ・キャラ解説・下書き試聴 | voicevox |
71
+ | 本人ナレーションの本番(CM・ブランドコンテンツ) | fal-qwen3(`--profile owner-ja` 等) |
72
+ | 多言語展開(自分の声のまま他言語) | fal-qwen3(クロスリンガルクローン) |
73
+
74
+ **二段運用(推奨フロー)**: まず `--engine voicevox` で仮ナレを生成し `--apply` して尺とテンポを
75
+ 確定する。方針が固まったら、同じ `--reading-file`(必要なら微調整)・同じ `--t` で
76
+ `--engine fal-qwen3 --profile <name> --yes --apply` を実行し、同じ `id` は使わずに新しい narration
77
+ エントリとして本番音声へ差し替える(古い仮ナレのエントリは編集者が削除する)。仮ナレの段階では
78
+ 費用が発生しないため、テンポ調整の反復を何度でも無償で行える。
@@ -0,0 +1,36 @@
1
+ # 読み前処理規約(表示原稿 → 読み原稿)
2
+
3
+ TTS(voicevox / fal-qwen3 いずれも)に渡すのは表示原稿そのものではなく、読み上げ用に前処理した
4
+ **読み原稿**である。表示原稿と読み原稿は非可逆な変換関係にあるため、両方を独立フィールドとして
5
+ `edit.json` に保存する(ハードルール 3、契約
6
+ [docs/contract-2026-07-20-edit-json-v1-narration.md](../../docs/contract-2026-07-20-edit-json-v1-narration.md) §5)。
7
+
8
+ - `script`: 人間が読む正本。字幕連携などの元テキストとしてもそのまま使える表示原稿
9
+ - `reading`: 前処理後、実際に TTS へ渡した文字列
10
+
11
+ ## 変換対象
12
+
13
+ - **英字固有名詞・略語**: カタカナへ変換する。例: 「AKARI Video」→「アカリビデオ」
14
+ (英語読みのまま TTS に渡すと発音が崩れる。実測: エンジンが「AKARI Video」を英語風に読み、
15
+ 聞き取りづらい結果になった)
16
+ - **難読語・専門用語**: 意図した読みにならない漢字・略号は平仮名または想定する読みのカタカナへ
17
+ 開く
18
+ - **数字・日付・単位**: TTS エンジン側の数字読み上げが期待どおりでない場合は、読み下した文字列
19
+ (例: 「2026年7月20日」→「にせんにじゅうろくねんしちがつはつか」)に置き換える。ただし
20
+ 多くのエンジンは算用数字のままでも正しく読めるため、**実際に生成して耳で確認してから**
21
+ 変換の要否を判断する(先回りして全数字を機械的に開かない)
22
+
23
+ ## 手順
24
+
25
+ 1. 表示原稿(`script`)を用意する(人間が書いた原稿、または analyze-footage の captions 由来など)
26
+ 2. 上記の変換対象に該当する箇所だけをかな化・カタカナ化し、読み原稿(`reading`)を作る
27
+ 3. `reading` を `--reading-file` に、`script` を `--script-file` に渡して生成する
28
+ 4. 生成音声を耳で確認する。発音が崩れている固有名詞があれば、その語だけをさらにかな化して
29
+ 再生成する(原稿全体を作り直さない)
30
+
31
+ ## 両方を保存する理由
32
+
33
+ かな化は多くの場合、人手または非決定的なルールベース処理を経ており、`reading` から `script` を
34
+ 機械的に逆算できない。再生成(同じ音声を別エンジンで作り直す等)や人間レビュー(`script` は
35
+ 読みやすい正本として、`reading` は生成の実態を追跡する記録として)の両方に必要なため、
36
+ どちらか一方だけを保存して済ませない。