akari-video 1.3.0-beta.4 → 1.3.0-beta.5
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/bin/akari.mjs +3 -2
- package/package.json +4 -1
- package/src/assets-command.mjs +2 -1
- package/src/captions-command.mjs +2 -1
- package/src/capture-command.mjs +2 -6
- package/src/clean-command.mjs +38 -28
- package/src/cli.mjs +28 -21
- package/src/doctor-command.mjs +26 -25
- package/src/generate-command.mjs +2 -1
- package/src/history-policy.mjs +2 -0
- package/src/i18n.mjs +47 -0
- package/src/internal-command.mjs +8 -7
- package/src/kits.mjs +21 -20
- package/src/media-command.mjs +2 -1
- package/src/messages.mjs +87 -102
- package/src/migrate-command.mjs +22 -24
- package/src/narration-command.mjs +164 -149
- package/src/new-command.mjs +35 -18
- package/src/repo-assets.mjs +10 -0
- package/src/runtime-diagnostics.mjs +8 -7
- package/src/self-update.mjs +20 -19
- package/src/skills-command.mjs +12 -14
- package/src/speakers-command.mjs +17 -0
- package/src/store-command.mjs +59 -62
- package/src/store-device-connect.mjs +13 -12
- package/src/storyboard-command.mjs +4 -3
- package/src/task-labels.mjs +15 -8
- package/src/tools-command.mjs +17 -0
- package/src/tts-engines.mjs +32 -24
- package/src/update-check.mjs +3 -2
- package/src/vendor-sources.mjs +18 -1
- package/src/voice-command.mjs +83 -82
- package/src/world-command.mjs +2 -1
- package/vendor/.akari-capability-sources.json +18 -0
- package/vendor/docs/contract-2026-08-28-gpu-export-v0.md +3 -0
- package/vendor/docs/contract-2026-10-10-channel-people-design-v0.md +41 -0
- package/vendor/docs/contract-2026-10-11-content-language.md +13 -0
- package/vendor/docs/contract-2026-10-11-speaker-split-v0.md +112 -0
- package/vendor/docs/contract-2026-10-11-ui-i18n.md +15 -0
- package/vendor/packages/akari-launcher/package.json +4 -1
- package/vendor/packages/akari-launcher/src/history-policy.mjs +2 -0
- package/vendor/packages/akari-tools/bin/speakers.mjs +91 -0
- package/vendor/packages/akari-tools/bin/tools.mjs +304 -0
- package/vendor/packages/akari-tools/package.json +4 -1
- package/vendor/packages/akari-tools/src/common/main-module.mjs +11 -0
- package/vendor/packages/akari-tools/src/decision-log/i18n.mjs +15 -0
- package/vendor/packages/akari-tools/src/i18n.mjs +24 -0
- package/vendor/packages/akari-tools/src/media/common.mjs +227 -0
- package/vendor/packages/akari-voice/package.json +11 -0
- package/vendor/packages/akari-voice/src/audio.mjs +38 -0
- package/vendor/packages/akari-voice/src/centroids.mjs +62 -0
- package/vendor/packages/akari-voice/src/diarize.mjs +102 -0
- package/vendor/packages/akari-voice/src/dictionary.mjs +22 -0
- package/vendor/packages/akari-voice/src/embed.mjs +77 -0
- package/vendor/packages/akari-voice/src/fbank.mjs +100 -0
- package/vendor/packages/akari-voice/src/identify.mjs +38 -0
- package/vendor/packages/akari-voice/src/index.mjs +9 -0
- package/vendor/packages/akari-voice/src/voice-home.mjs +56 -0
- package/vendor/packages/akari-voice/src/voices-file.mjs +41 -0
- package/vendor/packages/analysis-report/render-analysis-report.mjs +11 -3
- package/vendor/packages/analysis-report/report-i18n.mjs +61 -0
- package/vendor/packages/analysis-report/template.html +21 -21
- package/vendor/packages/asset-resolver/src/project-root.mjs +26 -0
- package/vendor/packages/asset-resolver/test/project-root.test.mjs +109 -0
- package/vendor/packages/content-language/README.md +9 -0
- package/vendor/packages/content-language/package.json +13 -0
- package/vendor/packages/content-language/src/caption-defaults.json +16 -0
- package/vendor/packages/content-language/src/index.mjs +42 -0
- package/vendor/packages/content-language/src/node.mjs +104 -0
- package/vendor/packages/content-language/test/content-language.test.mjs +114 -0
- package/vendor/packages/decision-log-report/render-decision-log-report.mjs +38 -33
- package/vendor/packages/decision-log-report/template.html +19 -19
- package/vendor/packages/edit-lint/README.md +1 -0
- package/vendor/packages/edit-lint/src/edit-lint.mjs +13 -11
- package/vendor/packages/edit-lint/src/engine-capabilities.json +1 -0
- package/vendor/packages/edit-lint/src/i18n.mjs +29 -0
- package/vendor/packages/edit-lint/src/license-findings.mjs +4 -3
- package/vendor/packages/edit-lint/src/lint/captions.mjs +27 -9
- package/vendor/packages/edit-lint/src/lint/cuts-tracks.mjs +4 -5
- package/vendor/packages/edit-lint/src/lint/edit-v2.mjs +18 -8
- package/vendor/packages/edit-lint/src/lint/engine-capabilities.mjs +8 -5
- package/vendor/packages/edit-lint/src/lint/intake.mjs +5 -3
- package/vendor/packages/edit-lint/src/lint/look-adjust.mjs +6 -5
- package/vendor/packages/edit-lint/src/lint/media-checks.mjs +10 -10
- package/vendor/packages/edit-lint/src/lint/overlays.mjs +13 -12
- package/vendor/packages/edit-lint/src/lint/review.mjs +2 -1
- package/vendor/packages/edit-lint/src/lint/shared.mjs +2 -1
- package/vendor/packages/edit-lint/src/lint/v2-projection.mjs +8 -7
- package/vendor/packages/edit-lint/src/report.mjs +12 -11
- package/vendor/packages/edit-lint/src/world-scene-declaration.mjs +20 -18
- package/vendor/packages/edit-store/lib/caption-display.js +27 -6
- package/vendor/packages/edit-store/lib/edit-v2-item-write.d.ts +3 -0
- package/vendor/packages/edit-store/lib/edit-v2-item-write.js +15 -3
- package/vendor/packages/edit-store/lib/edit-v2.d.ts +3 -0
- package/vendor/packages/edit-store/lib/edit-v2.js +9 -0
- package/vendor/packages/edit-store/lib/generated/edit-v2-keys.d.ts +1 -1
- package/vendor/packages/edit-store/lib/generated/edit-v2-keys.js +1 -1
- package/vendor/packages/edit-store/lib/transform-keyframe-edit.d.ts +17 -2
- package/vendor/packages/edit-store/lib/transform-keyframe-edit.js +102 -7
- package/vendor/packages/edit-store/lib/webview-kernel.js +33 -0
- package/vendor/packages/i18n/index.cjs +107 -0
- package/vendor/packages/i18n/index.d.ts +13 -0
- package/vendor/packages/i18n/index.mjs +2 -0
- package/vendor/packages/i18n/locales/en/annotations.json +1149 -0
- package/vendor/packages/i18n/locales/en/annotationscommon.json +896 -0
- package/vendor/packages/i18n/locales/en/cli.json +734 -0
- package/vendor/packages/i18n/locales/en/common.json +6 -0
- package/vendor/packages/i18n/locales/en/companion.json +19 -0
- package/vendor/packages/i18n/locales/en/decision-log.json +28 -0
- package/vendor/packages/i18n/locales/en/inspector.json +1324 -0
- package/vendor/packages/i18n/locales/en/lint-messages.json +146 -0
- package/vendor/packages/i18n/locales/en/lint.json +14 -0
- package/vendor/packages/i18n/locales/en/partner.json +287 -0
- package/vendor/packages/i18n/locales/en/preview.json +675 -0
- package/vendor/packages/i18n/locales/en/project.json +873 -0
- package/vendor/packages/i18n/locales/en/render.json +116 -0
- package/vendor/packages/i18n/locales/en/report-analysis.json +114 -0
- package/vendor/packages/i18n/locales/en/report-cards.json +328 -0
- package/vendor/packages/i18n/locales/en/report-decision.json +46 -0
- package/vendor/packages/i18n/locales/en/report-project.json +22 -0
- package/vendor/packages/i18n/locales/en/settings.json +6 -0
- package/vendor/packages/i18n/locales/en/shell.json +558 -0
- package/vendor/packages/i18n/locales/en/skills.json +54 -0
- package/vendor/packages/i18n/locales/en/surfaces.json +2226 -0
- package/vendor/packages/i18n/locales/en/tabs.json +5 -0
- package/vendor/packages/i18n/locales/en/theme.json +32 -0
- package/vendor/packages/i18n/locales/en/tools.json +245 -0
- package/vendor/packages/i18n/locales/en/transcript.json +755 -0
- package/vendor/packages/i18n/locales/en/vibe.json +290 -0
- package/vendor/packages/i18n/locales/en/world.json +22 -0
- package/vendor/packages/i18n/locales/index.cjs +63 -0
- package/vendor/packages/i18n/locales/ja/annotations.json +1149 -0
- package/vendor/packages/i18n/locales/ja/annotationscommon.json +896 -0
- package/vendor/packages/i18n/locales/ja/cli.json +734 -0
- package/vendor/packages/i18n/locales/ja/common.json +6 -0
- package/vendor/packages/i18n/locales/ja/companion.json +19 -0
- package/vendor/packages/i18n/locales/ja/decision-log.json +28 -0
- package/vendor/packages/i18n/locales/ja/inspector.json +1324 -0
- package/vendor/packages/i18n/locales/ja/lint-messages.json +146 -0
- package/vendor/packages/i18n/locales/ja/lint.json +14 -0
- package/vendor/packages/i18n/locales/ja/partner.json +287 -0
- package/vendor/packages/i18n/locales/ja/preview.json +675 -0
- package/vendor/packages/i18n/locales/ja/project.json +873 -0
- package/vendor/packages/i18n/locales/ja/render.json +116 -0
- package/vendor/packages/i18n/locales/ja/report-analysis.json +114 -0
- package/vendor/packages/i18n/locales/ja/report-cards.json +328 -0
- package/vendor/packages/i18n/locales/ja/report-decision.json +46 -0
- package/vendor/packages/i18n/locales/ja/report-project.json +22 -0
- package/vendor/packages/i18n/locales/ja/settings.json +6 -0
- package/vendor/packages/i18n/locales/ja/shell.json +558 -0
- package/vendor/packages/i18n/locales/ja/skills.json +54 -0
- package/vendor/packages/i18n/locales/ja/surfaces.json +2226 -0
- package/vendor/packages/i18n/locales/ja/tabs.json +5 -0
- package/vendor/packages/i18n/locales/ja/theme.json +32 -0
- package/vendor/packages/i18n/locales/ja/tools.json +245 -0
- package/vendor/packages/i18n/locales/ja/transcript.json +755 -0
- package/vendor/packages/i18n/locales/ja/vibe.json +290 -0
- package/vendor/packages/i18n/locales/ja/world.json +22 -0
- package/vendor/packages/i18n/package.json +16 -0
- package/vendor/packages/i18n/test/catalog-loader.test.mjs +78 -0
- package/vendor/packages/i18n/test/child-process-language.test.mjs +37 -0
- package/vendor/packages/i18n/test/i18n.test.mjs +149 -0
- package/vendor/packages/media-bin/bin/audio-measure.mjs +4 -7
- package/vendor/packages/media-bin/test/audio-measure.test.mjs +26 -0
- package/vendor/packages/overlay-runtime/runtimes.mjs +49 -12
- package/vendor/packages/overlay-runtime/src/interaction.css +17 -0
- package/vendor/packages/overlay-runtime/src/interaction.js +451 -12
- package/vendor/packages/overlay-runtime/src/item-motion.js +32 -1
- package/vendor/packages/overlay-runtime/src/overlay-runtime.js +37 -1
- package/vendor/packages/overlay-runtime/src/parts.mjs +3 -1
- package/vendor/packages/overlay-runtime/src/text-split.js +9 -4
- package/vendor/packages/overlay-runtime/src/three-runtime.js +395 -9
- package/vendor/packages/project-scaffold/src/index.mjs +51 -25
- package/vendor/packages/render-cut/src/fragment-assets.mjs +5 -4
- package/vendor/packages/render-cut/src/i18n.mjs +23 -0
- package/vendor/packages/render-cut/src/render-inputs.mjs +9 -2
- package/vendor/packages/schemas/analysis.schema.json +5 -0
- package/vendor/packages/schemas/bin/validate-captions.mjs +6 -19
- package/vendor/packages/schemas/bin/validate-intake.mjs +11 -1
- package/vendor/packages/schemas/edit.schema.json +6 -0
- package/vendor/packages/schemas/engine-capabilities.json +1 -0
- package/vendor/packages/schemas/intake.schema.json +5 -0
- package/vendor/packages/schemas/test/content-language.test.mjs +44 -0
- package/vendor/packages/schemas/test/engine-capabilities.test.mjs +1 -1
- package/vendor/packages/schemas/test/fixtures/content-language/analysis.json +9 -0
- package/vendor/packages/schemas/test/fixtures/content-language/intake.json +9 -0
- package/vendor/packages/schemas/test/validate-captions.test.mjs +8 -0
- package/vendor/packages/word-book/src/index.mjs +5 -5
- package/vendor/skills/address-review/SKILL.md +53 -55
- package/vendor/skills/akari/SKILL.md +86 -75
- package/vendor/skills/analyze-footage/SKILL.md +44 -40
- package/vendor/skills/analyze-footage/analysis-json.md +49 -48
- package/vendor/skills/analyze-footage/bin/speechanalyzer-helper.swift +9 -4
- package/vendor/skills/analyze-footage/bin/test/transcribe-sa-locale.test.mjs +166 -0
- package/vendor/skills/analyze-footage/bin/transcribe-sa.mjs +47 -16
- package/vendor/skills/analyze-footage/events-and-hooks.md +75 -82
- package/vendor/skills/analyze-footage/keyframes-and-review.md +41 -50
- package/vendor/skills/analyze-footage/lang/en.md +23 -0
- package/vendor/skills/analyze-footage/lang/ja.md +9 -0
- package/vendor/skills/analyze-footage/media-and-transcript.md +65 -43
- package/vendor/skills/analyze-footage/person-matte.md +96 -145
- package/vendor/skills/analyze-footage/references/akari-data-contract.md +3 -2
- package/vendor/skills/analyze-footage/vision-tracks.md +107 -216
- package/vendor/skills/analyze-footage/workflow.md +65 -64
- package/vendor/skills/analyze-project/SKILL.md +59 -61
- package/vendor/skills/analyze-project/collect.md +31 -35
- package/vendor/skills/analyze-project/decision-record.md +43 -42
- package/vendor/skills/analyze-project/interpretation.md +122 -132
- package/vendor/skills/analyze-project/interview.md +44 -46
- package/vendor/skills/analyze-project/references/interpretation-shape.md +15 -17
- package/vendor/skills/analyze-project/references/open-questions-examples.md +26 -26
- package/vendor/skills/analyze-project/validate-and-render.md +37 -38
- package/vendor/skills/bake-3d/SKILL.md +49 -55
- package/vendor/skills/beat-sync-edit/SKILL.md +50 -64
- package/vendor/skills/beat-sync-edit/generator.md +38 -48
- package/vendor/skills/beat-sync-edit/pitfalls.md +32 -37
- package/vendor/skills/beat-sync-edit/verify-loop.md +30 -43
- package/vendor/skills/compile-review-session/SKILL.md +44 -46
- package/vendor/skills/compile-review-session/compilation-rules.md +141 -146
- package/vendor/skills/create-project/SKILL.md +58 -54
- package/vendor/skills/critique-cut/SKILL.md +62 -66
- package/vendor/skills/critique-cut/workflow.md +65 -67
- package/vendor/skills/declare-audio/SKILL.md +32 -52
- package/vendor/skills/declare-audio/after-save.md +24 -35
- package/vendor/skills/declare-audio/launch.md +29 -40
- package/vendor/skills/declare-audio/what-to-declare.md +30 -38
- package/vendor/skills/design-world/SKILL.md +31 -33
- package/vendor/skills/design-world/guide.md +12 -9
- package/vendor/skills/design-world/world.md +30 -32
- package/vendor/skills/edit-lint/SKILL.md +112 -100
- package/vendor/skills/edit-lint/preview.md +26 -26
- package/vendor/skills/edit-plan/SKILL.md +41 -80
- package/vendor/skills/edit-plan/approvals-and-generation.md +57 -66
- package/vendor/skills/edit-plan/autonomy.md +46 -46
- package/vendor/skills/edit-plan/avatar-resolution.md +91 -150
- package/vendor/skills/edit-plan/beat-sync.md +275 -436
- package/vendor/skills/edit-plan/beats.md +63 -101
- package/vendor/skills/edit-plan/emphasis-detection.md +110 -169
- package/vendor/skills/edit-plan/execution.md +94 -132
- package/vendor/skills/edit-plan/expression-selection.md +138 -218
- package/vendor/skills/edit-plan/lang/en.md +17 -0
- package/vendor/skills/edit-plan/lang/ja.md +76 -0
- package/vendor/skills/edit-plan/plan-json.md +29 -51
- package/vendor/skills/edit-plan/recipe.md +38 -70
- package/vendor/skills/edit-plan/report-guide.md +126 -182
- package/vendor/skills/edit-plan/workflow.md +54 -95
- package/vendor/skills/export-nle/SKILL.md +52 -68
- package/vendor/skills/generate-media/SKILL.md +28 -28
- package/vendor/skills/generate-media/chain.md +20 -20
- package/vendor/skills/generate-media/engines.md +17 -15
- package/vendor/skills/generate-media/still.md +25 -29
- package/vendor/skills/generate-media/video.md +25 -26
- package/vendor/skills/generate-narration/SKILL.md +28 -30
- package/vendor/skills/generate-narration/avatar-voice.md +25 -41
- package/vendor/skills/generate-narration/engines.md +85 -125
- package/vendor/skills/generate-narration/lang/en.md +23 -0
- package/vendor/skills/generate-narration/lang/ja.md +68 -0
- package/vendor/skills/generate-narration/reading-text.md +14 -29
- package/vendor/skills/generate-narration/voice-profile-setup.md +47 -69
- package/vendor/skills/harvest-asset/SKILL.md +105 -82
- package/vendor/skills/manage-connections/SKILL.md +89 -96
- package/vendor/skills/manage-connections/bin/doctor.mjs +105 -50
- package/vendor/skills/manage-connections/bin/test/doctor-i18n.test.mjs +76 -0
- package/vendor/skills/overlay-authoring/3d.md +284 -516
- package/vendor/skills/overlay-authoring/SKILL.md +42 -47
- package/vendor/skills/overlay-authoring/device-materials.md +16 -38
- package/vendor/skills/overlay-authoring/glass.md +34 -58
- package/vendor/skills/overlay-authoring/lang/en.md +40 -0
- package/vendor/skills/overlay-authoring/lang/ja.md +58 -0
- package/vendor/skills/overlay-authoring/motion.md +97 -116
- package/vendor/skills/overlay-authoring/table.md +32 -32
- package/vendor/skills/overlay-authoring/telop.md +115 -154
- package/vendor/skills/overlay-authoring/text-behind-person.md +96 -137
- package/vendor/skills/overlay-authoring/thumbnail.md +72 -72
- package/vendor/skills/overlay-authoring/world.md +14 -39
- package/vendor/skills/render-cut/SKILL.md +63 -89
- package/vendor/skills/research-plan/SKILL.md +53 -49
- package/vendor/skills/research-plan/competitor.md +29 -34
- package/vendor/skills/research-plan/ideate.md +32 -37
- package/vendor/skills/research-plan/lang/en.md +5 -0
- package/vendor/skills/research-plan/lang/ja.md +14 -0
- package/vendor/skills/research-plan/shotlist.md +28 -28
- package/vendor/skills/research-plan/storyboard.md +50 -49
- package/vendor/skills/research-plan/trends.md +21 -21
- package/vendor/skills/setup-audio-library/SKILL.md +76 -88
- package/vendor/skills/setup-audio-library/assisted-fetch.md +39 -42
- package/vendor/skills/setup-audio-library/candidate-list.md +36 -40
- package/vendor/skills/setup-audio-library/drop-folder.md +43 -51
- package/vendor/skills/setup-audio-library/first-party.md +42 -42
- package/vendor/skills/setup-audio-library/gallery.md +31 -37
- package/vendor/skills/setup-audio-library/store-unlock.md +24 -25
- package/vendor/skills/setup-chat-approval/SKILL.md +27 -27
- package/vendor/skills/setup-chat-approval/setup-token.md +34 -34
- package/vendor/skills/setup-chat-approval/smoke-test.md +25 -25
- package/vendor/skills/setup-library/SKILL.md +32 -32
- package/vendor/skills/setup-library/fetch-and-validate.md +73 -57
- package/vendor/skills/setup-library/starter-pack.md +35 -32
- package/vendor/skills/setup-library/tools-check.md +52 -49
- package/vendor/skills/setup-remote/SKILL.md +28 -28
- package/vendor/skills/setup-remote/doctor-and-install.md +28 -28
- package/vendor/skills/setup-remote/serve-preview.md +35 -34
- package/vendor/skills/setup-remote/taildrop-inbox.md +40 -38
- package/vendor/skills/verify/SKILL.md +197 -128
- package/vendor/templates/project-default/.claude/settings.json +3 -1
- package/vendor/templates/project-default/AGENTS.md +83 -83
- package/vendor/templates/project-default/CLAUDE.md +58 -57
- package/vendor/templates/project-default/akari.sh +54 -41
- package/vendor/packages/project-scaffold/test/create-project.test.mjs +0 -193
- package/vendor/packages/project-scaffold/test/hidden-adapters.test.mjs +0 -16
- package/vendor/packages/project-scaffold/test/kit-skill-adapter.test.mjs +0 -38
- package/vendor/packages/project-scaffold/test/opencode-scaffold.test.mjs +0 -94
- package/vendor/packages/project-scaffold/test/skill-adapter-link.test.mjs +0 -210
package/bin/akari.mjs
CHANGED
|
@@ -22,6 +22,7 @@ import { resolveRuntimePaths } from '../src/runtime-diagnostics.mjs';
|
|
|
22
22
|
import { maybeApplyPendingUpdateOnLaunch, resolveInstalledVersionInfo } from '../src/update-check.mjs';
|
|
23
23
|
import { describeCliHelp, describeInstalledVersions, firstArgumentTypoError } from '../src/messages.mjs';
|
|
24
24
|
import { suggestFirstArgument } from '../src/first-arg-guard.mjs';
|
|
25
|
+
import { cliText } from '../src/i18n.mjs';
|
|
25
26
|
|
|
26
27
|
// `akari --version` / `-v`: インストール済みの版を表示するだけの最小コマンド
|
|
27
28
|
// (タスク契約 2026-08-11-update-u4-cli-self-update の受け入れ条件 —
|
|
@@ -41,8 +42,8 @@ async function printVersion() {
|
|
|
41
42
|
// `--help` は claude/opencode へそのまま転送されてしまっていた — AKARI Video 自身の
|
|
42
43
|
// コマンド一覧が一度も出ない行き止まりだったため新設した)。
|
|
43
44
|
async function printCliHelp() {
|
|
44
|
-
for (const line of [...describeCliHelp(), '
|
|
45
|
-
'
|
|
45
|
+
for (const line of [...describeCliHelp(), cliText('cli.help.commands.world'),
|
|
46
|
+
cliText('cli.help.commands.skills')]) {
|
|
46
47
|
console.log(line);
|
|
47
48
|
}
|
|
48
49
|
return { exitCode: 0 };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "akari-video",
|
|
3
|
-
"version": "1.3.0-beta.
|
|
3
|
+
"version": "1.3.0-beta.5",
|
|
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": {
|
|
@@ -34,6 +34,9 @@
|
|
|
34
34
|
"engines": {
|
|
35
35
|
"node": ">=20"
|
|
36
36
|
},
|
|
37
|
+
"devDependencies": {
|
|
38
|
+
"@akari-video/content-language": "0.0.0"
|
|
39
|
+
},
|
|
37
40
|
"scripts": {
|
|
38
41
|
"prepack": "node scripts/prepack.mjs",
|
|
39
42
|
"postpack": "node scripts/prepack.mjs clean",
|
package/src/assets-command.mjs
CHANGED
|
@@ -3,6 +3,7 @@ import { dirname, resolve } from 'node:path';
|
|
|
3
3
|
import { pathToFileURL } from 'node:url';
|
|
4
4
|
|
|
5
5
|
import { resolveLauncherAssets } from './repo-assets.mjs';
|
|
6
|
+
import { cliText } from './i18n.mjs';
|
|
6
7
|
import { assetsResolverUnavailableError } from './messages.mjs';
|
|
7
8
|
|
|
8
9
|
/**
|
|
@@ -35,7 +36,7 @@ export async function runAssetsCommand(args, options = {}) {
|
|
|
35
36
|
// first-party Sounds fetcher, while the resolver catalog contains only individual IDs.
|
|
36
37
|
if (args[0] === 'fetch' && /^akari-sounds-[a-z0-9-]+$/u.test(args[1] ?? '')) {
|
|
37
38
|
if (!assets?.audioFetchScriptPath) {
|
|
38
|
-
logError('
|
|
39
|
+
logError(cliText('cli.assets.error.soundsScriptMissing'));
|
|
39
40
|
return { exitCode: 1 };
|
|
40
41
|
}
|
|
41
42
|
const spawn = options.spawnSoundsCli ?? defaultSpawnAssetsCli;
|
package/src/captions-command.mjs
CHANGED
|
@@ -2,12 +2,13 @@ import { spawnSync } from "node:child_process";
|
|
|
2
2
|
import { existsSync } from "node:fs";
|
|
3
3
|
|
|
4
4
|
import { resolveLauncherAssets } from "./repo-assets.mjs";
|
|
5
|
+
import { cliText } from './i18n.mjs';
|
|
5
6
|
|
|
6
7
|
export async function runCaptionsCommand(argv, options = {}) {
|
|
7
8
|
const logError = options.error ?? options.logError ?? ((line) => console.error(line));
|
|
8
9
|
const assets = options.assets ?? resolveLauncherAssets();
|
|
9
10
|
if (!assets.captionsScript || !existsSync(assets.captionsScript)) {
|
|
10
|
-
logError(
|
|
11
|
+
logError(cliText('cli.captions.error.scriptMissing'));
|
|
11
12
|
return { exitCode: 1 };
|
|
12
13
|
}
|
|
13
14
|
|
package/src/capture-command.mjs
CHANGED
|
@@ -2,6 +2,7 @@ import { spawnSync } from "node:child_process";
|
|
|
2
2
|
import { existsSync } from "node:fs";
|
|
3
3
|
|
|
4
4
|
import { CAPTURE_SCRIPT_RELATIVE, resolveLauncherAssets } from "./repo-assets.mjs";
|
|
5
|
+
import { cliText } from './i18n.mjs';
|
|
5
6
|
|
|
6
7
|
export async function runCaptureCommand(argv, options = {}) {
|
|
7
8
|
const logError = options.error ?? options.logError ?? ((line) => console.error(line));
|
|
@@ -10,12 +11,7 @@ export async function runCaptureCommand(argv, options = {}) {
|
|
|
10
11
|
// 再インストールで直る欠けではない(同梱漏れは配布物側の問題)。欠けている同梱物と
|
|
11
12
|
// 探索した置き場を名指しして、報告・切り分けに使える形で止める(issue #74)。
|
|
12
13
|
const missing = assets.captureScript ?? CAPTURE_SCRIPT_RELATIVE;
|
|
13
|
-
logError(
|
|
14
|
-
`akari capture の実行スクリプトが見つかりません: ${missing}`
|
|
15
|
-
+ `(探索先: ${assets.repoRoot ?? "不明"})。`
|
|
16
|
-
+ "この AKARI Video 配布物に packages/akari-tools/bin/capture.mjs が同梱されていません。"
|
|
17
|
-
+ "バージョンと OS を添えて https://github.com/AkariLabs/akari-video/issues へ報告してください。",
|
|
18
|
-
);
|
|
14
|
+
logError(cliText('cli.capture.error.scriptMissing', { missing, root: assets.repoRoot ?? cliText('cli.capture.label.unknown') }));
|
|
19
15
|
return { exitCode: 1 };
|
|
20
16
|
}
|
|
21
17
|
|
package/src/clean-command.mjs
CHANGED
|
@@ -3,6 +3,7 @@ import path from 'node:path';
|
|
|
3
3
|
import { createInterface } from 'node:readline/promises';
|
|
4
4
|
|
|
5
5
|
import { classifyProject } from './clean-manifest.mjs';
|
|
6
|
+
import { cliText, cliValue } from './i18n.mjs';
|
|
6
7
|
|
|
7
8
|
export async function runCleanCommand(args, options = {}) {
|
|
8
9
|
const log = options.log ?? ((line) => console.log(line));
|
|
@@ -24,7 +25,7 @@ export async function runCleanCommand(args, options = {}) {
|
|
|
24
25
|
const editStat = await statPath(path.join(parsed.projectRoot, 'edit.json'));
|
|
25
26
|
if (!editStat.isFile()) throw Object.assign(new Error('not a file'), { code: 'ENOENT' });
|
|
26
27
|
} catch {
|
|
27
|
-
error(
|
|
28
|
+
error(cliText('cli.clean.error.editMissing', { root: parsed.projectRoot }));
|
|
28
29
|
return { exitCode: 2 };
|
|
29
30
|
}
|
|
30
31
|
|
|
@@ -37,32 +38,32 @@ export async function runCleanCommand(args, options = {}) {
|
|
|
37
38
|
readFile: options.readFile,
|
|
38
39
|
});
|
|
39
40
|
} catch (cause) {
|
|
40
|
-
error(
|
|
41
|
+
error(cliText('cli.clean.error.inspectFailed', { message: messageOf(cause) }));
|
|
41
42
|
return { exitCode: 2 };
|
|
42
43
|
}
|
|
43
44
|
|
|
44
45
|
if (parsed.json) {
|
|
45
|
-
log(JSON.stringify(classification));
|
|
46
|
+
log(JSON.stringify(localizeClassification(classification)));
|
|
46
47
|
} else {
|
|
47
48
|
for (const line of formatClassification(classification)) log(line);
|
|
48
49
|
for (const warning of provenanceWarnings(classification)) log(warning);
|
|
49
50
|
}
|
|
50
51
|
|
|
51
52
|
if (parsed.dryRun || classification.disposable.length === 0) {
|
|
52
|
-
if (!parsed.json && classification.disposable.length === 0) log('
|
|
53
|
+
if (!parsed.json && classification.disposable.length === 0) log(cliText('cli.clean.status.nothingToDelete'));
|
|
53
54
|
return { exitCode: 0, classification, removed: [], failures: [] };
|
|
54
55
|
}
|
|
55
56
|
|
|
56
57
|
if (!parsed.yes) {
|
|
57
58
|
const isTTY = options.isTTY ?? Boolean(process.stdin.isTTY && process.stdout.isTTY);
|
|
58
59
|
if (!isTTY) {
|
|
59
|
-
error('
|
|
60
|
+
error(cliText('cli.clean.error.approvalRequired'));
|
|
60
61
|
return { exitCode: 2, classification, removed: [], failures: [] };
|
|
61
62
|
}
|
|
62
63
|
const answer = options.prompt ? await options.prompt() : await promptForConfirmation();
|
|
63
64
|
const accepted = typeof answer === 'boolean' ? answer : /^(?:y|yes)$/iu.test(String(answer).trim());
|
|
64
65
|
if (!accepted) {
|
|
65
|
-
if (!parsed.json) log('
|
|
66
|
+
if (!parsed.json) log(cliText('cli.clean.status.cancelled'));
|
|
66
67
|
return { exitCode: 0, classification, removed: [], failures: [] };
|
|
67
68
|
}
|
|
68
69
|
}
|
|
@@ -75,7 +76,7 @@ export async function runCleanCommand(args, options = {}) {
|
|
|
75
76
|
if (!isInside(parsed.projectRoot, target) || target === parsed.projectRoot) {
|
|
76
77
|
const failure = { path: entry.path, code: 'OUTSIDE_PROJECT' };
|
|
77
78
|
failures.push(failure);
|
|
78
|
-
error(
|
|
79
|
+
error(cliText('cli.clean.error.deleteFailed', { path: entry.path, code: failure.code }));
|
|
79
80
|
continue;
|
|
80
81
|
}
|
|
81
82
|
try {
|
|
@@ -84,15 +85,15 @@ export async function runCleanCommand(args, options = {}) {
|
|
|
84
85
|
} catch (cause) {
|
|
85
86
|
const code = errorCode(cause);
|
|
86
87
|
failures.push({ path: entry.path, code });
|
|
87
|
-
error(
|
|
88
|
+
error(cliText('cli.clean.error.deleteFailed', { path: entry.path, code }));
|
|
88
89
|
}
|
|
89
90
|
}
|
|
90
91
|
|
|
91
92
|
if (failures.length > 0) {
|
|
92
|
-
error('
|
|
93
|
+
error(cliText('cli.clean.error.partialDelete'));
|
|
93
94
|
return { exitCode: 1, classification, removed, failures };
|
|
94
95
|
}
|
|
95
|
-
if (!parsed.json) log(
|
|
96
|
+
if (!parsed.json) log(cliText('cli.clean.status.deleted', { count: removed.length, n: removed.length }));
|
|
96
97
|
return { exitCode: 0, classification, removed, failures };
|
|
97
98
|
}
|
|
98
99
|
|
|
@@ -100,9 +101,9 @@ export function parseArguments(args, cwd = process.cwd()) {
|
|
|
100
101
|
const allowed = new Set(['--dry-run', '--yes', '--json', '--help']);
|
|
101
102
|
const flags = args.filter((value) => value.startsWith('-'));
|
|
102
103
|
const unknown = [...new Set(flags.filter((value) => !allowed.has(value)))];
|
|
103
|
-
if (unknown.length > 0) return { ok: false, message:
|
|
104
|
+
if (unknown.length > 0) return { ok: false, message: cliText('cli.clean.error.unknownOption', { options: unknown.join(', ') }) };
|
|
104
105
|
const positional = args.filter((value) => !value.startsWith('-'));
|
|
105
|
-
if (positional.length > 1) return { ok: false, message: '
|
|
106
|
+
if (positional.length > 1) return { ok: false, message: cliText('cli.clean.error.multipleRoots') };
|
|
106
107
|
const flagSet = new Set(flags);
|
|
107
108
|
return {
|
|
108
109
|
ok: true,
|
|
@@ -116,39 +117,48 @@ export function parseArguments(args, cwd = process.cwd()) {
|
|
|
116
117
|
|
|
117
118
|
export function cleanHelp() {
|
|
118
119
|
return [
|
|
119
|
-
'
|
|
120
|
+
cliText('cli.clean.help.usage'),
|
|
120
121
|
'',
|
|
121
|
-
'
|
|
122
|
-
'
|
|
122
|
+
cliText('cli.clean.help.description'),
|
|
123
|
+
cliText('cli.clean.help.default'),
|
|
123
124
|
'',
|
|
124
|
-
'
|
|
125
|
-
' --yes 一覧を表示した後、削除可能なものだけを削除',
|
|
126
|
-
' --json 分類結果を JSON で表示',
|
|
127
|
-
' --help このヘルプを表示',
|
|
125
|
+
...['dryRun', 'yes', 'json', 'help'].map((name) => cliText(`cli.clean.help.${name}`)),
|
|
128
126
|
];
|
|
129
127
|
}
|
|
130
128
|
|
|
131
129
|
export function formatClassification(classification) {
|
|
132
130
|
const lines = [];
|
|
133
131
|
for (const [className, heading] of [
|
|
134
|
-
['disposable', '
|
|
135
|
-
['keep', '
|
|
136
|
-
['undecided', '
|
|
132
|
+
['disposable', cliText('cli.clean.category.disposable')],
|
|
133
|
+
['keep', cliText('cli.clean.category.keep')],
|
|
134
|
+
['undecided', cliText('cli.clean.category.undecided')],
|
|
137
135
|
]) {
|
|
138
136
|
lines.push(heading);
|
|
139
137
|
const entries = classification[className];
|
|
140
|
-
if (entries.length === 0) lines.push('
|
|
138
|
+
if (entries.length === 0) lines.push(cliText('cli.clean.category.empty'));
|
|
141
139
|
for (const entry of entries) {
|
|
142
140
|
const provenance = entry.provenance
|
|
143
|
-
?
|
|
141
|
+
? cliText('cli.clean.entry.provenance', { origin: entry.provenance.origin, generator: entry.provenance.generator })
|
|
144
142
|
: '';
|
|
145
|
-
lines.push(
|
|
143
|
+
lines.push(cliText('cli.clean.entry.row', { path: entry.path, files: entry.files, n: entry.files, bytes: formatBytes(entry.bytes), reason: cliValue('cli.clean.reason.', entry.reason), provenance }));
|
|
146
144
|
}
|
|
147
145
|
}
|
|
148
|
-
lines.push(
|
|
146
|
+
lines.push(cliText('cli.clean.category.total', { bytes: formatBytes(classification.totals.disposable.bytes) }));
|
|
149
147
|
return lines;
|
|
150
148
|
}
|
|
151
149
|
|
|
150
|
+
function localizeClassification(classification) {
|
|
151
|
+
const result = { ...classification };
|
|
152
|
+
for (const category of ['disposable', 'keep', 'undecided']) {
|
|
153
|
+
result[category] = classification[category].map((entry) => ({
|
|
154
|
+
...entry,
|
|
155
|
+
reason: cliValue('cli.clean.reason.', entry.reason),
|
|
156
|
+
...(entry.held_reason ? { held_reason: cliValue('cli.clean.reason.', entry.held_reason) } : {}),
|
|
157
|
+
}));
|
|
158
|
+
}
|
|
159
|
+
return result;
|
|
160
|
+
}
|
|
161
|
+
|
|
152
162
|
export function formatBytes(bytes) {
|
|
153
163
|
if (bytes < 1024) return `${bytes} B`;
|
|
154
164
|
const units = ['KB', 'MB', 'GB'];
|
|
@@ -164,13 +174,13 @@ export function formatBytes(bytes) {
|
|
|
164
174
|
function provenanceWarnings(classification) {
|
|
165
175
|
return classification.keep
|
|
166
176
|
.filter((entry) => entry.provenance?.origin_exists === false)
|
|
167
|
-
.map((entry) =>
|
|
177
|
+
.map((entry) => cliText('cli.clean.warning.provenanceMissing', { origin: entry.provenance.origin }));
|
|
168
178
|
}
|
|
169
179
|
|
|
170
180
|
async function promptForConfirmation() {
|
|
171
181
|
const readline = createInterface({ input: process.stdin, output: process.stdout });
|
|
172
182
|
try {
|
|
173
|
-
return await readline.question('
|
|
183
|
+
return await readline.question(cliText('cli.clean.prompt.delete'));
|
|
174
184
|
} finally {
|
|
175
185
|
readline.close();
|
|
176
186
|
}
|
package/src/cli.mjs
CHANGED
|
@@ -26,8 +26,11 @@ import { runDecisionLogCommand } from './decision-log-command.mjs';
|
|
|
26
26
|
import { runCaptionsCommand } from './captions-command.mjs';
|
|
27
27
|
import { runCaptureCommand } from './capture-command.mjs';
|
|
28
28
|
import { runMediaCommand } from './media-command.mjs';
|
|
29
|
+
import { runSpeakersCommand } from './speakers-command.mjs';
|
|
30
|
+
import { runToolsCommand } from './tools-command.mjs';
|
|
29
31
|
import { runWordBookCommand } from './word-book-command.mjs';
|
|
30
32
|
import { resolveRuntimePaths } from './runtime-diagnostics.mjs';
|
|
33
|
+
import { cliText } from './i18n.mjs';
|
|
31
34
|
|
|
32
35
|
// run を直接呼ぶ利用者と入口で、同じサブコマンドの表を使う。
|
|
33
36
|
export const runSubcommands = {
|
|
@@ -35,6 +38,8 @@ export const runSubcommands = {
|
|
|
35
38
|
captions: runCaptionsCommand,
|
|
36
39
|
capture: runCaptureCommand,
|
|
37
40
|
media: runMediaCommand,
|
|
41
|
+
speakers: runSpeakersCommand,
|
|
42
|
+
tools: runToolsCommand,
|
|
38
43
|
'word-book': runWordBookCommand,
|
|
39
44
|
};
|
|
40
45
|
|
|
@@ -51,7 +56,7 @@ export async function run(args, options = {}) {
|
|
|
51
56
|
const retiredBrowserCommand = 'chrome';
|
|
52
57
|
if (args[0] === retiredBrowserCommand) {
|
|
53
58
|
const error = options.error ?? ((line) => console.error(line));
|
|
54
|
-
error(
|
|
59
|
+
error(cliText('cli.launcher.error.retiredBrowser', { command: retiredBrowserCommand }));
|
|
55
60
|
return { exitCode: 1 };
|
|
56
61
|
}
|
|
57
62
|
if (Object.hasOwn(runSubcommands, args[0])) return runSubcommands[args[0]](args.slice(1), options);
|
|
@@ -84,9 +89,9 @@ export async function run(args, options = {}) {
|
|
|
84
89
|
const bareNonInteractive = args.length === 0 && !isTTY;
|
|
85
90
|
if (!isTTY && !autoConfirm && !hereOnly && !detectProjectState(projectRoot).scaffolded) {
|
|
86
91
|
const output = bareNonInteractive ? log : (options.error ?? ((line) => console.error(line)));
|
|
87
|
-
output(
|
|
92
|
+
output(cliText('cli.launcher.project.uninitialized', { root: projectRoot }));
|
|
88
93
|
output(bareNonInteractive
|
|
89
|
-
? '
|
|
94
|
+
? cliText('cli.launcher.project.nonInteractive')
|
|
90
95
|
: nonInteractiveUninitializedGuidance());
|
|
91
96
|
return { exitCode: bareNonInteractive ? 0 : 2, scaffolded: false, claudeLaunched: false, opencodeLaunched: false };
|
|
92
97
|
}
|
|
@@ -100,48 +105,50 @@ export async function run(args, options = {}) {
|
|
|
100
105
|
try {
|
|
101
106
|
const creatorRoot = await defaultLoadCreatorRootModule(assets);
|
|
102
107
|
const migration = await creatorRoot?.migrateAssetLibrary({ env, platform, automatic: true, notify: log });
|
|
103
|
-
for (const failure of migration?.failures ?? []) log(
|
|
108
|
+
for (const failure of migration?.failures ?? []) log(cliText('cli.launcher.assets.migrationRetry', { message: failure.message }));
|
|
104
109
|
} catch (error) {
|
|
105
|
-
log(
|
|
110
|
+
log(cliText('cli.launcher.assets.migrationRetry', { message: error.message }));
|
|
106
111
|
}
|
|
107
112
|
|
|
108
113
|
let state = detectProjectState(projectRoot);
|
|
109
114
|
|
|
110
115
|
if (!state.scaffolded) {
|
|
111
|
-
log(
|
|
116
|
+
log(cliText('cli.launcher.project.uninitialized', { root: projectRoot }));
|
|
112
117
|
if (!assets.templateDir || !assets.scaffoldModulePath) {
|
|
113
|
-
log('
|
|
118
|
+
log(cliText('cli.launcher.project.templateMissing'));
|
|
114
119
|
} else {
|
|
115
|
-
log('
|
|
120
|
+
log(cliText('cli.launcher.project.creating'));
|
|
116
121
|
try {
|
|
117
122
|
const report = await scaffold(projectRoot, assets);
|
|
118
|
-
log(
|
|
123
|
+
log(cliText('cli.launcher.project.created', { copied: report.copy.copiedFiles.length,
|
|
124
|
+
fallback: cliText('cli.launcher.project.fallbackCount', { count: report.fallback.writtenFiles.length, n: report.fallback.writtenFiles.length }),
|
|
125
|
+
git: report.git.action, n: report.copy.copiedFiles.length }));
|
|
119
126
|
} catch (error) {
|
|
120
127
|
// scaffold の失敗で claude 起動まで止めない(「最後に claude を exec」は不変条件)。
|
|
121
|
-
log(
|
|
128
|
+
log(cliText('cli.launcher.project.createFailed', { message: error instanceof Error ? error.message : String(error) }));
|
|
122
129
|
}
|
|
123
130
|
state = detectProjectState(projectRoot);
|
|
124
131
|
}
|
|
125
132
|
} else {
|
|
126
|
-
log(
|
|
133
|
+
log(cliText('cli.launcher.project.existing', { root: projectRoot }));
|
|
127
134
|
}
|
|
128
135
|
|
|
129
136
|
const taskLabels = loadTaskLabels(assets.schemasSourceDir);
|
|
130
137
|
log(describeIntake(state.intake, taskLabels));
|
|
131
138
|
|
|
132
139
|
if (state.scaffolded && assets.doctorScript) {
|
|
133
|
-
log('
|
|
140
|
+
log(cliText('cli.launcher.doctor.checking'));
|
|
134
141
|
try {
|
|
135
142
|
runDoctor(assets.doctorScript, projectRoot);
|
|
136
143
|
} catch (error) {
|
|
137
|
-
log(
|
|
144
|
+
log(cliText('cli.launcher.doctor.failed', { message: error instanceof Error ? error.message : String(error) }));
|
|
138
145
|
}
|
|
139
146
|
const runtimeDiagnostics = options.runtimeDiagnostics ?? resolveRuntimePaths({ ...options, env, platform });
|
|
140
147
|
log(describeVersionStatus(versionInfo, readCacheSync(resolveCachePath(env)), runtimeDiagnostics));
|
|
141
148
|
}
|
|
142
149
|
|
|
143
150
|
if (bareNonInteractive) {
|
|
144
|
-
log('
|
|
151
|
+
log(cliText('cli.launcher.project.nonInteractive'));
|
|
145
152
|
return { exitCode: 0, scaffolded: state.scaffolded, claudeLaunched: false, opencodeLaunched: false };
|
|
146
153
|
}
|
|
147
154
|
|
|
@@ -161,11 +168,11 @@ export async function run(args, options = {}) {
|
|
|
161
168
|
try {
|
|
162
169
|
await (options.showAssetIntro ?? maybeShowAssetIntroNotice)({ env, log });
|
|
163
170
|
} catch (error) {
|
|
164
|
-
log(
|
|
171
|
+
log(cliText('cli.launcher.assets.noticeFailed', { message: error instanceof Error ? error.message : String(error) }));
|
|
165
172
|
}
|
|
166
173
|
|
|
167
174
|
if (useOpencode) {
|
|
168
|
-
log('
|
|
175
|
+
log(cliText('cli.launcher.agent.startOpencode'));
|
|
169
176
|
const opencodePath = resolveOpencode();
|
|
170
177
|
if (!opencodePath) {
|
|
171
178
|
log(opencodeMissingGuidance());
|
|
@@ -179,14 +186,14 @@ export async function run(args, options = {}) {
|
|
|
179
186
|
} else {
|
|
180
187
|
const claudePath = resolveClaude();
|
|
181
188
|
if (claudePath) {
|
|
182
|
-
log('
|
|
189
|
+
log(cliText('cli.launcher.agent.startClaude'));
|
|
183
190
|
const claudeArgs = autoConfirm ? ['--permission-mode', 'acceptEdits', ...filteredArgs] : filteredArgs;
|
|
184
191
|
const result = spawnClaude(claudePath, claudeArgs, projectRoot);
|
|
185
192
|
const exitCode = typeof result.status === 'number' ? result.status : (result.error ? 1 : 0);
|
|
186
193
|
return { exitCode, scaffolded: state.scaffolded, claudeLaunched: true };
|
|
187
194
|
}
|
|
188
195
|
|
|
189
|
-
log('
|
|
196
|
+
log(cliText('cli.launcher.agent.claudeMissing'));
|
|
190
197
|
const opencodePath = resolveOpencode();
|
|
191
198
|
if (!opencodePath) {
|
|
192
199
|
log(claudeMissingGuidance());
|
|
@@ -296,8 +303,8 @@ export async function runUpdateCommand(args, options = {}) {
|
|
|
296
303
|
if (forceRequested
|
|
297
304
|
&& versionInfo.installRefStatus === 'missing'
|
|
298
305
|
&& runtimeDiagnostics.render_cut.origin !== 'monorepo') {
|
|
299
|
-
log('
|
|
300
|
-
log('
|
|
306
|
+
log(cliText('cli.update.force.unavailable'));
|
|
307
|
+
log(cliText('cli.update.force.installGuide'));
|
|
301
308
|
}
|
|
302
309
|
return { exitCode: 0 };
|
|
303
310
|
}
|
|
@@ -308,7 +315,7 @@ export async function runUpdateCommand(args, options = {}) {
|
|
|
308
315
|
for (const line of describeInstalledVersions(versionInfo, runtimeDiagnostics)) {
|
|
309
316
|
log(line);
|
|
310
317
|
}
|
|
311
|
-
log(
|
|
318
|
+
log(cliText('cli.update.feed.latest', { version: feed.product, channel: '' }));
|
|
312
319
|
if (forceRequested) {
|
|
313
320
|
log(describeForceReinstall(versionInfo, feed.product));
|
|
314
321
|
}
|
package/src/doctor-command.mjs
CHANGED
|
@@ -1,22 +1,18 @@
|
|
|
1
1
|
import { doctorExitCode, resolveDoctorReport } from './runtime-diagnostics.mjs';
|
|
2
|
+
import { cliText, cliLanguage } from './i18n.mjs';
|
|
2
3
|
|
|
3
|
-
const usage = [
|
|
4
|
-
'使い方: akari doctor [--json]',
|
|
5
|
-
'',
|
|
6
|
-
'必須部品の実在、解決元、PATH を確認します。',
|
|
7
|
-
' --json 機械可読な診断結果を 1 オブジェクトで出力',
|
|
8
|
-
].join('\n');
|
|
4
|
+
const usage = () => ['usage', 'blank', 'description', 'json'].map((name) => name === 'blank' ? '' : cliText(`cli.doctor.help.${name}`)).join('\n');
|
|
9
5
|
|
|
10
6
|
export async function runDoctorCommand(argv, options = {}) {
|
|
11
7
|
const log = options.log ?? ((line) => process.stdout.write(`${line}\n`));
|
|
12
8
|
const error = options.error ?? ((line) => process.stderr.write(`${line}\n`));
|
|
13
9
|
if (argv.includes('--help') || argv.includes('-h')) {
|
|
14
|
-
log(usage);
|
|
10
|
+
log(usage());
|
|
15
11
|
return { exitCode: 0 };
|
|
16
12
|
}
|
|
17
13
|
const unknown = argv.find((argument) => argument !== '--json');
|
|
18
14
|
if (unknown) {
|
|
19
|
-
error(
|
|
15
|
+
error(`${cliText('cli.doctor.error.unknownOption', { option: unknown })}\n${usage()}`);
|
|
20
16
|
return { exitCode: 2 };
|
|
21
17
|
}
|
|
22
18
|
|
|
@@ -30,49 +26,54 @@ export function formatDoctorReport(report) {
|
|
|
30
26
|
const rows = [
|
|
31
27
|
['cli', 'ok', `v${report.cli.version} — ${report.cli.entry_path}`],
|
|
32
28
|
['node', report.cli.node?.runtime ?? 'unknown', report.cli.node
|
|
33
|
-
? `v${report.cli.node.version} — ${report.cli.node.exec_path}${report.cli.node.runtime === 'electron' ? '
|
|
34
|
-
: '
|
|
29
|
+
? `v${report.cli.node.version} — ${report.cli.node.exec_path}${report.cli.node.runtime === 'electron' ? cliText('cli.doctor.detail.electronNode') : ''}`
|
|
30
|
+
: cliText('cli.doctor.detail.noInfo')],
|
|
35
31
|
['app_managed', report.app_managed.status, detail(report.app_managed.path, report.app_managed.version)],
|
|
36
32
|
['app_bundle', report.app_bundle.found ? 'found' : 'missing', detail(report.app_bundle.path, report.app_bundle.version)],
|
|
37
|
-
['render_cut', report.render_cut.origin, report.render_cut.path ?? '
|
|
38
|
-
['edit_lint', report.edit_lint.origin, report.edit_lint.path ?? '
|
|
39
|
-
['ffmpeg', report.ffmpeg.origin, report.ffmpeg.path ?? '
|
|
40
|
-
['ffprobe', report.ffprobe.origin, report.ffprobe.path ?? '
|
|
41
|
-
['gpu_export', report.gpu_export?.available ? 'ok' : 'unavailable', report.gpu_export?.reason ?? '
|
|
33
|
+
['render_cut', report.render_cut.origin, report.render_cut.path ?? cliText('cli.doctor.detail.missing')],
|
|
34
|
+
['edit_lint', report.edit_lint.origin, report.edit_lint.path ?? cliText('cli.doctor.detail.missing')],
|
|
35
|
+
['ffmpeg', report.ffmpeg.origin, report.ffmpeg.path ?? cliText('cli.doctor.detail.missing')],
|
|
36
|
+
['ffprobe', report.ffprobe.origin, report.ffprobe.path ?? cliText('cli.doctor.detail.missing')],
|
|
37
|
+
['gpu_export', report.gpu_export?.available ? 'ok' : 'unavailable', localizeGpuReason(report.gpu_export?.reason) ?? cliText('cli.doctor.detail.noInfo')],
|
|
42
38
|
['fal_key', report.fal_key?.source ?? 'missing', report.fal_key?.source === 'env'
|
|
43
|
-
? '
|
|
39
|
+
? cliText('cli.doctor.detail.falEnv')
|
|
44
40
|
: report.fal_key?.source === 'credentials.env'
|
|
45
41
|
? report.fal_key.credentials_path
|
|
46
|
-
: '
|
|
47
|
-
['
|
|
42
|
+
: cliText('cli.doctor.detail.falMissing')],
|
|
43
|
+
[cliText('cli.doctor.detail.keyLocation'), cliText(`cli.doctor.location.${({ 新: 'new', 旧: 'old', 両方: 'both', なし: 'none' })[report.fal_key?.location] ?? 'none'}`), cliText('cli.doctor.detail.keyLocationLegend')],
|
|
48
44
|
['path', report.path.on_path ? 'ok' : 'missing', report.path.cli_shim_dir],
|
|
49
45
|
];
|
|
50
46
|
const widths = [
|
|
51
|
-
Math.max('
|
|
52
|
-
Math.max('
|
|
47
|
+
Math.max(cliText('cli.doctor.table.item').length, ...rows.map((row) => row[0].length)),
|
|
48
|
+
Math.max(cliText('cli.doctor.table.status').length, ...rows.map((row) => row[1].length)),
|
|
53
49
|
];
|
|
54
50
|
const lines = [
|
|
55
51
|
'AKARI Video doctor',
|
|
56
52
|
'',
|
|
57
|
-
`${'
|
|
53
|
+
`${cliText('cli.doctor.table.item').padEnd(widths[0])} ${cliText('cli.doctor.table.status').padEnd(widths[1])} ${cliText('cli.doctor.table.detail')}`,
|
|
58
54
|
`${'-'.repeat(widths[0])} ${'-'.repeat(widths[1])} ${'-'.repeat(20)}`,
|
|
59
55
|
...rows.map((row) => `${row[0].padEnd(widths[0])} ${row[1].padEnd(widths[1])} ${row[2]}`),
|
|
60
56
|
'',
|
|
61
|
-
|
|
57
|
+
cliText('cli.doctor.table.verdict', { verdict: report.verdict }),
|
|
62
58
|
];
|
|
63
59
|
const steps = [...report.next_steps];
|
|
64
60
|
if (report.cli.node?.runtime === 'electron' && report.cli.node.exec_path && report.render_cut.path) {
|
|
65
61
|
const quote = (value) => `"${value.replaceAll('"', '\\"')}"`;
|
|
66
|
-
steps.push(
|
|
62
|
+
steps.push(cliText('cli.doctor.detail.nodeExport', { node: quote(report.cli.node.exec_path), render: quote(report.render_cut.path) }));
|
|
67
63
|
}
|
|
68
64
|
if (steps.length > 0) {
|
|
69
|
-
lines.push('
|
|
65
|
+
lines.push(cliText('cli.doctor.table.nextSteps'));
|
|
70
66
|
lines.push(...steps.map((step) => ` - ${step}`));
|
|
71
67
|
}
|
|
72
68
|
return lines.join('\n');
|
|
73
69
|
}
|
|
74
70
|
|
|
75
71
|
function detail(path, version) {
|
|
76
|
-
const location = path ?? '
|
|
72
|
+
const location = path ?? cliText('cli.doctor.detail.missing');
|
|
77
73
|
return version ? `v${version} — ${location}` : location;
|
|
78
74
|
}
|
|
75
|
+
|
|
76
|
+
function localizeGpuReason(reason) {
|
|
77
|
+
if (!reason || cliLanguage() === 'ja') return reason;
|
|
78
|
+
return reason.replace(cliText('cli.doctor.detail.gpuRepoReason', {}, 'ja'), cliText('cli.doctor.detail.gpuRepoReason'));
|
|
79
|
+
}
|
package/src/generate-command.mjs
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import { spawnSync } from "node:child_process";
|
|
2
2
|
|
|
3
3
|
import { resolveLauncherAssets } from "./repo-assets.mjs";
|
|
4
|
+
import { cliText } from './i18n.mjs';
|
|
4
5
|
|
|
5
6
|
export async function runGenerateCommand(args, options = {}) {
|
|
6
7
|
const logError = options.logError ?? ((line) => console.error(line));
|
|
7
8
|
const assets = options.assets ?? resolveLauncherAssets();
|
|
8
9
|
const spawn = options.spawn ?? spawnSync;
|
|
9
10
|
if (!assets.generateScript) {
|
|
10
|
-
logError(
|
|
11
|
+
logError(cliText('cli.generate.error.scriptMissing'));
|
|
11
12
|
logError(" npm install -g akari-video");
|
|
12
13
|
return { exitCode: 1 };
|
|
13
14
|
}
|
package/src/history-policy.mjs
CHANGED
package/src/i18n.mjs
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { readFileSync } from 'node:fs';
|
|
2
|
+
import { createRequire } from 'node:module';
|
|
3
|
+
import { join, resolve } from 'node:path';
|
|
4
|
+
import { fileURLToPath, pathToFileURL } from 'node:url';
|
|
5
|
+
|
|
6
|
+
const sourceUrl = import.meta.url;
|
|
7
|
+
const require = createRequire(sourceUrl || pathToFileURL(__filename));
|
|
8
|
+
const roots = sourceUrl
|
|
9
|
+
? ['../../i18n', '../vendor/packages/i18n'].map(root => fileURLToPath(new URL(`${root}/`, sourceUrl)))
|
|
10
|
+
: [...(process.resourcesPath ? [join(process.resourcesPath, 'packages/i18n')] : []),
|
|
11
|
+
resolve(process.cwd(), '../../packages/i18n'), resolve(process.cwd(), 'packages/i18n')];
|
|
12
|
+
let core = null;
|
|
13
|
+
for (const root of roots) {
|
|
14
|
+
try { core = require(join(root, 'index.cjs')); break; }
|
|
15
|
+
catch { /* Try the packaged copy next. */ }
|
|
16
|
+
}
|
|
17
|
+
const normalizeLanguage = core?.normalizeLanguage ?? ((value) => typeof value === 'string' && /^ja/i.test(value) ? 'ja' : 'en');
|
|
18
|
+
const getLanguage = core?.getLanguage ?? (() => normalizeLanguage(process.env.AKARI_LANG ?? Intl.DateTimeFormat().resolvedOptions().locale));
|
|
19
|
+
|
|
20
|
+
function catalog(language) {
|
|
21
|
+
for (const root of roots) {
|
|
22
|
+
try { return JSON.parse(readFileSync(join(root, 'locales', language, 'cli.json'), 'utf8')); }
|
|
23
|
+
catch { /* Try the packaged catalog next. */ }
|
|
24
|
+
}
|
|
25
|
+
return {};
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const catalogs = { ja: catalog('ja'), en: catalog('en') };
|
|
29
|
+
export const cliLanguage = getLanguage;
|
|
30
|
+
|
|
31
|
+
export function cliText(key, params = {}, language = getLanguage()) {
|
|
32
|
+
const selectedLanguage = normalizeLanguage(language);
|
|
33
|
+
const chosen = catalogs[selectedLanguage];
|
|
34
|
+
const n = Number(params.n);
|
|
35
|
+
const suffix = Number.isFinite(n) ? new Intl.PluralRules(selectedLanguage).select(n) : null;
|
|
36
|
+
const requested = suffix && (Object.hasOwn(chosen, `${key}_${suffix}`) || Object.hasOwn(catalogs.en, `${key}_${suffix}`))
|
|
37
|
+
? `${key}_${suffix}` : key;
|
|
38
|
+
const fallback = requested.endsWith('_one') ? `${key}_other` : requested;
|
|
39
|
+
const value = chosen[requested] ?? chosen[fallback] ?? catalogs.en[requested] ?? catalogs.en[fallback] ?? key;
|
|
40
|
+
return value.replace(/\{([a-zA-Z][a-zA-Z0-9]*)\}/g, (match, name) => params[name] === undefined ? match : String(params[name]));
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export function cliValue(prefix, value) {
|
|
44
|
+
if (getLanguage() === 'ja' || typeof value !== 'string') return value;
|
|
45
|
+
const entry = Object.entries(catalogs.ja).find(([key, source]) => key.startsWith(prefix) && source === value);
|
|
46
|
+
return entry ? cliText(entry[0]) : value;
|
|
47
|
+
}
|