akari-video 1.5.1 → 1.5.2-beta.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 (316) hide show
  1. package/README.md +8 -3
  2. package/bin/akari.mjs +6 -0
  3. package/package.json +1 -1
  4. package/src/cli.mjs +4 -0
  5. package/src/geo-command.mjs +18 -0
  6. package/src/lint-command.mjs +85 -0
  7. package/src/messages.mjs +1 -1
  8. package/src/narration-command.mjs +11 -7
  9. package/src/preview-command.mjs +281 -0
  10. package/src/project-state.mjs +1 -1
  11. package/src/repo-assets.mjs +26 -7
  12. package/src/status-core/status.mjs +5 -5
  13. package/src/status-core/workspace.mjs +1 -1
  14. package/src/store-command.mjs +1 -1
  15. package/src/tts-engines.mjs +39 -18
  16. package/src/vendor-sources.mjs +4 -0
  17. package/vendor/.akari-capability-sources.json +77 -75
  18. package/vendor/catalog/audio/candidates-legacy.json +4 -4
  19. package/vendor/catalog/audio/candidates.html +1 -1
  20. package/vendor/catalog/audio/candidates.json +2 -2
  21. package/vendor/packages/akari-launcher/README.md +8 -3
  22. package/vendor/packages/akari-launcher/package.json +1 -1
  23. package/vendor/packages/akari-tools/README.md +1 -0
  24. package/vendor/packages/akari-tools/bin/geo.mjs +176 -0
  25. package/vendor/packages/akari-tools/bin/speakers.mjs +0 -0
  26. package/vendor/packages/akari-tools/package.json +1 -0
  27. package/vendor/packages/akari-tools/src/geo/png.mjs +164 -0
  28. package/vendor/packages/akari-tools/src/geo/point.mjs +202 -0
  29. package/vendor/packages/akari-tools/src/geo/raster.mjs +177 -0
  30. package/vendor/packages/akari-tools/src/geo/terrain.mjs +243 -0
  31. package/vendor/packages/akari-tools/src/geo/tiles.mjs +114 -0
  32. package/vendor/packages/audio-library-setup/README.md +1 -1
  33. package/vendor/packages/audio-library-setup/bin/beat-grid.mjs +3 -3
  34. package/vendor/packages/audio-library-setup/bin/fetch-akari-sounds.mjs +1 -1
  35. package/vendor/packages/audio-library-setup/bin/generate-candidates-html.mjs +1 -1
  36. package/vendor/packages/audio-library-setup/bin/suggest-bgm.mjs +2 -2
  37. package/vendor/packages/audio-library-setup/shared/akari-sounds.mjs +1 -1
  38. package/vendor/packages/audio-library-setup/shared/candidates.mjs +4 -4
  39. package/vendor/packages/creator-root/src/index.mjs +1 -1
  40. package/vendor/packages/creator-root/test/direct-tts-providers.test.mjs +3 -0
  41. package/vendor/packages/edit-lint/README.md +19 -1
  42. package/vendor/packages/edit-lint/src/edit-lint.mjs +143 -20
  43. package/vendor/packages/edit-lint/src/fix.mjs +252 -0
  44. package/vendor/packages/edit-lint/src/i18n.mjs +4 -0
  45. package/vendor/packages/edit-lint/src/lint/box-sizing-messages.json +4 -0
  46. package/vendor/packages/edit-lint/src/lint/caption-fonts.mjs +139 -0
  47. package/vendor/packages/edit-lint/src/lint/captions.mjs +5 -3
  48. package/vendor/packages/edit-lint/src/lint/cuts-tracks.mjs +76 -1
  49. package/vendor/packages/edit-lint/src/lint/fragment-box-sizing.mjs +385 -0
  50. package/vendor/packages/edit-lint/src/lint/fragment-css-collision.mjs +73 -0
  51. package/vendor/packages/edit-lint/src/lint/fragment-css.mjs +74 -0
  52. package/vendor/packages/edit-lint/src/lint/overlays.mjs +543 -12
  53. package/vendor/packages/edit-lint/src/lint/review.mjs +1 -1
  54. package/vendor/packages/edit-store/lib/internal-model.d.ts +15 -8
  55. package/vendor/packages/edit-store/lib/internal-model.js +94 -28
  56. package/vendor/packages/edit-store/lib/webview-kernel.js +24 -7
  57. package/vendor/packages/i18n/locales/en/cli.json +32 -3
  58. package/vendor/packages/i18n/locales/en/lint-messages.json +15 -1
  59. package/vendor/packages/i18n/locales/en/project.json +1 -0
  60. package/vendor/packages/i18n/locales/en/skills.json +35 -37
  61. package/vendor/packages/i18n/locales/en/tools.json +16 -2
  62. package/vendor/packages/i18n/locales/ja/cli.json +32 -3
  63. package/vendor/packages/i18n/locales/ja/lint-messages.json +15 -1
  64. package/vendor/packages/i18n/locales/ja/project.json +1 -0
  65. package/vendor/packages/i18n/locales/ja/skills.json +35 -37
  66. package/vendor/packages/i18n/locales/ja/tools.json +16 -2
  67. package/vendor/packages/overlay-runtime/README.md +44 -15
  68. package/vendor/packages/overlay-runtime/runtimes.mjs +67 -2
  69. package/vendor/packages/overlay-runtime/src/fragment-css-scope.mjs +660 -0
  70. package/vendor/packages/overlay-runtime/src/interaction.js +2 -2
  71. package/vendor/packages/overlay-runtime/src/motion-vocab.css +1 -1
  72. package/vendor/packages/overlay-runtime/src/overlay-runtime.js +21 -2
  73. package/vendor/packages/overlay-runtime/src/three-runtime.js +1812 -44
  74. package/vendor/packages/overlay-runtime/src/vendor/three-bundle.js +978 -289
  75. package/vendor/packages/overlay-runtime/src/viewport-units.js +1 -1
  76. package/vendor/packages/project-scaffold/src/index.mjs +35 -9
  77. package/vendor/packages/schemas/ai-models.json +19 -0
  78. package/vendor/packages/schemas/ai-models.schema.json +1 -0
  79. package/vendor/packages/schemas/examples/kit-manifest-v1-name-collision/manifest.json +1 -1
  80. package/vendor/packages/schemas/examples/kit-manifest-v1-name-collision/skills/{edit-lint → verify-edit}/SKILL.md +1 -1
  81. package/vendor/packages/schemas/review.schema.json +2 -2
  82. package/vendor/packages/schemas/skill-renames.mjs +436 -0
  83. package/vendor/packages/schemas/skill-renames.schema.json +43 -0
  84. package/vendor/packages/schemas/test/ai-models.test.mjs +20 -2
  85. package/vendor/packages/schemas/test/kit-manifest.test.mjs +1 -1
  86. package/vendor/packages/schemas/test/skill-renames.test.mjs +117 -0
  87. package/vendor/packages/schemas/test/validate-captions.test.mjs +1 -1
  88. package/vendor/packages/schemas/test/validate-cut-candidates.test.mjs +2 -2
  89. package/vendor/packages/schemas/test/validate-review.test.mjs +2 -2
  90. package/vendor/packages/schemas/test/validate-semantic-keep-plan.test.mjs +2 -2
  91. package/vendor/skills/akari/SKILL.md +3 -3
  92. package/vendor/skills/analyze-footage/SKILL.md +1 -1
  93. package/vendor/skills/analyze-footage/bin/person-matte/resolve-packages.mjs +1 -1
  94. package/vendor/skills/analyze-footage/events-and-hooks.md +1 -1
  95. package/vendor/skills/{declare-audio → analyze-music}/SKILL.md +5 -5
  96. package/vendor/skills/{declare-audio → analyze-music}/after-save.md +2 -2
  97. package/vendor/skills/analyze-project/SKILL.md +3 -3
  98. package/vendor/skills/analyze-project/collect.md +1 -1
  99. package/vendor/skills/analyze-project/decision-record.md +8 -8
  100. package/vendor/skills/analyze-project/interpretation.md +3 -3
  101. package/vendor/skills/analyze-project/interview.md +1 -1
  102. package/vendor/skills/analyze-project/references/open-questions-examples.md +4 -4
  103. package/vendor/skills/author-overlay/3d.md +5 -0
  104. package/vendor/skills/{overlay-authoring → author-overlay}/SKILL.md +4 -4
  105. package/vendor/skills/{overlay-authoring → author-overlay}/dev-fixtures/test_device_materials.py +1 -1
  106. package/vendor/skills/{overlay-authoring → author-overlay}/telop.md +1 -1
  107. package/vendor/skills/{overlay-authoring → author-overlay}/thumbnail.md +1 -1
  108. package/vendor/skills/author-scene3d/SKILL.md +45 -0
  109. package/vendor/skills/{bake-3d/SKILL.md → author-scene3d/bake.md} +11 -25
  110. package/vendor/skills/{overlay-authoring → author-scene3d}/device-materials.md +3 -3
  111. package/vendor/skills/{overlay-authoring/3d.md → author-scene3d/live.md} +126 -24
  112. package/vendor/skills/{design-world → author-world}/SKILL.md +2 -2
  113. package/vendor/skills/{address-review → edit-from-review}/SKILL.md +6 -6
  114. package/vendor/skills/{address-review → edit-from-review}/bin/list.mjs +2 -2
  115. package/vendor/skills/{address-review → edit-from-review}/bin/respond.mjs +1 -1
  116. package/vendor/skills/{beat-sync-edit → edit-to-beat}/SKILL.md +6 -6
  117. package/vendor/skills/{beat-sync-edit → edit-to-beat}/generator.md +1 -1
  118. package/vendor/skills/{beat-sync-edit → edit-to-beat}/pitfalls.md +1 -1
  119. package/vendor/skills/generate-image/SKILL.md +42 -0
  120. package/vendor/skills/generate-image/image.md +38 -0
  121. package/vendor/skills/generate-narration/SKILL.md +4 -4
  122. package/vendor/skills/generate-narration/avatar-voice.md +2 -2
  123. package/vendor/skills/generate-narration/engines.md +79 -63
  124. package/vendor/skills/generate-narration/lang/en.md +8 -6
  125. package/vendor/skills/generate-narration/lang/ja.md +17 -11
  126. package/vendor/skills/generate-narration/voice-profile-setup.md +3 -3
  127. package/vendor/skills/{generate-media → generate-video}/SKILL.md +9 -7
  128. package/vendor/skills/{generate-media → generate-video}/chain.md +1 -1
  129. package/vendor/skills/generate-video/engines.md +23 -0
  130. package/vendor/skills/generate-video/still.md +65 -0
  131. package/vendor/skills/{generate-media → generate-video}/video.md +1 -1
  132. package/vendor/skills/harvest-asset/SKILL.md +1 -1
  133. package/vendor/skills/{record-playbook → harvest-playbook}/SKILL.md +4 -4
  134. package/vendor/skills/{record-playbook → harvest-playbook}/bin/record-playbook.mjs +2 -2
  135. package/vendor/skills/{record-playbook → harvest-playbook}/test/record-beats.test.mjs +2 -2
  136. package/vendor/skills/{edit-plan → plan-edit}/SKILL.md +5 -5
  137. package/vendor/skills/{edit-plan → plan-edit}/approvals-and-generation.md +2 -2
  138. package/vendor/skills/{edit-plan → plan-edit}/autonomy.md +2 -2
  139. package/vendor/skills/{edit-plan → plan-edit}/avatar-resolution.md +2 -2
  140. package/vendor/skills/{edit-plan → plan-edit}/beat-sync.md +6 -6
  141. package/vendor/skills/{edit-plan → plan-edit}/execution.md +3 -3
  142. package/vendor/skills/{edit-plan → plan-edit}/expression-selection.md +4 -4
  143. package/vendor/skills/{edit-plan → plan-edit}/plan-json.md +1 -1
  144. package/vendor/skills/{edit-plan → plan-edit}/recipe.md +1 -1
  145. package/vendor/skills/{edit-plan → plan-edit}/report-guide.md +9 -9
  146. package/vendor/skills/{edit-plan → plan-edit}/workflow.md +4 -4
  147. package/vendor/skills/{research-plan → plan-video}/SKILL.md +5 -5
  148. package/vendor/skills/{research-plan → plan-video}/competitor.md +2 -2
  149. package/vendor/skills/{research-plan → plan-video}/ideate.md +1 -1
  150. package/vendor/skills/{research-plan → plan-video}/lang/ja.md +1 -1
  151. package/vendor/skills/{research-plan → plan-video}/storyboard.md +1 -1
  152. package/vendor/skills/{research-plan → plan-video}/trends.md +1 -1
  153. package/vendor/skills/renames.json +23 -0
  154. package/vendor/skills/render-cut/SKILL.md +3 -3
  155. package/vendor/skills/{critique-cut → review-cut}/SKILL.md +7 -7
  156. package/vendor/skills/{critique-cut → review-cut}/bin/index.js +1 -1
  157. package/vendor/skills/{critique-cut → review-cut}/workflow.md +3 -3
  158. package/vendor/skills/{compile-review-session → review-from-recording}/SKILL.md +5 -5
  159. package/vendor/skills/{compile-review-session → review-from-recording}/bin/compile-review-session.mjs +1 -1
  160. package/vendor/skills/{compile-review-session → review-from-recording}/bin/core/install-root.mjs +2 -2
  161. package/vendor/skills/{compile-review-session → review-from-recording}/dev-fixtures/README.md +4 -4
  162. package/vendor/skills/{compile-review-session → review-from-recording}/dev-fixtures/issue-69-review-json/README.md +6 -6
  163. package/vendor/skills/{compile-review-session → review-from-recording}/dev-fixtures/issue-69-review-json/reproduce.mjs +1 -1
  164. package/vendor/skills/review-from-recording/dev-fixtures/issue-79/README.md +3 -0
  165. package/vendor/skills/{compile-review-session → review-from-recording}/test/helpers/issue-79-fixture.mjs +1 -1
  166. package/vendor/skills/{compile-review-session → review-from-recording}/test/issue-79-snapshot.test.mjs +1 -1
  167. package/vendor/skills/setup-chat-approval/SKILL.md +2 -2
  168. package/vendor/skills/setup-chat-approval/bin/resolve-packages.mjs +1 -1
  169. package/vendor/skills/setup-chat-approval/setup-token.md +1 -1
  170. package/vendor/skills/{manage-connections → setup-connections}/SKILL.md +57 -11
  171. package/vendor/skills/{manage-connections → setup-connections}/bin/doctor.mjs +1 -1
  172. package/vendor/skills/{manage-connections → setup-connections}/bin/resolve-packages.mjs +1 -1
  173. package/vendor/skills/setup-connections/dev-fixtures/resolve-packages-newest/README.md +17 -0
  174. package/vendor/skills/{manage-connections → setup-connections}/dev-fixtures/resolve-packages-newest/reproduce.mjs +2 -2
  175. package/vendor/skills/{manage-connections → setup-connections}/test/resolve-packages-newest.test.mjs +1 -1
  176. package/vendor/skills/setup-library/SKILL.md +83 -2
  177. package/vendor/skills/{setup-audio-library/assisted-fetch.md → setup-library/audio-assisted-fetch.md} +2 -2
  178. package/vendor/skills/{setup-audio-library/candidate-list.md → setup-library/audio-candidate-list.md} +1 -1
  179. package/vendor/skills/{setup-audio-library/drop-folder.md → setup-library/audio-drop-folder.md} +3 -3
  180. package/vendor/skills/{setup-audio-library/gallery.md → setup-library/audio-gallery.md} +2 -2
  181. package/vendor/skills/setup-library/fetch-and-validate.md +1 -1
  182. package/vendor/skills/setup-library/tools-check.md +1 -1
  183. package/vendor/skills/{create-project → setup-project}/SKILL.md +2 -2
  184. package/vendor/skills/{edit-lint → verify-edit}/SKILL.md +2 -2
  185. package/vendor/skills/{verify → verify-project}/SKILL.md +2 -2
  186. package/vendor/templates/project-default/.claude/skills/README.md +5 -4
  187. package/vendor/templates/project-default/.opencode/hooks/session-start.mjs +2 -2
  188. package/vendor/templates/project-default/.opencode/skills/analyze-footage.yml +1 -1
  189. package/vendor/templates/project-default/.opencode/skills/{edit-plan.yml → plan-edit.yml} +2 -2
  190. package/vendor/templates/project-default/.opencode/skills/{create-project.yml → setup-project.yml} +2 -2
  191. package/vendor/templates/project-default/AGENTS.md +6 -5
  192. package/vendor/templates/project-default/CLAUDE.md +6 -5
  193. package/vendor/skills/compile-review-session/dev-fixtures/issue-79/README.md +0 -3
  194. package/vendor/skills/connect/SKILL.md +0 -24
  195. package/vendor/skills/generate-media/engines.md +0 -25
  196. package/vendor/skills/generate-media/still.md +0 -75
  197. package/vendor/skills/manage-connections/dev-fixtures/resolve-packages-newest/README.md +0 -17
  198. package/vendor/skills/setup-audio-library/SKILL.md +0 -96
  199. /package/vendor/skills/{declare-audio → analyze-music}/launch.md +0 -0
  200. /package/vendor/skills/{declare-audio → analyze-music}/what-to-declare.md +0 -0
  201. /package/vendor/skills/{overlay-authoring → author-overlay}/glass.md +0 -0
  202. /package/vendor/skills/{overlay-authoring → author-overlay}/lang/en.md +0 -0
  203. /package/vendor/skills/{overlay-authoring → author-overlay}/lang/ja.md +0 -0
  204. /package/vendor/skills/{overlay-authoring → author-overlay}/motion.md +0 -0
  205. /package/vendor/skills/{overlay-authoring → author-overlay}/table.md +0 -0
  206. /package/vendor/skills/{overlay-authoring → author-overlay}/text-behind-person.md +0 -0
  207. /package/vendor/skills/{overlay-authoring → author-overlay}/world.md +0 -0
  208. /package/vendor/skills/{overlay-authoring → author-scene3d}/scripts/device_materials.py +0 -0
  209. /package/vendor/skills/{design-world → author-world}/bin/expand-template.mjs +0 -0
  210. /package/vendor/skills/{design-world → author-world}/bin/test/expand-template.test.mjs +0 -0
  211. /package/vendor/skills/{design-world → author-world}/bin/test/package.json +0 -0
  212. /package/vendor/skills/{design-world → author-world}/guide.md +0 -0
  213. /package/vendor/skills/{design-world → author-world}/templates/browser-to-chat.json +0 -0
  214. /package/vendor/skills/{design-world → author-world}/templates/paper-to-browser.json +0 -0
  215. /package/vendor/skills/{design-world → author-world}/templates/street-to-room.json +0 -0
  216. /package/vendor/skills/{design-world → author-world}/world.md +0 -0
  217. /package/vendor/skills/{address-review → edit-from-review}/bin/core/review-store.mjs +0 -0
  218. /package/vendor/skills/{address-review → edit-from-review}/dev-fixtures/fixture-project/captions.json +0 -0
  219. /package/vendor/skills/{address-review → edit-from-review}/dev-fixtures/fixture-project/edit.json +0 -0
  220. /package/vendor/skills/{address-review → edit-from-review}/dev-fixtures/fixture-project/review.json +0 -0
  221. /package/vendor/skills/{address-review → edit-from-review}/test/review-loss.test.mjs +0 -0
  222. /package/vendor/skills/{address-review → edit-from-review}/test/review-store.test.mjs +0 -0
  223. /package/vendor/skills/{beat-sync-edit → edit-to-beat}/templates/gen-timeline.mjs +0 -0
  224. /package/vendor/skills/{beat-sync-edit → edit-to-beat}/verify-loop.md +0 -0
  225. /package/vendor/skills/{edit-plan → plan-edit}/beats.md +0 -0
  226. /package/vendor/skills/{edit-plan → plan-edit}/bin/candidate-core.mjs +0 -0
  227. /package/vendor/skills/{edit-plan → plan-edit}/bin/canonical-json.mjs +0 -0
  228. /package/vendor/skills/{edit-plan → plan-edit}/bin/contract-semantics.mjs +0 -0
  229. /package/vendor/skills/{edit-plan → plan-edit}/bin/errors.mjs +0 -0
  230. /package/vendor/skills/{edit-plan → plan-edit}/bin/generated/contract-validators.cjs +0 -0
  231. /package/vendor/skills/{edit-plan → plan-edit}/bin/generated/runtime/equal.cjs +0 -0
  232. /package/vendor/skills/{edit-plan → plan-edit}/bin/generated/runtime/fast-deep-equal-index-9a360c74.cjs +0 -0
  233. /package/vendor/skills/{edit-plan → plan-edit}/bin/generated/runtime/licenses/ajv.txt +0 -0
  234. /package/vendor/skills/{edit-plan → plan-edit}/bin/generated/runtime/licenses/fast-deep-equal.txt +0 -0
  235. /package/vendor/skills/{edit-plan → plan-edit}/bin/generated/runtime/ucs2length.cjs +0 -0
  236. /package/vendor/skills/{edit-plan → plan-edit}/bin/propose-cut-candidates.mjs +0 -0
  237. /package/vendor/skills/{edit-plan → plan-edit}/bin/runtime-support.mjs +0 -0
  238. /package/vendor/skills/{edit-plan → plan-edit}/bin/test/candidate-core.test.mjs +0 -0
  239. /package/vendor/skills/{edit-plan → plan-edit}/bin/test/contract-validators-regen.test.mjs +0 -0
  240. /package/vendor/skills/{edit-plan → plan-edit}/bin/test/errors.test.mjs +0 -0
  241. /package/vendor/skills/{edit-plan → plan-edit}/bin/test/l1-real-media.test.mjs +0 -0
  242. /package/vendor/skills/{edit-plan → plan-edit}/bin/test/propose-cut-candidates.test.mjs +0 -0
  243. /package/vendor/skills/{edit-plan → plan-edit}/bin/test/runtime-support.test.mjs +0 -0
  244. /package/vendor/skills/{edit-plan → plan-edit}/bin/test/scale.test.mjs +0 -0
  245. /package/vendor/skills/{edit-plan → plan-edit}/emphasis-detection.md +0 -0
  246. /package/vendor/skills/{edit-plan → plan-edit}/lang/en.md +0 -0
  247. /package/vendor/skills/{edit-plan → plan-edit}/lang/ja.md +0 -0
  248. /package/vendor/skills/{edit-plan → plan-edit}/references/asset.decisions.example.json +0 -0
  249. /package/vendor/skills/{edit-plan → plan-edit}/references/cut-candidate-policy.a4-conversation-v1.json +0 -0
  250. /package/vendor/skills/{edit-plan → plan-edit}/references/event.example.json +0 -0
  251. /package/vendor/skills/{research-plan → plan-video}/lang/en.md +0 -0
  252. /package/vendor/skills/{research-plan → plan-video}/shotlist.md +0 -0
  253. /package/vendor/skills/{critique-cut → review-cut}/bin/used-ranges.mjs +0 -0
  254. /package/vendor/skills/{critique-cut → review-cut}/bin/used-ranges.test.mjs +0 -0
  255. /package/vendor/skills/{compile-review-session → review-from-recording}/bin/core/canvas-compiler.mjs +0 -0
  256. /package/vendor/skills/{compile-review-session → review-from-recording}/bin/core/compiler.mjs +0 -0
  257. /package/vendor/skills/{compile-review-session → review-from-recording}/bin/core/review-store.mjs +0 -0
  258. /package/vendor/skills/{compile-review-session → review-from-recording}/bin/core/time-mapping.mjs +0 -0
  259. /package/vendor/skills/{compile-review-session → review-from-recording}/bin/core/transcription.mjs +0 -0
  260. /package/vendor/skills/{compile-review-session → review-from-recording}/compilation-rules.md +0 -0
  261. /package/vendor/skills/{compile-review-session → review-from-recording}/dev-fixtures/fixture-project/review/sessions/s-0001/audio.wav +0 -0
  262. /package/vendor/skills/{compile-review-session → review-from-recording}/dev-fixtures/fixture-project/review/sessions/s-0001/edit.snapshot.json +0 -0
  263. /package/vendor/skills/{compile-review-session → review-from-recording}/dev-fixtures/fixture-project/review/sessions/s-0001/events.jsonl +0 -0
  264. /package/vendor/skills/{compile-review-session → review-from-recording}/dev-fixtures/fixture-project/review/sessions/s-0001/session.json +0 -0
  265. /package/vendor/skills/{compile-review-session → review-from-recording}/dev-fixtures/fixture-project/review/sessions/s-0002/audio.wav +0 -0
  266. /package/vendor/skills/{compile-review-session → review-from-recording}/dev-fixtures/fixture-project/review/sessions/s-0002/edit.snapshot.json +0 -0
  267. /package/vendor/skills/{compile-review-session → review-from-recording}/dev-fixtures/fixture-project/review/sessions/s-0002/events.jsonl +0 -0
  268. /package/vendor/skills/{compile-review-session → review-from-recording}/dev-fixtures/fixture-project/review/sessions/s-0002/session.json +0 -0
  269. /package/vendor/skills/{compile-review-session → review-from-recording}/dev-fixtures/fixture-project/review/sessions/s-0003/audio.wav +0 -0
  270. /package/vendor/skills/{compile-review-session → review-from-recording}/dev-fixtures/fixture-project/review/sessions/s-0003/edit.snapshot.json +0 -0
  271. /package/vendor/skills/{compile-review-session → review-from-recording}/dev-fixtures/fixture-project/review/sessions/s-0003/events.jsonl +0 -0
  272. /package/vendor/skills/{compile-review-session → review-from-recording}/dev-fixtures/fixture-project/review/sessions/s-0003/session.json +0 -0
  273. /package/vendor/skills/{compile-review-session → review-from-recording}/dev-fixtures/fixture-project/review/sessions/s-0004/audio.wav +0 -0
  274. /package/vendor/skills/{compile-review-session → review-from-recording}/dev-fixtures/fixture-project/review/sessions/s-0004/edit.snapshot.json +0 -0
  275. /package/vendor/skills/{compile-review-session → review-from-recording}/dev-fixtures/fixture-project/review/sessions/s-0004/events.jsonl +0 -0
  276. /package/vendor/skills/{compile-review-session → review-from-recording}/dev-fixtures/fixture-project/review/sessions/s-0004/session.json +0 -0
  277. /package/vendor/skills/{compile-review-session → review-from-recording}/dev-fixtures/fixture-project/review/sessions/s-0005/session.json +0 -0
  278. /package/vendor/skills/{compile-review-session → review-from-recording}/dev-fixtures/fixture-project/review/sessions/s-0006/audio.wav +0 -0
  279. /package/vendor/skills/{compile-review-session → review-from-recording}/dev-fixtures/fixture-project/review/sessions/s-0006/events.jsonl +0 -0
  280. /package/vendor/skills/{compile-review-session → review-from-recording}/dev-fixtures/fixture-project/review/sessions/s-0006/session.json +0 -0
  281. /package/vendor/skills/{compile-review-session → review-from-recording}/dev-fixtures/fixture-project/review/sessions/s-0007/audio.wav +0 -0
  282. /package/vendor/skills/{compile-review-session → review-from-recording}/dev-fixtures/fixture-project/review/sessions/s-0007/edit.snapshot.json +0 -0
  283. /package/vendor/skills/{compile-review-session → review-from-recording}/dev-fixtures/fixture-project/review/sessions/s-0007/events.jsonl +0 -0
  284. /package/vendor/skills/{compile-review-session → review-from-recording}/dev-fixtures/fixture-project/review/sessions/s-0007/session.json +0 -0
  285. /package/vendor/skills/{compile-review-session → review-from-recording}/dev-fixtures/fixture-project/review/sessions/s-0008/audio.wav +0 -0
  286. /package/vendor/skills/{compile-review-session → review-from-recording}/dev-fixtures/fixture-project/review/sessions/s-0008/edit.snapshot.json +0 -0
  287. /package/vendor/skills/{compile-review-session → review-from-recording}/dev-fixtures/fixture-project/review/sessions/s-0008/events.jsonl +0 -0
  288. /package/vendor/skills/{compile-review-session → review-from-recording}/dev-fixtures/fixture-project/review/sessions/s-0008/session.json +0 -0
  289. /package/vendor/skills/{compile-review-session → review-from-recording}/dev-fixtures/fixture-project/review/sessions/s-0008/transcript.json +0 -0
  290. /package/vendor/skills/{compile-review-session → review-from-recording}/dev-fixtures/fixture-project/review/sessions/s-0009/audio.wav +0 -0
  291. /package/vendor/skills/{compile-review-session → review-from-recording}/dev-fixtures/fixture-project/review/sessions/s-0009/edit.snapshot.json +0 -0
  292. /package/vendor/skills/{compile-review-session → review-from-recording}/dev-fixtures/fixture-project/review/sessions/s-0009/events.jsonl +0 -0
  293. /package/vendor/skills/{compile-review-session → review-from-recording}/dev-fixtures/fixture-project/review/sessions/s-0009/session.json +0 -0
  294. /package/vendor/skills/{compile-review-session → review-from-recording}/dev-fixtures/fixture-project/review/sessions/s-0010/audio.wav +0 -0
  295. /package/vendor/skills/{compile-review-session → review-from-recording}/dev-fixtures/fixture-project/review/sessions/s-0010/edit.snapshot.json +0 -0
  296. /package/vendor/skills/{compile-review-session → review-from-recording}/dev-fixtures/fixture-project/review/sessions/s-0010/events.jsonl +0 -0
  297. /package/vendor/skills/{compile-review-session → review-from-recording}/dev-fixtures/fixture-project/review/sessions/s-0010/session.json +0 -0
  298. /package/vendor/skills/{compile-review-session → review-from-recording}/dev-fixtures/fixture-project/review.json +0 -0
  299. /package/vendor/skills/{compile-review-session → review-from-recording}/dev-fixtures/issue-79/reproduce.mjs +0 -0
  300. /package/vendor/skills/{compile-review-session → review-from-recording}/test/canvas-compiler.test.mjs +0 -0
  301. /package/vendor/skills/{compile-review-session → review-from-recording}/test/compiler.test.mjs +0 -0
  302. /package/vendor/skills/{compile-review-session → review-from-recording}/test/install-root.test.mjs +0 -0
  303. /package/vendor/skills/{compile-review-session → review-from-recording}/test/review-loss.test.mjs +0 -0
  304. /package/vendor/skills/{compile-review-session → review-from-recording}/test/ui-events.test.mjs +0 -0
  305. /package/vendor/skills/{manage-connections → setup-connections}/bin/resolve-connections.mjs +0 -0
  306. /package/vendor/skills/{manage-connections → setup-connections}/bin/test/doctor-i18n.test.mjs +0 -0
  307. /package/vendor/skills/{manage-connections → setup-connections}/bin/test/resolve-packages.test.mjs +0 -0
  308. /package/vendor/skills/{manage-connections → setup-connections}/test/connectors-doctor.test.mjs +0 -0
  309. /package/vendor/skills/{manage-connections → setup-connections}/test/direct-tts-doctor.test.mjs +0 -0
  310. /package/vendor/skills/{manage-connections → setup-connections}/test/doctor-key-source.test.mjs +0 -0
  311. /package/vendor/skills/{manage-connections → setup-connections}/test/fieldreport-report-location.test.mjs +0 -0
  312. /package/vendor/skills/{manage-connections → setup-connections}/test/resolve-connections-defaults.test.mjs +0 -0
  313. /package/vendor/skills/{manage-connections → setup-connections}/test/resolve-connections.test.mjs +0 -0
  314. /package/vendor/skills/{setup-audio-library/first-party.md → setup-library/audio-first-party.md} +0 -0
  315. /package/vendor/skills/{setup-audio-library/store-unlock.md → setup-library/audio-store-unlock.md} +0 -0
  316. /package/vendor/skills/{edit-lint → verify-edit}/preview.md +0 -0
