akari-video 1.5.1 → 1.5.2-beta.1
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.
- package/README.md +2 -2
- package/bin/akari.mjs +4 -0
- package/package.json +1 -1
- package/src/cli.mjs +4 -0
- package/src/lint-command.mjs +85 -0
- package/src/messages.mjs +1 -1
- package/src/narration-command.mjs +11 -7
- package/src/preview-command.mjs +281 -0
- package/src/repo-assets.mjs +24 -7
- package/src/status-core/status.mjs +2 -2
- package/src/store-command.mjs +1 -1
- package/src/tts-engines.mjs +39 -18
- package/vendor/.akari-capability-sources.json +34 -32
- package/vendor/catalog/audio/candidates-legacy.json +4 -4
- package/vendor/catalog/audio/candidates.html +1 -1
- package/vendor/catalog/audio/candidates.json +2 -2
- package/vendor/packages/akari-launcher/README.md +2 -2
- package/vendor/packages/akari-launcher/package.json +1 -1
- package/vendor/packages/akari-tools/bin/speakers.mjs +0 -0
- package/vendor/packages/audio-library-setup/README.md +1 -1
- package/vendor/packages/audio-library-setup/bin/fetch-akari-sounds.mjs +1 -1
- package/vendor/packages/audio-library-setup/bin/generate-candidates-html.mjs +1 -1
- package/vendor/packages/audio-library-setup/shared/akari-sounds.mjs +1 -1
- package/vendor/packages/audio-library-setup/shared/candidates.mjs +4 -4
- package/vendor/packages/creator-root/src/index.mjs +1 -1
- package/vendor/packages/creator-root/test/direct-tts-providers.test.mjs +3 -0
- package/vendor/packages/edit-lint/README.md +19 -1
- package/vendor/packages/edit-lint/src/edit-lint.mjs +143 -20
- package/vendor/packages/edit-lint/src/fix.mjs +252 -0
- package/vendor/packages/edit-lint/src/i18n.mjs +4 -0
- package/vendor/packages/edit-lint/src/lint/box-sizing-messages.json +4 -0
- package/vendor/packages/edit-lint/src/lint/caption-fonts.mjs +139 -0
- package/vendor/packages/edit-lint/src/lint/captions.mjs +5 -3
- package/vendor/packages/edit-lint/src/lint/cuts-tracks.mjs +76 -1
- package/vendor/packages/edit-lint/src/lint/fragment-box-sizing.mjs +385 -0
- package/vendor/packages/edit-lint/src/lint/fragment-css-collision.mjs +73 -0
- package/vendor/packages/edit-lint/src/lint/fragment-css.mjs +74 -0
- package/vendor/packages/edit-lint/src/lint/overlays.mjs +147 -7
- package/vendor/packages/edit-lint/src/lint/review.mjs +1 -1
- package/vendor/packages/edit-store/lib/internal-model.d.ts +15 -8
- package/vendor/packages/edit-store/lib/internal-model.js +94 -28
- package/vendor/packages/edit-store/lib/webview-kernel.js +24 -7
- package/vendor/packages/i18n/locales/en/cli.json +31 -3
- package/vendor/packages/i18n/locales/en/lint-messages.json +15 -1
- package/vendor/packages/i18n/locales/en/project.json +1 -0
- package/vendor/packages/i18n/locales/en/skills.json +21 -23
- package/vendor/packages/i18n/locales/en/tools.json +13 -1
- package/vendor/packages/i18n/locales/ja/cli.json +31 -3
- package/vendor/packages/i18n/locales/ja/lint-messages.json +15 -1
- package/vendor/packages/i18n/locales/ja/project.json +1 -0
- package/vendor/packages/i18n/locales/ja/skills.json +21 -23
- package/vendor/packages/i18n/locales/ja/tools.json +13 -1
- package/vendor/packages/overlay-runtime/README.md +44 -15
- package/vendor/packages/overlay-runtime/src/three-runtime.js +671 -40
- package/vendor/packages/overlay-runtime/src/vendor/three-bundle.js +978 -289
- package/vendor/packages/project-scaffold/src/index.mjs +34 -8
- package/vendor/packages/schemas/ai-models.json +19 -0
- package/vendor/packages/schemas/ai-models.schema.json +1 -0
- package/vendor/packages/schemas/examples/kit-manifest-v1-name-collision/manifest.json +1 -1
- package/vendor/packages/schemas/examples/kit-manifest-v1-name-collision/skills/{edit-lint → verify-edit}/SKILL.md +1 -1
- package/vendor/packages/schemas/review.schema.json +2 -2
- package/vendor/packages/schemas/skill-renames.mjs +393 -0
- package/vendor/packages/schemas/skill-renames.schema.json +43 -0
- package/vendor/packages/schemas/test/ai-models.test.mjs +20 -2
- package/vendor/packages/schemas/test/kit-manifest.test.mjs +1 -1
- package/vendor/packages/schemas/test/skill-renames.test.mjs +117 -0
- package/vendor/packages/schemas/test/validate-captions.test.mjs +1 -1
- package/vendor/packages/schemas/test/validate-review.test.mjs +2 -2
- package/vendor/skills/analyze-footage/bin/person-matte/resolve-packages.mjs +1 -1
- package/vendor/skills/author-scene3d/SKILL.md +45 -0
- package/vendor/skills/{bake-3d/SKILL.md → author-scene3d/bake.md} +11 -25
- package/vendor/skills/{overlay-authoring → author-scene3d}/device-materials.md +3 -3
- package/vendor/skills/author-scene3d/live.md +575 -0
- package/vendor/skills/declare-audio/SKILL.md +2 -2
- package/vendor/skills/{address-review → edit-from-review}/SKILL.md +6 -6
- package/vendor/skills/{address-review → edit-from-review}/bin/list.mjs +2 -2
- package/vendor/skills/{address-review → edit-from-review}/bin/respond.mjs +1 -1
- package/vendor/skills/edit-plan/SKILL.md +1 -1
- package/vendor/skills/edit-plan/autonomy.md +2 -2
- package/vendor/skills/edit-plan/avatar-resolution.md +1 -1
- package/vendor/skills/edit-plan/beat-sync.md +3 -3
- package/vendor/skills/edit-plan/execution.md +1 -1
- package/vendor/skills/edit-plan/expression-selection.md +3 -3
- package/vendor/skills/edit-plan/plan-json.md +1 -1
- package/vendor/skills/edit-plan/workflow.md +1 -1
- package/vendor/skills/{beat-sync-edit → edit-to-beat}/SKILL.md +2 -2
- package/vendor/skills/{beat-sync-edit → edit-to-beat}/pitfalls.md +1 -1
- package/vendor/skills/generate-image/SKILL.md +42 -0
- package/vendor/skills/generate-image/image.md +38 -0
- package/vendor/skills/generate-narration/SKILL.md +4 -4
- package/vendor/skills/generate-narration/engines.md +79 -63
- package/vendor/skills/generate-narration/lang/en.md +8 -6
- package/vendor/skills/generate-narration/lang/ja.md +17 -11
- package/vendor/skills/generate-narration/voice-profile-setup.md +3 -3
- package/vendor/skills/{generate-media → generate-video}/SKILL.md +8 -6
- package/vendor/skills/{generate-media → generate-video}/chain.md +1 -1
- package/vendor/skills/generate-video/engines.md +23 -0
- package/vendor/skills/generate-video/still.md +65 -0
- package/vendor/skills/overlay-authoring/3d.md +3 -575
- package/vendor/skills/overlay-authoring/SKILL.md +3 -3
- package/vendor/skills/overlay-authoring/dev-fixtures/test_device_materials.py +1 -1
- package/vendor/skills/overlay-authoring/telop.md +1 -1
- package/vendor/skills/renames.json +16 -0
- package/vendor/skills/render-cut/SKILL.md +2 -2
- package/vendor/skills/research-plan/SKILL.md +1 -1
- package/vendor/skills/research-plan/competitor.md +2 -2
- package/vendor/skills/research-plan/lang/ja.md +1 -1
- package/vendor/skills/research-plan/trends.md +1 -1
- package/vendor/skills/{critique-cut → review-cut}/SKILL.md +6 -6
- package/vendor/skills/{critique-cut → review-cut}/bin/index.js +1 -1
- package/vendor/skills/{critique-cut → review-cut}/workflow.md +3 -3
- package/vendor/skills/{compile-review-session → review-from-recording}/SKILL.md +5 -5
- package/vendor/skills/{compile-review-session → review-from-recording}/bin/compile-review-session.mjs +1 -1
- package/vendor/skills/{compile-review-session → review-from-recording}/bin/core/install-root.mjs +2 -2
- package/vendor/skills/{compile-review-session → review-from-recording}/dev-fixtures/README.md +4 -4
- package/vendor/skills/{compile-review-session → review-from-recording}/dev-fixtures/issue-69-review-json/README.md +6 -6
- package/vendor/skills/{compile-review-session → review-from-recording}/dev-fixtures/issue-69-review-json/reproduce.mjs +1 -1
- package/vendor/skills/review-from-recording/dev-fixtures/issue-79/README.md +3 -0
- package/vendor/skills/{compile-review-session → review-from-recording}/test/helpers/issue-79-fixture.mjs +1 -1
- package/vendor/skills/{compile-review-session → review-from-recording}/test/issue-79-snapshot.test.mjs +1 -1
- package/vendor/skills/setup-chat-approval/SKILL.md +2 -2
- package/vendor/skills/setup-chat-approval/bin/resolve-packages.mjs +1 -1
- package/vendor/skills/setup-chat-approval/setup-token.md +1 -1
- package/vendor/skills/{manage-connections → setup-connections}/SKILL.md +53 -7
- package/vendor/skills/{manage-connections → setup-connections}/bin/doctor.mjs +1 -1
- package/vendor/skills/{manage-connections → setup-connections}/bin/resolve-packages.mjs +1 -1
- package/vendor/skills/setup-connections/dev-fixtures/resolve-packages-newest/README.md +17 -0
- package/vendor/skills/{manage-connections → setup-connections}/dev-fixtures/resolve-packages-newest/reproduce.mjs +2 -2
- package/vendor/skills/{manage-connections → setup-connections}/test/resolve-packages-newest.test.mjs +1 -1
- package/vendor/skills/setup-library/SKILL.md +82 -1
- package/vendor/skills/{setup-audio-library/assisted-fetch.md → setup-library/audio-assisted-fetch.md} +2 -2
- package/vendor/skills/{setup-audio-library/candidate-list.md → setup-library/audio-candidate-list.md} +1 -1
- package/vendor/skills/{setup-audio-library/drop-folder.md → setup-library/audio-drop-folder.md} +3 -3
- package/vendor/skills/{setup-audio-library/gallery.md → setup-library/audio-gallery.md} +1 -1
- package/vendor/skills/setup-library/tools-check.md +1 -1
- package/vendor/skills/{edit-lint → verify-edit}/SKILL.md +2 -2
- package/vendor/skills/{verify → verify-project}/SKILL.md +2 -2
- package/vendor/templates/project-default/.claude/skills/README.md +4 -3
- package/vendor/templates/project-default/AGENTS.md +5 -4
- package/vendor/templates/project-default/CLAUDE.md +5 -4
- package/vendor/skills/compile-review-session/dev-fixtures/issue-79/README.md +0 -3
- package/vendor/skills/connect/SKILL.md +0 -24
- package/vendor/skills/generate-media/engines.md +0 -25
- package/vendor/skills/generate-media/still.md +0 -75
- package/vendor/skills/manage-connections/dev-fixtures/resolve-packages-newest/README.md +0 -17
- package/vendor/skills/setup-audio-library/SKILL.md +0 -96
- /package/vendor/skills/{overlay-authoring → author-scene3d}/scripts/device_materials.py +0 -0
- /package/vendor/skills/{address-review → edit-from-review}/bin/core/review-store.mjs +0 -0
- /package/vendor/skills/{address-review → edit-from-review}/dev-fixtures/fixture-project/captions.json +0 -0
- /package/vendor/skills/{address-review → edit-from-review}/dev-fixtures/fixture-project/edit.json +0 -0
- /package/vendor/skills/{address-review → edit-from-review}/dev-fixtures/fixture-project/review.json +0 -0
- /package/vendor/skills/{address-review → edit-from-review}/test/review-loss.test.mjs +0 -0
- /package/vendor/skills/{address-review → edit-from-review}/test/review-store.test.mjs +0 -0
- /package/vendor/skills/{beat-sync-edit → edit-to-beat}/generator.md +0 -0
- /package/vendor/skills/{beat-sync-edit → edit-to-beat}/templates/gen-timeline.mjs +0 -0
- /package/vendor/skills/{beat-sync-edit → edit-to-beat}/verify-loop.md +0 -0
- /package/vendor/skills/{generate-media → generate-video}/video.md +0 -0
- /package/vendor/skills/{critique-cut → review-cut}/bin/used-ranges.mjs +0 -0
- /package/vendor/skills/{critique-cut → review-cut}/bin/used-ranges.test.mjs +0 -0
- /package/vendor/skills/{compile-review-session → review-from-recording}/bin/core/canvas-compiler.mjs +0 -0
- /package/vendor/skills/{compile-review-session → review-from-recording}/bin/core/compiler.mjs +0 -0
- /package/vendor/skills/{compile-review-session → review-from-recording}/bin/core/review-store.mjs +0 -0
- /package/vendor/skills/{compile-review-session → review-from-recording}/bin/core/time-mapping.mjs +0 -0
- /package/vendor/skills/{compile-review-session → review-from-recording}/bin/core/transcription.mjs +0 -0
- /package/vendor/skills/{compile-review-session → review-from-recording}/compilation-rules.md +0 -0
- /package/vendor/skills/{compile-review-session → review-from-recording}/dev-fixtures/fixture-project/review/sessions/s-0001/audio.wav +0 -0
- /package/vendor/skills/{compile-review-session → review-from-recording}/dev-fixtures/fixture-project/review/sessions/s-0001/edit.snapshot.json +0 -0
- /package/vendor/skills/{compile-review-session → review-from-recording}/dev-fixtures/fixture-project/review/sessions/s-0001/events.jsonl +0 -0
- /package/vendor/skills/{compile-review-session → review-from-recording}/dev-fixtures/fixture-project/review/sessions/s-0001/session.json +0 -0
- /package/vendor/skills/{compile-review-session → review-from-recording}/dev-fixtures/fixture-project/review/sessions/s-0002/audio.wav +0 -0
- /package/vendor/skills/{compile-review-session → review-from-recording}/dev-fixtures/fixture-project/review/sessions/s-0002/edit.snapshot.json +0 -0
- /package/vendor/skills/{compile-review-session → review-from-recording}/dev-fixtures/fixture-project/review/sessions/s-0002/events.jsonl +0 -0
- /package/vendor/skills/{compile-review-session → review-from-recording}/dev-fixtures/fixture-project/review/sessions/s-0002/session.json +0 -0
- /package/vendor/skills/{compile-review-session → review-from-recording}/dev-fixtures/fixture-project/review/sessions/s-0003/audio.wav +0 -0
- /package/vendor/skills/{compile-review-session → review-from-recording}/dev-fixtures/fixture-project/review/sessions/s-0003/edit.snapshot.json +0 -0
- /package/vendor/skills/{compile-review-session → review-from-recording}/dev-fixtures/fixture-project/review/sessions/s-0003/events.jsonl +0 -0
- /package/vendor/skills/{compile-review-session → review-from-recording}/dev-fixtures/fixture-project/review/sessions/s-0003/session.json +0 -0
- /package/vendor/skills/{compile-review-session → review-from-recording}/dev-fixtures/fixture-project/review/sessions/s-0004/audio.wav +0 -0
- /package/vendor/skills/{compile-review-session → review-from-recording}/dev-fixtures/fixture-project/review/sessions/s-0004/edit.snapshot.json +0 -0
- /package/vendor/skills/{compile-review-session → review-from-recording}/dev-fixtures/fixture-project/review/sessions/s-0004/events.jsonl +0 -0
- /package/vendor/skills/{compile-review-session → review-from-recording}/dev-fixtures/fixture-project/review/sessions/s-0004/session.json +0 -0
- /package/vendor/skills/{compile-review-session → review-from-recording}/dev-fixtures/fixture-project/review/sessions/s-0005/session.json +0 -0
- /package/vendor/skills/{compile-review-session → review-from-recording}/dev-fixtures/fixture-project/review/sessions/s-0006/audio.wav +0 -0
- /package/vendor/skills/{compile-review-session → review-from-recording}/dev-fixtures/fixture-project/review/sessions/s-0006/events.jsonl +0 -0
- /package/vendor/skills/{compile-review-session → review-from-recording}/dev-fixtures/fixture-project/review/sessions/s-0006/session.json +0 -0
- /package/vendor/skills/{compile-review-session → review-from-recording}/dev-fixtures/fixture-project/review/sessions/s-0007/audio.wav +0 -0
- /package/vendor/skills/{compile-review-session → review-from-recording}/dev-fixtures/fixture-project/review/sessions/s-0007/edit.snapshot.json +0 -0
- /package/vendor/skills/{compile-review-session → review-from-recording}/dev-fixtures/fixture-project/review/sessions/s-0007/events.jsonl +0 -0
- /package/vendor/skills/{compile-review-session → review-from-recording}/dev-fixtures/fixture-project/review/sessions/s-0007/session.json +0 -0
- /package/vendor/skills/{compile-review-session → review-from-recording}/dev-fixtures/fixture-project/review/sessions/s-0008/audio.wav +0 -0
- /package/vendor/skills/{compile-review-session → review-from-recording}/dev-fixtures/fixture-project/review/sessions/s-0008/edit.snapshot.json +0 -0
- /package/vendor/skills/{compile-review-session → review-from-recording}/dev-fixtures/fixture-project/review/sessions/s-0008/events.jsonl +0 -0
- /package/vendor/skills/{compile-review-session → review-from-recording}/dev-fixtures/fixture-project/review/sessions/s-0008/session.json +0 -0
- /package/vendor/skills/{compile-review-session → review-from-recording}/dev-fixtures/fixture-project/review/sessions/s-0008/transcript.json +0 -0
- /package/vendor/skills/{compile-review-session → review-from-recording}/dev-fixtures/fixture-project/review/sessions/s-0009/audio.wav +0 -0
- /package/vendor/skills/{compile-review-session → review-from-recording}/dev-fixtures/fixture-project/review/sessions/s-0009/edit.snapshot.json +0 -0
- /package/vendor/skills/{compile-review-session → review-from-recording}/dev-fixtures/fixture-project/review/sessions/s-0009/events.jsonl +0 -0
- /package/vendor/skills/{compile-review-session → review-from-recording}/dev-fixtures/fixture-project/review/sessions/s-0009/session.json +0 -0
- /package/vendor/skills/{compile-review-session → review-from-recording}/dev-fixtures/fixture-project/review/sessions/s-0010/audio.wav +0 -0
- /package/vendor/skills/{compile-review-session → review-from-recording}/dev-fixtures/fixture-project/review/sessions/s-0010/edit.snapshot.json +0 -0
- /package/vendor/skills/{compile-review-session → review-from-recording}/dev-fixtures/fixture-project/review/sessions/s-0010/events.jsonl +0 -0
- /package/vendor/skills/{compile-review-session → review-from-recording}/dev-fixtures/fixture-project/review/sessions/s-0010/session.json +0 -0
- /package/vendor/skills/{compile-review-session → review-from-recording}/dev-fixtures/fixture-project/review.json +0 -0
- /package/vendor/skills/{compile-review-session → review-from-recording}/dev-fixtures/issue-79/reproduce.mjs +0 -0
- /package/vendor/skills/{compile-review-session → review-from-recording}/test/canvas-compiler.test.mjs +0 -0
- /package/vendor/skills/{compile-review-session → review-from-recording}/test/compiler.test.mjs +0 -0
- /package/vendor/skills/{compile-review-session → review-from-recording}/test/install-root.test.mjs +0 -0
- /package/vendor/skills/{compile-review-session → review-from-recording}/test/review-loss.test.mjs +0 -0
- /package/vendor/skills/{compile-review-session → review-from-recording}/test/ui-events.test.mjs +0 -0
- /package/vendor/skills/{manage-connections → setup-connections}/bin/resolve-connections.mjs +0 -0
- /package/vendor/skills/{manage-connections → setup-connections}/bin/test/doctor-i18n.test.mjs +0 -0
- /package/vendor/skills/{manage-connections → setup-connections}/bin/test/resolve-packages.test.mjs +0 -0
- /package/vendor/skills/{manage-connections → setup-connections}/test/connectors-doctor.test.mjs +0 -0
- /package/vendor/skills/{manage-connections → setup-connections}/test/direct-tts-doctor.test.mjs +0 -0
- /package/vendor/skills/{manage-connections → setup-connections}/test/doctor-key-source.test.mjs +0 -0
- /package/vendor/skills/{manage-connections → setup-connections}/test/fieldreport-report-location.test.mjs +0 -0
- /package/vendor/skills/{manage-connections → setup-connections}/test/resolve-connections-defaults.test.mjs +0 -0
- /package/vendor/skills/{manage-connections → setup-connections}/test/resolve-connections.test.mjs +0 -0
- /package/vendor/skills/{setup-audio-library/first-party.md → setup-library/audio-first-party.md} +0 -0
- /package/vendor/skills/{setup-audio-library/store-unlock.md → setup-library/audio-store-unlock.md} +0 -0
- /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/
|
|
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> ...`(
|
|
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)に保存し、購入済み一覧の確認と
|
package/bin/akari.mjs
CHANGED
|
@@ -17,6 +17,8 @@ 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 { runLintCommand } from '../src/lint-command.mjs';
|
|
21
|
+
import { runPreviewCommand } from '../src/preview-command.mjs';
|
|
20
22
|
import { runSkillsCommand, refreshEntrySkillOnLaunch } from '../src/skills-command.mjs';
|
|
21
23
|
import { resolveRuntimePaths } from '../src/runtime-diagnostics.mjs';
|
|
22
24
|
import { maybeApplyPendingUpdateOnLaunch, resolveInstalledVersionInfo } from '../src/update-check.mjs';
|
|
@@ -77,6 +79,8 @@ const commands = {
|
|
|
77
79
|
generate: runGenerateCommand,
|
|
78
80
|
storyboard: runStoryboardCommand,
|
|
79
81
|
world: runWorldCommand,
|
|
82
|
+
lint: runLintCommand,
|
|
83
|
+
preview: runPreviewCommand,
|
|
80
84
|
};
|
|
81
85
|
|
|
82
86
|
// トップレベルのフラグも、振り分けと候補判定に同じ表を使う。
|
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.1",
|
|
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,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', '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.
|
|
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 (
|
|
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 文字も出力しない(
|
|
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:
|
|
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.
|
|
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
|
+
}
|
package/src/repo-assets.mjs
CHANGED
|
@@ -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', '
|
|
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 と同型の解決方式。
|
|
@@ -48,13 +48,16 @@ export const GENERATE_CLI_RELATIVE = path.join('packages', 'generate', 'src', 'c
|
|
|
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
50
|
export const WORLD_VALIDATOR_RELATIVE = path.join('packages', 'schemas', 'bin', 'validate-world-map.mjs');
|
|
51
|
+
// ブラウザプレビューの実体。`akari preview` はこれを子プロセスで起動するだけで、
|
|
52
|
+
// サーバーを再実装しない(アプリでは extraResources、モノレポでは checkout から解決)。
|
|
53
|
+
export const PREVIEW_SERVER_SCRIPT_RELATIVE = path.join('packages', 'preview-server', 'src', 'server.mjs');
|
|
51
54
|
|
|
52
55
|
// launcher が直接または起動した CLI の子プロセスとして解決する実行体の正本。
|
|
53
56
|
// launcher-assets は resolveLauncherAssets() が資産フィールド単位で vendor を補完できる経路、
|
|
54
57
|
// resources は assets.repoRoot または実行中 CLI の位置から自己解決し、vendor を見ない経路。
|
|
55
58
|
// relative は上の解決定数だけから組み立て、配布検査と実行時解決の文字列を乖離させない。
|
|
56
59
|
export const LAUNCHER_SUBCOMMAND_EXECUTABLES = [
|
|
57
|
-
{ command: '接続 doctor(
|
|
60
|
+
{ command: '接続 doctor(setup-connections)', relative: DOCTOR_SCRIPT_RELATIVE, resolution: 'launcher-assets' },
|
|
58
61
|
{ command: 'akari new', relative: SCAFFOLD_MODULE_RELATIVE, resolution: 'launcher-assets' },
|
|
59
62
|
{ command: '初回動線(first-run)の作業場モジュール', relative: CREATOR_ROOT_MODULE_RELATIVE, resolution: 'launcher-assets' },
|
|
60
63
|
{ command: 'akari sounds', relative: AUDIO_FETCH_SCRIPT_RELATIVE, resolution: 'launcher-assets' },
|
|
@@ -74,7 +77,8 @@ export const LAUNCHER_SUBCOMMAND_EXECUTABLES = [
|
|
|
74
77
|
{ command: 'akari generate', relative: GENERATE_CLI_RELATIVE, resolution: 'launcher-assets' },
|
|
75
78
|
{ command: 'akari storyboard', relative: STORYBOARD_CLI_RELATIVE, resolution: 'launcher-assets' },
|
|
76
79
|
{ command: 'akari world', relative: WORLD_CLI_RELATIVE, resolution: 'resources' },
|
|
77
|
-
{ command: 'akari world check', relative: WORLD_VALIDATOR_RELATIVE, resolution: 'resources' }
|
|
80
|
+
{ command: 'akari world check', relative: WORLD_VALIDATOR_RELATIVE, resolution: 'resources' },
|
|
81
|
+
{ command: 'akari preview', relative: PREVIEW_SERVER_SCRIPT_RELATIVE, resolution: 'resources' }
|
|
78
82
|
];
|
|
79
83
|
|
|
80
84
|
/**
|
|
@@ -101,6 +105,7 @@ export function resolveRepoAssets(repoRoot = DEFAULT_REPO_ROOT_CANDIDATE) {
|
|
|
101
105
|
const wordBookScript = path.join(repoRoot, WORD_BOOK_SCRIPT_RELATIVE);
|
|
102
106
|
const generateScript = path.join(repoRoot, GENERATE_CLI_RELATIVE);
|
|
103
107
|
const storyboardScript = path.join(repoRoot, STORYBOARD_CLI_RELATIVE);
|
|
108
|
+
const previewServerScript = path.join(repoRoot, PREVIEW_SERVER_SCRIPT_RELATIVE);
|
|
104
109
|
|
|
105
110
|
return {
|
|
106
111
|
repoRoot,
|
|
@@ -124,23 +129,34 @@ export function resolveRepoAssets(repoRoot = DEFAULT_REPO_ROOT_CANDIDATE) {
|
|
|
124
129
|
...(existsSync(decisionLogScript) ? { decisionLogScript } : {}),
|
|
125
130
|
...(existsSync(wordBookScript) ? { wordBookScript } : {}),
|
|
126
131
|
...(existsSync(generateScript) ? { generateScript } : {}),
|
|
127
|
-
...(existsSync(storyboardScript) ? { storyboardScript } : {})
|
|
132
|
+
...(existsSync(storyboardScript) ? { storyboardScript } : {}),
|
|
133
|
+
...(existsSync(previewServerScript) ? { previewServerScript } : {})
|
|
128
134
|
};
|
|
129
135
|
}
|
|
130
136
|
|
|
131
137
|
/**
|
|
132
138
|
* ランチャー実行時の同梱物解決: 資産ごとにモノレポ checkout(開発時)→ vendor/
|
|
133
139
|
* (npm 配布時)の順で探す。checkout が一部の資産しか持たないパッケージ構成でも、
|
|
134
|
-
* 欠けたフィールドだけを vendor から補完する。
|
|
140
|
+
* 欠けたフィールドだけを vendor から補完する。preview-server だけは、asar 内の
|
|
141
|
+
* `lib/` 配置(checkout でも vendor でもない)からも見えるよう、Electron の
|
|
142
|
+
* resourcesPath を最後の探索先にする。
|
|
135
143
|
*/
|
|
136
144
|
export function resolveLauncherAssets({
|
|
137
145
|
candidateRoot = DEFAULT_REPO_ROOT_CANDIDATE,
|
|
138
|
-
vendorRoot = DEFAULT_VENDOR_ROOT
|
|
146
|
+
vendorRoot = DEFAULT_VENDOR_ROOT,
|
|
147
|
+
// asar 内の `lib/` 配置では checkout 側にも vendor 側にも preview-server が無い。
|
|
148
|
+
// アプリの extraResources(Electron の resourcesPath)を最後の探索先にする。
|
|
149
|
+
resourcesPath = process.resourcesPath
|
|
139
150
|
} = {}) {
|
|
140
151
|
const candidate = resolveRepoAssets(candidateRoot);
|
|
141
152
|
const vendor = resolveRepoAssets(vendorRoot);
|
|
142
153
|
const candidateHasAssets = Object.entries(candidate)
|
|
143
154
|
.some(([key, value]) => key !== 'repoRoot' && value !== null);
|
|
155
|
+
const resourcesPreviewServer = resourcesPath
|
|
156
|
+
? path.join(resourcesPath, PREVIEW_SERVER_SCRIPT_RELATIVE)
|
|
157
|
+
: null;
|
|
158
|
+
const previewServerScript = candidate.previewServerScript ?? vendor.previewServerScript
|
|
159
|
+
?? (resourcesPreviewServer && existsSync(resourcesPreviewServer) ? resourcesPreviewServer : null);
|
|
144
160
|
|
|
145
161
|
return {
|
|
146
162
|
repoRoot: candidateHasAssets ? candidateRoot : vendorRoot,
|
|
@@ -171,6 +187,7 @@ export function resolveLauncherAssets({
|
|
|
171
187
|
...(candidate.decisionLogScript ?? vendor.decisionLogScript ? { decisionLogScript: candidate.decisionLogScript ?? vendor.decisionLogScript } : {}),
|
|
172
188
|
...(candidate.wordBookScript ?? vendor.wordBookScript
|
|
173
189
|
? { wordBookScript: candidate.wordBookScript ?? vendor.wordBookScript }
|
|
174
|
-
: {})
|
|
190
|
+
: {}),
|
|
191
|
+
...(previewServerScript ? { previewServerScript } : {})
|
|
175
192
|
};
|
|
176
193
|
}
|
|
@@ -424,9 +424,9 @@ function routeForStage(stage, review, materials) {
|
|
|
424
424
|
interpretation_pending: [{ kind: "agent", action: "analyze-project", reason: "multiple materials require project interpretation" }, "analyze-project"],
|
|
425
425
|
planning_pending: [{ kind: "agent", action: "edit-plan", reason: materials.sources.length === 0 ? "zero-material planning has not started" : "plan.json is absent" }, "edit-plan"],
|
|
426
426
|
edit_pending: [{ kind: "agent", action: "edit-plan", reason: "edit.json is absent" }, "edit-plan"],
|
|
427
|
-
review_pending: [{ kind: "agent", action: "
|
|
427
|
+
review_pending: [{ kind: "agent", action: "edit-from-review", reason: `open review tickets: ${review.open}` }, "edit-from-review"],
|
|
428
428
|
human_review_pending: [{ kind: "human", action: "resolve-review", reason: `addressed review tickets: ${review.addressed}` }, null],
|
|
429
|
-
lint_pending: [{ kind: "agent", action: "edit
|
|
429
|
+
lint_pending: [{ kind: "agent", action: "verify-edit", reason: "current edit/review has no fresh PASS lint" }, "verify-edit"],
|
|
430
430
|
render_pending: [{ kind: "human", action: "render-cut", reason: "current render is not verified PASS" }, "render-cut"],
|
|
431
431
|
acceptance_pending: [{ kind: "human", action: "akari-accept", reason: "verified render needs final human acceptance" }, null],
|
|
432
432
|
};
|
package/src/store-command.mjs
CHANGED
|
@@ -48,7 +48,7 @@ export { readCredentials, resolveCredentialsPath } from './store-device-connect.
|
|
|
48
48
|
/**
|
|
49
49
|
* AKARI Store 連携(`akari store <connect|status|download|disconnect>`)。
|
|
50
50
|
*
|
|
51
|
-
* `connect` の既定は**デバイスコードフロー**(2026-08-03 オーナー要望「トークンの
|
|
51
|
+
* `akari store connect` の既定は**デバイスコードフロー**(2026-08-03 オーナー要望「トークンの
|
|
52
52
|
* 使い方とかみんなよくわからん」への回答): ブラウザが開き、ログイン → 承認ボタンで
|
|
53
53
|
* 完了する。トークンはユーザーの目に触れない。`--token akst_...` は上級者・自動化向けの
|
|
54
54
|
* 手動フォールバック。取得したトークンで本体から「何を購入済みか」(entitlements API)と
|