ローカル開発・ビルド・テスト
Utataneの開発へ参加する人や、自分の環境でビルド・改変したい人向けの案内です。
セットアップ
Section titled “セットアップ”git submodule update --init --recursivemise installmise run generatemise run buildUtatane.xcodeprojは生成物です。直接直しても次の生成で消えます。ターゲットやビルド設定はproject.ymlを変更して、mise run generateしてください。
kagariとLuaのビルド処理はutatane-modulesで管理します。Utataneと同じ親フォルダへチェックアウトし、git submodule update --init --recursiveとuv sync --lockedを実行してください。別の配置はUTATANE_MODULES_ROOTで指定します。Xcodeからuvが見つからない場合はUTATANE_UV_EXECUTABLEに絶対パスを指定します。
移植済みのSHIORI・SAORIはUtatane Modulesでビルド・配布します。アプリのビルドには含めません。
mise run lintmise run testmise run buildmise run checkmise run checkには、公開しているUKADOC対応表の構文名が本番コードから消えていないことを確認する検査も含まれます。新しく対応済みと記載する構文はScripts/check-ukadoc-compatibility.pyの一覧にも追加します。
テストの方針
Section titled “テストの方針”テスト件数を増やすこと自体は目標にしません。通信形式、互換仕様、保存データ、安全境界と、実際に起きた不具合の回帰確認を優先します。単純なプロパティ代入や、実装と同じ条件分岐をテスト側でも繰り返すだけの確認は追加しません。
パーサー、再生処理、画面制御の複数層を通る機能は、それぞれの責務だけを確認します。同じ結果を各層で重複して固定しないでください。同じ形式の入力を並べる場合は、引数付きテストへまとめます。
非同期処理の完了待ちには、テスト用のrequireEventuallyを使います。一定時間のTask.sleepだけで完了を決めつけると、負荷の高いCIで不安定になります。アニメーション時間やタイムアウトそのものを検査する場合だけ、経過時間をテスト条件に含めます。
失敗が不定期に起きる場合は、対象テストを絞って繰り返し、実行タスク、グローバルなAppKit状態、時計や一時ファイルの共有を確認します。修正後は対象テストだけで終わらせず、全テストも実行します。
SwiftPMやClangがキャッシュへ書けないと言い出したら、書ける場所を指定します。
SWIFTPM_MODULECACHE_OVERRIDE=/private/tmp/utatane-swift-module-cache \CLANG_MODULE_CACHE_PATH=/private/tmp/utatane-clang-module-cache \mise run check配布用アーカイブをローカルで作る
Section titled “配布用アーカイブをローカルで作る”ユニバーサルバイナリ(arm64 / x86_64)のビルド、Windows互換ホストおよびMCPサーバーの組み込み、ZIPアーカイブの作成をまとめて実行します。
mise run package生成物は dist/Utatane-macOS.zip に出力されます。
kagariとLuaのビルド・配布検証はUtatane Modules側で行います。
apps/Utatane/ SwiftUIアプリ、状態管理、設定・カレンダー・音声UI、各モジュールの結線packages/Package.swift Swift Package「UtataneKit」のProduct・Target・依存定義packages/core/ 共有データ型、ゴーストイベント、プロパティ、ログ保存packages/runtime/ ゴーストセッション、人格エンジン、会話カタログ、変数保存packages/ghost-kit/ ゴースト設定とdescript.txtの読み込みpackages/content/ NAR、ZIP、SSPコンテンツの取り込みpackages/sakura-script/ SakuraScriptの解析と再生モデルpackages/shell/ Shell、surfaces.txt、SERIKOの解析packages/balloon/ Balloon設定の解析packages/platform-macos/ サーフェス・バルーン描画、SakuraScript再生、デバッグUI、実行タスク管理packages/network/ 更新、RSS、HEADLINE、SSTP、WebSocket、時刻取得・ネットワーク診断packages/ai/ プロバイダー非依存のAI人格エンジンpackages/realtime/ Realtime APIのSDP接続要求、会話イベント・トランスクリプト処理packages/shiori/ SHIORIメッセージ、外部ローダー、FIRST専用実装packages/makoto/ MAKOTOトランスレータと人格応答への変換処理packages/plugin/ プラグイン検出、要求・イベント配送、dylib接続packages/native-saori/ SHIORIから外部SAORIへ接続するレジストリpackages/shiori/native/ FIRST専用の人格実装packages/shiori/external/ macOS外部SHIORIとWine上のWindows DLLへの接続packages/mcp-server/ Utatane操作用のstdio MCPサーバーpackages/はPackage.swiftを持つ単一のSwift Packageです。機能ごとのディレクトリをTargetとして登録し、依存方向と公開Productをこのファイルで管理します。パーサーや本体処理は各モジュールへ置き、SwiftUIアプリ固有の結線はapps/Utatane、再利用するmacOS表示・再生処理はplatform-macosへ分けます。SHIORIの共通電文、FIRST専用実装、外部モジュール接続はpackages/shiori内で管理します。
周辺のビルド・調査用コードは次の場所にあります。
Scripts/ 生成、検証、互換ホスト、リリース用スクリプトtools/windows-dll-host/ 汎用Windows DLLホストのソースtools/materia-shiori-host/ FIRST解析用ホストのソースLocalizations/ 文字列カタログの生成元JSONInternal-Docs/ 調査記録、TODO、実装上の補足コンテンツの静的検査
Section titled “コンテンツの静的検査”ゴーストのディレクトリを指定すると、必須ファイル、Shellの既定surfaceとelement画像、SHIORIの判定、辞書内の未対応SakuraScriptを確認できます。アプリではコンテンツエクスプローラでゴーストを選び、「互換性を検査」から同じ診断を表示できます。
swift run --package-path packages utatane-validate "/path/to/ghost"swift run --package-path packages utatane-validate --json "/path/to/ghost"エラーがある場合は終了コード1、警告だけなら0を返します。辞書言語の正規表現やパスを誤検出しないよう、SakuraScript検査は一般的なscope/surface命令を含む行に限定します。静的検査なので、辞書の実行時分岐、外部SHIORI/SAORI、実際の描画までは保証しません。
開発用パレットには、SHIORI Requestの手動送信・ログからの再送、表示中ログのコピー・保存、時計イベントと予定通知を確認する仮想時刻があります。仮想時刻は指定した瞬間から実時間と同じ速さで進み、無効にするとシステム時刻へ戻ります。
同梱コンテンツとローカル検証データ
Section titled “同梱コンテンツとローカル検証データ”再配布条件を確認済みの同梱コンテンツはContent/Bundledで管理します。riaの会話、シェル、専用バルーンを変更するときはこちらだけを編集してください。
Content/Bundled/Ghosts/ria/Content/Bundled/Balloons/ria/DebugビルドはBundledを優先し、次のgit管理外ディレクトリを重ねて読みます。こちらは手元だけで使うゴースト置き場です。
Content/Local/Ghosts/Content/Local/Balloons/Content/Local/Headline/Content/Local/Plugins/Content/Local/Skins/ カレンダースキン同梱対象でない実ゴーストや配布素材はコミットしないでください。利用条件を確認して、手元だけで使います。SHIORIとSAORIの実行方式は、SHIORI・SAORIの対応範囲で説明しています。
ゴースト・SHIORI・SAORIの制作者がUtatane対応を確認する手順は、制作者向けUtatane対応ガイドを参照してください。
firstのネイティブ解析テストは、実物をFixtureへコピーせず環境変数で指定します。未指定なら実物依存部分だけスキップされます。
UTATANE_FIRST_DLL="$HOME/Library/Application Support/Utatane/Ghosts/first/ghost/master/first.dll" \swift test --package-path packages --filter UtataneFirstNativeTestsMCPサーバー
Section titled “MCPサーバー”配布版ではUtatane.app/Contents/Helpers/utatane-mcpをMCPクライアントのstdioサーバーとして登録できます。先にUtataneを起動してください。
swift build --package-path packages -c release --product utatane-mcp