package/README.md CHANGED
@@ -21,7 +21,7 @@ akari
21
21
  │ (.akari/intake.json は status: "draft" で生成される)
22
22
  │
23
23
  ├─ 3. 接続状態を確認する:
24
- │ skills/manage-connections/bin/doctor.mjs を再利用して
24
+ │ skills/setup-connections/bin/doctor.mjs を再利用して
25
25
  │ .akari/connections.json の doctor ブロックを更新・表示する
26
26
  │ (キーの値は一切表示しない)
27
27
  │
@@ -47,7 +47,7 @@ DL・sha256 検証・適用まで実行。それ以外(npm グローバル / g
47
47
  `akari init`(作業場の作成・確認のみ)/
48
48
  `akari new <target-dir> [--template <path>]`(新規プロジェクト作成)/
49
49
  `akari narration generate ...`(VOICEVOX / fal-qwen3 ナレーション生成)/
50
- `akari internal beat-sync-<beatmap|probe-frame|render-when-idle> ...`(beat-sync-edit 内部実行物)/
50
+ `akari internal beat-sync-<beatmap|probe-frame|render-when-idle> ...`(edit-to-beat 内部実行物)/
51
51
  `akari sounds [--variant wav] [--force]`(公式音源の一括ダウンロード。プロンプトなし・headless 可)/
52
52
  `akari store <connect|status|install|download|disconnect>`(AKARI Store 連携。マイページで発行した
53
53
  接続トークンを `~/.akari/store-credentials.json`(0600)に保存し、購入済み一覧の確認と
@@ -58,7 +58,12 @@ zip を使う。`src/store-command.mjs`)/
58
58
  `packages/asset-resolver` の CLI への薄い委譲で、カタログ合成・entitlements 判定・
59
59
  sha256 検証・fail-closed は resolver 側の責務のまま。`src/assets-command.mjs`)/
