# akari-launcher（`akari` コマンド）

ライブラリの置き場は既定で作業場の `library/`。作業場が無いときは従来の `~/.akari/assets/` を使う。
`akari-assets list`（または `akari assets list`）の先頭行で実際の置き場を確認する。
以下の `<ライブラリの置き場>` はその表示先を指し、音源はその下の `audio/` に入る。

「UI に依存したくない。opencode 単体でも、どんなディレクトリでも始められるように」を
実現する薄いラッパー CLI。npm パッケージ名は `akari-video`、提供するコマンド名は `akari`
（npm の `akari` は別プロダクトが取得済みのため。オーナー裁定 2026-07-21 §8-2）。

## やること

```
akari
  │
  ├─ 1. doctor: カレントディレクトリが AKARI Video プロジェクトかを判定する
  │     （.akari/connections.json の有無）
  │
  ├─ 2. 未セットアップなら:
  │     日本語で案内 → project-scaffold を呼んで雛形を作成
  │     （.akari/intake.json は status: "draft" で生成される）
  │
  ├─ 3. 接続状態を確認する:
  │     skills/manage-connections/bin/doctor.mjs を再利用して
  │     .akari/connections.json の doctor ブロックを更新・表示する
  │     （キーの値は一切表示しない）
  │
  ├─ 4. 公式音源ライブラリ（AKARI Sounds）の初回セットアップ（src/sounds-setup.mjs）:
  │     未導入かつ TTY のとき生涯 1 回だけ [Y/n]（既定 Yes）を聞き、Yes なら
  │     packages/audio-library-setup/bin/fetch-akari-sounds.mjs で一括ダウンロード。
  │     n は marker（<ライブラリの置き場>/audio/.akari-sounds-declined.json）を書いて以後
  │     聞かない。再入口は `akari sounds`。失敗しても起動は止めない
  │
  └─ 5. 最後に opencode を exec する
        （PATH に opencode が無ければ、インストール案内を出して終了する）
```

install.sh 経由インストール（`~/.akari/app`）では、新版の検知・裏 staging DL・sha256 検証・
次回起動時の自動適用がすべて既定で走る（`AKARI_NO_AUTO_UPDATE=1` で無効化可）。起動を
ブロックすることは無く、適用は次回起動の頭でアトミックにスワップする（`src/update-check.mjs`
の `maybeStageInBackground` / `maybeApplyPendingUpdateOnLaunch`、実体は `src/self-update.mjs`
の `stageSelfUpdate` / `swapStagedApp`）。

サブコマンド: `akari update`（オンデマンドの確認・適用。install.sh 経由インストールなら
DL・sha256 検証・適用まで実行。それ以外（npm グローバル / git checkout）や旧フィードでは
更新案内のみ表示。`--rollback` で直前 1 世代へ戻す。`src/self-update.mjs`）/
`akari init`（作業場の作成・確認のみ）/
`akari new <target-dir> [--template <path>]`（新規プロジェクト作成）/
`akari narration generate ...`（VOICEVOX / fal-qwen3 ナレーション生成）/
`akari internal beat-sync-<beatmap|probe-frame|render-when-idle> ...`（beat-sync-edit 内部実行物）/
`akari sounds [--variant wav] [--force]`（公式音源の一括ダウンロード。プロンプトなし・headless 可）/
`akari store <connect|status|install|download|disconnect>`（AKARI Store 連携。マイページで発行した
接続トークンを `~/.akari/store-credentials.json`（0600）に保存し、購入済み一覧の確認と
配布物の取得ができる。`install <productId> [--from <zip>]` は購入パックを展開し、`PACK.json` の
収載素材を `<ライブラリの置き場>/installed.json` へ登録する。`--from` は開発・オフライン導入時に手元の
zip を使う。`src/store-command.mjs`）/
`akari assets <list|fetch|sync|...>`（素材カタログの一覧・取得・同期。
`packages/asset-resolver` の CLI への薄い委譲で、カタログ合成・entitlements 判定・
sha256 検証・fail-closed は resolver 側の責務のまま。`src/assets-command.mjs`）/
`akari clean [project-dir] [--dry-run] [--yes] [--json]`（使い捨ての中間ファイル、保持する
正本、判断が必要なものを容量付きで一覧する。既定は一覧のみで、削除可能なものだけを承認後に削除）。

## 拡張キット

`manifest.json` を持つ配布物を `akari store install <productId>` で導入すると、CLI / runtime の要件を検査し、素材とスキルを `~/.akari` 配下へ symlink で合成する。導入状況は `akari store status`、解除は `akari store uninstall <productId>` で確認・操作できる。Claude Code では初回だけ次を実行する。

```sh
claude plugin marketplace add ~/.akari/kits
claude plugin install akari-kits@akari-kits
```

`claude` が PATH に無い場合は、Claude Code のプラグイン設定で `~/.akari/kits` を marketplace として追加する。

