コンテンツにスキップ

ローカル開発・ビルド・テスト

Utataneの開発へ参加する人や、自分の環境でビルド・改変したい人向けの案内です。

  • macOS 14以降
  • Xcode 26以降
  • mise
  • Zig(Windows互換ホストのビルド用)
  • Python 3、curl(kagari依存ソースの取得・ビルド用。初回はネットワーク接続が必要)
ターミナルウィンドウ
git submodule update --init --recursive
mise install
mise run generate
mise run build

Utatane.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 lint
mise run test
mise run build
mise run check

mise run checkには、公開しているUKADOC対応表の構文名が本番コードから消えていないことを確認する検査も含まれます。新しく対応済みと記載する構文はScripts/check-ukadoc-compatibility.pyの一覧にも追加します。

テスト件数を増やすこと自体は目標にしません。通信形式、互換仕様、保存データ、安全境界と、実際に起きた不具合の回帰確認を優先します。単純なプロパティ代入や、実装と同じ条件分岐をテスト側でも繰り返すだけの確認は追加しません。

パーサー、再生処理、画面制御の複数層を通る機能は、それぞれの責務だけを確認します。同じ結果を各層で重複して固定しないでください。同じ形式の入力を並べる場合は、引数付きテストへまとめます。

非同期処理の完了待ちには、テスト用の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/ 文字列カタログの生成元JSON
Internal-Docs/ 調査記録、TODO、実装上の補足

ゴーストのディレクトリを指定すると、必須ファイル、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 UtataneFirstNativeTests

配布版ではUtatane.app/Contents/Helpers/utatane-mcpをMCPクライアントのstdioサーバーとして登録できます。先にUtataneを起動してください。

ターミナルウィンドウ
swift build --package-path packages -c release --product utatane-mcp