60
60
  `akari clean [project-dir] [--dry-run] [--yes] [--json]`(使い捨ての中間ファイル、保持する
61
- 正本、判断が必要なものを容量付きで一覧する。既定は一覧のみで、削除可能なものだけを承認後に削除)。
61
+ 正本、判断が必要なものを容量付きで一覧する。既定は一覧のみで、削除可能なものだけを承認後に削除)/
62
+ `akari geo terrain --bbox <西,南,東,北> --out <dir> [--zoom 1-14] [--max-tiles 64]`(国土地理院の
63
+ 標高・写真タイルから 3D 地形の `heightmap.png`・`texture.png`・`terrain.json` を作る)/
64
+ `akari geo point --terrain <terrain.json> --lonlat <経度,緯度>[,高さm]`(terrain.json の
65
+ declaration と同じ縮尺で経緯度を 3D 座標 `[x, y, z]` に直す。出典「国土地理院(地理院タイル)」の
66
+ 表示が利用条件)。
62
67
 
63
68
  ## 拡張キット
64
69
 
package/bin/akari.mjs CHANGED
@@ -17,6 +17,9 @@ import { runDoctorCommand } from '../src/doctor-command.mjs';
17
17
  import { runGenerateCommand } from '../src/generate-command.mjs';
18
18
  import { runStoryboardCommand } from '../src/storyboard-command.mjs';