`akari` に渡した引数はそのまま `opencode` に転送する（例: `akari --continue` は
`opencode --continue` を起動する）。

## 状態・受理・能力検索

```sh
akari status [project-path] --json
akari status [project-path] --full --json
akari accept [project-path]                         # 実 TTY でのみ対話記録
akari capability <query> --json
akari capability <query> --record-miss --json      # 0 hit のときだけ absence receipt
```

fast status は現在工程を決定的に返すが、最終受理を true にしない。full status だけが immutable
render receipt の全 input / output と人間受理 event を再検証し、`release.accepted:true` を返せる。
`accept` が作るのは協調的ローカル運用の人間操作記録であり、暗号学的な本人署名ではない。
capability の 0 hit receipt は `approved_to_build:false` 固定で、新設許可を意味しない。

## 3 入口の対応表

AKARI Video は「同じファイル契約（`.akari/` 配下の JSON）に収束する 3 つの入口」を
持つ（上位契約 §5）。

| 入口 | 実体 | 発動方法 |
|---|---|---|
| ターミナル | この `akari` ランチャー CLI | `npm i -g akari-video` で導入し、シェルで `akari`（または `akari --opencode`）と打つ |
| セッション内 | opencode スキルの自動発見、またはプラグインの `/akari` スラッシュコマンド | opencode セッション内で「新しい動画プロジェクトを作りたい」と発話、または Claude Code セッション内で `/akari` と打つ |
| アプリ | 接続ボタン（AKARI Video アプリ） | アプリの「はじめる」画面から接続 → はじめかた選択 |

3 つとも最終的に同じもの（`.akari/connections.json` / `.akari/intake.json` /
`akari new` が使う共通 project-scaffold）を読み書きするため、どの入口から始めても続きは他の入口から
再開できる。

## インストール

npm publish 済み（v0.1.0 から・provenance 付き）。npm 版はランチャー + エージェント
ワークフロー（skills / 雛形 / schemas を vendor 同梱）のみで、ブラウザプレビュー
（`packages/preview-server`）は含まない。フル構成はリポジトリのインストーラー
（`install.sh` — リリースタグ固定配布）を使う。実行方法:

```sh
# モノレポ checkout 内から、bin を直接実行する（opencode モード）
node packages/akari-launcher/bin/akari.mjs --opencode

# Claude Code モード
node packages/akari-launcher/bin/akari.mjs

# 既定の導入（npm publish 済み）
npm i -g akari-video && akari
npx akari-video
```

### akari doctor の cli.node

`akari doctor --json` の `cli.node` は、この CLI を動かしている実行体と、スクリプトを Node として呼ぶ方法を返す。

| フィールド | 意味 |
|---|---|
| `exec_path` | 診断を実行した実行体のパス。Electron アプリの EXE になることもある |
| `electron_run_as_node` | 診断を実行したプロセスの環境変数が `ELECTRON_RUN_AS_NODE=1` だったか |
| `version` | 実行体の Node のバージョン（Electron では内蔵の Node） |
| `runtime` | 実行体が `electron` か `node` か |
| `electron_version` | Electron のバージョン。Node 実行体では `null` |
| `run_as_node_supported` | Electron 実行体を Node として呼べるか |
| `required_env` | Node として呼ぶために必要な環境変数。Electron では `{ "ELECTRON_RUN_AS_NODE": "1" }`、Node では `{}` |
| `invocation` | `shell` は既定シェル、`example` はそのシェル用の呼び方。`cmd` と `sh` は両方常に出る。`<script>` を実際のスクリプトパスに置き換える |

`electron_run_as_node` は診断時の環境だけを表す。Node として使えるかは `runtime`、`run_as_node_supported`、`required_env` で判断する。`runtime` が `electron` なら `required_env` を付けて呼ぶ。Windows の `cmd` では `set "ELECTRON_RUN_AS_NODE=1"` と引用符で囲む。`set ELECTRON_RUN_AS_NODE=1 &&` と書くと末尾の空白が値に入る。

Electron を Node として呼んだプロセスから GUI の Electron を子プロセスとして起動するときは、子へ渡す環境から `ELECTRON_RUN_AS_NODE` を外す。

## 既知の制約

- npm tarball は追跡済み skills・雛形・schemas と capability source set を `vendor/` に同梱する。
  Claude plugin の status は単体コピーでも動くが、skill symlink と CLI capability は checkout / CLI
  の有無に依存し、利用不能なら明示的に unsupported とする。
- Windows での動作は未検証（`claude.exe` / `claude.cmd` の探索ロジックはあるが
  実機確認していない）。

## テスト

```sh
node --test test/*.mjs
```

`doctor` 分岐（セットアップ済み/未セットアップ）・scaffold 呼び出し（実 project-scaffold
を使った統合テストを含む）・`claude` 不在時の案内、の 3 系統 + 補助的な単体テストを含む。