19
19
  import { runWorldCommand } from '../src/world-command.mjs';
20
+ import { runGeoCommand } from '../src/geo-command.mjs';
21
+ import { runLintCommand } from '../src/lint-command.mjs';
22
+ import { runPreviewCommand } from '../src/preview-command.mjs';
20
23
  import { runSkillsCommand, refreshEntrySkillOnLaunch } from '../src/skills-command.mjs';
21
24
  import { resolveRuntimePaths } from '../src/runtime-diagnostics.mjs';
22
25
  import { maybeApplyPendingUpdateOnLaunch, resolveInstalledVersionInfo } from '../src/update-check.mjs';
@@ -77,6 +80,9 @@ const commands = {
77
80
  generate: runGenerateCommand,
78
81
  storyboard: runStoryboardCommand,
79
82
  world: runWorldCommand,
83
+ geo: runGeoCommand,
84
+ lint: runLintCommand,
85
+ preview: runPreviewCommand,
80
86
  };
81
87
 
82
88
  // トップレベルのフラグも、振り分けと候補判定に同じ表を使う。
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "akari-video",
3
- "version": "1.5.1",
3
+ "version": "1.5.2-beta.2",
4
4
  "description": "AKARI Video launcher CLI — start an AI-edited video project from any directory: scaffold, connection check, then hand over to Claude Code (or opencode). AKARI Video を opencode や Claude Code で、どのディレクトリからでも始めるための `akari` ランチャー CLI。接続確認(doctor)→ 未セットアップならプロジェクト雛形を作成 → AI エージェントを起動する。外部 npm 依存ゼロ(Node.js 組み込みモジュールのみ)。",
5
5
  "type": "module",
6
6
  "bin": {
package/src/cli.mjs CHANGED
@@ -34,6 +34,8 @@ import { runProjectCommand } from './project-command.mjs';
34
34
  import { runPlaybookCommand } from './playbook-command.mjs';
35
35
  import { runTemplateCommand } from './template-command.mjs';
36
36
  import { runRecipeCommand } from './recipe-command.mjs';
37
+ import { runLintCommand } from './lint-command.mjs';
38
+ import { runPreviewCommand } from './preview-command.mjs';
37
39
  import { resolveRuntimePaths } from './runtime-diagnostics.mjs';
38
40
  import { cliText } from './i18n.mjs';
39
41
 
@@ -51,6 +53,8 @@ export const runSubcommands = {
51
53
  playbook: runPlaybookCommand,
52
54
  template: runTemplateCommand,
53
55
  recipe: runRecipeCommand,
56
+ lint: runLintCommand,
57
+ preview: runPreviewCommand,
54
58
  };
55
59
 
56
60
  /**
@@ -0,0 +1,18 @@
1
+ import { existsSync } from 'node:fs';
2
+ import { cliText } from './i18n.mjs';
3
+ import { spawnSync } from 'node:child_process';
4
+ import path from 'node:path';
5
+
6
+ import { GEO_CLI_RELATIVE, resolveLauncherAssets } from './repo-assets.mjs';
7
+
8
+ export async function runGeoCommand(args, options = {}) {
9
+ const logError = options.logError ?? ((line) => console.error(line));
10
+ const assets = options.assets ?? resolveLauncherAssets();
11
+ const script = assets.repoRoot ? path.join(assets.repoRoot, GEO_CLI_RELATIVE) : null;
12
+ if (!script || !existsSync(script)) {
13
+ logError(cliText('cli.internal.error.scriptMissing', { command: 'geo' }));
14
+ return { exitCode: 1 };
15
+ }
16
+ const result = (options.spawn ?? spawnSync)(process.execPath, [script, ...args], { stdio: 'inherit' });
17
+ return { exitCode: typeof result?.status === 'number' ? result.status : 1 };
18
+ }
@@ -0,0 +1,85 @@
1
+ import { spawnSync } from 'node:child_process';
2
+ import { existsSync } from 'node:fs';
3
+
4
+ import { cliText } from './i18n.mjs';
5
+ import { resolveRuntimePaths } from './runtime-diagnostics.mjs';
6
+
7
+ // 値を 1 つ取るオプション。プロジェクトの位置引数と取り違えないよう読み飛ばす。
8
+ const VALUE_FLAGS = new Set([
9
+ '--engine',
10
+ '--silence-error-seconds',
11
+ '--max-volume-error-db',
12
+ '--caption-silence-warn-percent',
13
+ '--declarations',
14
+ '--ffprobe'
15
+ ]);
16
+
17
+ export function lintHelp() {
18
+ return [
19
+ cliText('cli.lint.help.usage'),
20
+ '',
21
+ cliText('cli.lint.help.description'),
22
+ cliText('cli.lint.help.project'),
23
+ cliText('cli.lint.help.fix'),
24
+ cliText('cli.lint.help.media'),
25
+ cliText('cli.lint.help.json'),
26
+ cliText('cli.lint.help.engine'),
27
+ cliText('cli.lint.help.help')
28
+ ];
29
+ }
30
+
31
+ function hasProjectArgument(argv) {
32
+ for (let index = 0; index < argv.length; index += 1) {
33
+ const argument = argv[index];
34
+ if (argument === '--') return index + 1 < argv.length;
35
+ if (VALUE_FLAGS.has(argument)) {
36
+ index += 1;
37
+ continue;
38
+ }
39
+ if (argument.startsWith('-')) continue;
40
+ return true;
41
+ }
42
+ return false;
43
+ }
44
+
45
+ /**
46
+ * `akari lint [<project>] [--fix] ...` — 決定論的な edit-lint CLI をそのまま呼ぶ。
47
+ * 既定では `--no-reports` を付けて一切書き込まない。`--fix` のときだけ edit-lint の
48
+ * 修正経路(退避・差分・再検査)を通す。
49
+ */
50
+ export async function runLintCommand(argv, options = {}) {
51
+ const log = options.log ?? ((line) => console.log(line));
52
+ const error = options.error ?? ((line) => console.error(line));
53
+
54
+ if (argv.includes('--help') || argv.includes('-h')) {
55
+ for (const line of lintHelp()) log(line);
56
+ return { exitCode: 0 };
57
+ }
58
+
59
+ const runtime = options.runtime ?? resolveRuntimePaths({ env: options.env ?? process.env });
60
+ const editLintPath = options.editLintPath ?? runtime.edit_lint?.path ?? null;
61
+ if (!editLintPath || !existsSync(editLintPath)) {
62
+ error(cliText('cli.lint.error.scriptMissing'));
63
+ return { exitCode: 2 };
64
+ }
65
+
66
+ const forwarded = [...argv];
67
+ if (!hasProjectArgument(forwarded)) forwarded.push('.');
68
+ if (!forwarded.includes('--fix')) forwarded.push('--no-reports');
69
+
70
+ const env = { ...(options.env ?? process.env) };
71
+ const electron = options.electronRuntime ?? Boolean(process.versions.electron);
72
+ if (electron && env.ELECTRON_RUN_AS_NODE !== '1') env.ELECTRON_RUN_AS_NODE = '1';
73
+
74
+ const spawn = options.spawn ?? spawnSync;
75
+ const result = spawn(options.execPath ?? process.execPath, [editLintPath, ...forwarded], {
76
+ stdio: options.stdio ?? 'inherit',
77
+ cwd: options.cwd ?? process.cwd(),
78
+ env
79
+ });
80
+ return {
81
+ exitCode: typeof result?.status === 'number' ? result.status : 2,
82
+ stdout: result?.stdout,
83
+ stderr: result?.stderr
84
+ };
85
+ }
package/src/messages.mjs CHANGED
@@ -335,7 +335,7 @@ export function describeCliHelp() {
335
335
  cliText('cli.help.header.usage'),
336
336
  '',
337
337
  cliText('cli.help.commands.heading'),
338
- ...['launch', 'store', 'sounds', 'doctor', 'speakers', 'toolsVoice', 'update', 'status', 'migrate', 'migrateLook', 'generate', 'storyboard', 'project', 'playbook', 'recipe', 'clean'].map((name) => cliText(`cli.help.commands.${name}`)),
338
+ ...['launch', 'preview', 'store', 'sounds', 'doctor', 'speakers', 'toolsVoice', 'update', 'status', 'migrate', 'migrateLook', 'generate', 'storyboard', 'project', 'playbook', 'recipe', 'geo', 'lint', 'clean'].map((name) => cliText(`cli.help.commands.${name}`)),
339
339
  '',
340
340
  cliText('cli.help.developer.heading'),
341
341
  ...['opencode', 'claude', 'yes', 'version', 'new', 'init', 'other', 'help'].map((name) => cliText(`cli.help.developer.${name}`)),
@@ -59,7 +59,7 @@ async function projectLanguage(projectRoot, cliLang) {
59
59
  const usage = (language) => [
60
60
  cliText('cli.narration.help.usage', {}, language),
61
61
  " akari narration generate \\",
62
- " --project <projectDir> [--engine <voicevox|gemini-tts|irodori|fal-qwen3|gemini-3.1-flash-tts|elevenlabs-v3|minimax-2.6-hd|chatterbox|index-tts-2|fish-s2.1-pro|gemini-3.8-flash-tts>] \\",
62
+ " --project <projectDir> [--engine <voicevox|gemini-tts|irodori|fal-qwen3|gemini-3.1-flash-tts|elevenlabs-v3|minimax-2.6-hd|chatterbox|index-tts-2|fish-s2.1-pro|fish-drama-3|gemini-3.8-flash-tts>] \\",
63
63
  cliText('cli.narration.help.reading', {}, language),
64
64
  cliText('cli.narration.help.timeline', {}, language),
65
65
  " [--lang <code>] [--speaker 3] [--voice Leda] [--style <text>] [--speed 1] \\",
@@ -322,10 +322,10 @@ async function parseArguments(argv) {
322
322
  irodoriTimeout();
323
323
  } else {
324
324
  const engine = ttsEngine(options.engine);
325
- options.voice ??= engine ? (engine.id === 'fish-s2.1-pro' && options.language !== 'ja' ? null
325
+ options.voice ??= engine ? (engine.provider === 'fish-audio' && options.language !== 'ja' ? null
326
326
  : engine.default_voices && Object.hasOwn(engine.default_voices, options.language)
327
327
  ? engine.default_voices[options.language] : engine.default_voice) : 'Leda';
328
- if (options.engine === 'fish-s2.1-pro' && !options.voice && !options.profile) {
328
+ if (engine?.provider === 'fish-audio' && !options.voice && !options.profile) {
329
329
  throw new PublicError(cliText('cli.narration.error.fishDefaultVoiceMissing'), 2);
330
330
  }
331
331
  }
@@ -773,7 +773,7 @@ function applyToEditJson(projectDir, entry, io) {
773
773
  // --- dry-run ---
774
774
 
775
775
  function maskKey(secret) {
776
- // 実際のキー文字は 1 文字も出力しない(manage-connections ハードルール「表示は常にマスク」)。
776
+ // 実際のキー文字は 1 文字も出力しない(setup-connections ハードルール「表示は常にマスク」)。
777
777
  return secret ? "***configured***" : "***unconfigured***";
778
778
  }
779
779
 
@@ -873,7 +873,7 @@ async function listEngines(runtime = {}) {
873
873
  id: engine.id, label: engine.label, languages: engine.languages, place: engine.place, provider: engine.provider,
874
874
  group: 'cloud', endpoint: engine.endpoint, price: engine.price,
875
875
  availability: directAvailability[engine.provider], default_voice: engine.default_voice,
876
- credit_required: false, supports: engine.supports,
876
+ credit_required: false, supports: engine.supports, ...(engine.candidate ? { candidate: true } : {}),
877
877
  })),
878
878
  ] };
879
879
  }
@@ -956,7 +956,7 @@ async function runDryRun(options, readingText, io) {
956
956
  emit({ dry_run: true, engine: engine.id, output_path: outputPath,
957
957
  estimated_cost_usd: estimateTtsCost(engine, readingText),
958
958
  request: { endpoint: engine.endpoint, headers: engine.provider === 'fish-audio'
959
- ? { Authorization: `Bearer ${maskKey(readProviderKey('FISH_AUDIO_API_KEY'))}`, model: 's2.1-pro',
959
+ ? { Authorization: `Bearer ${maskKey(readProviderKey('FISH_AUDIO_API_KEY'))}`, model: engine.model,
960
960
  'Content-Type': record ? 'application/msgpack' : 'application/json' }
961
961
  : { 'x-goog-api-key': maskKey(readProviderKey('GEMINI_API_KEY')), 'Content-Type': 'application/json' }, body } }, io.log);
962
962
  return;
@@ -1041,6 +1041,10 @@ async function runGenerate(options, io) {
1041
1041
  if (options.engine === 'chatterbox' && readingText.length > 300) {
1042
1042
  throw new PublicError(cliText('cli.narration.error.chatterboxLength'), 2);
1043
1043
  }
1044
+ // 候補は既定で選ばれない。名指しされた場合も、送信前に試聴前であることを 1 行で伝える。
1045
+ if (ttsEngine(options.engine)?.candidate) {
1046
+ io.logError(cliText('cli.narration.warning.candidateEngine', { engine: options.engine }));
1047
+ }
1044
1048
 
1045
1049
  if (options.dryRun) {
1046
1050
  await runDryRun(options, readingText, io);
@@ -1118,7 +1122,7 @@ async function runGenerate(options, io) {
1118
1122
  referenceAudio, referenceText: record?.meta.reference_text });
1119
1123
  audioBuffer = await synthesizeDirect(engine, payload, key);
1120
1124
  provenance = { provider: engine.provider, engine: engine.id,
1121
- model: engine.provider === 'fish-audio' ? 's2.1-pro' : 'gemini-3.8-flash-tts',
1125
+ model: engine.model ?? engine.id,
1122
1126
  voice: record ? `profile:${options.profile}` : options.voice,
1123
1127
  generated_at: new Date().toISOString(), price_verified: engine.price.verified };
1124
1128
  } else if (options.engine === "gemini-tts") {
@@ -0,0 +1,281 @@
1
+ import { spawn } from 'node:child_process';
2
+ import { existsSync, statSync } from 'node:fs';
3
+ import path from 'node:path';
4
+
5
+ import { PREVIEW_SERVER_SCRIPT_RELATIVE, resolveLauncherAssets } from './repo-assets.mjs';
6
+ import { cliText } from './i18n.mjs';
7
+
8
+ /**
9
+ * `akari preview [dir] [--port <port>] [--open]` — プロジェクトのプレビューを
10
+ * ブラウザで開く URL を出す。サーバーの実体は `packages/preview-server/src/server.mjs`
11
+ * (モノレポ checkout / アプリの Resources / 同梱されていれば npm vendor)を子プロセスとして
12
+ * 起動するだけで、ここでサーバーを再実装しない。
13
+ *
14
+ * 既定ポートは preview-server の既定(3000)。`akari.sh --preview` の既定は 4567 だが、
15
+ * シェル版の既存挙動は変えず、Node CLI 側はサーバー本体の既定に合わせる。
16
+ */
17
+
18
+ export const PREVIEW_DEFAULT_PORT = 3000;
19
+
20
+ export function previewHelp() {
21
+ return [
22
+ cliText('cli.preview.help.usage'),
23
+ '',
24
+ cliText('cli.preview.help.description'),
25
+ '',
26
+ cliText('cli.preview.help.port'),
27
+ cliText('cli.preview.help.open'),
28
+ cliText('cli.preview.help.help'),
29
+ ];
30
+ }
31
+
32
+ function isPort(value) {
33
+ return /^\d+$/u.test(value) && Number(value) >= 1 && Number(value) <= 65535;
34
+ }
35
+
36
+ /**
37
+ * 引数を解釈する。`help` は他引数より優先する(`--help` は常に成功で終わる)。
38
+ * `projectRoot` は決して実在確認しない — 呼び出し側が案内付きで止める。
39
+ */
40
+ export function parsePreviewArguments(args, cwd = process.cwd()) {
41
+ const positional = [];
42
+ let port = PREVIEW_DEFAULT_PORT;
43
+ let open = false;
44
+ let help = false;
45
+
46
+ for (let i = 0; i < args.length; i += 1) {
47
+ const arg = args[i];
48
+ if (arg === '-h' || arg === '--help') {
49
+ help = true;
50
+ continue;
51
+ }
52
+ if (arg === '-o' || arg === '--open') {
53
+ open = true;
54
+ continue;
55
+ }
56
+ if (arg === '-p' || arg === '--port') {
57
+ const value = args[i + 1];
58
+ if (value === undefined || value.startsWith('-')) {
59
+ return { ok: false, message: cliText('cli.preview.error.portMissing') };
60
+ }
61
+ i += 1;
62
+ if (!isPort(value)) {
63
+ return { ok: false, message: cliText('cli.preview.error.invalidPort', { port: value }) };
64
+ }
65
+ port = Number(value);
66
+ continue;
67
+ }
68
+ if (arg.startsWith('--port=')) {
69
+ const value = arg.slice('--port='.length);
70
+ if (!isPort(value)) {
71
+ return { ok: false, message: cliText('cli.preview.error.invalidPort', { port: value }) };
72
+ }
73
+ port = Number(value);
74
+ continue;
75
+ }
76
+ if (arg.startsWith('-')) {
77
+ return { ok: false, message: cliText('cli.preview.error.unknownOption', { option: arg }) };
78
+ }
79
+ positional.push(arg);
80
+ }
81
+
82
+ if (help) return { ok: true, help: true };
83
+ if (positional.length > 1) {
84
+ return { ok: false, message: cliText('cli.preview.error.multipleDirs') };
85
+ }
86
+ return {
87
+ ok: true,
88
+ help: false,
89
+ port,
90
+ open,
91
+ projectRoot: path.resolve(cwd, positional[0] ?? '.'),
92
+ };
93
+ }
94
+
95
+ /** サーバーが listen 後に出す URL 行だけを取り出す(banner の他行には反応しない)。 */
96
+ export function extractPreviewUrl(line) {
97
+ const match = /^\s*(http:\/\/(?:127\.0\.0\.1|localhost|\[[^\]]+\]|[^\s:]+):\d+)\s*$/u.exec(line);
98
+ return match ? match[1] : null;
99
+ }
100
+
101
+ function isDirectory(target, stat = statSync) {
102
+ try {
103
+ return stat(target).isDirectory();
104
+ } catch {
105
+ return false;
106
+ }
107
+ }
108
+
109
+ function defaultOpenBrowser(url, platform = process.platform) {
110
+ try {
111
+ const [command, args] = platform === 'win32'
112
+ ? ['cmd', ['/c', 'start', '', url]]
113
+ : [platform === 'darwin' ? 'open' : 'xdg-open', [url]];
114
+ const child = spawn(command, args, { detached: true, stdio: 'ignore' });
115
+ child.unref();
116
+ return true;
117
+ } catch {
118
+ return false;
119
+ }
120
+ }
121
+
122
+ export async function runPreviewCommand(args, options = {}) {
123
+ const log = options.log ?? ((line) => console.log(line));
124
+ const logError = options.error ?? options.logError ?? ((line) => console.error(line));
125
+ const parsed = parsePreviewArguments(args, options.cwd ?? process.cwd());
126
+
127
+ if (!parsed.ok) {
128
+ logError(parsed.message);
129
+ for (const line of previewHelp()) logError(line);
130
+ return { exitCode: 2 };
131
+ }
132
+ if (parsed.help) {
133
+ for (const line of previewHelp()) log(line);
134
+ return { exitCode: 0 };
135
+ }
136
+
137
+ const projectRoot = parsed.projectRoot;
138
+ if (!isDirectory(projectRoot, options.statSync ?? statSync)) {
139
+ logError(cliText('cli.preview.error.directoryMissing', { root: projectRoot }));
140
+ return { exitCode: 1 };
141
+ }
142
+
143
+ if (!(options.existsSync ?? existsSync)(path.join(projectRoot, '.akari'))) {
144
+ logError(cliText('cli.preview.error.notProject', { root: projectRoot }));
145
+ logError(cliText('cli.preview.error.projectGuidance'));
146
+ return { exitCode: 1 };
147
+ }
148
+
149
+ const assets = options.assets ?? resolveLauncherAssets({
150
+ resourcesPath: options.resourcesPath ?? process.resourcesPath,
151
+ });
152
+ const script = assets.previewServerScript;
153
+ if (!script || !(options.existsSync ?? existsSync)(script)) {
154
+ const missing = script ?? PREVIEW_SERVER_SCRIPT_RELATIVE;
155
+ const root = assets.repoRoot ?? cliText('cli.preview.label.unknown');
156
+ logError(cliText('cli.preview.error.serverMissing', { path: missing, root }));
157
+ return { exitCode: 1 };
158
+ }
159
+
160
+ return await startPreviewServer({
161
+ script,
162
+ projectRoot,
163
+ port: parsed.port,
164
+ open: parsed.open,
165
+ log,
166
+ logError,
167
+ env: options.env ?? process.env,
168
+ platform: options.platform ?? process.platform,
169
+ spawn: options.spawn ?? spawn,
170
+ openBrowser: options.openBrowser ?? defaultOpenBrowser,
171
+ });
172
+ }
173
+
174
+ function startPreviewServer({
175
+ script,
176
+ projectRoot,
177
+ port,
178
+ open,
179
+ log,
180
+ logError,
181
+ env,
182
+ platform,
183
+ spawn,
184
+ openBrowser,
185
+ }) {
186
+ return new Promise((resolve) => {
187
+ let child;
188
+ try {
189
+ child = spawn(process.execPath, [script, projectRoot, '--port', String(port)], {
190
+ cwd: projectRoot,
191
+ env,
192
+ stdio: ['ignore', 'pipe', 'pipe'],
193
+ });
194
+ } catch (cause) {
195
+ logError(cliText('cli.preview.error.spawnFailed', {
196
+ message: cause instanceof Error ? cause.message : String(cause),
197
+ }));
198
+ resolve({ exitCode: 1 });
199
+ return;
200
+ }
201
+
202
+ let ready = false;
203
+ let settled = false;
204
+ let outBuffer = '';
205
+ let errBuffer = '';
206
+ const pendingLines = [];
207
+
208
+ const emitLine = (line) => {
209
+ if (!ready) {
210
+ const url = extractPreviewUrl(line);
211
+ if (url) {
212
+ ready = true;
213
+ // URL を 1 行目に出す。banner は URL の後ろへ回し、起動ログも失わない。
214
+ log(url);
215
+ for (const pending of pendingLines) log(pending);
216
+ pendingLines.length = 0;
217
+ if (open) openBrowser(url, platform);
218
+ return true;
219
+ }
220
+ pendingLines.push(line);
221
+ return false;
222
+ }
223
+ log(line);
224
+ return true;
225
+ };
226
+
227
+ const onStdout = (chunk) => {
228
+ outBuffer += chunk;
229
+ let index;
230
+ while ((index = outBuffer.indexOf('\n')) >= 0) {
231
+ const line = outBuffer.slice(0, index).replace(/\r$/u, '');
232
+ outBuffer = outBuffer.slice(index + 1);
233
+ emitLine(line);
234
+ }
235
+ };
236
+
237
+ const onStderr = (chunk) => {
238
+ if (!ready) {
239
+ errBuffer += chunk;
240
+ return;
241
+ }
242
+ logError(chunk.replace(/\r?\n$/u, ''));
243
+ };
244
+
245
+ const onSignal = (signal) => {
246
+ try { child.kill(signal); } catch { /* 既に終了している。 */ }
247
+ };
248
+ const signals = ['SIGINT', 'SIGTERM'];
249
+ for (const signal of signals) process.on(signal, onSignal);
250
+
251
+ const cleanup = () => {
252
+ for (const signal of signals) process.off(signal, onSignal);
253
+ settled = true;
254
+ };
255
+
256
+ child.stdout?.setEncoding?.('utf8');
257
+ child.stderr?.setEncoding?.('utf8');
258
+ child.stdout?.on('data', onStdout);
259
+ child.stderr?.on('data', onStderr);
260
+
261
+ const finish = (code) => {
262
+ if (settled) return;
263
+ cleanup();
264
+ if (!ready) {
265
+ for (const line of pendingLines) logError(line);
266
+ if (outBuffer) logError(outBuffer);
267
+ if (errBuffer) logError(errBuffer.replace(/\r?\n$/u, ''));
268
+ logError(cliText('cli.preview.error.startFailed', { code: code ?? 1 }));
269
+ }
270
+ resolve({ exitCode: typeof code === 'number' ? code : 0 });
271
+ };
272
+
273
+ child.on('error', (cause) => {
274
+ logError(cliText('cli.preview.error.spawnFailed', {
275
+ message: cause instanceof Error ? cause.message : String(cause),
276
+ }));
277
+ finish(1);
278
+ });
279
+ child.on('exit', (code) => finish(code));
280
+ });
281
+ }
@@ -4,7 +4,7 @@ import path from 'node:path';
4
4
  /**
5
5
  * カレントプロジェクトが AKARI Video プロジェクトとしてセットアップ済みかを判定する。
6
6
  * `.akari/connections.json` の有無を「セットアップ済み」の判定基準にする
7
- * (`create-project` / `project-scaffold` が必ずこのファイルを雛形から生成するため)。
7
+ * (`setup-project` / `project-scaffold` が必ずこのファイルを雛形から生成するため)。
8
8
  *
9
9
  * 例外: `.akari/root.json`(作業場マニフェスト)を持つディレクトリは作業場ルートであって
10
10
  * プロジェクトではない。作業場層 `.akari/connections.json`(`packages/creator-root` の
@@ -19,7 +19,7 @@ const SKILLS_MARKER = path.join('skills', 'analyze-footage', 'SKILL.md');
19
19
  // 雛形側の .gitignore 実体は project-scaffold の writeFallbackTemplate が補完する。
20
20
  const TEMPLATE_MARKER = path.join('templates', 'project-default', 'CLAUDE.md');
21
21
  const SCHEMAS_MARKER = path.join('packages', 'schemas', 'analysis.schema.json');
22
- export const DOCTOR_SCRIPT_RELATIVE = path.join('skills', 'manage-connections', 'bin', 'doctor.mjs');
22
+ export const DOCTOR_SCRIPT_RELATIVE = path.join('skills', 'setup-connections', 'bin', 'doctor.mjs');
23
23
  export const SCAFFOLD_MODULE_RELATIVE = path.join('packages', 'project-scaffold', 'src', 'index.mjs');
24
24
  // 作業場(creator-root)モジュール。① Wave(packages/creator-root)の成果物で、本パッケージ
25
25
  // からは読み取り専用(動的 import のみ)。scaffoldModulePath と同型の解決方式。
@@ -47,14 +47,18 @@ export const WORD_BOOK_SCRIPT_RELATIVE = path.join('packages', 'akari-tools', 'b
47
47
  export const GENERATE_CLI_RELATIVE = path.join('packages', 'generate', 'src', 'cli', 'index.mjs');
48
48
  export const STORYBOARD_CLI_RELATIVE = path.join('packages', 'decision-cards', 'render-storyboard-print.mjs');
49
49
  export const WORLD_CLI_RELATIVE = path.join('packages', 'akari-tools', 'bin', 'world.mjs');
50
+ export const GEO_CLI_RELATIVE = path.join('packages', 'akari-tools', 'bin', 'geo.mjs');
50
51
  export const WORLD_VALIDATOR_RELATIVE = path.join('packages', 'schemas', 'bin', 'validate-world-map.mjs');
52
+ // ブラウザプレビューの実体。`akari preview` はこれを子プロセスで起動するだけで、
53
+ // サーバーを再実装しない(アプリでは extraResources、モノレポでは checkout から解決)。
54
+ export const PREVIEW_SERVER_SCRIPT_RELATIVE = path.join('packages', 'preview-server', 'src', 'server.mjs');
51
55
 
52
56
  // launcher が直接または起動した CLI の子プロセスとして解決する実行体の正本。
53
57
  // launcher-assets は resolveLauncherAssets() が資産フィールド単位で vendor を補完できる経路、
54
58
  // resources は assets.repoRoot または実行中 CLI の位置から自己解決し、vendor を見ない経路。
55
59
  // relative は上の解決定数だけから組み立て、配布検査と実行時解決の文字列を乖離させない。
56
60
  export const LAUNCHER_SUBCOMMAND_EXECUTABLES = [
57
- { command: '接続 doctor(manage-connections)', relative: DOCTOR_SCRIPT_RELATIVE, resolution: 'launcher-assets' },
61
+ { command: '接続 doctor(setup-connections)', relative: DOCTOR_SCRIPT_RELATIVE, resolution: 'launcher-assets' },
58
62
  { command: 'akari new', relative: SCAFFOLD_MODULE_RELATIVE, resolution: 'launcher-assets' },
59
63
  { command: '初回動線(first-run)の作業場モジュール', relative: CREATOR_ROOT_MODULE_RELATIVE, resolution: 'launcher-assets' },
60
64
  { command: 'akari sounds', relative: AUDIO_FETCH_SCRIPT_RELATIVE, resolution: 'launcher-assets' },
@@ -74,7 +78,9 @@ export const LAUNCHER_SUBCOMMAND_EXECUTABLES = [
74
78
  { command: 'akari generate', relative: GENERATE_CLI_RELATIVE, resolution: 'launcher-assets' },
75
79
  { command: 'akari storyboard', relative: STORYBOARD_CLI_RELATIVE, resolution: 'launcher-assets' },
76
80
  { command: 'akari world', relative: WORLD_CLI_RELATIVE, resolution: 'resources' },
77
- { command: 'akari world check', relative: WORLD_VALIDATOR_RELATIVE, resolution: 'resources' }
81
+ { command: 'akari geo', relative: GEO_CLI_RELATIVE, resolution: 'launcher-assets' },
82
+ { command: 'akari world check', relative: WORLD_VALIDATOR_RELATIVE, resolution: 'resources' },
83
+ { command: 'akari preview', relative: PREVIEW_SERVER_SCRIPT_RELATIVE, resolution: 'resources' }
78
84
  ];
79
85
 
80
86
  /**
@@ -101,6 +107,7 @@ export function resolveRepoAssets(repoRoot = DEFAULT_REPO_ROOT_CANDIDATE) {
101
107
  const wordBookScript = path.join(repoRoot, WORD_BOOK_SCRIPT_RELATIVE);
102
108
  const generateScript = path.join(repoRoot, GENERATE_CLI_RELATIVE);
103
109
  const storyboardScript = path.join(repoRoot, STORYBOARD_CLI_RELATIVE);
110
+ const previewServerScript = path.join(repoRoot, PREVIEW_SERVER_SCRIPT_RELATIVE);
104
111
 
105
112
  return {
106
113
  repoRoot,
@@ -124,23 +131,34 @@ export function resolveRepoAssets(repoRoot = DEFAULT_REPO_ROOT_CANDIDATE) {
124
131
  ...(existsSync(decisionLogScript) ? { decisionLogScript } : {}),
125
132
  ...(existsSync(wordBookScript) ? { wordBookScript } : {}),
126
133
  ...(existsSync(generateScript) ? { generateScript } : {}),
127
- ...(existsSync(storyboardScript) ? { storyboardScript } : {})
134
+ ...(existsSync(storyboardScript) ? { storyboardScript } : {}),
135
+ ...(existsSync(previewServerScript) ? { previewServerScript } : {})
128
136
  };
129
137
  }
130
138
 
131
139
  /**
132
140
  * ランチャー実行時の同梱物解決: 資産ごとにモノレポ checkout(開発時)→ vendor/
133
141
  * (npm 配布時)の順で探す。checkout が一部の資産しか持たないパッケージ構成でも、
134
- * 欠けたフィールドだけを vendor から補完する。
142
+ * 欠けたフィールドだけを vendor から補完する。preview-server だけは、asar 内の
143
+ * `lib/` 配置(checkout でも vendor でもない)からも見えるよう、Electron の
144
+ * resourcesPath を最後の探索先にする。
135
145
  */
136
146
  export function resolveLauncherAssets({
137
147
  candidateRoot = DEFAULT_REPO_ROOT_CANDIDATE,
138
- vendorRoot = DEFAULT_VENDOR_ROOT
148
+ vendorRoot = DEFAULT_VENDOR_ROOT,
149
+ // asar 内の `lib/` 配置では checkout 側にも vendor 側にも preview-server が無い。
150
+ // アプリの extraResources(Electron の resourcesPath)を最後の探索先にする。
151
+ resourcesPath = process.resourcesPath
139
152
  } = {}) {
140
153
  const candidate = resolveRepoAssets(candidateRoot);
141
154
  const vendor = resolveRepoAssets(vendorRoot);
142
155
  const candidateHasAssets = Object.entries(candidate)
143
156
  .some(([key, value]) => key !== 'repoRoot' && value !== null);
157
+ const resourcesPreviewServer = resourcesPath
158
+ ? path.join(resourcesPath, PREVIEW_SERVER_SCRIPT_RELATIVE)
159
+ : null;
160
+ const previewServerScript = candidate.previewServerScript ?? vendor.previewServerScript
161
+ ?? (resourcesPreviewServer && existsSync(resourcesPreviewServer) ? resourcesPreviewServer : null);
144
162
 
145
163
  return {
146
164
  repoRoot: candidateHasAssets ? candidateRoot : vendorRoot,
@@ -171,6 +189,7 @@ export function resolveLauncherAssets({
171
189
  ...(candidate.decisionLogScript ?? vendor.decisionLogScript ? { decisionLogScript: candidate.decisionLogScript ?? vendor.decisionLogScript } : {}),
172
190
  ...(candidate.wordBookScript ?? vendor.wordBookScript
173
191
  ? { wordBookScript: candidate.wordBookScript ?? vendor.wordBookScript }
174
- : {})
192
+ : {}),
193
+ ...(previewServerScript ? { previewServerScript } : {})
175
194
  };
176
195
  }