@elizaos/app-core 2.0.0-alpha.85 → 2.0.0-beta.2
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/account-pool.d.ts +6 -0
- package/account-pool.d.ts.map +1 -0
- package/account-pool.js +5 -0
- package/api/__tests__/sandbox-test-helpers.d.ts +10 -0
- package/api/__tests__/sandbox-test-helpers.d.ts.map +1 -0
- package/api/__tests__/sandbox-test-helpers.js +15 -0
- package/api/auth/audit.d.ts +52 -0
- package/api/auth/audit.d.ts.map +1 -0
- package/api/auth/audit.js +126 -0
- package/api/auth/auth-context.d.ts +40 -0
- package/api/auth/auth-context.d.ts.map +1 -0
- package/api/auth/auth-context.js +68 -0
- package/api/auth/bootstrap-token.d.ts +50 -0
- package/api/auth/bootstrap-token.d.ts.map +1 -0
- package/api/auth/bootstrap-token.js +157 -0
- package/api/auth/index.d.ts +14 -0
- package/api/auth/index.d.ts.map +1 -0
- package/api/auth/index.js +13 -0
- package/api/auth/passwords.d.ts +65 -0
- package/api/auth/passwords.d.ts.map +1 -0
- package/api/auth/passwords.js +87 -0
- package/api/auth/sensitive-rate-limit.d.ts +56 -0
- package/api/auth/sensitive-rate-limit.d.ts.map +1 -0
- package/api/auth/sensitive-rate-limit.js +95 -0
- package/api/auth/sessions.d.ts +152 -0
- package/api/auth/sessions.d.ts.map +1 -0
- package/api/auth/sessions.js +298 -0
- package/api/auth/tokens.d.ts +3 -0
- package/api/auth/tokens.d.ts.map +1 -0
- package/api/auth/tokens.js +13 -0
- package/api/auth-bootstrap-routes.d.ts +32 -0
- package/api/auth-bootstrap-routes.d.ts.map +1 -0
- package/api/auth-bootstrap-routes.js +179 -0
- package/api/auth-pairing-compat-routes.d.ts +17 -0
- package/api/auth-pairing-compat-routes.d.ts.map +1 -0
- package/api/auth-pairing-compat-routes.js +301 -0
- package/api/auth-session-routes.d.ts +31 -0
- package/api/auth-session-routes.d.ts.map +1 -0
- package/api/auth-session-routes.js +560 -0
- package/api/auth.d.ts +153 -0
- package/api/auth.d.ts.map +1 -0
- package/api/auth.js +290 -0
- package/api/automation-node-contributors.d.ts +14 -0
- package/api/automation-node-contributors.d.ts.map +1 -0
- package/api/automation-node-contributors.js +14 -0
- package/api/automations-compat-routes.d.ts +18 -0
- package/api/automations-compat-routes.d.ts.map +1 -0
- package/api/automations-compat-routes.js +274 -0
- package/api/catalog-routes.d.ts +4 -0
- package/api/catalog-routes.d.ts.map +1 -0
- package/api/catalog-routes.js +61 -0
- package/api/compat-route-shared.d.ts +29 -0
- package/api/compat-route-shared.d.ts.map +1 -0
- package/api/compat-route-shared.js +298 -0
- package/api/credential-resolver.d.ts +31 -0
- package/api/credential-resolver.d.ts.map +1 -0
- package/api/credential-resolver.js +199 -0
- package/api/database-rows-compat-routes.d.ts +4 -0
- package/api/database-rows-compat-routes.d.ts.map +1 -0
- package/api/database-rows-compat-routes.js +100 -0
- package/api/dev-compat-routes.d.ts +11 -0
- package/api/dev-compat-routes.d.ts.map +1 -0
- package/api/dev-compat-routes.js +144 -0
- package/api/dev-console-log.d.ts +21 -0
- package/api/dev-console-log.d.ts.map +1 -0
- package/api/dev-console-log.js +65 -0
- package/api/dev-stack.d.ts +49 -0
- package/api/dev-stack.d.ts.map +1 -0
- package/api/dev-stack.js +60 -0
- package/api/local-inference-compat-routes.d.ts +16 -0
- package/api/local-inference-compat-routes.d.ts.map +1 -0
- package/api/local-inference-compat-routes.js +617 -0
- package/api/onboarding-compat-routes.d.ts +4 -0
- package/api/onboarding-compat-routes.d.ts.map +1 -0
- package/api/onboarding-compat-routes.js +207 -0
- package/api/plugins-compat-routes.d.ts +103 -0
- package/api/plugins-compat-routes.d.ts.map +1 -0
- package/api/plugins-compat-routes.js +1181 -0
- package/api/response.d.ts +4 -0
- package/api/response.d.ts.map +1 -0
- package/api/response.js +28 -0
- package/api/runtime-mode-routes.d.ts +13 -0
- package/api/runtime-mode-routes.d.ts.map +1 -0
- package/api/runtime-mode-routes.js +32 -0
- package/api/secrets-inventory-routes.d.ts +39 -0
- package/api/secrets-inventory-routes.d.ts.map +1 -0
- package/api/secrets-inventory-routes.js +487 -0
- package/api/secrets-manager-routes.d.ts +9 -0
- package/api/secrets-manager-routes.d.ts.map +1 -0
- package/api/secrets-manager-routes.js +476 -0
- package/api/sensitive-request-routes.d.ts +20 -0
- package/api/sensitive-request-routes.d.ts.map +1 -0
- package/api/sensitive-request-routes.js +489 -0
- package/api/sensitive-request-store.d.ts +39 -0
- package/api/sensitive-request-store.d.ts.map +1 -0
- package/api/sensitive-request-store.js +204 -0
- package/api/server-config-filter.d.ts +14 -0
- package/api/server-config-filter.d.ts.map +1 -0
- package/api/server-config-filter.js +77 -0
- package/api/server-cors.d.ts +30 -0
- package/api/server-cors.d.ts.map +1 -0
- package/api/server-cors.js +128 -0
- package/api/server-html.d.ts +4 -0
- package/api/server-html.d.ts.map +1 -0
- package/api/server-html.js +5 -0
- package/api/server-onboarding-compat.d.ts +31 -0
- package/api/server-onboarding-compat.d.ts.map +1 -0
- package/api/server-onboarding-compat.js +283 -0
- package/api/server-security.d.ts +11 -0
- package/api/server-security.d.ts.map +1 -0
- package/api/server-security.js +29 -0
- package/api/server-startup.d.ts +5 -0
- package/api/server-startup.d.ts.map +1 -0
- package/api/server-startup.js +74 -0
- package/api/server-wallet-trade.d.ts +10 -0
- package/api/server-wallet-trade.d.ts.map +1 -0
- package/api/server-wallet-trade.js +240 -0
- package/api/server.d.ts +32 -0
- package/api/server.d.ts.map +1 -0
- package/api/server.js +768 -0
- package/api/workbench-compat-routes.d.ts +11 -0
- package/api/workbench-compat-routes.d.ts.map +1 -0
- package/api/workbench-compat-routes.js +325 -0
- package/benchmark/cua-routes.d.ts +10 -0
- package/benchmark/cua-routes.d.ts.map +1 -0
- package/benchmark/cua-routes.js +179 -0
- package/benchmark/lifeops-bench-handler.d.ts +94 -0
- package/benchmark/lifeops-bench-handler.d.ts.map +1 -0
- package/benchmark/lifeops-bench-handler.js +280 -0
- package/benchmark/lifeops-fake-backend.d.ts +227 -0
- package/benchmark/lifeops-fake-backend.d.ts.map +1 -0
- package/benchmark/lifeops-fake-backend.js +499 -0
- package/benchmark/mock-plugin-base.d.ts +9 -0
- package/benchmark/mock-plugin-base.d.ts.map +1 -0
- package/benchmark/mock-plugin-base.js +325 -0
- package/benchmark/mock-plugin.d.ts +3 -0
- package/benchmark/mock-plugin.d.ts.map +1 -0
- package/benchmark/mock-plugin.js +504 -0
- package/benchmark/params.d.ts +2 -0
- package/benchmark/params.d.ts.map +1 -0
- package/benchmark/params.js +18 -0
- package/benchmark/plugin.d.ts +42 -0
- package/benchmark/plugin.d.ts.map +1 -0
- package/benchmark/plugin.js +422 -0
- package/benchmark/replay-capture.d.ts +73 -0
- package/benchmark/replay-capture.d.ts.map +1 -0
- package/benchmark/replay-capture.js +223 -0
- package/benchmark/server-utils.d.ts +100 -0
- package/benchmark/server-utils.d.ts.map +1 -0
- package/benchmark/server-utils.js +289 -0
- package/benchmark/server.d.ts +2 -0
- package/benchmark/server.d.ts.map +1 -0
- package/benchmark/server.js +1176 -0
- package/browser.d.ts +13 -0
- package/browser.d.ts.map +1 -0
- package/browser.js +15 -0
- package/cli/argv.d.ts +17 -0
- package/cli/argv.d.ts.map +1 -0
- package/cli/argv.js +140 -0
- package/cli/banner.d.ts +11 -0
- package/cli/banner.d.ts.map +1 -0
- package/cli/banner.js +36 -0
- package/cli/cli-name.d.ts +5 -0
- package/cli/cli-name.d.ts.map +1 -0
- package/cli/cli-name.js +21 -0
- package/cli/cli-utils.d.ts +5 -0
- package/cli/cli-utils.d.ts.map +1 -0
- package/cli/cli-utils.js +13 -0
- package/cli/command-format.d.ts +2 -0
- package/cli/command-format.d.ts.map +1 -0
- package/cli/command-format.js +20 -0
- package/cli/doctor/checks.d.ts +96 -0
- package/cli/doctor/checks.d.ts.map +1 -0
- package/cli/doctor/checks.js +483 -0
- package/cli/git-commit.d.ts +5 -0
- package/cli/git-commit.d.ts.map +1 -0
- package/cli/git-commit.js +106 -0
- package/cli/parse-duration.d.ts +5 -0
- package/cli/parse-duration.d.ts.map +1 -0
- package/cli/parse-duration.js +27 -0
- package/cli/plugins-cli.d.ts +26 -0
- package/cli/plugins-cli.d.ts.map +1 -0
- package/cli/plugins-cli.js +892 -0
- package/cli/profile-utils.d.ts +3 -0
- package/cli/profile-utils.d.ts.map +1 -0
- package/cli/profile-utils.js +21 -0
- package/cli/profile.d.ts +15 -0
- package/cli/profile.d.ts.map +1 -0
- package/cli/profile.js +93 -0
- package/cli/program/build-program.d.ts +3 -0
- package/cli/program/build-program.d.ts.map +1 -0
- package/cli/program/build-program.js +12 -0
- package/cli/program/command-registry.d.ts +3 -0
- package/cli/program/command-registry.d.ts.map +1 -0
- package/cli/program/command-registry.js +24 -0
- package/cli/program/help.d.ts +3 -0
- package/cli/program/help.d.ts.map +1 -0
- package/cli/program/help.js +57 -0
- package/cli/program/preaction.d.ts +3 -0
- package/cli/program/preaction.d.ts.map +1 -0
- package/cli/program/preaction.js +40 -0
- package/cli/program/register.auth.d.ts +51 -0
- package/cli/program/register.auth.d.ts.map +1 -0
- package/cli/program/register.auth.js +203 -0
- package/cli/program/register.benchmark.d.ts +3 -0
- package/cli/program/register.benchmark.d.ts.map +1 -0
- package/cli/program/register.benchmark.js +12 -0
- package/cli/program/register.config.d.ts +3 -0
- package/cli/program/register.config.d.ts.map +1 -0
- package/cli/program/register.config.js +150 -0
- package/cli/program/register.configure.d.ts +3 -0
- package/cli/program/register.configure.d.ts.map +1 -0
- package/cli/program/register.configure.js +18 -0
- package/cli/program/register.dashboard.d.ts +3 -0
- package/cli/program/register.dashboard.d.ts.map +1 -0
- package/cli/program/register.dashboard.js +124 -0
- package/cli/program/register.db.d.ts +3 -0
- package/cli/program/register.db.d.ts.map +1 -0
- package/cli/program/register.db.js +45 -0
- package/cli/program/register.doctor.d.ts +3 -0
- package/cli/program/register.doctor.d.ts.map +1 -0
- package/cli/program/register.doctor.js +170 -0
- package/cli/program/register.models.d.ts +3 -0
- package/cli/program/register.models.d.ts.map +1 -0
- package/cli/program/register.models.js +32 -0
- package/cli/program/register.setup.d.ts +16 -0
- package/cli/program/register.setup.d.ts.map +1 -0
- package/cli/program/register.setup.js +333 -0
- package/cli/program/register.start.d.ts +3 -0
- package/cli/program/register.start.d.ts.map +1 -0
- package/cli/program/register.start.js +95 -0
- package/cli/program/register.subclis.d.ts +4 -0
- package/cli/program/register.subclis.d.ts.map +1 -0
- package/cli/program/register.subclis.js +87 -0
- package/cli/program/register.update.d.ts +12 -0
- package/cli/program/register.update.d.ts.map +1 -0
- package/cli/program/register.update.js +173 -0
- package/cli/program.d.ts +2 -0
- package/cli/program.d.ts.map +1 -0
- package/cli/program.js +1 -0
- package/cli/run-main.d.ts +2 -0
- package/cli/run-main.d.ts.map +1 -0
- package/cli/run-main.js +71 -0
- package/cli/version.d.ts +2 -0
- package/cli/version.d.ts.map +1 -0
- package/cli/version.js +2 -0
- package/connectors/capacitor-jsc.d.ts +66 -0
- package/connectors/capacitor-jsc.d.ts.map +1 -0
- package/connectors/capacitor-jsc.js +39 -0
- package/connectors/capacitor-quickjs.d.ts +64 -0
- package/connectors/capacitor-quickjs.d.ts.map +1 -0
- package/connectors/capacitor-quickjs.js +50 -0
- package/connectors/capacitor-sqlite.d.ts +41 -0
- package/connectors/capacitor-sqlite.d.ts.map +1 -0
- package/connectors/capacitor-sqlite.js +87 -0
- package/diagnostics/integration-observability.d.ts +40 -0
- package/diagnostics/integration-observability.d.ts.map +1 -0
- package/diagnostics/integration-observability.js +68 -0
- package/entry.d.ts +10 -0
- package/entry.d.ts.map +1 -0
- package/entry.js +66 -0
- package/index.d.ts +34 -4
- package/index.d.ts.map +1 -1
- package/index.js +42 -6
- package/package.json +81 -151
- package/packaging/PUBLISHING_GUIDE.md +707 -0
- package/packaging/debian/changelog +9 -0
- package/packaging/debian/control +26 -0
- package/packaging/debian/copyright +27 -0
- package/packaging/debian/elizaos-app.service +15 -0
- package/packaging/debian/install +4 -0
- package/packaging/debian/postinst +28 -0
- package/packaging/debian/prerm +14 -0
- package/packaging/debian/rules +44 -0
- package/packaging/debian/source/format +1 -0
- package/packaging/flatpak/README.md +150 -0
- package/packaging/flatpak/ai.elizaos.App.desktop +11 -0
- package/packaging/flatpak/ai.elizaos.App.metainfo.xml +81 -0
- package/packaging/flatpak/ai.elizaos.App.store.yml +142 -0
- package/packaging/flatpak/ai.elizaos.App.yml +142 -0
- package/packaging/flatpak/elizaos-app-wrapper.sh +5 -0
- package/packaging/flatpak/elizaos-app-wrapper.store.sh +16 -0
- package/packaging/flatpak/icons/128x128/ai.elizaos.App.png +0 -0
- package/packaging/flatpak/icons/256x256/ai.elizaos.App.png +0 -0
- package/packaging/flatpak/icons/512x512/ai.elizaos.App.png +0 -0
- package/packaging/homebrew/README.md +80 -0
- package/packaging/homebrew/elizaos-app.cask.rb +60 -0
- package/packaging/homebrew/elizaos-app.rb +49 -0
- package/packaging/inno/ElizaOSApp.iss +53 -0
- package/packaging/inno/build-inno.ps1 +231 -0
- package/packaging/msix/AppxManifest.store.xml +79 -0
- package/packaging/msix/AppxManifest.xml +53 -0
- package/packaging/msix/README.md +201 -0
- package/packaging/msix/assets/LargeTile.png +0 -0
- package/packaging/msix/assets/Square150x150Logo.png +0 -0
- package/packaging/msix/assets/Square44x44Logo.png +0 -0
- package/packaging/msix/assets/StoreLogo.png +0 -0
- package/packaging/msix/assets/Wide310x150Logo.png +0 -0
- package/packaging/msix/build-msix.ps1 +206 -0
- package/packaging/msix/generate-placeholder-assets.ps1 +49 -0
- package/packaging/msix/store/description.md +31 -0
- package/packaging/msix/store/listing.json +27 -0
- package/packaging/pypi/README.md +14 -0
- package/packaging/pypi/elizaos_app/__init__.py +7 -0
- package/packaging/pypi/elizaos_app/__main__.py +6 -0
- package/packaging/pypi/elizaos_app/cli.py +21 -0
- package/packaging/pypi/elizaos_app/loader.py +127 -0
- package/packaging/pypi/elizaos_app/py.typed +1 -0
- package/packaging/pypi/pyproject.toml +38 -0
- package/packaging/snap/snapcraft.yaml +560 -0
- package/packaging/test-packaging.sh +309 -0
- package/patches/@noble%2Fcurves@2.0.1.patch +33 -0
- package/patches/@pixiv%2Fthree-vrm@3.5.2.patch +26 -0
- package/patches/coding-agent-adapters@0.16.3.patch +44 -0
- package/patches/electrobun@1.16.0.patch +13 -0
- package/patches/llama-cpp-capacitor@0.1.5.patch +2387 -0
- package/patches/proper-lockfile@4.1.2.patch +14 -0
- package/patches/pty-manager@1.11.0.patch +194 -0
- package/permissions/types.d.ts +8 -0
- package/permissions/types.d.ts.map +1 -0
- package/permissions/types.js +7 -0
- package/platform/agent-browser-stub.d.ts +27 -0
- package/platform/agent-browser-stub.d.ts.map +1 -0
- package/platform/agent-browser-stub.js +16 -0
- package/platform/empty-node-module.d.ts +31 -0
- package/platform/empty-node-module.d.ts.map +1 -0
- package/platform/empty-node-module.js +22 -0
- package/platforms/android/Gemfile +6 -0
- package/platforms/android/README.md +79 -0
- package/platforms/android/app/build.gradle +124 -0
- package/platforms/android/app/capacitor.build.gradle +32 -0
- package/platforms/android/app/proguard-rules.pro +46 -0
- package/platforms/android/app/src/androidTest/java/ai/elizaos/app/ElizaOsInstrumentedTest.java +162 -0
- package/platforms/android/app/src/androidTest/java/com/getcapacitor/myapp/ExampleInstrumentedTest.java +26 -0
- package/platforms/android/app/src/main/AndroidManifest.xml +83 -0
- package/platforms/android/app/src/main/java/ai/elizaos/app/AgentPlugin.java +232 -0
- package/platforms/android/app/src/main/java/ai/elizaos/app/ElizaAgentService.java +1514 -0
- package/platforms/android/app/src/main/java/ai/elizaos/app/ElizaAssistActivity.java +21 -0
- package/platforms/android/app/src/main/java/ai/elizaos/app/ElizaBootReceiver.java +61 -0
- package/platforms/android/app/src/main/java/ai/elizaos/app/ElizaBrowserActivity.java +39 -0
- package/platforms/android/app/src/main/java/ai/elizaos/app/ElizaCalendarActivity.java +75 -0
- package/platforms/android/app/src/main/java/ai/elizaos/app/ElizaCameraActivity.java +54 -0
- package/platforms/android/app/src/main/java/ai/elizaos/app/ElizaClockActivity.java +70 -0
- package/platforms/android/app/src/main/java/ai/elizaos/app/ElizaContactsActivity.java +56 -0
- package/platforms/android/app/src/main/java/ai/elizaos/app/ElizaDialActivity.java +83 -0
- package/platforms/android/app/src/main/java/ai/elizaos/app/ElizaInCallService.java +168 -0
- package/platforms/android/app/src/main/java/ai/elizaos/app/ElizaMmsReceiver.java +70 -0
- package/platforms/android/app/src/main/java/ai/elizaos/app/ElizaNativeBridge.java +38 -0
- package/platforms/android/app/src/main/java/ai/elizaos/app/ElizaRespondViaMessageService.java +119 -0
- package/platforms/android/app/src/main/java/ai/elizaos/app/ElizaSmsComposeActivity.java +50 -0
- package/platforms/android/app/src/main/java/ai/elizaos/app/ElizaSmsReceiver.java +84 -0
- package/platforms/android/app/src/main/java/ai/elizaos/app/GatewayConnectionService.java +211 -0
- package/platforms/android/app/src/main/java/ai/elizaos/app/MainActivity.java +202 -0
- package/platforms/android/app/src/main/res/drawable/ic_launcher_background.xml +170 -0
- package/platforms/android/app/src/main/res/drawable/splash.png +0 -0
- package/platforms/android/app/src/main/res/drawable-land-hdpi/splash.png +0 -0
- package/platforms/android/app/src/main/res/drawable-land-mdpi/splash.png +0 -0
- package/platforms/android/app/src/main/res/drawable-land-xhdpi/splash.png +0 -0
- package/platforms/android/app/src/main/res/drawable-land-xxhdpi/splash.png +0 -0
- package/platforms/android/app/src/main/res/drawable-land-xxxhdpi/splash.png +0 -0
- package/platforms/android/app/src/main/res/drawable-port-hdpi/splash.png +0 -0
- package/platforms/android/app/src/main/res/drawable-port-mdpi/splash.png +0 -0
- package/platforms/android/app/src/main/res/drawable-port-xhdpi/splash.png +0 -0
- package/platforms/android/app/src/main/res/drawable-port-xxhdpi/splash.png +0 -0
- package/platforms/android/app/src/main/res/drawable-port-xxxhdpi/splash.png +0 -0
- package/platforms/android/app/src/main/res/drawable-v24/ic_launcher_foreground.xml +34 -0
- package/platforms/android/app/src/main/res/layout/activity_main.xml +12 -0
- package/platforms/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml +5 -0
- package/platforms/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml +5 -0
- package/platforms/android/app/src/main/res/mipmap-hdpi/ic_launcher.png +0 -0
- package/platforms/android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png +0 -0
- package/platforms/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png +0 -0
- package/platforms/android/app/src/main/res/mipmap-mdpi/ic_launcher.png +0 -0
- package/platforms/android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png +0 -0
- package/platforms/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png +0 -0
- package/platforms/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png +0 -0
- package/platforms/android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png +0 -0
- package/platforms/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png +0 -0
- package/platforms/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png +0 -0
- package/platforms/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png +0 -0
- package/platforms/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png +0 -0
- package/platforms/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png +0 -0
- package/platforms/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png +0 -0
- package/platforms/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png +0 -0
- package/platforms/android/app/src/main/res/values/ic_launcher_background.xml +4 -0
- package/platforms/android/app/src/main/res/values/strings.xml +7 -0
- package/platforms/android/app/src/main/res/values/styles.xml +22 -0
- package/platforms/android/app/src/main/res/xml/file_paths.xml +5 -0
- package/platforms/android/app/src/test/java/com/getcapacitor/myapp/ExampleUnitTest.java +18 -0
- package/platforms/android/build.gradle +63 -0
- package/platforms/android/capacitor-cordova-android-plugins/build.gradle +53 -0
- package/platforms/android/capacitor-cordova-android-plugins/cordova.variables.gradle +3 -0
- package/platforms/android/capacitor-cordova-android-plugins/src/main/AndroidManifest.xml +3 -0
- package/platforms/android/capacitor-cordova-android-plugins/src/main/java/.gitkeep +1 -0
- package/platforms/android/capacitor-cordova-android-plugins/src/main/res/.gitkeep +1 -0
- package/platforms/android/capacitor.settings.gradle +45 -0
- package/platforms/android/fastlane/Appfile +2 -0
- package/platforms/android/fastlane/Fastfile +59 -0
- package/platforms/android/fastlane/metadata/android/en-US/full_description.txt +24 -0
- package/platforms/android/fastlane/metadata/android/en-US/short_description.txt +1 -0
- package/platforms/android/fastlane/metadata/android/en-US/title.txt +1 -0
- package/platforms/android/fastlane/metadata/android/en-US/video.txt +0 -0
- package/platforms/android/gradle/wrapper/gradle-wrapper.jar +0 -0
- package/platforms/android/gradle/wrapper/gradle-wrapper.properties +7 -0
- package/platforms/android/gradle.properties +27 -0
- package/platforms/android/gradlew +251 -0
- package/platforms/android/gradlew.bat +94 -0
- package/platforms/android/settings.gradle +13 -0
- package/platforms/android/variables.gradle +17 -0
- package/platforms/electrobun/.generated/brand-config.json +8 -0
- package/platforms/electrobun/README.md +44 -0
- package/platforms/electrobun/assets/appIcon.ico +0 -0
- package/platforms/electrobun/assets/appIcon.iconset/icon_128x128.png +0 -0
- package/platforms/electrobun/assets/appIcon.iconset/icon_128x128@2x.png +0 -0
- package/platforms/electrobun/assets/appIcon.iconset/icon_16x16.png +0 -0
- package/platforms/electrobun/assets/appIcon.iconset/icon_16x16@2x.png +0 -0
- package/platforms/electrobun/assets/appIcon.iconset/icon_256x256.png +0 -0
- package/platforms/electrobun/assets/appIcon.iconset/icon_256x256@2x.png +0 -0
- package/platforms/electrobun/assets/appIcon.iconset/icon_32x32.png +0 -0
- package/platforms/electrobun/assets/appIcon.iconset/icon_32x32@2x.png +0 -0
- package/platforms/electrobun/assets/appIcon.iconset/icon_512x512.png +0 -0
- package/platforms/electrobun/assets/appIcon.iconset/icon_512x512@2x.png +0 -0
- package/platforms/electrobun/assets/appIcon.png +0 -0
- package/platforms/electrobun/assets/brand-config.json +8 -0
- package/platforms/electrobun/biome.json +11 -0
- package/platforms/electrobun/electrobun.config.ts +435 -0
- package/platforms/electrobun/entitlements/README.md +54 -0
- package/platforms/electrobun/entitlements/mas-child.entitlements +10 -0
- package/platforms/electrobun/entitlements/mas.entitlements +41 -0
- package/platforms/electrobun/native/macos/window-effects.mm +1030 -0
- package/platforms/electrobun/package.json +42 -0
- package/platforms/electrobun/scripts/bin/zip +2 -0
- package/platforms/electrobun/scripts/build-macos-effects.sh +31 -0
- package/platforms/electrobun/scripts/build-whisper-universal.sh +137 -0
- package/platforms/electrobun/scripts/build-whisper.sh +95 -0
- package/platforms/electrobun/scripts/ensure-whisper-model.sh +93 -0
- package/platforms/electrobun/scripts/hdiutil-wrapper.sh +33 -0
- package/platforms/electrobun/scripts/lib/app-dir.mjs +74 -0
- package/platforms/electrobun/scripts/lib/repo-root.mjs +77 -0
- package/platforms/electrobun/scripts/local-adhoc-sign-macos.ts +214 -0
- package/platforms/electrobun/scripts/macos-direct-launcher.c +84 -0
- package/platforms/electrobun/scripts/postwrap-diagnostics.ts +423 -0
- package/platforms/electrobun/scripts/postwrap-sign-runtime-macos.ts +352 -0
- package/platforms/electrobun/scripts/sign-windows.ps1 +121 -0
- package/platforms/electrobun/scripts/smoke-test-windows.ps1 +907 -0
- package/platforms/electrobun/scripts/smoke-test.sh +1186 -0
- package/platforms/electrobun/scripts/stage-macos-release-artifacts.sh +491 -0
- package/platforms/electrobun/scripts/sync-web-assets.mjs +48 -0
- package/platforms/electrobun/scripts/verify-rpc-handlers.ts +162 -0
- package/platforms/electrobun/scripts/verify-windows-installer-proof.ps1 +203 -0
- package/platforms/electrobun/scripts/xcrun-wrapper.sh +80 -0
- package/platforms/electrobun/scripts/zip-wrapper.sh +6 -0
- package/platforms/electrobun/src/__stubs__/bun-ffi.ts +51 -0
- package/platforms/electrobun/src/__stubs__/electrobun-bun.ts +20 -0
- package/platforms/electrobun/src/agent-ready-state.ts +35 -0
- package/platforms/electrobun/src/agent-reset-from-main.ts +87 -0
- package/platforms/electrobun/src/api-base.ts +169 -0
- package/platforms/electrobun/src/application-menu-action-registry.ts +21 -0
- package/platforms/electrobun/src/application-menu.ts +418 -0
- package/platforms/electrobun/src/background-notice.ts +65 -0
- package/platforms/electrobun/src/brand-config.ts +184 -0
- package/platforms/electrobun/src/bridge/browser-tabs-renderer-registry.ts +60 -0
- package/platforms/electrobun/src/bridge/electrobun-direct-rpc.ts +430 -0
- package/platforms/electrobun/src/bridge/electrobun-preload.ts +1 -0
- package/platforms/electrobun/src/bridge/electrobun-stub.ts +21 -0
- package/platforms/electrobun/src/browser-workspace-bridge-server.ts +284 -0
- package/platforms/electrobun/src/cloud-auth-window.ts +216 -0
- package/platforms/electrobun/src/cloud-disconnect-from-main.ts +118 -0
- package/platforms/electrobun/src/constants.ts +2 -0
- package/platforms/electrobun/src/desktop-http-request.test.ts +85 -0
- package/platforms/electrobun/src/desktop-http-request.ts +103 -0
- package/platforms/electrobun/src/desktop-test-bridge-server.ts +248 -0
- package/platforms/electrobun/src/devtools-layout.ts +63 -0
- package/platforms/electrobun/src/diagnostic-format.ts +65 -0
- package/platforms/electrobun/src/fatal-shutdown.test.ts +30 -0
- package/platforms/electrobun/src/fatal-shutdown.ts +10 -0
- package/platforms/electrobun/src/floating-chat-window.ts +239 -0
- package/platforms/electrobun/src/index.ts +2510 -0
- package/platforms/electrobun/src/libMacWindowEffects.dylib +0 -0
- package/platforms/electrobun/src/lifecycle/api-base-owner.ts +119 -0
- package/platforms/electrobun/src/lifecycle/desktop-session-prime.ts +77 -0
- package/platforms/electrobun/src/logger.ts +23 -0
- package/platforms/electrobun/src/main-window-runtime.ts +117 -0
- package/platforms/electrobun/src/main-window-session.ts +88 -0
- package/platforms/electrobun/src/menu-reset-from-main.ts +211 -0
- package/platforms/electrobun/src/native/agent.ts +1963 -0
- package/platforms/electrobun/src/native/auth-bridge.ts +525 -0
- package/platforms/electrobun/src/native/browser-workspace.ts +574 -0
- package/platforms/electrobun/src/native/camera.ts +68 -0
- package/platforms/electrobun/src/native/canvas.ts +504 -0
- package/platforms/electrobun/src/native/credentials.ts +765 -0
- package/platforms/electrobun/src/native/desktop.ts +2317 -0
- package/platforms/electrobun/src/native/editor-bridge.ts +292 -0
- package/platforms/electrobun/src/native/file-watcher.ts +220 -0
- package/platforms/electrobun/src/native/gateway.ts +218 -0
- package/platforms/electrobun/src/native/gpu-window.ts +301 -0
- package/platforms/electrobun/src/native/index.ts +105 -0
- package/platforms/electrobun/src/native/location.ts +110 -0
- package/platforms/electrobun/src/native/loopback-port.ts +81 -0
- package/platforms/electrobun/src/native/mac-window-effects.ts +178 -0
- package/platforms/electrobun/src/native/music-player.ts +61 -0
- package/platforms/electrobun/src/native/permissions-shared.ts +171 -0
- package/platforms/electrobun/src/native/permissions.ts +242 -0
- package/platforms/electrobun/src/native/power-state.ts +195 -0
- package/platforms/electrobun/src/native/screencapture.ts +654 -0
- package/platforms/electrobun/src/native/steward.ts +343 -0
- package/platforms/electrobun/src/native/swabble.ts +349 -0
- package/platforms/electrobun/src/native/talkmode.ts +441 -0
- package/platforms/electrobun/src/native/webgpu-browser-support.ts +220 -0
- package/platforms/electrobun/src/native/whisper.ts +280 -0
- package/platforms/electrobun/src/preload-validation.ts +65 -0
- package/platforms/electrobun/src/preload.js +1 -0
- package/platforms/electrobun/src/print-electrobun-dev-settings-banner.ts +140 -0
- package/platforms/electrobun/src/renderer-static.ts +77 -0
- package/platforms/electrobun/src/rpc-handlers.ts +1079 -0
- package/platforms/electrobun/src/rpc-schema.ts +1870 -0
- package/platforms/electrobun/src/runtime-layout.ts +150 -0
- package/platforms/electrobun/src/runtime-permissions.ts +131 -0
- package/platforms/electrobun/src/screenshot-dev-server.ts +125 -0
- package/platforms/electrobun/src/startup-trace.ts +351 -0
- package/platforms/electrobun/src/surface-windows.ts +475 -0
- package/platforms/electrobun/src/types/web-speech.d.ts +52 -0
- package/platforms/electrobun/src/types.ts +18 -0
- package/platforms/electrobun/src/windows-cef-profile.ts +124 -0
- package/platforms/electrobun/tsconfig.json +75 -0
- package/platforms/electrobun/vitest.electrobun.config.ts +54 -0
- package/platforms/ios/App/App/App.entitlements +18 -0
- package/platforms/ios/App/App/AppDelegate.swift +93 -0
- package/platforms/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-ios-marketing-1024.png +0 -0
- package/platforms/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-ipad-20x20@1x.png +0 -0
- package/platforms/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-ipad-20x20@2x.png +0 -0
- package/platforms/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-ipad-29x29@1x.png +0 -0
- package/platforms/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-ipad-29x29@2x.png +0 -0
- package/platforms/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-ipad-40x40@1x.png +0 -0
- package/platforms/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-ipad-40x40@2x.png +0 -0
- package/platforms/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-ipad-76x76@1x.png +0 -0
- package/platforms/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-ipad-76x76@2x.png +0 -0
- package/platforms/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-ipad-83_5x83_5@2x.png +0 -0
- package/platforms/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-iphone-20x20@2x.png +0 -0
- package/platforms/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-iphone-20x20@3x.png +0 -0
- package/platforms/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-iphone-29x29@2x.png +0 -0
- package/platforms/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-iphone-29x29@3x.png +0 -0
- package/platforms/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-iphone-40x40@2x.png +0 -0
- package/platforms/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-iphone-40x40@3x.png +0 -0
- package/platforms/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-iphone-60x60@2x.png +0 -0
- package/platforms/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-iphone-60x60@3x.png +0 -0
- package/platforms/ios/App/App/Assets.xcassets/AppIcon.appiconset/Contents.json +116 -0
- package/platforms/ios/App/App/Assets.xcassets/Contents.json +6 -0
- package/platforms/ios/App/App/Assets.xcassets/Splash.imageset/Contents.json +23 -0
- package/platforms/ios/App/App/Assets.xcassets/Splash.imageset/splash-2732x2732-1.png +0 -0
- package/platforms/ios/App/App/Assets.xcassets/Splash.imageset/splash-2732x2732-2.png +0 -0
- package/platforms/ios/App/App/Assets.xcassets/Splash.imageset/splash-2732x2732.png +0 -0
- package/platforms/ios/App/App/Base.lproj/LaunchScreen.storyboard +32 -0
- package/platforms/ios/App/App/Base.lproj/Main.storyboard +19 -0
- package/platforms/ios/App/App/ElizaIntentPlugin.swift +185 -0
- package/platforms/ios/App/App/Info.plist +123 -0
- package/platforms/ios/App/App/PrivacyInfo.xcprivacy +55 -0
- package/platforms/ios/App/App/SceneDelegate.swift +77 -0
- package/platforms/ios/App/App/WebsiteBlockerContentExtension/ActionRequestHandler.swift +142 -0
- package/platforms/ios/App/App/WebsiteBlockerContentExtension/Info.plist +29 -0
- package/platforms/ios/App/App/WebsiteBlockerContentExtension/PrivacyInfo.xcprivacy +23 -0
- package/platforms/ios/App/App/WebsiteBlockerContentExtension/WebsiteBlockerContentExtension.entitlements +10 -0
- package/platforms/ios/App/App.xcodeproj/project.pbxproj +596 -0
- package/platforms/ios/App/App.xcworkspace/contents.xcworkspacedata +10 -0
- package/platforms/ios/App/App.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +8 -0
- package/platforms/ios/App/ExportOptions.plist +18 -0
- package/platforms/ios/App/Podfile +51 -0
- package/platforms/ios/App/Podfile.lock +131 -0
- package/platforms/ios/Gemfile +6 -0
- package/platforms/ios/fastlane/Appfile +4 -0
- package/platforms/ios/fastlane/Fastfile +94 -0
- package/platforms/ios/fastlane/Matchfile +12 -0
- package/platforms/ios/fastlane/metadata/en-US/description.txt +22 -0
- package/platforms/ios/fastlane/metadata/en-US/keywords.txt +1 -0
- package/platforms/ios/fastlane/metadata/en-US/marketing_url.txt +1 -0
- package/platforms/ios/fastlane/metadata/en-US/name.txt +1 -0
- package/platforms/ios/fastlane/metadata/en-US/privacy_url.txt +1 -0
- package/platforms/ios/fastlane/metadata/en-US/promotional_text.txt +1 -0
- package/platforms/ios/fastlane/metadata/en-US/subtitle.txt +1 -0
- package/platforms/ios/fastlane/metadata/en-US/support_url.txt +1 -0
- package/register-runtime-hooks.d.ts +2 -0
- package/register-runtime-hooks.d.ts.map +1 -0
- package/register-runtime-hooks.js +13 -0
- package/registry/generate-apps.d.ts +2 -0
- package/registry/generate-apps.d.ts.map +1 -0
- package/registry/generate-apps.js +338 -0
- package/registry/generate.d.ts +2 -0
- package/registry/generate.d.ts.map +1 -0
- package/registry/generate.js +506 -0
- package/registry/index.d.ts +6 -0
- package/registry/index.d.ts.map +1 -0
- package/registry/index.js +68 -0
- package/registry/loader.d.ts +27 -0
- package/registry/loader.d.ts.map +1 -0
- package/registry/loader.js +111 -0
- package/registry/schema.d.ts +989 -0
- package/registry/schema.d.ts.map +1 -0
- package/registry/schema.js +264 -0
- package/runtime/api-dev-settings-banner.d.ts +7 -0
- package/runtime/api-dev-settings-banner.d.ts.map +1 -0
- package/runtime/api-dev-settings-banner.js +104 -0
- package/runtime/app-route-plugin-registry.d.ts +3 -0
- package/runtime/app-route-plugin-registry.d.ts.map +1 -0
- package/runtime/app-route-plugin-registry.js +1 -0
- package/runtime/build-character-from-config.d.ts +3 -0
- package/runtime/build-character-from-config.d.ts.map +1 -0
- package/runtime/build-character-from-config.js +59 -0
- package/runtime/build-variant.d.ts +8 -0
- package/runtime/build-variant.d.ts.map +1 -0
- package/runtime/build-variant.js +7 -0
- package/runtime/channel-plugin-map.d.ts +6 -0
- package/runtime/channel-plugin-map.d.ts.map +1 -0
- package/runtime/channel-plugin-map.js +38 -0
- package/runtime/dev-server.d.ts +2 -0
- package/runtime/dev-server.d.ts.map +1 -0
- package/runtime/dev-server.js +383 -0
- package/runtime/dev-settings-figlet-heading.d.ts +22 -0
- package/runtime/dev-settings-figlet-heading.d.ts.map +1 -0
- package/runtime/dev-settings-figlet-heading.js +55 -0
- package/runtime/eliza.d.ts +21 -0
- package/runtime/eliza.d.ts.map +1 -0
- package/runtime/eliza.js +863 -0
- package/runtime/embedding-manager-support.d.ts +77 -0
- package/runtime/embedding-manager-support.d.ts.map +1 -0
- package/runtime/embedding-manager-support.js +309 -0
- package/runtime/embedding-presets.d.ts +5 -0
- package/runtime/embedding-presets.d.ts.map +1 -0
- package/runtime/embedding-presets.js +47 -0
- package/runtime/embedding-warmup-policy.d.ts +13 -0
- package/runtime/embedding-warmup-policy.d.ts.map +1 -0
- package/runtime/embedding-warmup-policy.js +33 -0
- package/runtime/ensure-local-inference-handler.d.ts +25 -0
- package/runtime/ensure-local-inference-handler.d.ts.map +1 -0
- package/runtime/ensure-local-inference-handler.js +389 -0
- package/runtime/ensure-text-to-speech-handler.d.ts +18 -0
- package/runtime/ensure-text-to-speech-handler.d.ts.map +1 -0
- package/runtime/ensure-text-to-speech-handler.js +50 -0
- package/runtime/error-handlers.d.ts +12 -0
- package/runtime/error-handlers.d.ts.map +1 -0
- package/runtime/error-handlers.js +49 -0
- package/runtime/mobile-local-inference-gate.d.ts +21 -0
- package/runtime/mobile-local-inference-gate.d.ts.map +1 -0
- package/runtime/mobile-local-inference-gate.js +24 -0
- package/runtime/mobile-safe-runtime.d.ts +123 -0
- package/runtime/mobile-safe-runtime.d.ts.map +1 -0
- package/runtime/mobile-safe-runtime.js +290 -0
- package/runtime/mode/remote-forwarder.d.ts +35 -0
- package/runtime/mode/remote-forwarder.d.ts.map +1 -0
- package/runtime/mode/remote-forwarder.js +119 -0
- package/runtime/mode/route-mode-guard.d.ts +21 -0
- package/runtime/mode/route-mode-guard.d.ts.map +1 -0
- package/runtime/mode/route-mode-guard.js +30 -0
- package/runtime/mode/route-mode-matrix.d.ts +64 -0
- package/runtime/mode/route-mode-matrix.d.ts.map +1 -0
- package/runtime/mode/route-mode-matrix.js +125 -0
- package/runtime/mode/runtime-mode.d.ts +72 -0
- package/runtime/mode/runtime-mode.d.ts.map +1 -0
- package/runtime/mode/runtime-mode.js +167 -0
- package/runtime/runtime-bootstrap-policy.d.ts +17 -0
- package/runtime/runtime-bootstrap-policy.d.ts.map +1 -0
- package/runtime/runtime-bootstrap-policy.js +37 -0
- package/runtime/sandbox-policy.d.ts +8 -0
- package/runtime/sandbox-policy.d.ts.map +1 -0
- package/runtime/sandbox-policy.js +7 -0
- package/runtime/startup-overlay.d.ts +14 -0
- package/runtime/startup-overlay.d.ts.map +1 -0
- package/runtime/startup-overlay.js +55 -0
- package/runtime/telegram-standalone-handler.d.ts +34 -0
- package/runtime/telegram-standalone-handler.d.ts.map +1 -0
- package/runtime/telegram-standalone-handler.js +195 -0
- package/runtime/telegram-standalone-policy.d.ts +2 -0
- package/runtime/telegram-standalone-policy.d.ts.map +1 -0
- package/runtime/telegram-standalone-policy.js +14 -0
- package/scripts/README.md +27 -0
- package/scripts/align-electrobun-version.mjs +37 -0
- package/scripts/aosp/README.md +66 -0
- package/scripts/aosp/avd-test.mjs +403 -0
- package/scripts/aosp/boot-validate.mjs +536 -0
- package/scripts/aosp/build-aosp.mjs +448 -0
- package/scripts/aosp/build-bootanimation.mjs +178 -0
- package/scripts/aosp/capture-screens.mjs +325 -0
- package/scripts/aosp/compile-libllama.mjs +1333 -0
- package/scripts/aosp/compile-shim.mjs +328 -0
- package/scripts/aosp/e2e-validate.mjs +225 -0
- package/scripts/aosp/lib/load-variant-config.mjs +182 -0
- package/scripts/aosp/lint-init-rc.mjs +258 -0
- package/scripts/aosp/llama-cpp-patches/README.md +49 -0
- package/scripts/aosp/llama-cpp-patches/apply-patches.mjs +198 -0
- package/scripts/aosp/llama-cpp-patches/polarquant/0001-Q4_POLAR-register-GGML_TYPE_Q4_POLAR-45-and-block_q4.patch +108 -0
- package/scripts/aosp/llama-cpp-patches/polarquant/0002-Q4_POLAR-vendor-PolarQuant-ref-kernels-into-ggml-bas.patch +460 -0
- package/scripts/aosp/llama-cpp-patches/polarquant/0003-tests-cover-Q4_POLAR-fix-latent-buffer-overflow.patch +102 -0
- package/scripts/aosp/llama-cpp-patches/polarquant/0004-Q4_POLAR-gate-QJL-residual-on-runtime-flag-default-o.patch +97 -0
- package/scripts/aosp/llama-cpp-patches/qjl/0001-ggml-add-GGML_TYPE_QJL1_256-GGML_OP_ATTN_SCORE_QJL-e.patch +120 -0
- package/scripts/aosp/llama-cpp-patches/qjl/0002-ggml-register-QJL1_256-type-traits-ATTN_SCORE_QJL-op.patch +1392 -0
- package/scripts/aosp/llama-cpp-patches/qjl/0003-ggml-set-QJL1_256-blck_size-to-head_dim-128-not-sket.patch +56 -0
- package/scripts/aosp/llama-cpp-patches/qjl/0004-tests-add-test-qjl-cache-verifying-type-traits-score.patch +335 -0
- package/scripts/aosp/llama-cpp-patches/qjl/0005-ggml-flip-block_qjl1_256-to-signs-then-norm.patch +69 -0
- package/scripts/aosp/llama-shim/eliza_llama_shim.c +276 -0
- package/scripts/aosp/seccomp-shim/loader-wrap.c +141 -0
- package/scripts/aosp/seccomp-shim/sigsys-handler.c +338 -0
- package/scripts/aosp/sim.mjs +277 -0
- package/scripts/aosp/smoke-cuttlefish.mjs +673 -0
- package/scripts/aosp/stage-default-models.mjs +340 -0
- package/scripts/aosp/stage-models-dfm.mjs +384 -0
- package/scripts/aosp/sync-to-aosp.mjs +134 -0
- package/scripts/aosp/validate.mjs +1273 -0
- package/scripts/aosp/variant-config-schema.ts +10 -0
- package/scripts/audit-live-test-surface.mjs +590 -0
- package/scripts/audit-server-test-surface.mjs +163 -0
- package/scripts/benchmark-preflight.mjs +170 -0
- package/scripts/bin/.gitkeep +0 -0
- package/scripts/build-bundled-agent-skills-artifact.mjs +58 -0
- package/scripts/build-bundled-orchestrator-artifact.mjs +66 -0
- package/scripts/build-capacitor-app.mjs +122 -0
- package/scripts/build-electrobun-preload.mjs +117 -0
- package/scripts/build-flatpak.mjs +125 -0
- package/scripts/build-image.sh +461 -0
- package/scripts/build-llama-cpp-dflash.mjs +1866 -0
- package/scripts/build-native-plugins.mjs +153 -0
- package/scripts/build-patched-electrobun-cli.mjs +424 -0
- package/scripts/build-win.mjs +82 -0
- package/scripts/bump-elizaos.sh +438 -0
- package/scripts/check-i18n.mjs +328 -0
- package/scripts/check-secret-hygiene.mjs +344 -0
- package/scripts/check-upstream-drift.mjs +102 -0
- package/scripts/clean-repo.mjs +187 -0
- package/scripts/codesign-mas.mjs +297 -0
- package/scripts/container-entrypoint.mjs +101 -0
- package/scripts/coordinator-cross-platform-review.mjs +192 -0
- package/scripts/copy-package-assets.mjs +31 -0
- package/scripts/copy-runtime-node-modules.ts +1782 -0
- package/scripts/coverage-policy.d.mts +16 -0
- package/scripts/coverage-policy.mjs +38 -0
- package/scripts/css-coverage.mjs +241 -0
- package/scripts/deploy-image.sh +318 -0
- package/scripts/desktop-build.mjs +867 -0
- package/scripts/desktop-stack-status.mjs +80 -0
- package/scripts/dev-platform.mjs +975 -0
- package/scripts/dev-ui.mjs +1178 -0
- package/scripts/dev-win.mjs +25 -0
- package/scripts/disable-local-eliza-workspace.mjs +420 -0
- package/scripts/docker-ci-smoke.sh +500 -0
- package/scripts/docker-entrypoint.sh +11 -0
- package/scripts/docker-runtime-review.mjs +230 -0
- package/scripts/docs-list.js +206 -0
- package/scripts/ensure-avatars.mjs +335 -0
- package/scripts/ensure-bundled-workspaces.mjs +143 -0
- package/scripts/ensure-capacitor-platform.mjs +58 -0
- package/scripts/ensure-electrobun-core.mjs +318 -0
- package/scripts/ensure-generated-core-proto-js.mjs +125 -0
- package/scripts/ensure-shared-i18n-data.mjs +67 -0
- package/scripts/ensure-skills.mjs +177 -0
- package/scripts/ensure-type-package-aliases.mjs +246 -0
- package/scripts/ensure-vision-deps.mjs +196 -0
- package/scripts/entry.ts +11 -0
- package/scripts/find-collisions.mjs +765 -0
- package/scripts/find-duplicate-components.mjs +203 -0
- package/scripts/fix-workspace-deps.mjs +328 -0
- package/scripts/generate-onboarding-voicelines.mjs +194 -0
- package/scripts/generate-plugin-index.js +1055 -0
- package/scripts/generate-static-asset-manifest.mjs +15 -0
- package/scripts/generated/static-asset-manifest.json +4 -0
- package/scripts/i18n-dynamic-keys.json +128 -0
- package/scripts/init-submodules.mjs +425 -0
- package/scripts/ios-xcframework/README.md +233 -0
- package/scripts/ios-xcframework/build-xcframework.mjs +487 -0
- package/scripts/kernel-patches/metal-kernels.mjs +656 -0
- package/scripts/kernel-patches/vulkan-dispatch-patches/01-vulkan-shaders-gen.patch +41 -0
- package/scripts/kernel-patches/vulkan-dispatch-patches/02-ggml-vulkan-pipelines.patch +86 -0
- package/scripts/kernel-patches/vulkan-kernels.mjs +281 -0
- package/scripts/lib/allocate-loopback-port.mjs +58 -0
- package/scripts/lib/api-supervisor.mjs +115 -0
- package/scripts/lib/app-dir.mjs +74 -0
- package/scripts/lib/asset-cdn.mjs +118 -0
- package/scripts/lib/bun-version-guard.mjs +44 -0
- package/scripts/lib/capacitor-platform-templates.mjs +306 -0
- package/scripts/lib/capacitor-plugin-build-needed.mjs +79 -0
- package/scripts/lib/capacitor-plugin-names.mjs +35 -0
- package/scripts/lib/desktop-preflight.mjs +122 -0
- package/scripts/lib/desktop-stack-status.mjs +151 -0
- package/scripts/lib/dev-ui-onchain.mjs +22 -0
- package/scripts/lib/dev-ui-vision.mjs +15 -0
- package/scripts/lib/kill-process-tree.mjs +87 -0
- package/scripts/lib/kill-ui-listen-port.mjs +74 -0
- package/scripts/lib/node-path-env.mjs +11 -0
- package/scripts/lib/orchestrator-desktop-dev-banner.mjs +285 -0
- package/scripts/lib/patch-bun-exports.mjs +1446 -0
- package/scripts/lib/read-app-identity.mjs +54 -0
- package/scripts/lib/release-check-pack-dry-run.ts +34 -0
- package/scripts/lib/repo-root.mjs +77 -0
- package/scripts/lib/stage-android-agent.mjs +704 -0
- package/scripts/lib/static-asset-manifest.mjs +151 -0
- package/scripts/lib/sync-eliza-env-aliases.mjs +37 -0
- package/scripts/lib/vite-renderer-dist-stale.mjs +141 -0
- package/scripts/lib/workspace-discovery.mjs +108 -0
- package/scripts/lifeops-prompt-benchmark.ts +206 -0
- package/scripts/link-browser-server.mjs +157 -0
- package/scripts/link-docker-local-app-packages.mjs +345 -0
- package/scripts/link-external-plugins.mjs +195 -0
- package/scripts/mobile-auth-simulator-smoke.mjs +373 -0
- package/scripts/normalize-parallax-capture.ts +97 -0
- package/scripts/omnivoice-fuse/Makefile +44 -0
- package/scripts/omnivoice-fuse/README.md +266 -0
- package/scripts/omnivoice-fuse/cmake-graft.mjs +180 -0
- package/scripts/omnivoice-fuse/ffi-stub.c +222 -0
- package/scripts/omnivoice-fuse/ffi.h +158 -0
- package/scripts/omnivoice-fuse/libelizainference_stub.dylib +0 -0
- package/scripts/omnivoice-fuse/prepare.mjs +263 -0
- package/scripts/omnivoice-fuse/verify-symbols.mjs +138 -0
- package/scripts/pack-upstreams.mjs +392 -0
- package/scripts/patch-deps.mjs +597 -0
- package/scripts/patch-workspace-plugins.mjs +148 -0
- package/scripts/playwright-ui-live-stack.ts +667 -0
- package/scripts/playwright-ui-smoke-api-stub.mjs +1838 -0
- package/scripts/plugin-index-local-additions.json +12 -0
- package/scripts/plugin-metadata-overrides.json +165 -0
- package/scripts/pre-review-local.mjs +599 -0
- package/scripts/prepare-ios-cocoapods.sh +30 -0
- package/scripts/prepare-package-dist.mjs +358 -0
- package/scripts/process-vrms.mjs +203 -0
- package/scripts/prune-cdn-local-assets.mjs +44 -0
- package/scripts/publish-local-plugins-next.mjs +122 -0
- package/scripts/release-check.ts +1402 -0
- package/scripts/relink-workspace-packages-to-dist.mjs +115 -0
- package/scripts/replace-workspace-versions.mjs +128 -0
- package/scripts/report-coverage-surfaces.mjs +121 -0
- package/scripts/restore-workspace-refs.mjs +128 -0
- package/scripts/rt.mjs +29 -0
- package/scripts/rt.sh +4 -0
- package/scripts/run-biome-check.mjs +191 -0
- package/scripts/run-coding-agent-e2e.mjs +46 -0
- package/scripts/run-desktop-playwright.mjs +35 -0
- package/scripts/run-local-plugin-live-smoke.mjs +185 -0
- package/scripts/run-mobile-build.mjs +3308 -0
- package/scripts/run-node-runtime.mjs +75 -0
- package/scripts/run-node-tsx.mjs +62 -0
- package/scripts/run-node.mjs +294 -0
- package/scripts/run-playwright.mjs +66 -0
- package/scripts/run-production-build.mjs +138 -0
- package/scripts/run-release-contract-suite.mjs +57 -0
- package/scripts/run-repo-setup.mjs +230 -0
- package/scripts/run-screenshotter.mjs +140 -0
- package/scripts/run-ui-smoke-playwright-suite.mjs +96 -0
- package/scripts/run-windows-smoke-launcher.ps1 +35 -0
- package/scripts/run-with-env.mjs +60 -0
- package/scripts/runtime-package-manifest.ts +107 -0
- package/scripts/sandbox-setup.sh +7 -0
- package/scripts/sanitize-npm-package-metadata.mjs +165 -0
- package/scripts/set-package-version.mjs +13 -0
- package/scripts/setup-upstreams.mjs +838 -0
- package/scripts/smoke-api-status.mjs +113 -0
- package/scripts/smoke-lifeops.mjs +305 -0
- package/scripts/startup-integration-script-drift.test.ts +94 -0
- package/scripts/sync-desktop-renderer.mjs +308 -0
- package/scripts/sync-dod-gap-issues-lib.mjs +214 -0
- package/scripts/sync-dod-gap-issues.mjs +218 -0
- package/scripts/type-audit.mjs +606 -0
- package/scripts/validate-cdn-assets.mjs +307 -0
- package/scripts/validate-regression-matrix.mjs +360 -0
- package/scripts/workspace-plugin-patches/plugin-anthropic-elizaos-core-api-compat.patch +34 -0
- package/scripts/workspace-prepare.mjs +192 -0
- package/scripts/worktree-env.sh +41 -0
- package/scripts/write-build-info.ts +69 -0
- package/scripts/write-homepage-release-data.mjs +393 -0
- package/security/agent-vault-id.d.ts +16 -0
- package/security/agent-vault-id.d.ts.map +1 -0
- package/security/agent-vault-id.js +32 -0
- package/security/cloud-secret-store.d.ts +34 -0
- package/security/cloud-secret-store.d.ts.map +1 -0
- package/security/cloud-secret-store.js +65 -0
- package/security/export-guard.d.ts +34 -0
- package/security/export-guard.d.ts.map +1 -0
- package/security/export-guard.js +127 -0
- package/security/hydrate-wallet-keys-from-platform-store.d.ts +13 -0
- package/security/hydrate-wallet-keys-from-platform-store.d.ts.map +1 -0
- package/security/hydrate-wallet-keys-from-platform-store.js +116 -0
- package/security/platform-secure-store-node.d.ts +13 -0
- package/security/platform-secure-store-node.d.ts.map +1 -0
- package/security/platform-secure-store-node.js +311 -0
- package/security/platform-secure-store.d.ts +47 -0
- package/security/platform-secure-store.d.ts.map +1 -0
- package/security/platform-secure-store.js +10 -0
- package/security/wallet-os-store-actions.d.ts +45 -0
- package/security/wallet-os-store-actions.d.ts.map +1 -0
- package/security/wallet-os-store-actions.js +125 -0
- package/services/account-pool.d.ts +134 -0
- package/services/account-pool.d.ts.map +1 -0
- package/services/account-pool.js +693 -0
- package/services/account-usage.d.ts +75 -0
- package/services/account-usage.d.ts.map +1 -0
- package/services/account-usage.js +179 -0
- package/services/auth-store.d.ts +179 -0
- package/services/auth-store.d.ts.map +1 -0
- package/services/auth-store.js +404 -0
- package/services/cloud-jwks-store.d.ts +62 -0
- package/services/cloud-jwks-store.d.ts.map +1 -0
- package/services/cloud-jwks-store.js +118 -0
- package/services/connector-target-catalog.d.ts +78 -0
- package/services/connector-target-catalog.d.ts.map +1 -0
- package/services/connector-target-catalog.js +64 -0
- package/services/discord-target-source.d.ts +53 -0
- package/services/discord-target-source.d.ts.map +1 -0
- package/services/discord-target-source.js +116 -0
- package/services/github-credentials.d.ts +95 -0
- package/services/github-credentials.d.ts.map +1 -0
- package/services/github-credentials.js +144 -0
- package/services/local-inference/__stress__/cache-stress-helpers.d.ts +76 -0
- package/services/local-inference/__stress__/cache-stress-helpers.d.ts.map +1 -0
- package/services/local-inference/__stress__/cache-stress-helpers.js +238 -0
- package/services/local-inference/active-model.d.ts +180 -0
- package/services/local-inference/active-model.d.ts.map +1 -0
- package/services/local-inference/active-model.js +362 -0
- package/services/local-inference/assignments.d.ts +58 -0
- package/services/local-inference/assignments.d.ts.map +1 -0
- package/services/local-inference/assignments.js +179 -0
- package/services/local-inference/backend.d.ts +200 -0
- package/services/local-inference/backend.d.ts.map +1 -0
- package/services/local-inference/backend.js +242 -0
- package/services/local-inference/bundled-models.d.ts +34 -0
- package/services/local-inference/bundled-models.d.ts.map +1 -0
- package/services/local-inference/bundled-models.js +104 -0
- package/services/local-inference/cache-bridge.d.ts +184 -0
- package/services/local-inference/cache-bridge.d.ts.map +1 -0
- package/services/local-inference/cache-bridge.js +333 -0
- package/services/local-inference/catalog.d.ts +57 -0
- package/services/local-inference/catalog.d.ts.map +1 -0
- package/services/local-inference/catalog.js +262 -0
- package/services/local-inference/conversation-registry.d.ts +122 -0
- package/services/local-inference/conversation-registry.d.ts.map +1 -0
- package/services/local-inference/conversation-registry.js +182 -0
- package/services/local-inference/device-bridge.d.ts +139 -0
- package/services/local-inference/device-bridge.d.ts.map +1 -0
- package/services/local-inference/device-bridge.js +774 -0
- package/services/local-inference/dflash-doctor.d.ts +27 -0
- package/services/local-inference/dflash-doctor.d.ts.map +1 -0
- package/services/local-inference/dflash-doctor.js +149 -0
- package/services/local-inference/dflash-server.d.ts +248 -0
- package/services/local-inference/dflash-server.d.ts.map +1 -0
- package/services/local-inference/dflash-server.js +1076 -0
- package/services/local-inference/downloader.d.ts +48 -0
- package/services/local-inference/downloader.d.ts.map +1 -0
- package/services/local-inference/downloader.js +688 -0
- package/services/local-inference/engine.d.ts +282 -0
- package/services/local-inference/engine.d.ts.map +1 -0
- package/services/local-inference/engine.js +743 -0
- package/services/local-inference/external-scanner.d.ts +17 -0
- package/services/local-inference/external-scanner.d.ts.map +1 -0
- package/services/local-inference/external-scanner.js +261 -0
- package/services/local-inference/handler-registry.d.ts +72 -0
- package/services/local-inference/handler-registry.d.ts.map +1 -0
- package/services/local-inference/handler-registry.js +159 -0
- package/services/local-inference/hardware.d.ts +26 -0
- package/services/local-inference/hardware.d.ts.map +1 -0
- package/services/local-inference/hardware.js +139 -0
- package/services/local-inference/hf-search.d.ts +19 -0
- package/services/local-inference/hf-search.d.ts.map +1 -0
- package/services/local-inference/hf-search.js +169 -0
- package/services/local-inference/index.d.ts +10 -0
- package/services/local-inference/index.d.ts.map +1 -0
- package/services/local-inference/index.js +7 -0
- package/services/local-inference/llama-server-metrics.d.ts +108 -0
- package/services/local-inference/llama-server-metrics.d.ts.map +1 -0
- package/services/local-inference/llama-server-metrics.js +175 -0
- package/services/local-inference/manifest/index.d.ts +4 -0
- package/services/local-inference/manifest/index.d.ts.map +1 -0
- package/services/local-inference/manifest/index.js +5 -0
- package/services/local-inference/manifest/schema.d.ts +419 -0
- package/services/local-inference/manifest/schema.d.ts.map +1 -0
- package/services/local-inference/manifest/schema.js +227 -0
- package/services/local-inference/manifest/types.d.ts +23 -0
- package/services/local-inference/manifest/types.d.ts.map +1 -0
- package/services/local-inference/manifest/types.js +5 -0
- package/services/local-inference/manifest/validator.d.ts +43 -0
- package/services/local-inference/manifest/validator.d.ts.map +1 -0
- package/services/local-inference/manifest/validator.js +180 -0
- package/services/local-inference/paths.d.ts +8 -0
- package/services/local-inference/paths.d.ts.map +1 -0
- package/services/local-inference/paths.js +7 -0
- package/services/local-inference/providers.d.ts +61 -0
- package/services/local-inference/providers.d.ts.map +1 -0
- package/services/local-inference/providers.js +334 -0
- package/services/local-inference/ram-budget.d.ts +57 -0
- package/services/local-inference/ram-budget.d.ts.map +1 -0
- package/services/local-inference/ram-budget.js +107 -0
- package/services/local-inference/readiness.d.ts +9 -0
- package/services/local-inference/readiness.d.ts.map +1 -0
- package/services/local-inference/readiness.js +153 -0
- package/services/local-inference/recommendation.d.ts +62 -0
- package/services/local-inference/recommendation.d.ts.map +1 -0
- package/services/local-inference/recommendation.js +309 -0
- package/services/local-inference/registry.d.ts +35 -0
- package/services/local-inference/registry.d.ts.map +1 -0
- package/services/local-inference/registry.js +117 -0
- package/services/local-inference/router-handler.d.ts +51 -0
- package/services/local-inference/router-handler.d.ts.map +1 -0
- package/services/local-inference/router-handler.js +165 -0
- package/services/local-inference/routing-policy.d.ts +55 -0
- package/services/local-inference/routing-policy.d.ts.map +1 -0
- package/services/local-inference/routing-policy.js +195 -0
- package/services/local-inference/routing-preferences.d.ts +8 -0
- package/services/local-inference/routing-preferences.d.ts.map +1 -0
- package/services/local-inference/routing-preferences.js +7 -0
- package/services/local-inference/service.d.ts +88 -0
- package/services/local-inference/service.d.ts.map +1 -0
- package/services/local-inference/service.js +210 -0
- package/services/local-inference/session-pool.d.ts +72 -0
- package/services/local-inference/session-pool.d.ts.map +1 -0
- package/services/local-inference/session-pool.js +125 -0
- package/services/local-inference/types.d.ts +309 -0
- package/services/local-inference/types.d.ts.map +1 -0
- package/services/local-inference/types.js +23 -0
- package/services/local-inference/verify.d.ts +8 -0
- package/services/local-inference/verify.d.ts.map +1 -0
- package/services/local-inference/verify.js +7 -0
- package/services/local-inference/voice/barge-in.d.ts +15 -0
- package/services/local-inference/voice/barge-in.d.ts.map +1 -0
- package/services/local-inference/voice/barge-in.js +20 -0
- package/services/local-inference/voice/engine-bridge.d.ts +256 -0
- package/services/local-inference/voice/engine-bridge.d.ts.map +1 -0
- package/services/local-inference/voice/engine-bridge.js +398 -0
- package/services/local-inference/voice/ffi-bindings.d.ts +114 -0
- package/services/local-inference/voice/ffi-bindings.d.ts.map +1 -0
- package/services/local-inference/voice/ffi-bindings.js +281 -0
- package/services/local-inference/voice/index.d.ts +51 -0
- package/services/local-inference/voice/index.d.ts.map +1 -0
- package/services/local-inference/voice/index.js +50 -0
- package/services/local-inference/voice/lifecycle.d.ts +135 -0
- package/services/local-inference/voice/lifecycle.d.ts.map +1 -0
- package/services/local-inference/voice/lifecycle.js +189 -0
- package/services/local-inference/voice/phoneme-tokenizer.d.ts +58 -0
- package/services/local-inference/voice/phoneme-tokenizer.d.ts.map +1 -0
- package/services/local-inference/voice/phoneme-tokenizer.js +53 -0
- package/services/local-inference/voice/phrase-cache.d.ts +24 -0
- package/services/local-inference/voice/phrase-cache.d.ts.map +1 -0
- package/services/local-inference/voice/phrase-cache.js +32 -0
- package/services/local-inference/voice/phrase-chunker.d.ts +20 -0
- package/services/local-inference/voice/phrase-chunker.d.ts.map +1 -0
- package/services/local-inference/voice/phrase-chunker.js +85 -0
- package/services/local-inference/voice/ring-buffer.d.ts +40 -0
- package/services/local-inference/voice/ring-buffer.d.ts.map +1 -0
- package/services/local-inference/voice/ring-buffer.js +85 -0
- package/services/local-inference/voice/rollback-queue.d.ts +24 -0
- package/services/local-inference/voice/rollback-queue.d.ts.map +1 -0
- package/services/local-inference/voice/rollback-queue.js +49 -0
- package/services/local-inference/voice/scheduler.d.ts +47 -0
- package/services/local-inference/voice/scheduler.d.ts.map +1 -0
- package/services/local-inference/voice/scheduler.js +123 -0
- package/services/local-inference/voice/shared-resources.d.ts +119 -0
- package/services/local-inference/voice/shared-resources.d.ts.map +1 -0
- package/services/local-inference/voice/shared-resources.js +83 -0
- package/services/local-inference/voice/speaker-preset-cache.d.ts +28 -0
- package/services/local-inference/voice/speaker-preset-cache.d.ts.map +1 -0
- package/services/local-inference/voice/speaker-preset-cache.js +44 -0
- package/services/local-inference/voice/types.d.ts +80 -0
- package/services/local-inference/voice/types.d.ts.map +1 -0
- package/services/local-inference/voice/voice-preset-format.d.ts +56 -0
- package/services/local-inference/voice/voice-preset-format.d.ts.map +1 -0
- package/services/local-inference/voice/voice-preset-format.js +184 -0
- package/services/persistence.d.ts +48 -0
- package/services/persistence.d.ts.map +1 -0
- package/services/persistence.js +128 -0
- package/services/plugin-installer.d.ts +22 -0
- package/services/plugin-installer.d.ts.map +1 -0
- package/services/plugin-installer.js +41 -0
- package/services/secrets-manager-installer.d.ts +140 -0
- package/services/secrets-manager-installer.d.ts.map +1 -0
- package/services/secrets-manager-installer.js +374 -0
- package/services/steward-credentials.d.ts +37 -0
- package/services/steward-credentials.d.ts.map +1 -0
- package/services/steward-credentials.js +93 -0
- package/services/steward-sidecar/health-check.d.ts +9 -0
- package/services/steward-sidecar/health-check.d.ts.map +1 -0
- package/services/steward-sidecar/health-check.js +34 -0
- package/services/steward-sidecar/helpers.d.ts +21 -0
- package/services/steward-sidecar/helpers.d.ts.map +1 -0
- package/services/steward-sidecar/helpers.js +71 -0
- package/services/steward-sidecar/process-management.d.ts +9 -0
- package/services/steward-sidecar/process-management.d.ts.map +1 -0
- package/services/steward-sidecar/process-management.js +53 -0
- package/services/steward-sidecar/types.d.ts +60 -0
- package/services/steward-sidecar/types.d.ts.map +1 -0
- package/services/steward-sidecar/types.js +17 -0
- package/services/steward-sidecar/wallet-setup.d.ts +9 -0
- package/services/steward-sidecar/wallet-setup.d.ts.map +1 -0
- package/services/steward-sidecar/wallet-setup.js +114 -0
- package/services/steward-sidecar.d.ts +70 -0
- package/services/steward-sidecar.d.ts.map +1 -0
- package/services/steward-sidecar.js +385 -0
- package/services/tool-call-cache/index.d.ts +13 -0
- package/services/tool-call-cache/index.d.ts.map +1 -0
- package/services/tool-call-cache/index.js +11 -0
- package/services/trigger-event-bridge.d.ts +52 -0
- package/services/trigger-event-bridge.d.ts.map +1 -0
- package/services/trigger-event-bridge.js +217 -0
- package/services/update-notifier.d.ts +6 -0
- package/services/update-notifier.d.ts.map +1 -0
- package/services/update-notifier.js +33 -0
- package/services/vault-bootstrap.d.ts +31 -0
- package/services/vault-bootstrap.d.ts.map +1 -0
- package/services/vault-bootstrap.js +209 -0
- package/services/vault-mirror.d.ts +44 -0
- package/services/vault-mirror.d.ts.map +1 -0
- package/services/vault-mirror.js +80 -0
- package/styles/electrobun-mac-window-drag.css +66 -0
- package/test/helpers/__tests__/live-agent-test.smoke.test.ts +105 -0
- package/test/helpers/action-assertions.ts +364 -0
- package/test/helpers/action-spy.ts +354 -0
- package/test/helpers/browser-launch.ts +103 -0
- package/test/helpers/browser-mocks.ts +275 -0
- package/test/helpers/conditional-tests.ts +42 -0
- package/test/helpers/conversation-harness.ts +334 -0
- package/test/helpers/http.ts +150 -0
- package/test/helpers/i18n.ts +5 -0
- package/test/helpers/isolated-config.ts +34 -0
- package/test/helpers/live-agent-test.ts +660 -0
- package/test/helpers/live-child-env.ts +72 -0
- package/test/helpers/live-provider.test.ts +124 -0
- package/test/helpers/live-provider.ts +362 -0
- package/test/helpers/live-runtime-server.ts +88 -0
- package/test/helpers/loopback.ts +33 -0
- package/test/helpers/pglite-runtime.ts +173 -0
- package/test/helpers/react-test.ts +40 -0
- package/test/helpers/real-connector.ts +250 -0
- package/test/helpers/real-runtime.ts +543 -0
- package/test/helpers/skip-without.ts +53 -0
- package/test/helpers/stochastic-test.ts +186 -0
- package/test/helpers/test-utils.ts +94 -0
- package/test/helpers/trajectory-assertions.ts +168 -0
- package/test/helpers/trajectory-harness.test.ts +101 -0
- package/test/helpers/trajectory-harness.ts +988 -0
- package/test/scripts/managed-test-command.mjs +632 -0
- package/test/scripts/task-agent-live-smoke.ts +1335 -0
- package/test/scripts/test-parallel.mjs +237 -0
- package/test/scripts/test-root-unit.mjs +169 -0
- package/test/scripts/test-runner.mjs +78 -0
- package/test/scripts/validate-all-features.sh +541 -0
- package/test-support/test-helpers.d.ts +111 -0
- package/test-support/test-helpers.d.ts.map +1 -0
- package/test-support/test-helpers.js +410 -0
- package/ui-compat.d.ts +3 -0
- package/ui-compat.d.ts.map +1 -0
- package/ui-compat.js +3 -0
- package/utils/eliza-root.d.ts +9 -0
- package/utils/eliza-root.d.ts.map +1 -0
- package/utils/eliza-root.js +101 -0
- package/utils/globals.d.ts +7 -0
- package/utils/globals.d.ts.map +1 -0
- package/utils/globals.js +47 -0
- package/App.d.ts +0 -5
- package/App.d.ts.map +0 -1
- package/App.js +0 -220
- package/LICENSE +0 -21
- package/actions/character.d.ts +0 -39
- package/actions/character.d.ts.map +0 -1
- package/actions/character.js +0 -247
- package/actions/chat-helpers.d.ts +0 -47
- package/actions/chat-helpers.d.ts.map +0 -1
- package/actions/chat-helpers.js +0 -79
- package/actions/cloud.d.ts +0 -17
- package/actions/cloud.d.ts.map +0 -1
- package/actions/cloud.js +0 -43
- package/actions/index.d.ts +0 -12
- package/actions/index.d.ts.map +0 -1
- package/actions/index.js +0 -11
- package/actions/lifecycle.d.ts +0 -43
- package/actions/lifecycle.d.ts.map +0 -1
- package/actions/lifecycle.js +0 -118
- package/actions/onboarding.d.ts +0 -13
- package/actions/onboarding.d.ts.map +0 -1
- package/actions/onboarding.js +0 -26
- package/actions/triggers.d.ts +0 -23
- package/actions/triggers.d.ts.map +0 -1
- package/actions/triggers.js +0 -148
- package/api/client.d.ts +0 -2742
- package/api/client.d.ts.map +0 -1
- package/api/client.js +0 -2520
- package/api/index.d.ts +0 -2
- package/api/index.d.ts.map +0 -1
- package/api/index.js +0 -1
- package/autonomy/index.d.ts +0 -48
- package/autonomy/index.d.ts.map +0 -1
- package/autonomy/index.js +0 -330
- package/bridge/capacitor-bridge.d.ts +0 -153
- package/bridge/capacitor-bridge.d.ts.map +0 -1
- package/bridge/capacitor-bridge.js +0 -193
- package/bridge/electrobun-rpc.d.ts +0 -28
- package/bridge/electrobun-rpc.d.ts.map +0 -1
- package/bridge/electrobun-rpc.js +0 -35
- package/bridge/electrobun-runtime.d.ts +0 -3
- package/bridge/electrobun-runtime.d.ts.map +0 -1
- package/bridge/electrobun-runtime.js +0 -17
- package/bridge/index.d.ts +0 -6
- package/bridge/index.d.ts.map +0 -1
- package/bridge/index.js +0 -5
- package/bridge/native-plugins.d.ts +0 -82
- package/bridge/native-plugins.d.ts.map +0 -1
- package/bridge/native-plugins.js +0 -39
- package/bridge/plugin-bridge.d.ts +0 -116
- package/bridge/plugin-bridge.d.ts.map +0 -1
- package/bridge/plugin-bridge.js +0 -203
- package/bridge/storage-bridge.d.ts +0 -39
- package/bridge/storage-bridge.d.ts.map +0 -1
- package/bridge/storage-bridge.js +0 -135
- package/chat/index.d.ts +0 -57
- package/chat/index.d.ts.map +0 -1
- package/chat/index.js +0 -160
- package/coding/index.d.ts +0 -25
- package/coding/index.d.ts.map +0 -1
- package/coding/index.js +0 -25
- package/components/AdvancedPageView.d.ts +0 -17
- package/components/AdvancedPageView.d.ts.map +0 -1
- package/components/AdvancedPageView.js +0 -146
- package/components/AgentActivityBox.d.ts +0 -7
- package/components/AgentActivityBox.d.ts.map +0 -1
- package/components/AgentActivityBox.js +0 -25
- package/components/ApiKeyConfig.d.ts +0 -26
- package/components/ApiKeyConfig.d.ts.map +0 -1
- package/components/ApiKeyConfig.js +0 -119
- package/components/AppsPageView.d.ts +0 -7
- package/components/AppsPageView.d.ts.map +0 -1
- package/components/AppsPageView.js +0 -31
- package/components/AppsView.d.ts +0 -8
- package/components/AppsView.d.ts.map +0 -1
- package/components/AppsView.js +0 -149
- package/components/AvatarLoader.d.ts +0 -13
- package/components/AvatarLoader.d.ts.map +0 -1
- package/components/AvatarLoader.js +0 -53
- package/components/AvatarSelector.d.ts +0 -23
- package/components/AvatarSelector.d.ts.map +0 -1
- package/components/AvatarSelector.js +0 -105
- package/components/BscTradePanel.d.ts +0 -22
- package/components/BscTradePanel.d.ts.map +0 -1
- package/components/BscTradePanel.js +0 -221
- package/components/BugReportModal.d.ts +0 -2
- package/components/BugReportModal.d.ts.map +0 -1
- package/components/BugReportModal.js +0 -219
- package/components/CharacterRoster.d.ts +0 -31
- package/components/CharacterRoster.d.ts.map +0 -1
- package/components/CharacterRoster.js +0 -41
- package/components/CharacterView.d.ts +0 -8
- package/components/CharacterView.d.ts.map +0 -1
- package/components/CharacterView.js +0 -685
- package/components/ChatAvatar.d.ts +0 -8
- package/components/ChatAvatar.d.ts.map +0 -1
- package/components/ChatAvatar.js +0 -89
- package/components/ChatComposer.d.ts +0 -37
- package/components/ChatComposer.d.ts.map +0 -1
- package/components/ChatComposer.js +0 -136
- package/components/ChatMessage.d.ts +0 -24
- package/components/ChatMessage.d.ts.map +0 -1
- package/components/ChatMessage.js +0 -187
- package/components/ChatModalView.d.ts +0 -10
- package/components/ChatModalView.d.ts.map +0 -1
- package/components/ChatModalView.js +0 -57
- package/components/ChatView.d.ts +0 -14
- package/components/ChatView.d.ts.map +0 -1
- package/components/ChatView.js +0 -526
- package/components/CloudOnboarding.d.ts +0 -7
- package/components/CloudOnboarding.d.ts.map +0 -1
- package/components/CloudOnboarding.js +0 -22
- package/components/CloudSourceControls.d.ts +0 -13
- package/components/CloudSourceControls.d.ts.map +0 -1
- package/components/CloudSourceControls.js +0 -16
- package/components/CodingAgentSettingsSection.d.ts +0 -8
- package/components/CodingAgentSettingsSection.d.ts.map +0 -1
- package/components/CodingAgentSettingsSection.js +0 -292
- package/components/CommandPalette.d.ts +0 -2
- package/components/CommandPalette.d.ts.map +0 -1
- package/components/CommandPalette.js +0 -181
- package/components/CompanionSceneHost.d.ts +0 -14
- package/components/CompanionSceneHost.d.ts.map +0 -1
- package/components/CompanionSceneHost.js +0 -362
- package/components/CompanionShell.d.ts +0 -17
- package/components/CompanionShell.d.ts.map +0 -1
- package/components/CompanionShell.js +0 -15
- package/components/CompanionView.d.ts +0 -2
- package/components/CompanionView.d.ts.map +0 -1
- package/components/CompanionView.js +0 -22
- package/components/ConfigPageView.d.ts +0 -11
- package/components/ConfigPageView.d.ts.map +0 -1
- package/components/ConfigPageView.js +0 -311
- package/components/ConfigSaveFooter.d.ts +0 -8
- package/components/ConfigSaveFooter.d.ts.map +0 -1
- package/components/ConfigSaveFooter.js +0 -10
- package/components/ConfirmModal.d.ts +0 -61
- package/components/ConfirmModal.d.ts.map +0 -1
- package/components/ConfirmModal.js +0 -164
- package/components/ConnectionFailedBanner.d.ts +0 -6
- package/components/ConnectionFailedBanner.d.ts.map +0 -1
- package/components/ConnectionFailedBanner.js +0 -22
- package/components/ConnectorsPageView.d.ts +0 -7
- package/components/ConnectorsPageView.d.ts.map +0 -1
- package/components/ConnectorsPageView.js +0 -8
- package/components/ConversationsSidebar.d.ts +0 -9
- package/components/ConversationsSidebar.d.ts.map +0 -1
- package/components/ConversationsSidebar.js +0 -116
- package/components/CustomActionEditor.d.ts +0 -10
- package/components/CustomActionEditor.d.ts.map +0 -1
- package/components/CustomActionEditor.js +0 -596
- package/components/CustomActionsPanel.d.ts +0 -9
- package/components/CustomActionsPanel.d.ts.map +0 -1
- package/components/CustomActionsPanel.js +0 -107
- package/components/CustomActionsView.d.ts +0 -2
- package/components/CustomActionsView.d.ts.map +0 -1
- package/components/CustomActionsView.js +0 -134
- package/components/DatabasePageView.d.ts +0 -5
- package/components/DatabasePageView.d.ts.map +0 -1
- package/components/DatabasePageView.js +0 -28
- package/components/DatabaseView.d.ts +0 -9
- package/components/DatabaseView.d.ts.map +0 -1
- package/components/DatabaseView.js +0 -311
- package/components/ElizaCloudDashboard.d.ts +0 -2
- package/components/ElizaCloudDashboard.d.ts.map +0 -1
- package/components/ElizaCloudDashboard.js +0 -657
- package/components/EmotePicker.d.ts +0 -2
- package/components/EmotePicker.d.ts.map +0 -1
- package/components/EmotePicker.js +0 -343
- package/components/ErrorBoundary.d.ts +0 -22
- package/components/ErrorBoundary.d.ts.map +0 -1
- package/components/ErrorBoundary.js +0 -31
- package/components/FineTuningView.d.ts +0 -2
- package/components/FineTuningView.d.ts.map +0 -1
- package/components/FineTuningView.js +0 -433
- package/components/FlaminaGuide.d.ts +0 -10
- package/components/FlaminaGuide.d.ts.map +0 -1
- package/components/FlaminaGuide.js +0 -64
- package/components/GameView.d.ts +0 -11
- package/components/GameView.d.ts.map +0 -1
- package/components/GameView.js +0 -294
- package/components/GameViewOverlay.d.ts +0 -8
- package/components/GameViewOverlay.d.ts.map +0 -1
- package/components/GameViewOverlay.js +0 -70
- package/components/GlobalEmoteOverlay.d.ts +0 -2
- package/components/GlobalEmoteOverlay.d.ts.map +0 -1
- package/components/GlobalEmoteOverlay.js +0 -112
- package/components/Header.d.ts +0 -9
- package/components/Header.d.ts.map +0 -1
- package/components/Header.js +0 -123
- package/components/HeartbeatsView.d.ts +0 -2
- package/components/HeartbeatsView.d.ts.map +0 -1
- package/components/HeartbeatsView.js +0 -378
- package/components/InventoryView.d.ts +0 -10
- package/components/InventoryView.d.ts.map +0 -1
- package/components/InventoryView.js +0 -176
- package/components/KnowledgeView.d.ts +0 -20
- package/components/KnowledgeView.d.ts.map +0 -1
- package/components/KnowledgeView.js +0 -483
- package/components/LanguageDropdown.d.ts +0 -30
- package/components/LanguageDropdown.d.ts.map +0 -1
- package/components/LanguageDropdown.js +0 -99
- package/components/LifoMonitorPanel.d.ts +0 -21
- package/components/LifoMonitorPanel.d.ts.map +0 -1
- package/components/LifoMonitorPanel.js +0 -24
- package/components/LifoSandboxView.d.ts +0 -5
- package/components/LifoSandboxView.d.ts.map +0 -1
- package/components/LifoSandboxView.js +0 -333
- package/components/LoadingScreen.d.ts +0 -13
- package/components/LoadingScreen.d.ts.map +0 -1
- package/components/LoadingScreen.js +0 -70
- package/components/LogsPageView.d.ts +0 -2
- package/components/LogsPageView.d.ts.map +0 -1
- package/components/LogsPageView.js +0 -7
- package/components/LogsView.d.ts +0 -5
- package/components/LogsView.d.ts.map +0 -1
- package/components/LogsView.js +0 -71
- package/components/MediaGalleryView.d.ts +0 -9
- package/components/MediaGalleryView.d.ts.map +0 -1
- package/components/MediaGalleryView.js +0 -236
- package/components/MediaSettingsSection.d.ts +0 -11
- package/components/MediaSettingsSection.d.ts.map +0 -1
- package/components/MediaSettingsSection.js +0 -329
- package/components/MessageContent.d.ts +0 -51
- package/components/MessageContent.d.ts.map +0 -1
- package/components/MessageContent.js +0 -553
- package/components/OnboardingWizard.d.ts +0 -2
- package/components/OnboardingWizard.d.ts.map +0 -1
- package/components/OnboardingWizard.js +0 -86
- package/components/PairingView.d.ts +0 -5
- package/components/PairingView.d.ts.map +0 -1
- package/components/PairingView.js +0 -29
- package/components/PermissionsSection.d.ts +0 -20
- package/components/PermissionsSection.d.ts.map +0 -1
- package/components/PermissionsSection.js +0 -573
- package/components/PluginsPageView.d.ts +0 -5
- package/components/PluginsPageView.d.ts.map +0 -1
- package/components/PluginsPageView.js +0 -8
- package/components/PluginsView.d.ts +0 -21
- package/components/PluginsView.d.ts.map +0 -1
- package/components/PluginsView.js +0 -1534
- package/components/ProviderSwitcher.d.ts +0 -42
- package/components/ProviderSwitcher.d.ts.map +0 -1
- package/components/ProviderSwitcher.js +0 -493
- package/components/RestartBanner.d.ts +0 -2
- package/components/RestartBanner.d.ts.map +0 -1
- package/components/RestartBanner.js +0 -36
- package/components/RuntimeView.d.ts +0 -10
- package/components/RuntimeView.d.ts.map +0 -1
- package/components/RuntimeView.js +0 -165
- package/components/SaveCommandModal.d.ts +0 -12
- package/components/SaveCommandModal.d.ts.map +0 -1
- package/components/SaveCommandModal.js +0 -84
- package/components/SecretsView.d.ts +0 -9
- package/components/SecretsView.d.ts.map +0 -1
- package/components/SecretsView.js +0 -249
- package/components/SettingsView.d.ts +0 -9
- package/components/SettingsView.d.ts.map +0 -1
- package/components/SettingsView.js +0 -230
- package/components/ShellOverlays.d.ts +0 -8
- package/components/ShellOverlays.d.ts.map +0 -1
- package/components/ShellOverlays.js +0 -10
- package/components/ShortcutsOverlay.d.ts +0 -2
- package/components/ShortcutsOverlay.d.ts.map +0 -1
- package/components/ShortcutsOverlay.js +0 -79
- package/components/SkillsView.d.ts +0 -11
- package/components/SkillsView.d.ts.map +0 -1
- package/components/SkillsView.js +0 -358
- package/components/StartupFailureView.d.ts +0 -8
- package/components/StartupFailureView.d.ts.map +0 -1
- package/components/StartupFailureView.js +0 -16
- package/components/StreamView.d.ts +0 -16
- package/components/StreamView.d.ts.map +0 -1
- package/components/StreamView.js +0 -300
- package/components/StripeEmbeddedCheckout.d.ts +0 -24
- package/components/StripeEmbeddedCheckout.d.ts.map +0 -1
- package/components/StripeEmbeddedCheckout.js +0 -101
- package/components/SubscriptionStatus.d.ts +0 -23
- package/components/SubscriptionStatus.d.ts.map +0 -1
- package/components/SubscriptionStatus.js +0 -301
- package/components/SystemWarningBanner.d.ts +0 -6
- package/components/SystemWarningBanner.d.ts.map +0 -1
- package/components/SystemWarningBanner.js +0 -46
- package/components/ThemeToggle.d.ts +0 -21
- package/components/ThemeToggle.d.ts.map +0 -1
- package/components/ThemeToggle.js +0 -24
- package/components/TrajectoriesView.d.ts +0 -12
- package/components/TrajectoriesView.d.ts.map +0 -1
- package/components/TrajectoriesView.js +0 -183
- package/components/TrajectoryDetailView.d.ts +0 -13
- package/components/TrajectoryDetailView.d.ts.map +0 -1
- package/components/TrajectoryDetailView.js +0 -112
- package/components/TriggersView.d.ts +0 -2
- package/components/TriggersView.d.ts.map +0 -1
- package/components/TriggersView.js +0 -1
- package/components/VectorBrowserView.d.ts +0 -10
- package/components/VectorBrowserView.d.ts.map +0 -1
- package/components/VectorBrowserView.js +0 -1000
- package/components/VoiceConfigView.d.ts +0 -11
- package/components/VoiceConfigView.d.ts.map +0 -1
- package/components/VoiceConfigView.js +0 -331
- package/components/VrmStage.d.ts +0 -28
- package/components/VrmStage.d.ts.map +0 -1
- package/components/VrmStage.js +0 -178
- package/components/WhatsAppQrOverlay.d.ts +0 -8
- package/components/WhatsAppQrOverlay.d.ts.map +0 -1
- package/components/WhatsAppQrOverlay.js +0 -63
- package/components/apps/AppDetailPane.d.ts +0 -15
- package/components/apps/AppDetailPane.d.ts.map +0 -1
- package/components/apps/AppDetailPane.js +0 -13
- package/components/apps/AppsCatalogGrid.d.ts +0 -20
- package/components/apps/AppsCatalogGrid.d.ts.map +0 -1
- package/components/apps/AppsCatalogGrid.js +0 -18
- package/components/apps/extensions/registry.d.ts +0 -4
- package/components/apps/extensions/registry.d.ts.map +0 -1
- package/components/apps/extensions/registry.js +0 -7
- package/components/apps/extensions/types.d.ts +0 -7
- package/components/apps/extensions/types.d.ts.map +0 -1
- package/components/apps/helpers.d.ts +0 -7
- package/components/apps/helpers.d.ts.map +0 -1
- package/components/apps/helpers.js +0 -44
- package/components/avatar/VrmAnimationLoader.d.ts +0 -30
- package/components/avatar/VrmAnimationLoader.d.ts.map +0 -1
- package/components/avatar/VrmAnimationLoader.js +0 -99
- package/components/avatar/VrmBlinkController.d.ts +0 -37
- package/components/avatar/VrmBlinkController.d.ts.map +0 -1
- package/components/avatar/VrmBlinkController.js +0 -98
- package/components/avatar/VrmCameraManager.d.ts +0 -57
- package/components/avatar/VrmCameraManager.d.ts.map +0 -1
- package/components/avatar/VrmCameraManager.js +0 -277
- package/components/avatar/VrmEngine.d.ts +0 -246
- package/components/avatar/VrmEngine.d.ts.map +0 -1
- package/components/avatar/VrmEngine.js +0 -2087
- package/components/avatar/VrmFootShadow.d.ts +0 -18
- package/components/avatar/VrmFootShadow.d.ts.map +0 -1
- package/components/avatar/VrmFootShadow.js +0 -83
- package/components/avatar/VrmViewer.d.ts +0 -60
- package/components/avatar/VrmViewer.d.ts.map +0 -1
- package/components/avatar/VrmViewer.js +0 -396
- package/components/avatar/mixamoVRMRigMap.d.ts +0 -3
- package/components/avatar/mixamoVRMRigMap.d.ts.map +0 -1
- package/components/avatar/mixamoVRMRigMap.js +0 -56
- package/components/avatar/retargetMixamoFbxToVrm.d.ts +0 -9
- package/components/avatar/retargetMixamoFbxToVrm.d.ts.map +0 -1
- package/components/avatar/retargetMixamoFbxToVrm.js +0 -88
- package/components/avatar/retargetMixamoGltfToVrm.d.ts +0 -11
- package/components/avatar/retargetMixamoGltfToVrm.d.ts.map +0 -1
- package/components/avatar/retargetMixamoGltfToVrm.js +0 -80
- package/components/chainConfig.d.ts +0 -89
- package/components/chainConfig.d.ts.map +0 -1
- package/components/chainConfig.js +0 -287
- package/components/companion/CompanionHeader.d.ts +0 -15
- package/components/companion/CompanionHeader.d.ts.map +0 -1
- package/components/companion/CompanionHeader.js +0 -7
- package/components/companion/CompanionSceneHost.d.ts +0 -2
- package/components/companion/CompanionSceneHost.d.ts.map +0 -1
- package/components/companion/CompanionSceneHost.js +0 -1
- package/components/companion/VrmStage.d.ts +0 -3
- package/components/companion/VrmStage.d.ts.map +0 -1
- package/components/companion/VrmStage.js +0 -1
- package/components/companion/index.d.ts +0 -18
- package/components/companion/index.d.ts.map +0 -1
- package/components/companion/index.js +0 -17
- package/components/companion/walletUtils.d.ts +0 -95
- package/components/companion/walletUtils.d.ts.map +0 -1
- package/components/companion/walletUtils.js +0 -167
- package/components/companion-shell-styles.d.ts +0 -38
- package/components/companion-shell-styles.d.ts.map +0 -1
- package/components/companion-shell-styles.js +0 -248
- package/components/confirm-delete-control.d.ts +0 -16
- package/components/confirm-delete-control.d.ts.map +0 -1
- package/components/confirm-delete-control.js +0 -12
- package/components/conversations/ConversationListItem.d.ts +0 -31
- package/components/conversations/ConversationListItem.d.ts.map +0 -1
- package/components/conversations/ConversationListItem.js +0 -52
- package/components/conversations/conversation-utils.d.ts +0 -9
- package/components/conversations/conversation-utils.d.ts.map +0 -1
- package/components/conversations/conversation-utils.js +0 -138
- package/components/format.d.ts +0 -54
- package/components/format.d.ts.map +0 -1
- package/components/format.js +0 -82
- package/components/index.d.ts +0 -96
- package/components/index.d.ts.map +0 -1
- package/components/index.js +0 -95
- package/components/inventory/CopyableAddress.d.ts +0 -8
- package/components/inventory/CopyableAddress.d.ts.map +0 -1
- package/components/inventory/CopyableAddress.js +0 -18
- package/components/inventory/InventoryToolbar.d.ts +0 -25
- package/components/inventory/InventoryToolbar.d.ts.map +0 -1
- package/components/inventory/InventoryToolbar.js +0 -28
- package/components/inventory/NftGrid.d.ts +0 -13
- package/components/inventory/NftGrid.d.ts.map +0 -1
- package/components/inventory/NftGrid.js +0 -29
- package/components/inventory/TokenLogo.d.ts +0 -12
- package/components/inventory/TokenLogo.d.ts.map +0 -1
- package/components/inventory/TokenLogo.js +0 -33
- package/components/inventory/TokensTable.d.ts +0 -24
- package/components/inventory/TokensTable.d.ts.map +0 -1
- package/components/inventory/TokensTable.js +0 -26
- package/components/inventory/constants.d.ts +0 -52
- package/components/inventory/constants.d.ts.map +0 -1
- package/components/inventory/constants.js +0 -121
- package/components/inventory/index.d.ts +0 -9
- package/components/inventory/index.d.ts.map +0 -1
- package/components/inventory/index.js +0 -8
- package/components/inventory/media-url.d.ts +0 -6
- package/components/inventory/media-url.d.ts.map +0 -1
- package/components/inventory/media-url.js +0 -28
- package/components/inventory/useInventoryData.d.ts +0 -53
- package/components/inventory/useInventoryData.d.ts.map +0 -1
- package/components/inventory/useInventoryData.js +0 -332
- package/components/knowledge-upload-image.d.ts +0 -27
- package/components/knowledge-upload-image.d.ts.map +0 -1
- package/components/knowledge-upload-image.js +0 -146
- package/components/labels.d.ts +0 -6
- package/components/labels.d.ts.map +0 -1
- package/components/labels.js +0 -40
- package/components/onboarding/ActivateStep.d.ts +0 -2
- package/components/onboarding/ActivateStep.d.ts.map +0 -1
- package/components/onboarding/ActivateStep.js +0 -10
- package/components/onboarding/CloudLoginStep.d.ts +0 -2
- package/components/onboarding/CloudLoginStep.d.ts.map +0 -1
- package/components/onboarding/CloudLoginStep.js +0 -20
- package/components/onboarding/ConnectionStep.d.ts +0 -2
- package/components/onboarding/ConnectionStep.d.ts.map +0 -1
- package/components/onboarding/ConnectionStep.js +0 -609
- package/components/onboarding/IdentityStep.d.ts +0 -2
- package/components/onboarding/IdentityStep.d.ts.map +0 -1
- package/components/onboarding/IdentityStep.js +0 -102
- package/components/onboarding/OnboardingPanel.d.ts +0 -9
- package/components/onboarding/OnboardingPanel.d.ts.map +0 -1
- package/components/onboarding/OnboardingPanel.js +0 -24
- package/components/onboarding/OnboardingStepNav.d.ts +0 -2
- package/components/onboarding/OnboardingStepNav.d.ts.map +0 -1
- package/components/onboarding/OnboardingStepNav.js +0 -24
- package/components/onboarding/PermissionsStep.d.ts +0 -2
- package/components/onboarding/PermissionsStep.d.ts.map +0 -1
- package/components/onboarding/PermissionsStep.js +0 -7
- package/components/onboarding/RpcStep.d.ts +0 -2
- package/components/onboarding/RpcStep.d.ts.map +0 -1
- package/components/onboarding/RpcStep.js +0 -125
- package/components/onboarding/SaveKeysStep.d.ts +0 -2
- package/components/onboarding/SaveKeysStep.d.ts.map +0 -1
- package/components/onboarding/SaveKeysStep.js +0 -44
- package/components/onboarding/WelcomeStep.d.ts +0 -2
- package/components/onboarding/WelcomeStep.d.ts.map +0 -1
- package/components/onboarding/WelcomeStep.js +0 -30
- package/components/permissions/PermissionIcon.d.ts +0 -4
- package/components/permissions/PermissionIcon.d.ts.map +0 -1
- package/components/permissions/PermissionIcon.js +0 -12
- package/components/permissions/StreamingPermissions.d.ts +0 -20
- package/components/permissions/StreamingPermissions.d.ts.map +0 -1
- package/components/permissions/StreamingPermissions.js +0 -178
- package/components/plugins/showcase-data.d.ts +0 -7
- package/components/plugins/showcase-data.d.ts.map +0 -1
- package/components/plugins/showcase-data.js +0 -464
- package/components/shared/ShellHeaderControls.d.ts +0 -27
- package/components/shared/ShellHeaderControls.d.ts.map +0 -1
- package/components/shared/ShellHeaderControls.js +0 -55
- package/components/shared-companion-scene-context.d.ts +0 -3
- package/components/shared-companion-scene-context.d.ts.map +0 -1
- package/components/shared-companion-scene-context.js +0 -13
- package/components/skeletons.d.ts +0 -17
- package/components/skeletons.d.ts.map +0 -1
- package/components/skeletons.js +0 -22
- package/components/stream/ActivityFeed.d.ts +0 -5
- package/components/stream/ActivityFeed.d.ts.map +0 -1
- package/components/stream/ActivityFeed.js +0 -57
- package/components/stream/AvatarPip.d.ts +0 -5
- package/components/stream/AvatarPip.d.ts.map +0 -1
- package/components/stream/AvatarPip.js +0 -6
- package/components/stream/ChatContent.d.ts +0 -6
- package/components/stream/ChatContent.d.ts.map +0 -1
- package/components/stream/ChatContent.js +0 -69
- package/components/stream/ChatTicker.d.ts +0 -5
- package/components/stream/ChatTicker.d.ts.map +0 -1
- package/components/stream/ChatTicker.js +0 -34
- package/components/stream/IdleContent.d.ts +0 -5
- package/components/stream/IdleContent.d.ts.map +0 -1
- package/components/stream/IdleContent.js +0 -17
- package/components/stream/StatusBar.d.ts +0 -36
- package/components/stream/StatusBar.d.ts.map +0 -1
- package/components/stream/StatusBar.js +0 -140
- package/components/stream/StreamSettings.d.ts +0 -33
- package/components/stream/StreamSettings.d.ts.map +0 -1
- package/components/stream/StreamSettings.js +0 -99
- package/components/stream/StreamTerminal.d.ts +0 -2
- package/components/stream/StreamTerminal.d.ts.map +0 -1
- package/components/stream/StreamTerminal.js +0 -52
- package/components/stream/StreamVoiceConfig.d.ts +0 -10
- package/components/stream/StreamVoiceConfig.d.ts.map +0 -1
- package/components/stream/StreamVoiceConfig.js +0 -88
- package/components/stream/helpers.d.ts +0 -32
- package/components/stream/helpers.d.ts.map +0 -1
- package/components/stream/helpers.js +0 -110
- package/components/stream/overlays/OverlayLayer.d.ts +0 -20
- package/components/stream/overlays/OverlayLayer.d.ts.map +0 -1
- package/components/stream/overlays/OverlayLayer.js +0 -24
- package/components/stream/overlays/built-in/ActionTickerWidget.d.ts +0 -8
- package/components/stream/overlays/built-in/ActionTickerWidget.d.ts.map +0 -1
- package/components/stream/overlays/built-in/ActionTickerWidget.js +0 -44
- package/components/stream/overlays/built-in/AlertPopupWidget.d.ts +0 -7
- package/components/stream/overlays/built-in/AlertPopupWidget.d.ts.map +0 -1
- package/components/stream/overlays/built-in/AlertPopupWidget.js +0 -62
- package/components/stream/overlays/built-in/BrandingWidget.d.ts +0 -7
- package/components/stream/overlays/built-in/BrandingWidget.d.ts.map +0 -1
- package/components/stream/overlays/built-in/BrandingWidget.js +0 -36
- package/components/stream/overlays/built-in/CustomHtmlWidget.d.ts +0 -26
- package/components/stream/overlays/built-in/CustomHtmlWidget.d.ts.map +0 -1
- package/components/stream/overlays/built-in/CustomHtmlWidget.js +0 -78
- package/components/stream/overlays/built-in/PeonGlassWidget.d.ts +0 -11
- package/components/stream/overlays/built-in/PeonGlassWidget.d.ts.map +0 -1
- package/components/stream/overlays/built-in/PeonGlassWidget.js +0 -188
- package/components/stream/overlays/built-in/PeonHudWidget.d.ts +0 -10
- package/components/stream/overlays/built-in/PeonHudWidget.d.ts.map +0 -1
- package/components/stream/overlays/built-in/PeonHudWidget.js +0 -168
- package/components/stream/overlays/built-in/PeonSakuraWidget.d.ts +0 -11
- package/components/stream/overlays/built-in/PeonSakuraWidget.d.ts.map +0 -1
- package/components/stream/overlays/built-in/PeonSakuraWidget.js +0 -213
- package/components/stream/overlays/built-in/ThoughtBubbleWidget.d.ts +0 -8
- package/components/stream/overlays/built-in/ThoughtBubbleWidget.d.ts.map +0 -1
- package/components/stream/overlays/built-in/ThoughtBubbleWidget.js +0 -59
- package/components/stream/overlays/built-in/ViewerCountWidget.d.ts +0 -7
- package/components/stream/overlays/built-in/ViewerCountWidget.d.ts.map +0 -1
- package/components/stream/overlays/built-in/ViewerCountWidget.js +0 -34
- package/components/stream/overlays/built-in/index.d.ts +0 -13
- package/components/stream/overlays/built-in/index.d.ts.map +0 -1
- package/components/stream/overlays/built-in/index.js +0 -12
- package/components/stream/overlays/registry.d.ts +0 -11
- package/components/stream/overlays/registry.d.ts.map +0 -1
- package/components/stream/overlays/registry.js +0 -16
- package/components/stream/overlays/types.d.ts +0 -67
- package/components/stream/overlays/types.d.ts.map +0 -1
- package/components/stream/overlays/types.js +0 -7
- package/components/stream/overlays/useOverlayLayout.d.ts +0 -27
- package/components/stream/overlays/useOverlayLayout.d.ts.map +0 -1
- package/components/stream/overlays/useOverlayLayout.js +0 -162
- package/components/trajectory-format.d.ts +0 -6
- package/components/trajectory-format.d.ts.map +0 -1
- package/components/trajectory-format.js +0 -43
- package/components/ui-badges.d.ts +0 -23
- package/components/ui-badges.d.ts.map +0 -1
- package/components/ui-badges.js +0 -38
- package/components/ui-switch.d.ts +0 -14
- package/components/ui-switch.d.ts.map +0 -1
- package/components/ui-switch.js +0 -15
- package/components/vector-browser-three.d.ts +0 -4
- package/components/vector-browser-three.d.ts.map +0 -1
- package/components/vector-browser-three.js +0 -21
- package/config/branding.d.ts +0 -49
- package/config/branding.d.ts.map +0 -1
- package/config/branding.js +0 -16
- package/config/config-catalog.d.ts +0 -376
- package/config/config-catalog.d.ts.map +0 -1
- package/config/config-catalog.js +0 -724
- package/config/config-field.d.ts +0 -68
- package/config/config-field.d.ts.map +0 -1
- package/config/config-field.js +0 -840
- package/config/config-renderer.d.ts +0 -176
- package/config/config-renderer.d.ts.map +0 -1
- package/config/config-renderer.js +0 -405
- package/config/index.d.ts +0 -6
- package/config/index.d.ts.map +0 -1
- package/config/index.js +0 -5
- package/config/ui-renderer.d.ts +0 -26
- package/config/ui-renderer.d.ts.map +0 -1
- package/config/ui-renderer.js +0 -815
- package/config/ui-spec.d.ts +0 -164
- package/config/ui-spec.d.ts.map +0 -1
- package/config/ui-spec.js +0 -13
- package/events/index.d.ts +0 -48
- package/events/index.d.ts.map +0 -1
- package/events/index.js +0 -45
- package/hooks/index.d.ts +0 -15
- package/hooks/index.d.ts.map +0 -1
- package/hooks/index.js +0 -14
- package/hooks/useBugReport.d.ts +0 -14
- package/hooks/useBugReport.d.ts.map +0 -1
- package/hooks/useBugReport.js +0 -18
- package/hooks/useCanvasWindow.d.ts +0 -38
- package/hooks/useCanvasWindow.d.ts.map +0 -1
- package/hooks/useCanvasWindow.js +0 -273
- package/hooks/useChatAvatarVoice.d.ts +0 -10
- package/hooks/useChatAvatarVoice.d.ts.map +0 -1
- package/hooks/useChatAvatarVoice.js +0 -71
- package/hooks/useClickOutside.d.ts +0 -6
- package/hooks/useClickOutside.d.ts.map +0 -1
- package/hooks/useClickOutside.js +0 -25
- package/hooks/useContextMenu.d.ts +0 -17
- package/hooks/useContextMenu.d.ts.map +0 -1
- package/hooks/useContextMenu.js +0 -100
- package/hooks/useKeyboardShortcuts.d.ts +0 -17
- package/hooks/useKeyboardShortcuts.d.ts.map +0 -1
- package/hooks/useKeyboardShortcuts.js +0 -67
- package/hooks/useLifoSync.d.ts +0 -18
- package/hooks/useLifoSync.d.ts.map +0 -1
- package/hooks/useLifoSync.js +0 -113
- package/hooks/useMemoryMonitor.d.ts +0 -87
- package/hooks/useMemoryMonitor.d.ts.map +0 -1
- package/hooks/useMemoryMonitor.js +0 -209
- package/hooks/useRenderGuard.d.ts +0 -17
- package/hooks/useRenderGuard.d.ts.map +0 -1
- package/hooks/useRenderGuard.js +0 -36
- package/hooks/useRetakeCapture.d.ts +0 -12
- package/hooks/useRetakeCapture.d.ts.map +0 -1
- package/hooks/useRetakeCapture.js +0 -60
- package/hooks/useStreamPopoutNavigation.d.ts +0 -3
- package/hooks/useStreamPopoutNavigation.d.ts.map +0 -1
- package/hooks/useStreamPopoutNavigation.js +0 -17
- package/hooks/useTimeout.d.ts +0 -11
- package/hooks/useTimeout.d.ts.map +0 -1
- package/hooks/useTimeout.js +0 -32
- package/hooks/useVoiceChat.d.ts +0 -94
- package/hooks/useVoiceChat.d.ts.map +0 -1
- package/hooks/useVoiceChat.js +0 -1077
- package/hooks/useWhatsAppPairing.d.ts +0 -11
- package/hooks/useWhatsAppPairing.d.ts.map +0 -1
- package/hooks/useWhatsAppPairing.js +0 -95
- package/i18n/index.d.ts +0 -7
- package/i18n/index.d.ts.map +0 -1
- package/i18n/index.js +0 -53
- package/i18n/locales/en.json +0 -1268
- package/i18n/locales/es.json +0 -1236
- package/i18n/locales/ko.json +0 -1236
- package/i18n/locales/pt.json +0 -1236
- package/i18n/locales/zh-CN.json +0 -1236
- package/i18n/messages.d.ts +0 -6
- package/i18n/messages.d.ts.map +0 -1
- package/i18n/messages.js +0 -14
- package/navigation/index.d.ts +0 -27
- package/navigation/index.d.ts.map +0 -1
- package/navigation/index.js +0 -232
- package/onboarding-config.d.ts +0 -25
- package/onboarding-config.d.ts.map +0 -1
- package/onboarding-config.js +0 -76
- package/platform/browser-launch.d.ts +0 -2
- package/platform/browser-launch.d.ts.map +0 -1
- package/platform/browser-launch.js +0 -109
- package/platform/index.d.ts +0 -14
- package/platform/index.d.ts.map +0 -1
- package/platform/index.js +0 -24
- package/platform/init.d.ts +0 -40
- package/platform/init.d.ts.map +0 -1
- package/platform/init.js +0 -160
- package/platform/lifo.d.ts +0 -51
- package/platform/lifo.d.ts.map +0 -1
- package/platform/lifo.js +0 -138
- package/providers/index.d.ts +0 -19
- package/providers/index.d.ts.map +0 -1
- package/providers/index.js +0 -80
- package/shell-params.d.ts +0 -12
- package/shell-params.d.ts.map +0 -1
- package/shell-params.js +0 -19
- package/state/AppContext.d.ts +0 -12
- package/state/AppContext.d.ts.map +0 -1
- package/state/AppContext.js +0 -5102
- package/state/index.d.ts +0 -7
- package/state/index.d.ts.map +0 -1
- package/state/index.js +0 -6
- package/state/internal.d.ts +0 -7
- package/state/internal.d.ts.map +0 -1
- package/state/internal.js +0 -6
- package/state/onboarding-resume.d.ts +0 -11
- package/state/onboarding-resume.d.ts.map +0 -1
- package/state/onboarding-resume.js +0 -187
- package/state/parsers.d.ts +0 -26
- package/state/parsers.d.ts.map +0 -1
- package/state/parsers.js +0 -255
- package/state/persistence.d.ts +0 -59
- package/state/persistence.d.ts.map +0 -1
- package/state/persistence.js +0 -328
- package/state/shell-routing.d.ts +0 -12
- package/state/shell-routing.d.ts.map +0 -1
- package/state/shell-routing.js +0 -26
- package/state/types.d.ts +0 -426
- package/state/types.d.ts.map +0 -1
- package/state/types.js +0 -89
- package/state/ui-preferences.d.ts +0 -3
- package/state/ui-preferences.d.ts.map +0 -1
- package/state/ui-preferences.js +0 -1
- package/state/useApp.d.ts +0 -4
- package/state/useApp.d.ts.map +0 -1
- package/state/useApp.js +0 -22
- package/state/vrm.d.ts +0 -30
- package/state/vrm.d.ts.map +0 -1
- package/state/vrm.js +0 -82
- package/styles/anime.css +0 -6364
- package/styles/base.css +0 -255
- package/styles/onboarding-game.css +0 -1095
- package/styles/styles.css +0 -2087
- package/styles/xterm.css +0 -241
- package/types/index.d.ts +0 -657
- package/types/index.d.ts.map +0 -1
- package/types/index.js +0 -1
- package/utils/asset-url.d.ts +0 -26
- package/utils/asset-url.d.ts.map +0 -1
- package/utils/asset-url.js +0 -99
- package/utils/assistant-text.d.ts +0 -2
- package/utils/assistant-text.d.ts.map +0 -1
- package/utils/assistant-text.js +0 -161
- package/utils/clipboard.d.ts +0 -2
- package/utils/clipboard.d.ts.map +0 -1
- package/utils/clipboard.js +0 -38
- package/utils/desktop-dialogs.d.ts +0 -19
- package/utils/desktop-dialogs.d.ts.map +0 -1
- package/utils/desktop-dialogs.js +0 -50
- package/utils/eliza-globals.d.ts +0 -11
- package/utils/eliza-globals.d.ts.map +0 -1
- package/utils/eliza-globals.js +0 -33
- package/utils/index.d.ts +0 -8
- package/utils/index.d.ts.map +0 -1
- package/utils/index.js +0 -7
- package/utils/number-parsing.d.ts +0 -44
- package/utils/number-parsing.d.ts.map +0 -1
- package/utils/number-parsing.js +0 -56
- package/utils/openExternalUrl.d.ts +0 -2
- package/utils/openExternalUrl.d.ts.map +0 -1
- package/utils/openExternalUrl.js +0 -17
- package/utils/spoken-text.d.ts +0 -2
- package/utils/spoken-text.d.ts.map +0 -1
- package/utils/spoken-text.js +0 -56
- package/utils/streaming-text.d.ts +0 -3
- package/utils/streaming-text.d.ts.map +0 -1
- package/utils/streaming-text.js +0 -87
- package/voice/index.d.ts +0 -2
- package/voice/index.d.ts.map +0 -1
- package/voice/index.js +0 -1
- package/voice/types.d.ts +0 -25
- package/voice/types.d.ts.map +0 -1
- package/voice/types.js +0 -166
- package/wallet-rpc.d.ts +0 -8
- package/wallet-rpc.d.ts.map +0 -1
- package/wallet-rpc.js +0 -131
- /package/{components/apps/extensions → services/local-inference/voice}/types.js +0 -0
|
@@ -0,0 +1,3308 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Mobile build orchestrator for elizaOS apps.
|
|
4
|
+
*
|
|
5
|
+
* Builds an iOS or Android app from any elizaOS host app (Eliza, etc.).
|
|
6
|
+
* Reads app identity from the host's app.config.ts so web, desktop, and
|
|
7
|
+
* native builds share one canonical app contract.
|
|
8
|
+
*
|
|
9
|
+
* Usage: node scripts/run-mobile-build.mjs <android|android-cloud|android-system|ios|ios-overlay>
|
|
10
|
+
*
|
|
11
|
+
* Android targets:
|
|
12
|
+
* - android Sideload-only debug APK with the on-device agent runtime
|
|
13
|
+
* and AOSP/system-only permissions. NOT Play-Store-shippable.
|
|
14
|
+
* - android-cloud Play-Store-compliant thin Capacitor client backed by
|
|
15
|
+
* Eliza Cloud. No on-device agent, no default-role
|
|
16
|
+
* activities, no system-only permissions.
|
|
17
|
+
* - android-system Privileged platform-signed AOSP release APK for
|
|
18
|
+
* Milady OS / ElizaOS device builds.
|
|
19
|
+
*
|
|
20
|
+
* Phases:
|
|
21
|
+
* 1. Resolve config — read app.config.ts for appId / appName
|
|
22
|
+
* 2. Build web — vite build → dist/
|
|
23
|
+
* 3. Capacitor sync — generate native platform projects
|
|
24
|
+
* 4. Overlay native — permissions, services, entitlements, Podfile
|
|
25
|
+
* 5. Platform patches — Gradle template, SPM compat, xcconfig
|
|
26
|
+
* 5b. Stage Android agent — bun + musl + libstdc++ + libgcc + bundle
|
|
27
|
+
* into packages/app/android/app/src/main/assets/agent/
|
|
28
|
+
* (Android targets only; see
|
|
29
|
+
* scripts/lib/stage-android-agent.mjs and
|
|
30
|
+
* docs/agent-on-mobile.md).
|
|
31
|
+
* 6. Native build — gradlew / xcodebuild
|
|
32
|
+
*/
|
|
33
|
+
import { spawn } from "node:child_process";
|
|
34
|
+
import fs from "node:fs";
|
|
35
|
+
import os from "node:os";
|
|
36
|
+
import path from "node:path";
|
|
37
|
+
import process from "node:process";
|
|
38
|
+
import { fileURLToPath } from "node:url";
|
|
39
|
+
import {
|
|
40
|
+
loadAospVariantConfig,
|
|
41
|
+
resolveAppConfigPath,
|
|
42
|
+
} from "./aosp/lib/load-variant-config.mjs";
|
|
43
|
+
import { resolveMainAppDir } from "./lib/app-dir.mjs";
|
|
44
|
+
import {
|
|
45
|
+
isCapacitorPlatformReady as isCapacitorPlatformReadyImpl,
|
|
46
|
+
resolvePlatformTemplateRoot as resolvePlatformTemplateRootImpl,
|
|
47
|
+
syncPlatformTemplateFiles as syncPlatformTemplateFilesImpl,
|
|
48
|
+
} from "./lib/capacitor-platform-templates.mjs";
|
|
49
|
+
import { resolveRepoRootFromImportMeta } from "./lib/repo-root.mjs";
|
|
50
|
+
import { stageAndroidAgentRuntime } from "./lib/stage-android-agent.mjs";
|
|
51
|
+
|
|
52
|
+
// ── Paths ───────────────────────────────────────────────────────────────
|
|
53
|
+
|
|
54
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
55
|
+
const repoRoot = resolveRepoRootFromImportMeta(import.meta.url, {
|
|
56
|
+
fallbackToCwd: true,
|
|
57
|
+
});
|
|
58
|
+
const appCoreRoot = path.resolve(__dirname, "..");
|
|
59
|
+
const packagesRoot = path.resolve(appCoreRoot, "..");
|
|
60
|
+
const appDir = resolveMainAppDir(repoRoot, "app");
|
|
61
|
+
const iosDir = path.join(appDir, "ios", "App");
|
|
62
|
+
const androidDir = path.join(appDir, "android");
|
|
63
|
+
|
|
64
|
+
// AOSP system APK staging path. Brand-aware: forks declare their vendor
|
|
65
|
+
// dir + APK name in `app.config.ts > aosp:`. When that block is present
|
|
66
|
+
// (Milady, etc.), stage to `<repoRoot>/os/android/vendor/<vendorDir>/
|
|
67
|
+
// apps/<appName>/<appName>.apk`. When absent, fall back to the upstream
|
|
68
|
+
// elizaOS path under packages/os/.
|
|
69
|
+
function resolveSystemApkStagingDir() {
|
|
70
|
+
let variant = null;
|
|
71
|
+
try {
|
|
72
|
+
variant = loadAospVariantConfig({
|
|
73
|
+
appConfigPath: resolveAppConfigPath({ repoRoot, flagValue: null }),
|
|
74
|
+
});
|
|
75
|
+
} catch {
|
|
76
|
+
// app.config.ts missing or malformed — fall through to the elizaOS
|
|
77
|
+
// default. The upstream layout is the right answer for forks that
|
|
78
|
+
// never set up an aosp: block.
|
|
79
|
+
}
|
|
80
|
+
if (variant) {
|
|
81
|
+
const vendorDir = path.join(
|
|
82
|
+
repoRoot,
|
|
83
|
+
"os",
|
|
84
|
+
"android",
|
|
85
|
+
"vendor",
|
|
86
|
+
variant.vendorDir,
|
|
87
|
+
);
|
|
88
|
+
return {
|
|
89
|
+
vendorDir,
|
|
90
|
+
apkDir: path.join(vendorDir, "apps", variant.appName),
|
|
91
|
+
apkName: `${variant.appName}.apk`,
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
const elizaOsVendorDir = path.join(
|
|
95
|
+
repoRoot,
|
|
96
|
+
"packages",
|
|
97
|
+
"os",
|
|
98
|
+
"android",
|
|
99
|
+
"vendor",
|
|
100
|
+
"eliza",
|
|
101
|
+
);
|
|
102
|
+
return {
|
|
103
|
+
vendorDir: elizaOsVendorDir,
|
|
104
|
+
apkDir: path.join(elizaOsVendorDir, "apps", "Eliza"),
|
|
105
|
+
apkName: "Eliza.apk",
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
const systemApkStaging = resolveSystemApkStagingDir();
|
|
109
|
+
const elizaOsApkDir = systemApkStaging.apkDir;
|
|
110
|
+
const elizaOsApkName = systemApkStaging.apkName;
|
|
111
|
+
const platformsDir = path.join(appCoreRoot, "platforms");
|
|
112
|
+
const nativePluginsDir = path.join(packagesRoot, "native-plugins");
|
|
113
|
+
const androidAgentSpikeDir = path.join(
|
|
114
|
+
repoRoot,
|
|
115
|
+
"scripts",
|
|
116
|
+
"spike-android-agent",
|
|
117
|
+
);
|
|
118
|
+
// ── Phase 1: Resolve app identity from app.config.ts ────────────────────
|
|
119
|
+
|
|
120
|
+
function readAppIdentity() {
|
|
121
|
+
const cfgPath = path.join(appDir, "app.config.ts");
|
|
122
|
+
if (!fs.existsSync(cfgPath)) {
|
|
123
|
+
throw new Error(`app.config.ts not found at ${cfgPath}`);
|
|
124
|
+
}
|
|
125
|
+
const src = fs.readFileSync(cfgPath, "utf8");
|
|
126
|
+
const appId = src.match(/appId:\s*["']([^"']+)["']/)?.[1];
|
|
127
|
+
const appName = src.match(/appName:\s*["']([^"']+)["']/)?.[1];
|
|
128
|
+
const urlScheme = src.match(/urlScheme:\s*["']([^"']+)["']/)?.[1] ?? appId;
|
|
129
|
+
if (!appId || !appName) {
|
|
130
|
+
throw new Error("Could not parse appId/appName from app.config.ts");
|
|
131
|
+
}
|
|
132
|
+
// android.userAgentMarkers is an optional array literal nested under
|
|
133
|
+
// `android: { ... }`. Parse the array body via regex (rather than
|
|
134
|
+
// executing the TS file) so this script stays bun-import-free.
|
|
135
|
+
const userAgentMarkers = parseAndroidUserAgentMarkers(src);
|
|
136
|
+
return { appId, appName, urlScheme, userAgentMarkers };
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
function parseAndroidUserAgentMarkers(configSrc) {
|
|
140
|
+
const block = configSrc.match(
|
|
141
|
+
/android\s*:\s*\{[\s\S]*?userAgentMarkers\s*:\s*\[([\s\S]*?)\]/,
|
|
142
|
+
);
|
|
143
|
+
if (!block) return [];
|
|
144
|
+
const body = block[1];
|
|
145
|
+
const markers = [];
|
|
146
|
+
const entryRe =
|
|
147
|
+
/\{\s*systemProp\s*:\s*["']([^"']+)["']\s*,\s*uaPrefix\s*:\s*["']([^"']+)["']\s*[,}]/g;
|
|
148
|
+
while (true) {
|
|
149
|
+
const m = entryRe.exec(body);
|
|
150
|
+
if (!m) break;
|
|
151
|
+
markers.push({ systemProp: m[1], uaPrefix: m[2] });
|
|
152
|
+
}
|
|
153
|
+
return markers;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
const APP = readAppIdentity();
|
|
157
|
+
console.log(`[mobile-build] App: ${APP.appName} (${APP.appId})`);
|
|
158
|
+
|
|
159
|
+
// ── Helpers ─────────────────────────────────────────────────────────────
|
|
160
|
+
|
|
161
|
+
function run(command, args, { cwd, env = process.env } = {}) {
|
|
162
|
+
return new Promise((resolve, reject) => {
|
|
163
|
+
const child = spawn(command, args, { cwd, env, stdio: "inherit" });
|
|
164
|
+
child.on("exit", (code, signal) => {
|
|
165
|
+
if (signal) return reject(new Error(`${command} killed by ${signal}`));
|
|
166
|
+
if ((code ?? 1) !== 0)
|
|
167
|
+
return reject(new Error(`${command} exited with code ${code ?? 1}`));
|
|
168
|
+
resolve();
|
|
169
|
+
});
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
function runCapacitor(args) {
|
|
174
|
+
return run(
|
|
175
|
+
process.execPath,
|
|
176
|
+
[
|
|
177
|
+
path.join(
|
|
178
|
+
appDir,
|
|
179
|
+
"node_modules",
|
|
180
|
+
"@capacitor",
|
|
181
|
+
"cli",
|
|
182
|
+
"bin",
|
|
183
|
+
"capacitor",
|
|
184
|
+
),
|
|
185
|
+
...args,
|
|
186
|
+
],
|
|
187
|
+
{ cwd: appDir },
|
|
188
|
+
);
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
function firstExisting(paths) {
|
|
192
|
+
for (const p of paths) {
|
|
193
|
+
if (p && fs.existsSync(p)) return p;
|
|
194
|
+
}
|
|
195
|
+
return null;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
function resolveExecutable(name) {
|
|
199
|
+
const pathValue = process.env.PATH ?? "";
|
|
200
|
+
for (const dir of pathValue.split(path.delimiter)) {
|
|
201
|
+
if (!dir) continue;
|
|
202
|
+
const candidate = path.join(dir, name);
|
|
203
|
+
try {
|
|
204
|
+
fs.accessSync(candidate, fs.constants.X_OK);
|
|
205
|
+
return candidate;
|
|
206
|
+
} catch {
|
|
207
|
+
// Keep searching PATH.
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
return null;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
function resolveBunExecutable() {
|
|
214
|
+
if (process.versions.bun) return process.execPath;
|
|
215
|
+
return resolveExecutable("bun");
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
function resolveAndroidSdkRoot() {
|
|
219
|
+
return firstExisting([
|
|
220
|
+
process.env.ANDROID_SDK_ROOT,
|
|
221
|
+
process.env.ANDROID_HOME,
|
|
222
|
+
path.join(os.homedir(), "Library", "Android", "sdk"),
|
|
223
|
+
path.join(os.homedir(), "Android", "Sdk"),
|
|
224
|
+
]);
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
function resolveViteCli() {
|
|
228
|
+
const viteCli = firstExisting([
|
|
229
|
+
path.join(appDir, "node_modules", ".bin", "vite"),
|
|
230
|
+
path.join(repoRoot, "node_modules", ".bin", "vite"),
|
|
231
|
+
path.join(appDir, "node_modules", "vite", "bin", "vite.js"),
|
|
232
|
+
path.join(repoRoot, "node_modules", "vite", "bin", "vite.js"),
|
|
233
|
+
]);
|
|
234
|
+
if (!viteCli) {
|
|
235
|
+
throw new Error("vite CLI not found; run bun install");
|
|
236
|
+
}
|
|
237
|
+
return viteCli;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
function resolveJavaHome() {
|
|
241
|
+
return firstExisting([
|
|
242
|
+
process.env.JAVA_HOME,
|
|
243
|
+
"/opt/homebrew/opt/openjdk@21",
|
|
244
|
+
"/usr/local/opt/openjdk@21",
|
|
245
|
+
"/usr/lib/jvm/temurin-21-jdk-amd64",
|
|
246
|
+
"/usr/lib/jvm/java-21-openjdk-amd64",
|
|
247
|
+
"/usr/lib/jvm/java-21-openjdk",
|
|
248
|
+
]);
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
function prependPath(env, entries) {
|
|
252
|
+
const sep = process.platform === "win32" ? ";" : ":";
|
|
253
|
+
const valid = entries.filter(Boolean);
|
|
254
|
+
return valid.length
|
|
255
|
+
? `${valid.join(sep)}${sep}${env.PATH ?? ""}`
|
|
256
|
+
: (env.PATH ?? "");
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
function escapeJavaString(value) {
|
|
260
|
+
return value.replace(/\\/g, "\\\\").replace(/"/g, '\\"');
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
function escapeXmlText(value) {
|
|
264
|
+
return value
|
|
265
|
+
.replace(/&/g, "&")
|
|
266
|
+
.replace(/</g, "<")
|
|
267
|
+
.replace(/>/g, ">");
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
function escapeXcodeBuildSetting(value) {
|
|
271
|
+
return `"${value.replace(/\\/g, "\\\\").replace(/"/g, '\\"')}"`;
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
function replaceOrInsertPlistString(content, key, value) {
|
|
275
|
+
const escapedValue = escapeXmlText(value);
|
|
276
|
+
const keyRe = escapeRegExp(key);
|
|
277
|
+
const existingRe = new RegExp(
|
|
278
|
+
`(<key>${keyRe}</key>\\s*<string>)[^<]*(</string>)`,
|
|
279
|
+
);
|
|
280
|
+
if (existingRe.test(content)) {
|
|
281
|
+
return content.replace(existingRe, `$1${escapedValue}$2`);
|
|
282
|
+
}
|
|
283
|
+
return content.replace(
|
|
284
|
+
"</dict>",
|
|
285
|
+
`\t<key>${key}</key>\n\t<string>${escapedValue}</string>\n</dict>`,
|
|
286
|
+
);
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
function ensurePlistArrayStrings(content, key, values) {
|
|
290
|
+
const escapedValues = values.map(escapeXmlText);
|
|
291
|
+
const keyRe = escapeRegExp(key);
|
|
292
|
+
const arrayRe = new RegExp(
|
|
293
|
+
`(<key>${keyRe}</key>\\s*<array>)([\\s\\S]*?)(\\s*</array>)`,
|
|
294
|
+
);
|
|
295
|
+
const match = content.match(arrayRe);
|
|
296
|
+
if (!match) {
|
|
297
|
+
const body = escapedValues
|
|
298
|
+
.map((value) => `\t\t<string>${value}</string>`)
|
|
299
|
+
.join("\n");
|
|
300
|
+
return insertBeforeRootPlistDictClose(
|
|
301
|
+
content,
|
|
302
|
+
`\t<key>${key}</key>\n\t<array>\n${body}\n\t</array>\n</dict>`,
|
|
303
|
+
);
|
|
304
|
+
}
|
|
305
|
+
let body = match[2];
|
|
306
|
+
for (const value of escapedValues) {
|
|
307
|
+
if (!body.includes(`<string>${value}</string>`)) {
|
|
308
|
+
body += `\n\t\t<string>${value}</string>`;
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
return content.replace(arrayRe, `$1${body}$3`);
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
function insertBeforeRootPlistDictClose(content, insertion) {
|
|
315
|
+
const rootClose = "\n</dict>\n</plist>";
|
|
316
|
+
const index = content.lastIndexOf(rootClose);
|
|
317
|
+
if (index >= 0) {
|
|
318
|
+
return `${content.slice(0, index)}\n${insertion}${content.slice(index + "\n</dict>".length)}`;
|
|
319
|
+
}
|
|
320
|
+
const fallbackIndex = content.lastIndexOf("</dict>");
|
|
321
|
+
if (fallbackIndex < 0) return content;
|
|
322
|
+
return `${content.slice(0, fallbackIndex)}${insertion}${content.slice(fallbackIndex + "</dict>".length)}`;
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
function ensurePlistUrlScheme(content, urlScheme) {
|
|
326
|
+
const escapedScheme = escapeXmlText(urlScheme);
|
|
327
|
+
const urlTypesRe =
|
|
328
|
+
/(<key>CFBundleURLTypes<\/key>\s*<array>)([\s\S]*?)(\s*<\/array>)/;
|
|
329
|
+
const entry = `
|
|
330
|
+
<dict>
|
|
331
|
+
<key>CFBundleURLName</key>
|
|
332
|
+
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
|
333
|
+
<key>CFBundleURLSchemes</key>
|
|
334
|
+
<array>
|
|
335
|
+
<string>${escapedScheme}</string>
|
|
336
|
+
</array>
|
|
337
|
+
</dict>`;
|
|
338
|
+
const match = content.match(urlTypesRe);
|
|
339
|
+
if (!match) {
|
|
340
|
+
return insertBeforeRootPlistDictClose(
|
|
341
|
+
content,
|
|
342
|
+
`\t<key>CFBundleURLTypes</key>\n\t<array>${entry}\n\t</array>\n</dict>`,
|
|
343
|
+
);
|
|
344
|
+
}
|
|
345
|
+
if (match[2].includes(`<string>${escapedScheme}</string>`)) {
|
|
346
|
+
return content;
|
|
347
|
+
}
|
|
348
|
+
return content.replace(urlTypesRe, `$1${match[2]}${entry}$3`);
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
/**
|
|
352
|
+
* Resolve the real filesystem path to a node_modules package (follows bun
|
|
353
|
+
* symlinks). Returns a path relative to `relativeTo`.
|
|
354
|
+
*/
|
|
355
|
+
function resolvePackagePath(pkgName, relativeTo) {
|
|
356
|
+
const linked = resolvePackageAbsolutePath(pkgName);
|
|
357
|
+
if (!linked) return null;
|
|
358
|
+
return path.relative(relativeTo, linked);
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
function resolvePackageAbsolutePath(pkgName) {
|
|
362
|
+
const appPackage = path.join(appDir, "node_modules", ...pkgName.split("/"));
|
|
363
|
+
const rootNodeModulesPackage = path.join(
|
|
364
|
+
repoRoot,
|
|
365
|
+
"node_modules",
|
|
366
|
+
...pkgName.split("/"),
|
|
367
|
+
);
|
|
368
|
+
const candidates = [appPackage, rootNodeModulesPackage];
|
|
369
|
+
for (const bunStore of [
|
|
370
|
+
path.join(appDir, "node_modules", ".bun"),
|
|
371
|
+
path.join(repoRoot, "node_modules", ".bun"),
|
|
372
|
+
]) {
|
|
373
|
+
if (!fs.existsSync(bunStore)) continue;
|
|
374
|
+
for (const entry of fs.readdirSync(bunStore, { withFileTypes: true })) {
|
|
375
|
+
if (!entry.isDirectory()) continue;
|
|
376
|
+
candidates.push(
|
|
377
|
+
path.join(bunStore, entry.name, "node_modules", ...pkgName.split("/")),
|
|
378
|
+
);
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
const linked = candidates.find((candidate) => fs.existsSync(candidate));
|
|
382
|
+
if (!linked) return null;
|
|
383
|
+
return fs.realpathSync(linked);
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
function resolveNativePluginPackagePath(pkgName, relativeTo) {
|
|
387
|
+
const match = pkgName.match(/^@elizaos\/capacitor-(.+)$/);
|
|
388
|
+
if (match) {
|
|
389
|
+
const localPluginRoot = path.join(nativePluginsDir, match[1]);
|
|
390
|
+
if (fs.existsSync(path.join(localPluginRoot, "package.json"))) {
|
|
391
|
+
return path.relative(relativeTo, localPluginRoot);
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
return resolvePackagePath(pkgName, relativeTo);
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
export function resolvePlatformTemplateRoot(
|
|
398
|
+
platform,
|
|
399
|
+
{ repoRootValue = repoRoot } = {},
|
|
400
|
+
) {
|
|
401
|
+
return resolvePlatformTemplateRootImpl(platform, { repoRootValue });
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
export function syncPlatformTemplateFiles(
|
|
405
|
+
platform,
|
|
406
|
+
{ repoRootValue = repoRoot, appDirValue = appDir, log = console.log } = {},
|
|
407
|
+
) {
|
|
408
|
+
return syncPlatformTemplateFilesImpl(platform, {
|
|
409
|
+
repoRootValue,
|
|
410
|
+
appDirValue,
|
|
411
|
+
log,
|
|
412
|
+
});
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
export function isCapacitorPlatformReady(
|
|
416
|
+
platform,
|
|
417
|
+
{ appDirValue = appDir } = {},
|
|
418
|
+
) {
|
|
419
|
+
return isCapacitorPlatformReadyImpl(platform, { appDirValue });
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
function replaceInFile(filePath, replacements) {
|
|
423
|
+
if (!fs.existsSync(filePath)) return false;
|
|
424
|
+
let content = fs.readFileSync(filePath, "utf8");
|
|
425
|
+
const original = content;
|
|
426
|
+
for (const [search, replacement] of replacements) {
|
|
427
|
+
content = content.replaceAll(search, replacement);
|
|
428
|
+
}
|
|
429
|
+
if (content === original) return false;
|
|
430
|
+
fs.writeFileSync(filePath, content, "utf8");
|
|
431
|
+
return true;
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
function packageNameToPath(packageName) {
|
|
435
|
+
return path.join(...packageName.split("."));
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
export function applyIosAppIdentity({
|
|
439
|
+
appDirValue = appDir,
|
|
440
|
+
appId = APP.appId,
|
|
441
|
+
appName = APP.appName,
|
|
442
|
+
appGroup = `group.${appId}`,
|
|
443
|
+
developmentTeam = process.env.ELIZA_IOS_DEVELOPMENT_TEAM ??
|
|
444
|
+
process.env.ELIZA_IOS_DEVELOPMENT_TEAM ??
|
|
445
|
+
null,
|
|
446
|
+
log = console.log,
|
|
447
|
+
} = {}) {
|
|
448
|
+
const iosAppRoot = path.join(appDirValue, "ios", "App");
|
|
449
|
+
const changed = [];
|
|
450
|
+
const projectPath = path.join(iosAppRoot, "App.xcodeproj", "project.pbxproj");
|
|
451
|
+
if (fs.existsSync(projectPath)) {
|
|
452
|
+
let project = fs.readFileSync(projectPath, "utf8");
|
|
453
|
+
const original = project;
|
|
454
|
+
project = project.replace(
|
|
455
|
+
/PRODUCT_BUNDLE_IDENTIFIER = [A-Za-z0-9_.-]+\.WebsiteBlockerContentExtension;/g,
|
|
456
|
+
`PRODUCT_BUNDLE_IDENTIFIER = ${appId}.WebsiteBlockerContentExtension;`,
|
|
457
|
+
);
|
|
458
|
+
project = project.replace(
|
|
459
|
+
/PRODUCT_BUNDLE_IDENTIFIER = (?![A-Za-z0-9_.-]+\.WebsiteBlockerContentExtension;)[A-Za-z0-9_.-]+;/g,
|
|
460
|
+
`PRODUCT_BUNDLE_IDENTIFIER = ${appId};`,
|
|
461
|
+
);
|
|
462
|
+
const displayNameSetting = `ELIZA_DISPLAY_NAME = ${escapeXcodeBuildSetting(appName)};`;
|
|
463
|
+
if (project.includes("ELIZA_DISPLAY_NAME = ")) {
|
|
464
|
+
project = project.replace(
|
|
465
|
+
/ELIZA_DISPLAY_NAME = .*?;/g,
|
|
466
|
+
displayNameSetting,
|
|
467
|
+
);
|
|
468
|
+
} else {
|
|
469
|
+
project = project.replace(
|
|
470
|
+
new RegExp(
|
|
471
|
+
`(^[ \\t]*MARKETING_VERSION = 1\\.0;\\n)([ \\t]*)PRODUCT_BUNDLE_IDENTIFIER = ${escapeRegExp(appId)};`,
|
|
472
|
+
"m",
|
|
473
|
+
),
|
|
474
|
+
`$1$2${displayNameSetting}\n$2PRODUCT_BUNDLE_IDENTIFIER = ${appId};`,
|
|
475
|
+
);
|
|
476
|
+
}
|
|
477
|
+
if (developmentTeam) {
|
|
478
|
+
project = project.replace(
|
|
479
|
+
/DEVELOPMENT_TEAM = [A-Z0-9]+;/g,
|
|
480
|
+
`DEVELOPMENT_TEAM = ${developmentTeam};`,
|
|
481
|
+
);
|
|
482
|
+
}
|
|
483
|
+
if (project !== original) {
|
|
484
|
+
fs.writeFileSync(projectPath, project, "utf8");
|
|
485
|
+
changed.push(path.relative(iosAppRoot, projectPath));
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
const replacements = [
|
|
490
|
+
["group.ai.elizaos.app", appGroup],
|
|
491
|
+
["group.app.eliza", appGroup],
|
|
492
|
+
["group.com.miladyai.milady", appGroup],
|
|
493
|
+
['"group.ai.elizaos.app"', `"${appGroup}"`],
|
|
494
|
+
['"group.app.eliza"', `"${appGroup}"`],
|
|
495
|
+
['"group.com.miladyai.milady"', `"${appGroup}"`],
|
|
496
|
+
];
|
|
497
|
+
for (const relPath of [
|
|
498
|
+
path.join("App", "App.entitlements"),
|
|
499
|
+
path.join("App", "ScreenTimeSupport.swift"),
|
|
500
|
+
path.join(
|
|
501
|
+
"App",
|
|
502
|
+
"WebsiteBlockerContentExtension",
|
|
503
|
+
"WebsiteBlockerContentExtension.entitlements",
|
|
504
|
+
),
|
|
505
|
+
path.join(
|
|
506
|
+
"App",
|
|
507
|
+
"WebsiteBlockerContentExtension",
|
|
508
|
+
"ActionRequestHandler.swift",
|
|
509
|
+
),
|
|
510
|
+
]) {
|
|
511
|
+
const filePath = path.join(iosAppRoot, relPath);
|
|
512
|
+
if (replaceInFile(filePath, replacements)) {
|
|
513
|
+
changed.push(relPath);
|
|
514
|
+
}
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
const extensionId = `${appId}.WebsiteBlockerContentExtension`;
|
|
518
|
+
const fastlaneReplacements = [
|
|
519
|
+
[
|
|
520
|
+
'ENV["APP_IDENTIFIER"] || "ai.elizaos.app"',
|
|
521
|
+
`ENV["APP_IDENTIFIER"] || "${appId}"`,
|
|
522
|
+
],
|
|
523
|
+
[
|
|
524
|
+
'ENV["APP_IDENTIFIER_EXTRA"] || ""',
|
|
525
|
+
`ENV["APP_IDENTIFIER_EXTRA"] || "${extensionId}"`,
|
|
526
|
+
],
|
|
527
|
+
];
|
|
528
|
+
for (const relPath of [
|
|
529
|
+
path.join("fastlane", "Appfile"),
|
|
530
|
+
path.join("fastlane", "Fastfile"),
|
|
531
|
+
path.join("fastlane", "Matchfile"),
|
|
532
|
+
]) {
|
|
533
|
+
const filePath = path.join(path.dirname(iosAppRoot), relPath);
|
|
534
|
+
if (replaceInFile(filePath, fastlaneReplacements)) {
|
|
535
|
+
changed.push(relPath);
|
|
536
|
+
}
|
|
537
|
+
}
|
|
538
|
+
if (changed.length > 0) {
|
|
539
|
+
log(`[mobile-build] Applied iOS identity ${appId}.`);
|
|
540
|
+
}
|
|
541
|
+
return changed;
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
// ── Phase 2: Build web bundle ───────────────────────────────────────────
|
|
545
|
+
|
|
546
|
+
async function buildWeb(platform) {
|
|
547
|
+
const capacitorTarget =
|
|
548
|
+
platform === "android-system" || platform === "android-cloud"
|
|
549
|
+
? "android"
|
|
550
|
+
: platform === "ios-overlay"
|
|
551
|
+
? "ios"
|
|
552
|
+
: platform;
|
|
553
|
+
// Android runtime mode mirrors the iOS runtime mode pattern: `cloud`
|
|
554
|
+
// means the renderer should treat Eliza Cloud as the only hosting target
|
|
555
|
+
// (Play-Store-compliant thin client; no on-device agent), while `local`
|
|
556
|
+
// is the default sideload/AOSP behavior. Surfaced to the renderer via
|
|
557
|
+
// VITE_ELIZA_ANDROID_RUNTIME_MODE so it can hide the Local picker option.
|
|
558
|
+
const androidRuntimeMode =
|
|
559
|
+
platform === "android-cloud"
|
|
560
|
+
? "cloud"
|
|
561
|
+
: platform === "android" || platform === "android-system"
|
|
562
|
+
? "local"
|
|
563
|
+
: null;
|
|
564
|
+
const env = {
|
|
565
|
+
...process.env,
|
|
566
|
+
ELIZA_CAPACITOR_BUILD_TARGET: capacitorTarget,
|
|
567
|
+
MILADY_CAPACITOR_BUILD_TARGET: capacitorTarget,
|
|
568
|
+
...(androidRuntimeMode
|
|
569
|
+
? {
|
|
570
|
+
VITE_ELIZA_ANDROID_RUNTIME_MODE: androidRuntimeMode,
|
|
571
|
+
VITE_MILADY_ANDROID_RUNTIME_MODE: androidRuntimeMode,
|
|
572
|
+
}
|
|
573
|
+
: {}),
|
|
574
|
+
};
|
|
575
|
+
const bun = resolveBunExecutable();
|
|
576
|
+
if (bun) {
|
|
577
|
+
await run(bun, ["run", "build:web"], { cwd: appDir, env });
|
|
578
|
+
return;
|
|
579
|
+
}
|
|
580
|
+
await run(process.execPath, [resolveViteCli(), "build"], {
|
|
581
|
+
cwd: appDir,
|
|
582
|
+
env,
|
|
583
|
+
});
|
|
584
|
+
}
|
|
585
|
+
|
|
586
|
+
// ── Phase 3: Capacitor sync ────────────────────────────────────────────
|
|
587
|
+
|
|
588
|
+
async function ensurePlatform(platform) {
|
|
589
|
+
const dir = platform === "android" ? androidDir : iosDir;
|
|
590
|
+
if (!fs.existsSync(dir)) {
|
|
591
|
+
const copied = syncPlatformTemplateFiles(platform);
|
|
592
|
+
if (copied.length === 0) {
|
|
593
|
+
console.log(`[mobile-build] Adding Capacitor ${platform} platform...`);
|
|
594
|
+
await runCapacitor(["add", platform]);
|
|
595
|
+
}
|
|
596
|
+
}
|
|
597
|
+
if (!isCapacitorPlatformReady(platform)) {
|
|
598
|
+
syncPlatformTemplateFiles(platform);
|
|
599
|
+
}
|
|
600
|
+
}
|
|
601
|
+
|
|
602
|
+
// ── Phase 4: Android native overlay ─────────────────────────────────────
|
|
603
|
+
|
|
604
|
+
/** Permissions that Capacitor sync doesn't generate (it only adds INTERNET). */
|
|
605
|
+
const ANDROID_PERMISSIONS = [
|
|
606
|
+
"READ_CONTACTS",
|
|
607
|
+
"WRITE_CONTACTS",
|
|
608
|
+
"CALL_PHONE",
|
|
609
|
+
"READ_PHONE_STATE",
|
|
610
|
+
"ANSWER_PHONE_CALLS",
|
|
611
|
+
"MANAGE_OWN_CALLS",
|
|
612
|
+
"READ_CALL_LOG",
|
|
613
|
+
"WRITE_CALL_LOG",
|
|
614
|
+
"READ_SMS",
|
|
615
|
+
"SEND_SMS",
|
|
616
|
+
"RECEIVE_SMS",
|
|
617
|
+
"RECEIVE_MMS",
|
|
618
|
+
"RECEIVE_WAP_PUSH",
|
|
619
|
+
"RECORD_AUDIO",
|
|
620
|
+
"CAMERA",
|
|
621
|
+
"ACCESS_FINE_LOCATION",
|
|
622
|
+
"ACCESS_COARSE_LOCATION",
|
|
623
|
+
"ACCESS_BACKGROUND_LOCATION",
|
|
624
|
+
"FOREGROUND_SERVICE",
|
|
625
|
+
"FOREGROUND_SERVICE_DATA_SYNC",
|
|
626
|
+
"FOREGROUND_SERVICE_SPECIAL_USE",
|
|
627
|
+
"POST_NOTIFICATIONS",
|
|
628
|
+
"WAKE_LOCK",
|
|
629
|
+
"RECEIVE_BOOT_COMPLETED",
|
|
630
|
+
"SYSTEM_ALERT_WINDOW",
|
|
631
|
+
// PACKAGE_USAGE_STATS is granted via the privapp-permissions whitelist;
|
|
632
|
+
// MANAGE_APP_OPS_MODES is what ElizaBootReceiver actually needs to
|
|
633
|
+
// reflectively flip the GET_USAGE_STATS appop to ALLOWED at boot.
|
|
634
|
+
// Without MANAGE_APP_OPS_MODES the receiver throws SecurityException
|
|
635
|
+
// and PACKAGE_USAGE_STATS stays appop-default-denied, which breaks
|
|
636
|
+
// priv-app usage-stats access. See vendor/eliza/permissions/
|
|
637
|
+
// privapp-permissions-com.elizaai.eliza.xml.
|
|
638
|
+
"PACKAGE_USAGE_STATS",
|
|
639
|
+
"MANAGE_APP_OPS_MODES",
|
|
640
|
+
];
|
|
641
|
+
|
|
642
|
+
function replaceOrInsertGradleString(content, key, value) {
|
|
643
|
+
// AGP-modern uses `key = "value"`, AGP-legacy uses `key "value"`. Match
|
|
644
|
+
// either and preserve the existing assignment shape so we don't flip
|
|
645
|
+
// styles unnecessarily. The namespace declaration ships in the modern
|
|
646
|
+
// form on Android Gradle Plugin 8+ generated projects, while
|
|
647
|
+
// applicationId is still emitted in the legacy form by Capacitor's
|
|
648
|
+
// template — both must be patchable.
|
|
649
|
+
const re = new RegExp(`(${key}\\s*=?\\s*)["'][^"']+["']`);
|
|
650
|
+
if (re.test(content)) {
|
|
651
|
+
return content.replace(re, `$1"${value}"`);
|
|
652
|
+
}
|
|
653
|
+
return content;
|
|
654
|
+
}
|
|
655
|
+
|
|
656
|
+
function appendMissingGradleDependency(content, notation) {
|
|
657
|
+
if (content.includes(notation)) return content;
|
|
658
|
+
return content.replace(
|
|
659
|
+
/dependencies\s*\{/,
|
|
660
|
+
`dependencies {\n implementation "${notation}"`,
|
|
661
|
+
);
|
|
662
|
+
}
|
|
663
|
+
|
|
664
|
+
/**
|
|
665
|
+
* Inject `buildFeatures { buildConfig true }` and the `AOSP_BUILD`
|
|
666
|
+
* buildConfigField into the app-level build.gradle.
|
|
667
|
+
*
|
|
668
|
+
* Why: `ElizaAgentService` reads `BuildConfig.AOSP_BUILD` to decide whether
|
|
669
|
+
* to export `ELIZA_LOCAL_LLAMA=1` to the spawned bun process (see
|
|
670
|
+
* eliza/packages/agent/src/runtime/aosp-llama-adapter.ts). AGP 8+ defaults
|
|
671
|
+
* `buildFeatures.buildConfig` to false, so without the flag flip the
|
|
672
|
+
* BuildConfig.java is never generated and the Java service refuses to
|
|
673
|
+
* compile. The boolean field defaults to false, so the Capacitor APK build
|
|
674
|
+
* keeps DeviceBridge inference; the AOSP build flow flips it to true via
|
|
675
|
+
* the `-PelizaAospBuild=true` gradle property documented in
|
|
676
|
+
* scripts/elizaos/build-aosp.mjs and SETUP_AOSP.md.
|
|
677
|
+
*/
|
|
678
|
+
function injectBuildConfigAospField(content) {
|
|
679
|
+
let next = content;
|
|
680
|
+
if (!/\bbuildFeatures\s*\{/.test(next)) {
|
|
681
|
+
next = next.replace(
|
|
682
|
+
/android\s*\{/,
|
|
683
|
+
`android {\n buildFeatures {\n buildConfig true\n }\n`,
|
|
684
|
+
);
|
|
685
|
+
} else if (!/buildConfig\s+true/.test(next)) {
|
|
686
|
+
next = next.replace(
|
|
687
|
+
/buildFeatures\s*\{/,
|
|
688
|
+
"buildFeatures {\n buildConfig true",
|
|
689
|
+
);
|
|
690
|
+
}
|
|
691
|
+
if (!/buildConfigField\s+["']boolean["'],\s*["']AOSP_BUILD["']/.test(next)) {
|
|
692
|
+
next = next.replace(
|
|
693
|
+
/defaultConfig\s*\{/,
|
|
694
|
+
`defaultConfig {\n buildConfigField "boolean", "AOSP_BUILD", "\${project.findProperty('elizaAospBuild') ?: 'false'}"\n`,
|
|
695
|
+
);
|
|
696
|
+
}
|
|
697
|
+
return next;
|
|
698
|
+
}
|
|
699
|
+
|
|
700
|
+
/**
|
|
701
|
+
* Inject the `androidResources { noCompress += [...] }` block that keeps
|
|
702
|
+
* `.tar.gz`, `.tar`, `.gguf`, and `.so` files byte-identical in the
|
|
703
|
+
* packaged APK.
|
|
704
|
+
*
|
|
705
|
+
* Why: aapt2's default packaging treats `.gz` and `.tar.gz` as
|
|
706
|
+
* "compressed-extension-to-preserve-uncompressed" and rewrites the entry
|
|
707
|
+
* to a plain `.tar`. PGlite's runtime extension loader resolves
|
|
708
|
+
* `vector.tar.gz` and `fuzzystrmatch.tar.gz` via
|
|
709
|
+
* `new URL("../X", import.meta.url)`; when aapt2 strips the `.gz` the
|
|
710
|
+
* loader can't find the file and the runtime falls over at first
|
|
711
|
+
* Postgres extension call.
|
|
712
|
+
*
|
|
713
|
+
* Idempotent: re-runs are no-ops once the block is present. The matcher
|
|
714
|
+
* accepts AGP-modern `androidResources` and legacy `aaptOptions` blocks,
|
|
715
|
+
* but only injects when neither already lists `tar.gz`.
|
|
716
|
+
*/
|
|
717
|
+
export function injectNoCompressTarGz(content) {
|
|
718
|
+
if (/noCompress[^\n]*['"]tar\.gz['"]/.test(content)) return content;
|
|
719
|
+
const block =
|
|
720
|
+
`\n // Preserve .tar.gz / .tar / .gguf / .so as-is in the packaged APK.\n` +
|
|
721
|
+
` // aapt2 otherwise rewrites .tar.gz to .tar and PGlite's runtime\n` +
|
|
722
|
+
` // extension loader fails to find vector.tar.gz / fuzzystrmatch.tar.gz.\n` +
|
|
723
|
+
` androidResources {\n` +
|
|
724
|
+
` noCompress += ['gguf', 'tar.gz', 'so', 'tar']\n` +
|
|
725
|
+
` }\n`;
|
|
726
|
+
// Inject just before the closing brace of the top-level `android { ... }`
|
|
727
|
+
// block. Match the LAST `}` in the file as a heuristic that's robust
|
|
728
|
+
// against arbitrary middle content.
|
|
729
|
+
const androidOpen = content.search(/\n\s*android\s*\{/);
|
|
730
|
+
if (androidOpen < 0) return content;
|
|
731
|
+
// Find the matching closing brace by counting from the open.
|
|
732
|
+
let depth = 0;
|
|
733
|
+
let i = content.indexOf("{", androidOpen);
|
|
734
|
+
while (i < content.length) {
|
|
735
|
+
const ch = content[i];
|
|
736
|
+
if (ch === "{") depth += 1;
|
|
737
|
+
else if (ch === "}") {
|
|
738
|
+
depth -= 1;
|
|
739
|
+
if (depth === 0) {
|
|
740
|
+
return content.slice(0, i) + block + content.slice(i);
|
|
741
|
+
}
|
|
742
|
+
}
|
|
743
|
+
i += 1;
|
|
744
|
+
}
|
|
745
|
+
return content;
|
|
746
|
+
}
|
|
747
|
+
|
|
748
|
+
/**
|
|
749
|
+
* Keep packaged Android native libraries extracted on install.
|
|
750
|
+
*
|
|
751
|
+
* Normal Capacitor installs run as `untrusted_app`, which cannot execute
|
|
752
|
+
* bun/musl files copied into app data. ElizaAgentService therefore prefers
|
|
753
|
+
* the same payload shipped as libeliza_* native libraries; those files must
|
|
754
|
+
* exist on disk under nativeLibraryDir for ProcessBuilder to execute them.
|
|
755
|
+
*/
|
|
756
|
+
export function injectNativeLibLegacyPackaging(content) {
|
|
757
|
+
if (/useLegacyPackaging\s*=\s*true/.test(content)) return content;
|
|
758
|
+
if (/jniLibs\s*\{/.test(content)) {
|
|
759
|
+
return content.replace(
|
|
760
|
+
/jniLibs\s*\{/,
|
|
761
|
+
"jniLibs {\n useLegacyPackaging = true",
|
|
762
|
+
);
|
|
763
|
+
}
|
|
764
|
+
if (/packaging\s*\{/.test(content)) {
|
|
765
|
+
return content.replace(
|
|
766
|
+
/packaging\s*\{/,
|
|
767
|
+
"packaging {\n jniLibs {\n useLegacyPackaging = true\n }",
|
|
768
|
+
);
|
|
769
|
+
}
|
|
770
|
+
|
|
771
|
+
const block =
|
|
772
|
+
`\n packaging {\n` +
|
|
773
|
+
` jniLibs {\n` +
|
|
774
|
+
` useLegacyPackaging = true\n` +
|
|
775
|
+
` }\n` +
|
|
776
|
+
` }\n`;
|
|
777
|
+
const androidOpen = content.search(/\n\s*android\s*\{/);
|
|
778
|
+
if (androidOpen < 0) return content;
|
|
779
|
+
let depth = 0;
|
|
780
|
+
let i = content.indexOf("{", androidOpen);
|
|
781
|
+
while (i < content.length) {
|
|
782
|
+
const ch = content[i];
|
|
783
|
+
if (ch === "{") depth += 1;
|
|
784
|
+
else if (ch === "}") {
|
|
785
|
+
depth -= 1;
|
|
786
|
+
if (depth === 0) {
|
|
787
|
+
return content.slice(0, i) + block + content.slice(i);
|
|
788
|
+
}
|
|
789
|
+
}
|
|
790
|
+
i += 1;
|
|
791
|
+
}
|
|
792
|
+
return content;
|
|
793
|
+
}
|
|
794
|
+
|
|
795
|
+
/**
|
|
796
|
+
* Inject an optional app-thinning hook for `assets/agent/`.
|
|
797
|
+
*
|
|
798
|
+
* Local mode on stock Capacitor APKs now depends on the staged bun runtime,
|
|
799
|
+
* agent-bundle, and PGlite payload, so the default mobile build must keep
|
|
800
|
+
* assets/agent/*. CI/release jobs that deliberately want a cloud-only slim APK
|
|
801
|
+
* can opt into stripping with `-PelizaStripAgentAssets=true`.
|
|
802
|
+
*
|
|
803
|
+
* Idempotent: re-runs are no-ops once the block is present.
|
|
804
|
+
*/
|
|
805
|
+
/**
|
|
806
|
+
* Inject the `copyForkLlamaLib` Gradle task that bundles the buun-llama-cpp
|
|
807
|
+
* fork's android-arm64 .so into the APK's jniLibs/. The fork's specialized
|
|
808
|
+
* KV cache types (turbo3, turbo4, turbo3_tcq) and DFlash spec-decoding kernels
|
|
809
|
+
* live in this .so; without it, mobile only gets stock llama.cpp.
|
|
810
|
+
*
|
|
811
|
+
* Resolution order for the libdir:
|
|
812
|
+
* 1. -Peliza.dflash.android.libdir=<path> (gradle property)
|
|
813
|
+
* 2. ELIZA_DFLASH_ANDROID_LIBDIR env var
|
|
814
|
+
* 3. ~/.eliza/local-inference/bin/dflash/android-arm64-{cpu,vulkan}/
|
|
815
|
+
*
|
|
816
|
+
* Skips with a clear log when no path is configured or the dir doesn't exist,
|
|
817
|
+
* so a desktop dev still gets a working APK without local fork builds.
|
|
818
|
+
*
|
|
819
|
+
* Idempotent: re-runs are no-ops once the block is present.
|
|
820
|
+
*/
|
|
821
|
+
export function injectCopyForkLlamaLibTask(content) {
|
|
822
|
+
if (/\[copyForkLlamaLib\]/.test(content)) return content;
|
|
823
|
+
const block =
|
|
824
|
+
`\n// Bundle the buun-llama-cpp fork's android-arm64 .so into the APK so\n` +
|
|
825
|
+
`// mobile gets DFlash + TurboQuant KV cache + QJL kernels. Stock\n` +
|
|
826
|
+
`// llama-cpp-capacitor's .so still ships when the fork lib dir is missing.\n` +
|
|
827
|
+
`def resolveForkLlamaLibDir = { ->\n` +
|
|
828
|
+
` def fromProp = project.findProperty('eliza.dflash.android.libdir')\n` +
|
|
829
|
+
` if (fromProp) return fromProp.toString()\n` +
|
|
830
|
+
` def fromEnv = System.getenv('ELIZA_DFLASH_ANDROID_LIBDIR')\n` +
|
|
831
|
+
` if (fromEnv) return fromEnv\n` +
|
|
832
|
+
` def stateDir = System.getenv('ELIZA_STATE_DIR') ?: "\${System.getProperty('user.home')}/.eliza"\n` +
|
|
833
|
+
` def candidates = ['vulkan', 'cpu'].collect { backend ->\n` +
|
|
834
|
+
` "\${stateDir}/local-inference/bin/dflash/android-arm64-\${backend}"\n` +
|
|
835
|
+
` }\n` +
|
|
836
|
+
` return candidates.find { new File(it).isDirectory() }\n` +
|
|
837
|
+
`}\n` +
|
|
838
|
+
`\n` +
|
|
839
|
+
`task copyForkLlamaLib {\n` +
|
|
840
|
+
` doLast {\n` +
|
|
841
|
+
` def libDir = resolveForkLlamaLibDir()\n` +
|
|
842
|
+
` if (!libDir) {\n` +
|
|
843
|
+
` println "[copyForkLlamaLib] no fork lib dir configured (set -Peliza.dflash.android.libdir or build via packages/app-core/scripts/build-llama-cpp-dflash.mjs --target android-arm64-vulkan); APK ships stock llama-cpp-capacitor only"\n` +
|
|
844
|
+
` return\n` +
|
|
845
|
+
` }\n` +
|
|
846
|
+
` def srcDir = new File(libDir.toString())\n` +
|
|
847
|
+
` if (!srcDir.isDirectory()) {\n` +
|
|
848
|
+
` println "[copyForkLlamaLib] fork lib dir \${libDir} does not exist; APK ships stock llama-cpp-capacitor only"\n` +
|
|
849
|
+
` return\n` +
|
|
850
|
+
` }\n` +
|
|
851
|
+
` def jniDir = file('src/main/jniLibs/arm64-v8a')\n` +
|
|
852
|
+
` jniDir.mkdirs()\n` +
|
|
853
|
+
` def assetsDir = file('src/main/assets')\n` +
|
|
854
|
+
` assetsDir.mkdirs()\n` +
|
|
855
|
+
` int copied = 0\n` +
|
|
856
|
+
` srcDir.eachFile { src ->\n` +
|
|
857
|
+
` if (src.name.endsWith('.so')) {\n` +
|
|
858
|
+
` def dst = new File(jniDir, src.name)\n` +
|
|
859
|
+
` dst.bytes = src.bytes\n` +
|
|
860
|
+
` copied++\n` +
|
|
861
|
+
` }\n` +
|
|
862
|
+
` if (src.name == 'kernels.json') {\n` +
|
|
863
|
+
` def dst = new File(assetsDir, 'llama-cpp-kernels.json')\n` +
|
|
864
|
+
` dst.bytes = src.bytes\n` +
|
|
865
|
+
` println "[copyForkLlamaLib] staged kernels.json as assets/llama-cpp-kernels.json"\n` +
|
|
866
|
+
` }\n` +
|
|
867
|
+
` }\n` +
|
|
868
|
+
` println "[copyForkLlamaLib] copied \${copied} .so file(s) from \${libDir} to \${jniDir}"\n` +
|
|
869
|
+
` }\n` +
|
|
870
|
+
`}\n` +
|
|
871
|
+
`\n` +
|
|
872
|
+
`afterEvaluate {\n` +
|
|
873
|
+
` tasks.matching { it.name == 'preBuild' }.all { it.dependsOn copyForkLlamaLib }\n` +
|
|
874
|
+
`}\n`;
|
|
875
|
+
const androidOpen = content.search(/\n\s*android\s*\{/);
|
|
876
|
+
if (androidOpen < 0) return content;
|
|
877
|
+
let depth = 0;
|
|
878
|
+
let i = content.indexOf("{", androidOpen);
|
|
879
|
+
while (i < content.length) {
|
|
880
|
+
const ch = content[i];
|
|
881
|
+
if (ch === "{") depth += 1;
|
|
882
|
+
else if (ch === "}") {
|
|
883
|
+
depth -= 1;
|
|
884
|
+
if (depth === 0) {
|
|
885
|
+
return content.slice(0, i + 1) + block + content.slice(i + 1);
|
|
886
|
+
}
|
|
887
|
+
}
|
|
888
|
+
i += 1;
|
|
889
|
+
}
|
|
890
|
+
return content;
|
|
891
|
+
}
|
|
892
|
+
|
|
893
|
+
export function injectAospAssetThinning(content) {
|
|
894
|
+
if (/\[app-thinning\]/.test(content)) return content;
|
|
895
|
+
const block =
|
|
896
|
+
`\n// Optional app thinning: keep assets/agent/ by default so stock\n` +
|
|
897
|
+
`// Capacitor APKs can run the bundled local agent. Set\n` +
|
|
898
|
+
`// -PelizaStripAgentAssets=true only for an explicitly cloud-only slim APK.\n` +
|
|
899
|
+
`afterEvaluate {\n` +
|
|
900
|
+
` tasks.matching { it.name.startsWith('merge') && it.name.endsWith('Assets') }.all { mergeTask ->\n` +
|
|
901
|
+
` mergeTask.inputs.property('elizaAospBuild', project.findProperty('elizaAospBuild') ?: 'false')\n` +
|
|
902
|
+
` mergeTask.inputs.property('elizaStripAgentAssets', project.findProperty('elizaStripAgentAssets') ?: 'false')\n` +
|
|
903
|
+
` mergeTask.doLast {\n` +
|
|
904
|
+
` if (project.findProperty('elizaAospBuild') != 'true' && project.findProperty('elizaStripAgentAssets') == 'true') {\n` +
|
|
905
|
+
` def assetsDir = mergeTask.outputDir.get().asFile\n` +
|
|
906
|
+
` def agentDir = new File(assetsDir, 'agent')\n` +
|
|
907
|
+
` if (agentDir.exists()) {\n` +
|
|
908
|
+
` println "[app-thinning] removing assets/agent/ from \${mergeTask.name} (explicit slim Capacitor build)"\n` +
|
|
909
|
+
` agentDir.deleteDir()\n` +
|
|
910
|
+
` }\n` +
|
|
911
|
+
` } else {\n` +
|
|
912
|
+
` println "[app-thinning] keeping assets/agent/ in \${mergeTask.name} (local-agent capable build)"\n` +
|
|
913
|
+
` }\n` +
|
|
914
|
+
` }\n` +
|
|
915
|
+
` }\n` +
|
|
916
|
+
`}\n`;
|
|
917
|
+
const androidOpen = content.search(/\n\s*android\s*\{/);
|
|
918
|
+
if (androidOpen < 0) return content;
|
|
919
|
+
let depth = 0;
|
|
920
|
+
let i = content.indexOf("{", androidOpen);
|
|
921
|
+
while (i < content.length) {
|
|
922
|
+
const ch = content[i];
|
|
923
|
+
if (ch === "{") depth += 1;
|
|
924
|
+
else if (ch === "}") {
|
|
925
|
+
depth -= 1;
|
|
926
|
+
if (depth === 0) {
|
|
927
|
+
return content.slice(0, i + 1) + block + content.slice(i + 1);
|
|
928
|
+
}
|
|
929
|
+
}
|
|
930
|
+
i += 1;
|
|
931
|
+
}
|
|
932
|
+
return content;
|
|
933
|
+
}
|
|
934
|
+
|
|
935
|
+
const ANDROID_OFFICIAL_CAPACITOR_PACKAGES = [
|
|
936
|
+
"@capacitor/app",
|
|
937
|
+
"@capacitor/barcode-scanner",
|
|
938
|
+
"@capacitor/browser",
|
|
939
|
+
"@capacitor/haptics",
|
|
940
|
+
"@capacitor/keyboard",
|
|
941
|
+
"@capacitor/preferences",
|
|
942
|
+
"@capacitor/push-notifications",
|
|
943
|
+
"@capacitor/status-bar",
|
|
944
|
+
];
|
|
945
|
+
|
|
946
|
+
function patchInstalledCapacitorPluginGradleForAgp9(pkgName) {
|
|
947
|
+
const pkgRel = resolvePackagePath(pkgName, androidDir);
|
|
948
|
+
if (!pkgRel) return;
|
|
949
|
+
patchGradleFileForAgp9(
|
|
950
|
+
path.resolve(androidDir, pkgRel, "android", "build.gradle"),
|
|
951
|
+
pkgName,
|
|
952
|
+
);
|
|
953
|
+
}
|
|
954
|
+
|
|
955
|
+
function patchOfficialCapacitorGradleForAgp9() {
|
|
956
|
+
for (const pkgName of ANDROID_OFFICIAL_CAPACITOR_PACKAGES) {
|
|
957
|
+
patchInstalledCapacitorPluginGradleForAgp9(pkgName);
|
|
958
|
+
}
|
|
959
|
+
}
|
|
960
|
+
|
|
961
|
+
function patchLlamaCppCapacitorGradle() {
|
|
962
|
+
const pkgRel = resolvePackagePath("llama-cpp-capacitor", androidDir);
|
|
963
|
+
if (!pkgRel) return;
|
|
964
|
+
patchGradleFileForAgp9(
|
|
965
|
+
path.resolve(androidDir, pkgRel, "android", "build.gradle"),
|
|
966
|
+
"llama-cpp-capacitor",
|
|
967
|
+
);
|
|
968
|
+
}
|
|
969
|
+
|
|
970
|
+
function patchGradleFileForAgp9(filePath, label) {
|
|
971
|
+
if (!fs.existsSync(filePath)) return;
|
|
972
|
+
const current = fs.readFileSync(filePath, "utf8");
|
|
973
|
+
const patched = current
|
|
974
|
+
.replace(
|
|
975
|
+
/^\s*apply plugin:\s*['"](org\.jetbrains\.kotlin\.android|kotlin-android)['"]\s*\r?\n/gm,
|
|
976
|
+
"",
|
|
977
|
+
)
|
|
978
|
+
.replace(/\n\s*kotlin\s*\{\s*jvmToolchain\(\d+\)\s*\}\s*/g, "\n")
|
|
979
|
+
.replace(
|
|
980
|
+
/getDefaultProguardFile\('proguard-android\.txt'\)/g,
|
|
981
|
+
"getDefaultProguardFile('proguard-android-optimize.txt')",
|
|
982
|
+
);
|
|
983
|
+
if (patched !== current) {
|
|
984
|
+
fs.writeFileSync(filePath, patched, "utf8");
|
|
985
|
+
console.log(`[mobile-build] Patched ${label} Gradle for AGP 9.`);
|
|
986
|
+
}
|
|
987
|
+
}
|
|
988
|
+
|
|
989
|
+
function patchNativePluginGradleForAgp9() {
|
|
990
|
+
if (!fs.existsSync(nativePluginsDir)) return;
|
|
991
|
+
for (const entry of fs.readdirSync(nativePluginsDir, {
|
|
992
|
+
withFileTypes: true,
|
|
993
|
+
})) {
|
|
994
|
+
if (!entry.isDirectory()) continue;
|
|
995
|
+
patchGradleFileForAgp9(
|
|
996
|
+
path.join(nativePluginsDir, entry.name, "android", "build.gradle"),
|
|
997
|
+
`@elizaos/capacitor-${entry.name}`,
|
|
998
|
+
);
|
|
999
|
+
}
|
|
1000
|
+
}
|
|
1001
|
+
|
|
1002
|
+
function appendMissingAndroidManifestBlock(xml, marker, block) {
|
|
1003
|
+
if (xml.includes(marker)) return xml;
|
|
1004
|
+
return xml.replace("</manifest>", `${block}\n</manifest>`);
|
|
1005
|
+
}
|
|
1006
|
+
|
|
1007
|
+
function appendMissingApplicationBlock(xml, marker, block) {
|
|
1008
|
+
if (xml.includes(marker)) return xml;
|
|
1009
|
+
return xml.replace("</application>", `${block}\n </application>`);
|
|
1010
|
+
}
|
|
1011
|
+
|
|
1012
|
+
function escapeRegExp(value) {
|
|
1013
|
+
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
1014
|
+
}
|
|
1015
|
+
|
|
1016
|
+
function removeApplicationComponentBlock(xml, componentName) {
|
|
1017
|
+
const escapedName = escapeRegExp(componentName);
|
|
1018
|
+
const componentRe = new RegExp(
|
|
1019
|
+
`\\n\\s*<(activity|service|receiver)\\b(?=[^>]*android:name="${escapedName}")[\\s\\S]*?<\\/\\1>\\s*`,
|
|
1020
|
+
"g",
|
|
1021
|
+
);
|
|
1022
|
+
return xml.replace(componentRe, "\n");
|
|
1023
|
+
}
|
|
1024
|
+
|
|
1025
|
+
function removeApplicationComponentClassBlock(xml, className) {
|
|
1026
|
+
const escapedName = escapeRegExp(className);
|
|
1027
|
+
const pairedRe = new RegExp(
|
|
1028
|
+
`\\n\\s*<(activity|service|receiver)\\b(?=[^>]*android:name="[^"]*\\.?${escapedName}")[\\s\\S]*?<\\/\\1>\\s*`,
|
|
1029
|
+
"g",
|
|
1030
|
+
);
|
|
1031
|
+
const selfClosingRe = new RegExp(
|
|
1032
|
+
`\\n\\s*<(activity|service|receiver)\\b(?=[^>]*android:name="[^"]*\\.?${escapedName}")[^>]*/>\\s*`,
|
|
1033
|
+
"g",
|
|
1034
|
+
);
|
|
1035
|
+
return xml.replace(pairedRe, "\n").replace(selfClosingRe, "\n");
|
|
1036
|
+
}
|
|
1037
|
+
|
|
1038
|
+
function removeStaleAndroidJavaSourceRoots(dstJava) {
|
|
1039
|
+
const candidates = [
|
|
1040
|
+
"ai.elizaos.app",
|
|
1041
|
+
"com.elizaai.eliza",
|
|
1042
|
+
"com.miladyai.milady",
|
|
1043
|
+
APP.appId,
|
|
1044
|
+
];
|
|
1045
|
+
for (const packageName of candidates) {
|
|
1046
|
+
const candidate = path.join(
|
|
1047
|
+
androidDir,
|
|
1048
|
+
"app",
|
|
1049
|
+
"src",
|
|
1050
|
+
"main",
|
|
1051
|
+
"java",
|
|
1052
|
+
packageNameToPath(packageName),
|
|
1053
|
+
);
|
|
1054
|
+
if (candidate !== dstJava && fs.existsSync(candidate)) {
|
|
1055
|
+
fs.rmSync(candidate, { recursive: true, force: true });
|
|
1056
|
+
}
|
|
1057
|
+
}
|
|
1058
|
+
}
|
|
1059
|
+
|
|
1060
|
+
// Replace the BRAND_USER_AGENT_MARKERS array contents in the templated
|
|
1061
|
+
// MainActivity.java with framework default + entries from
|
|
1062
|
+
// `app.config.ts > android.userAgentMarkers`. Idempotent: re-running on
|
|
1063
|
+
// already-injected source produces the same result because we re-emit
|
|
1064
|
+
// the canonical default + configured set every time.
|
|
1065
|
+
function injectBrandUserAgentMarkers(javaSource, markers) {
|
|
1066
|
+
const arrayRe =
|
|
1067
|
+
/(private static final UserAgentMarker\[\] BRAND_USER_AGENT_MARKERS = new UserAgentMarker\[\]\s*\{)([\s\S]*?)(\};)/m;
|
|
1068
|
+
if (!arrayRe.test(javaSource)) {
|
|
1069
|
+
return javaSource;
|
|
1070
|
+
}
|
|
1071
|
+
const lines = [
|
|
1072
|
+
` new UserAgentMarker("ro.elizaos.product", "ElizaOS/"),`,
|
|
1073
|
+
];
|
|
1074
|
+
for (const marker of markers) {
|
|
1075
|
+
const systemProp = escapeJavaString(marker.systemProp);
|
|
1076
|
+
const uaPrefix = escapeJavaString(marker.uaPrefix);
|
|
1077
|
+
lines.push(` new UserAgentMarker("${systemProp}", "${uaPrefix}"),`);
|
|
1078
|
+
}
|
|
1079
|
+
return javaSource.replace(arrayRe, `$1\n${lines.join("\n")}\n $3`);
|
|
1080
|
+
}
|
|
1081
|
+
|
|
1082
|
+
function ensureElizaOsActivityFilters(xml) {
|
|
1083
|
+
if (xml.includes("android.intent.category.HOME")) {
|
|
1084
|
+
return xml;
|
|
1085
|
+
}
|
|
1086
|
+
const mainActivityRe =
|
|
1087
|
+
/(<activity\b(?=[\s\S]*?android:name="\.?MainActivity")[\s\S]*?)(\n\s*<\/activity>)/m;
|
|
1088
|
+
const homeFilter = `
|
|
1089
|
+
<intent-filter>
|
|
1090
|
+
<action android:name="android.intent.action.MAIN" />
|
|
1091
|
+
<category android:name="android.intent.category.HOME" />
|
|
1092
|
+
<category android:name="android.intent.category.DEFAULT" />
|
|
1093
|
+
</intent-filter>
|
|
1094
|
+
`;
|
|
1095
|
+
return xml.replace(mainActivityRe, `$1${homeFilter}$2`);
|
|
1096
|
+
}
|
|
1097
|
+
|
|
1098
|
+
function ensureAndroidMainActivityUrlSchemeFilter(xml) {
|
|
1099
|
+
const mainActivityRe =
|
|
1100
|
+
/(<activity\b(?=[\s\S]*?android:name="\.?MainActivity")[\s\S]*?)(\n\s*<\/activity>)/m;
|
|
1101
|
+
const match = xml.match(mainActivityRe);
|
|
1102
|
+
if (!match) return xml;
|
|
1103
|
+
|
|
1104
|
+
const mainActivity = `${match[1]}${match[2]}`;
|
|
1105
|
+
const hasCustomSchemeFilter =
|
|
1106
|
+
mainActivity.includes("android.intent.action.VIEW") &&
|
|
1107
|
+
mainActivity.includes("android.intent.category.BROWSABLE") &&
|
|
1108
|
+
(mainActivity.includes('android:scheme="@string/custom_url_scheme"') ||
|
|
1109
|
+
mainActivity.includes(`android:scheme="${APP.urlScheme}"`));
|
|
1110
|
+
if (hasCustomSchemeFilter) return xml;
|
|
1111
|
+
|
|
1112
|
+
const authFilter = `
|
|
1113
|
+
<intent-filter>
|
|
1114
|
+
<action android:name="android.intent.action.VIEW" />
|
|
1115
|
+
<category android:name="android.intent.category.DEFAULT" />
|
|
1116
|
+
<category android:name="android.intent.category.BROWSABLE" />
|
|
1117
|
+
<data android:scheme="@string/custom_url_scheme" />
|
|
1118
|
+
</intent-filter>
|
|
1119
|
+
`;
|
|
1120
|
+
return xml.replace(mainActivityRe, `$1${authFilter}$2`);
|
|
1121
|
+
}
|
|
1122
|
+
|
|
1123
|
+
function overlayAndroid() {
|
|
1124
|
+
const srcJava = path.join(
|
|
1125
|
+
platformsDir,
|
|
1126
|
+
"android",
|
|
1127
|
+
"app",
|
|
1128
|
+
"src",
|
|
1129
|
+
"main",
|
|
1130
|
+
"java",
|
|
1131
|
+
"ai",
|
|
1132
|
+
"elizaos",
|
|
1133
|
+
"app",
|
|
1134
|
+
);
|
|
1135
|
+
const gradlePath = path.join(androidDir, "app", "build.gradle");
|
|
1136
|
+
const androidPackage = APP.appId;
|
|
1137
|
+
const dstJava = path.join(
|
|
1138
|
+
androidDir,
|
|
1139
|
+
"app",
|
|
1140
|
+
"src",
|
|
1141
|
+
"main",
|
|
1142
|
+
"java",
|
|
1143
|
+
packageNameToPath(androidPackage),
|
|
1144
|
+
);
|
|
1145
|
+
const legacyJava = path.join(
|
|
1146
|
+
androidDir,
|
|
1147
|
+
"app",
|
|
1148
|
+
"src",
|
|
1149
|
+
"main",
|
|
1150
|
+
"java",
|
|
1151
|
+
"ai",
|
|
1152
|
+
"elizaos",
|
|
1153
|
+
"app",
|
|
1154
|
+
);
|
|
1155
|
+
const appIdJava = path.join(
|
|
1156
|
+
androidDir,
|
|
1157
|
+
"app",
|
|
1158
|
+
"src",
|
|
1159
|
+
"main",
|
|
1160
|
+
"java",
|
|
1161
|
+
...APP.appId.split("."),
|
|
1162
|
+
);
|
|
1163
|
+
|
|
1164
|
+
if (fs.existsSync(srcJava)) {
|
|
1165
|
+
removeStaleAndroidJavaSourceRoots(dstJava);
|
|
1166
|
+
for (const staleJava of [legacyJava, appIdJava]) {
|
|
1167
|
+
if (staleJava !== dstJava) {
|
|
1168
|
+
fs.rmSync(staleJava, { recursive: true, force: true });
|
|
1169
|
+
}
|
|
1170
|
+
}
|
|
1171
|
+
fs.mkdirSync(dstJava, { recursive: true });
|
|
1172
|
+
for (const file of [
|
|
1173
|
+
"GatewayConnectionService.java",
|
|
1174
|
+
"AgentPlugin.java",
|
|
1175
|
+
"ElizaNativeBridge.java",
|
|
1176
|
+
"MainActivity.java",
|
|
1177
|
+
"ElizaAgentService.java",
|
|
1178
|
+
"ElizaAssistActivity.java",
|
|
1179
|
+
"ElizaBootReceiver.java",
|
|
1180
|
+
"ElizaBrowserActivity.java",
|
|
1181
|
+
"ElizaCalendarActivity.java",
|
|
1182
|
+
"ElizaCameraActivity.java",
|
|
1183
|
+
"ElizaClockActivity.java",
|
|
1184
|
+
"ElizaContactsActivity.java",
|
|
1185
|
+
"ElizaDialActivity.java",
|
|
1186
|
+
"ElizaInCallService.java",
|
|
1187
|
+
"ElizaMmsReceiver.java",
|
|
1188
|
+
"ElizaRespondViaMessageService.java",
|
|
1189
|
+
"ElizaSmsComposeActivity.java",
|
|
1190
|
+
"ElizaSmsReceiver.java",
|
|
1191
|
+
]) {
|
|
1192
|
+
const src = path.join(srcJava, file);
|
|
1193
|
+
if (!fs.existsSync(src)) continue;
|
|
1194
|
+
let code = fs.readFileSync(src, "utf8");
|
|
1195
|
+
code = code.replace(
|
|
1196
|
+
/^package\s+ai\.elizaos\.app;/m,
|
|
1197
|
+
`package ${androidPackage};`,
|
|
1198
|
+
);
|
|
1199
|
+
code = code.replaceAll(
|
|
1200
|
+
"ai.elizaos.app.action.",
|
|
1201
|
+
`${androidPackage}.action.`,
|
|
1202
|
+
);
|
|
1203
|
+
code = code.replaceAll("ai.elizaos.app://", `${APP.urlScheme}://`);
|
|
1204
|
+
code = code.replaceAll(
|
|
1205
|
+
"elizaOS Gateway",
|
|
1206
|
+
`${escapeJavaString(APP.appName)} Gateway`,
|
|
1207
|
+
);
|
|
1208
|
+
code = code.replaceAll(
|
|
1209
|
+
"Shows elizaOS gateway connection status",
|
|
1210
|
+
`Shows ${escapeJavaString(APP.appName)} gateway connection status`,
|
|
1211
|
+
);
|
|
1212
|
+
if (file === "MainActivity.java") {
|
|
1213
|
+
code = injectBrandUserAgentMarkers(code, APP.userAgentMarkers ?? []);
|
|
1214
|
+
}
|
|
1215
|
+
fs.writeFileSync(path.join(dstJava, file), code, "utf8");
|
|
1216
|
+
}
|
|
1217
|
+
console.log("[mobile-build] Overlaid Android Java sources.");
|
|
1218
|
+
}
|
|
1219
|
+
|
|
1220
|
+
// Merge AndroidManifest.xml
|
|
1221
|
+
const manifestPath = path.join(
|
|
1222
|
+
androidDir,
|
|
1223
|
+
"app",
|
|
1224
|
+
"src",
|
|
1225
|
+
"main",
|
|
1226
|
+
"AndroidManifest.xml",
|
|
1227
|
+
);
|
|
1228
|
+
if (fs.existsSync(manifestPath)) {
|
|
1229
|
+
let xml = fs.readFileSync(manifestPath, "utf8");
|
|
1230
|
+
let dirty = false;
|
|
1231
|
+
|
|
1232
|
+
if (!xml.includes("usesCleartextTraffic")) {
|
|
1233
|
+
xml = xml.replace(
|
|
1234
|
+
"<application",
|
|
1235
|
+
'<application\n android:usesCleartextTraffic="true"',
|
|
1236
|
+
);
|
|
1237
|
+
dirty = true;
|
|
1238
|
+
}
|
|
1239
|
+
if (!xml.includes("<queries>")) {
|
|
1240
|
+
xml = xml.replace(
|
|
1241
|
+
/(\s*)<application/,
|
|
1242
|
+
'\n <queries>\n <package android:name="com.google.android.apps.healthdata" />\n </queries>\n\n <application',
|
|
1243
|
+
);
|
|
1244
|
+
dirty = true;
|
|
1245
|
+
}
|
|
1246
|
+
xml = appendMissingAndroidManifestBlock(
|
|
1247
|
+
xml,
|
|
1248
|
+
"android.hardware.telephony",
|
|
1249
|
+
' <uses-feature android:name="android.hardware.telephony" android:required="false" />',
|
|
1250
|
+
);
|
|
1251
|
+
const withElizaOsActivityFilters = ensureElizaOsActivityFilters(xml);
|
|
1252
|
+
if (withElizaOsActivityFilters !== xml) {
|
|
1253
|
+
xml = withElizaOsActivityFilters;
|
|
1254
|
+
dirty = true;
|
|
1255
|
+
}
|
|
1256
|
+
const withUrlSchemeFilter = ensureAndroidMainActivityUrlSchemeFilter(xml);
|
|
1257
|
+
if (withUrlSchemeFilter !== xml) {
|
|
1258
|
+
xml = withUrlSchemeFilter;
|
|
1259
|
+
dirty = true;
|
|
1260
|
+
}
|
|
1261
|
+
const gatewayServiceName = `${androidPackage}.GatewayConnectionService`;
|
|
1262
|
+
const gatewayServicePattern =
|
|
1263
|
+
/\n\s*<service\b[^>]*android:name="[^"]*GatewayConnectionService"[^>]*\/>\s*/g;
|
|
1264
|
+
const withoutGatewayServices = xml.replace(gatewayServicePattern, "\n");
|
|
1265
|
+
if (withoutGatewayServices !== xml) {
|
|
1266
|
+
xml = withoutGatewayServices;
|
|
1267
|
+
dirty = true;
|
|
1268
|
+
}
|
|
1269
|
+
xml = xml.replace(
|
|
1270
|
+
"</application>",
|
|
1271
|
+
`\n <service\n android:name="${gatewayServiceName}"\n android:exported="false"\n android:foregroundServiceType="dataSync" />\n </application>`,
|
|
1272
|
+
);
|
|
1273
|
+
dirty = true;
|
|
1274
|
+
|
|
1275
|
+
// ElizaAgentService — special-use foreground service that owns the
|
|
1276
|
+
// local Eliza agent process. Nested <property> tag carries the Android
|
|
1277
|
+
// 14+ specialUse subtype. Pattern matches both self-closing and
|
|
1278
|
+
// explicit-close forms so re-runs collapse cleanly.
|
|
1279
|
+
const agentServiceName = `${androidPackage}.ElizaAgentService`;
|
|
1280
|
+
const agentServiceSelfClosingPattern =
|
|
1281
|
+
/\n\s*<service\b[^>]*android:name="[^"]*ElizaAgentService"[^>]*\/>\s*/g;
|
|
1282
|
+
const agentServicePairedPattern =
|
|
1283
|
+
/\n\s*<service\b[^>]*android:name="[^"]*ElizaAgentService"[\s\S]*?<\/service>\s*/g;
|
|
1284
|
+
const withoutAgentServiceSelfClose = xml.replace(
|
|
1285
|
+
agentServiceSelfClosingPattern,
|
|
1286
|
+
"\n",
|
|
1287
|
+
);
|
|
1288
|
+
if (withoutAgentServiceSelfClose !== xml) {
|
|
1289
|
+
xml = withoutAgentServiceSelfClose;
|
|
1290
|
+
dirty = true;
|
|
1291
|
+
}
|
|
1292
|
+
const withoutAgentServicePaired = xml.replace(
|
|
1293
|
+
agentServicePairedPattern,
|
|
1294
|
+
"\n",
|
|
1295
|
+
);
|
|
1296
|
+
if (withoutAgentServicePaired !== xml) {
|
|
1297
|
+
xml = withoutAgentServicePaired;
|
|
1298
|
+
dirty = true;
|
|
1299
|
+
}
|
|
1300
|
+
xml = xml.replace(
|
|
1301
|
+
"</application>",
|
|
1302
|
+
`\n <service\n android:name="${agentServiceName}"\n android:exported="false"\n android:foregroundServiceType="specialUse">\n <property\n android:name="android.app.PROPERTY_SPECIAL_USE_FGS_SUBTYPE"\n android:value="local-agent-runtime" />\n </service>\n </application>`,
|
|
1303
|
+
);
|
|
1304
|
+
dirty = true;
|
|
1305
|
+
for (const component of [
|
|
1306
|
+
"ElizaDialActivity",
|
|
1307
|
+
"ElizaAssistActivity",
|
|
1308
|
+
"ElizaInCallService",
|
|
1309
|
+
"ElizaSmsReceiver",
|
|
1310
|
+
"ElizaMmsReceiver",
|
|
1311
|
+
"ElizaRespondViaMessageService",
|
|
1312
|
+
"ElizaSmsComposeActivity",
|
|
1313
|
+
"ElizaBootReceiver",
|
|
1314
|
+
"ElizaBrowserActivity",
|
|
1315
|
+
"ElizaContactsActivity",
|
|
1316
|
+
"ElizaCameraActivity",
|
|
1317
|
+
"ElizaClockActivity",
|
|
1318
|
+
"ElizaCalendarActivity",
|
|
1319
|
+
]) {
|
|
1320
|
+
const nextXml = removeApplicationComponentBlock(
|
|
1321
|
+
xml,
|
|
1322
|
+
`${androidPackage}.${component}`,
|
|
1323
|
+
);
|
|
1324
|
+
if (nextXml !== xml) {
|
|
1325
|
+
xml = nextXml;
|
|
1326
|
+
dirty = true;
|
|
1327
|
+
}
|
|
1328
|
+
}
|
|
1329
|
+
for (const component of [
|
|
1330
|
+
"ElizaDialActivity",
|
|
1331
|
+
"ElizaAssistActivity",
|
|
1332
|
+
"ElizaInCallService",
|
|
1333
|
+
"ElizaSmsReceiver",
|
|
1334
|
+
"ElizaMmsReceiver",
|
|
1335
|
+
"ElizaRespondViaMessageService",
|
|
1336
|
+
"ElizaSmsComposeActivity",
|
|
1337
|
+
"ElizaBootReceiver",
|
|
1338
|
+
"ElizaBrowserActivity",
|
|
1339
|
+
"ElizaContactsActivity",
|
|
1340
|
+
"ElizaCameraActivity",
|
|
1341
|
+
"ElizaClockActivity",
|
|
1342
|
+
"ElizaCalendarActivity",
|
|
1343
|
+
"MiladyDialActivity",
|
|
1344
|
+
"MiladyAssistActivity",
|
|
1345
|
+
"MiladyInCallService",
|
|
1346
|
+
"MiladySmsReceiver",
|
|
1347
|
+
"MiladyMmsReceiver",
|
|
1348
|
+
"MiladyRespondViaMessageService",
|
|
1349
|
+
"MiladySmsComposeActivity",
|
|
1350
|
+
"MiladyBootReceiver",
|
|
1351
|
+
]) {
|
|
1352
|
+
const nextXml = removeApplicationComponentClassBlock(xml, component);
|
|
1353
|
+
if (nextXml !== xml) {
|
|
1354
|
+
xml = nextXml;
|
|
1355
|
+
dirty = true;
|
|
1356
|
+
}
|
|
1357
|
+
}
|
|
1358
|
+
xml = appendMissingApplicationBlock(
|
|
1359
|
+
xml,
|
|
1360
|
+
`${androidPackage}.ElizaDialActivity`,
|
|
1361
|
+
`
|
|
1362
|
+
<activity
|
|
1363
|
+
android:name="${androidPackage}.ElizaDialActivity"
|
|
1364
|
+
android:exported="true"
|
|
1365
|
+
android:theme="@style/AppTheme.NoActionBar">
|
|
1366
|
+
<intent-filter>
|
|
1367
|
+
<action android:name="android.intent.action.DIAL" />
|
|
1368
|
+
<category android:name="android.intent.category.DEFAULT" />
|
|
1369
|
+
</intent-filter>
|
|
1370
|
+
<intent-filter>
|
|
1371
|
+
<action android:name="android.intent.action.DIAL" />
|
|
1372
|
+
<category android:name="android.intent.category.DEFAULT" />
|
|
1373
|
+
<data android:scheme="tel" />
|
|
1374
|
+
</intent-filter>
|
|
1375
|
+
</activity>`,
|
|
1376
|
+
);
|
|
1377
|
+
xml = appendMissingApplicationBlock(
|
|
1378
|
+
xml,
|
|
1379
|
+
`${androidPackage}.ElizaAssistActivity`,
|
|
1380
|
+
`
|
|
1381
|
+
<activity
|
|
1382
|
+
android:name="${androidPackage}.ElizaAssistActivity"
|
|
1383
|
+
android:exported="true"
|
|
1384
|
+
android:theme="@style/AppTheme.NoActionBar">
|
|
1385
|
+
<intent-filter>
|
|
1386
|
+
<action android:name="android.intent.action.ASSIST" />
|
|
1387
|
+
<category android:name="android.intent.category.DEFAULT" />
|
|
1388
|
+
</intent-filter>
|
|
1389
|
+
</activity>`,
|
|
1390
|
+
);
|
|
1391
|
+
xml = appendMissingApplicationBlock(
|
|
1392
|
+
xml,
|
|
1393
|
+
`${androidPackage}.ElizaInCallService`,
|
|
1394
|
+
`
|
|
1395
|
+
<service
|
|
1396
|
+
android:name="${androidPackage}.ElizaInCallService"
|
|
1397
|
+
android:exported="true"
|
|
1398
|
+
android:permission="android.permission.BIND_INCALL_SERVICE">
|
|
1399
|
+
<meta-data
|
|
1400
|
+
android:name="android.telecom.IN_CALL_SERVICE_UI"
|
|
1401
|
+
android:value="true" />
|
|
1402
|
+
<meta-data
|
|
1403
|
+
android:name="android.telecom.IN_CALL_SERVICE_RINGING"
|
|
1404
|
+
android:value="true" />
|
|
1405
|
+
<intent-filter>
|
|
1406
|
+
<action android:name="android.telecom.InCallService" />
|
|
1407
|
+
</intent-filter>
|
|
1408
|
+
</service>`,
|
|
1409
|
+
);
|
|
1410
|
+
xml = appendMissingApplicationBlock(
|
|
1411
|
+
xml,
|
|
1412
|
+
`${androidPackage}.ElizaSmsReceiver`,
|
|
1413
|
+
`
|
|
1414
|
+
<receiver
|
|
1415
|
+
android:name="${androidPackage}.ElizaSmsReceiver"
|
|
1416
|
+
android:exported="true"
|
|
1417
|
+
android:permission="android.permission.BROADCAST_SMS">
|
|
1418
|
+
<intent-filter>
|
|
1419
|
+
<action android:name="android.provider.Telephony.SMS_DELIVER" />
|
|
1420
|
+
</intent-filter>
|
|
1421
|
+
</receiver>`,
|
|
1422
|
+
);
|
|
1423
|
+
xml = appendMissingApplicationBlock(
|
|
1424
|
+
xml,
|
|
1425
|
+
`${androidPackage}.ElizaMmsReceiver`,
|
|
1426
|
+
`
|
|
1427
|
+
<receiver
|
|
1428
|
+
android:name="${androidPackage}.ElizaMmsReceiver"
|
|
1429
|
+
android:exported="true"
|
|
1430
|
+
android:permission="android.permission.BROADCAST_WAP_PUSH">
|
|
1431
|
+
<intent-filter>
|
|
1432
|
+
<action android:name="android.provider.Telephony.WAP_PUSH_DELIVER" />
|
|
1433
|
+
<data android:mimeType="application/vnd.wap.mms-message" />
|
|
1434
|
+
</intent-filter>
|
|
1435
|
+
</receiver>`,
|
|
1436
|
+
);
|
|
1437
|
+
xml = appendMissingApplicationBlock(
|
|
1438
|
+
xml,
|
|
1439
|
+
`${androidPackage}.ElizaRespondViaMessageService`,
|
|
1440
|
+
`
|
|
1441
|
+
<service
|
|
1442
|
+
android:name="${androidPackage}.ElizaRespondViaMessageService"
|
|
1443
|
+
android:exported="true"
|
|
1444
|
+
android:permission="android.permission.SEND_RESPOND_VIA_MESSAGE">
|
|
1445
|
+
<intent-filter>
|
|
1446
|
+
<action android:name="android.intent.action.RESPOND_VIA_MESSAGE" />
|
|
1447
|
+
<data android:scheme="sms" />
|
|
1448
|
+
<data android:scheme="smsto" />
|
|
1449
|
+
<data android:scheme="mms" />
|
|
1450
|
+
<data android:scheme="mmsto" />
|
|
1451
|
+
</intent-filter>
|
|
1452
|
+
</service>`,
|
|
1453
|
+
);
|
|
1454
|
+
xml = appendMissingApplicationBlock(
|
|
1455
|
+
xml,
|
|
1456
|
+
`${androidPackage}.ElizaSmsComposeActivity`,
|
|
1457
|
+
`
|
|
1458
|
+
<activity
|
|
1459
|
+
android:name="${androidPackage}.ElizaSmsComposeActivity"
|
|
1460
|
+
android:exported="true"
|
|
1461
|
+
android:theme="@style/AppTheme.NoActionBar">
|
|
1462
|
+
<intent-filter>
|
|
1463
|
+
<action android:name="android.intent.action.SENDTO" />
|
|
1464
|
+
<category android:name="android.intent.category.DEFAULT" />
|
|
1465
|
+
<data android:scheme="sms" />
|
|
1466
|
+
<data android:scheme="smsto" />
|
|
1467
|
+
<data android:scheme="mms" />
|
|
1468
|
+
<data android:scheme="mmsto" />
|
|
1469
|
+
</intent-filter>
|
|
1470
|
+
</activity>`,
|
|
1471
|
+
);
|
|
1472
|
+
xml = appendMissingApplicationBlock(
|
|
1473
|
+
xml,
|
|
1474
|
+
`${androidPackage}.ElizaBootReceiver`,
|
|
1475
|
+
`
|
|
1476
|
+
<receiver
|
|
1477
|
+
android:name="${androidPackage}.ElizaBootReceiver"
|
|
1478
|
+
android:directBootAware="true"
|
|
1479
|
+
android:exported="false">
|
|
1480
|
+
<intent-filter>
|
|
1481
|
+
<action android:name="android.intent.action.LOCKED_BOOT_COMPLETED" />
|
|
1482
|
+
<action android:name="android.intent.action.BOOT_COMPLETED" />
|
|
1483
|
+
</intent-filter>
|
|
1484
|
+
</receiver>`,
|
|
1485
|
+
);
|
|
1486
|
+
// Browser: replaces stripped Browser2 as the only http(s) handler.
|
|
1487
|
+
xml = appendMissingApplicationBlock(
|
|
1488
|
+
xml,
|
|
1489
|
+
`${androidPackage}.ElizaBrowserActivity`,
|
|
1490
|
+
`
|
|
1491
|
+
<activity
|
|
1492
|
+
android:name="${androidPackage}.ElizaBrowserActivity"
|
|
1493
|
+
android:exported="true"
|
|
1494
|
+
android:theme="@style/AppTheme.NoActionBar">
|
|
1495
|
+
<intent-filter>
|
|
1496
|
+
<action android:name="android.intent.action.VIEW" />
|
|
1497
|
+
<category android:name="android.intent.category.DEFAULT" />
|
|
1498
|
+
<category android:name="android.intent.category.BROWSABLE" />
|
|
1499
|
+
<data android:scheme="http" />
|
|
1500
|
+
<data android:scheme="https" />
|
|
1501
|
+
</intent-filter>
|
|
1502
|
+
<intent-filter>
|
|
1503
|
+
<action android:name="android.intent.action.WEB_SEARCH" />
|
|
1504
|
+
<category android:name="android.intent.category.DEFAULT" />
|
|
1505
|
+
</intent-filter>
|
|
1506
|
+
</activity>`,
|
|
1507
|
+
);
|
|
1508
|
+
// Contacts: replaces stripped Contacts. Handles content://contacts.
|
|
1509
|
+
xml = appendMissingApplicationBlock(
|
|
1510
|
+
xml,
|
|
1511
|
+
`${androidPackage}.ElizaContactsActivity`,
|
|
1512
|
+
`
|
|
1513
|
+
<activity
|
|
1514
|
+
android:name="${androidPackage}.ElizaContactsActivity"
|
|
1515
|
+
android:exported="true"
|
|
1516
|
+
android:label="Contacts"
|
|
1517
|
+
android:theme="@style/AppTheme.NoActionBar">
|
|
1518
|
+
<intent-filter>
|
|
1519
|
+
<action android:name="android.intent.action.MAIN" />
|
|
1520
|
+
<category android:name="android.intent.category.LAUNCHER" />
|
|
1521
|
+
<category android:name="android.intent.category.APP_CONTACTS" />
|
|
1522
|
+
</intent-filter>
|
|
1523
|
+
<intent-filter>
|
|
1524
|
+
<action android:name="android.intent.action.VIEW" />
|
|
1525
|
+
<category android:name="android.intent.category.DEFAULT" />
|
|
1526
|
+
<data android:mimeType="vnd.android.cursor.dir/contact" />
|
|
1527
|
+
<data android:mimeType="vnd.android.cursor.dir/person" />
|
|
1528
|
+
</intent-filter>
|
|
1529
|
+
<intent-filter>
|
|
1530
|
+
<action android:name="android.intent.action.VIEW" />
|
|
1531
|
+
<category android:name="android.intent.category.DEFAULT" />
|
|
1532
|
+
<data android:mimeType="vnd.android.cursor.item/contact" />
|
|
1533
|
+
<data android:mimeType="vnd.android.cursor.item/person" />
|
|
1534
|
+
</intent-filter>
|
|
1535
|
+
</activity>`,
|
|
1536
|
+
);
|
|
1537
|
+
// Camera: replaces stripped Camera2. STILL_IMAGE_CAMERA + IMAGE_CAPTURE.
|
|
1538
|
+
xml = appendMissingApplicationBlock(
|
|
1539
|
+
xml,
|
|
1540
|
+
`${androidPackage}.ElizaCameraActivity`,
|
|
1541
|
+
`
|
|
1542
|
+
<activity
|
|
1543
|
+
android:name="${androidPackage}.ElizaCameraActivity"
|
|
1544
|
+
android:exported="true"
|
|
1545
|
+
android:label="Camera"
|
|
1546
|
+
android:theme="@style/AppTheme.NoActionBar">
|
|
1547
|
+
<intent-filter>
|
|
1548
|
+
<action android:name="android.intent.action.MAIN" />
|
|
1549
|
+
<category android:name="android.intent.category.LAUNCHER" />
|
|
1550
|
+
</intent-filter>
|
|
1551
|
+
<intent-filter>
|
|
1552
|
+
<action android:name="android.media.action.STILL_IMAGE_CAMERA" />
|
|
1553
|
+
<category android:name="android.intent.category.DEFAULT" />
|
|
1554
|
+
</intent-filter>
|
|
1555
|
+
<intent-filter>
|
|
1556
|
+
<action android:name="android.media.action.IMAGE_CAPTURE" />
|
|
1557
|
+
<category android:name="android.intent.category.DEFAULT" />
|
|
1558
|
+
</intent-filter>
|
|
1559
|
+
<intent-filter>
|
|
1560
|
+
<action android:name="android.media.action.VIDEO_CAPTURE" />
|
|
1561
|
+
<category android:name="android.intent.category.DEFAULT" />
|
|
1562
|
+
</intent-filter>
|
|
1563
|
+
</activity>`,
|
|
1564
|
+
);
|
|
1565
|
+
// Clock: replaces stripped DeskClock. SET_ALARM is critical.
|
|
1566
|
+
xml = appendMissingApplicationBlock(
|
|
1567
|
+
xml,
|
|
1568
|
+
`${androidPackage}.ElizaClockActivity`,
|
|
1569
|
+
`
|
|
1570
|
+
<activity
|
|
1571
|
+
android:name="${androidPackage}.ElizaClockActivity"
|
|
1572
|
+
android:exported="true"
|
|
1573
|
+
android:label="Clock"
|
|
1574
|
+
android:theme="@style/AppTheme.NoActionBar">
|
|
1575
|
+
<intent-filter>
|
|
1576
|
+
<action android:name="android.intent.action.MAIN" />
|
|
1577
|
+
<category android:name="android.intent.category.LAUNCHER" />
|
|
1578
|
+
</intent-filter>
|
|
1579
|
+
<intent-filter>
|
|
1580
|
+
<action android:name="android.intent.action.SET_ALARM" />
|
|
1581
|
+
<category android:name="android.intent.category.DEFAULT" />
|
|
1582
|
+
</intent-filter>
|
|
1583
|
+
<intent-filter>
|
|
1584
|
+
<action android:name="android.intent.action.SHOW_ALARMS" />
|
|
1585
|
+
<category android:name="android.intent.category.DEFAULT" />
|
|
1586
|
+
</intent-filter>
|
|
1587
|
+
<intent-filter>
|
|
1588
|
+
<action android:name="android.intent.action.SET_TIMER" />
|
|
1589
|
+
<category android:name="android.intent.category.DEFAULT" />
|
|
1590
|
+
</intent-filter>
|
|
1591
|
+
<intent-filter>
|
|
1592
|
+
<action android:name="android.intent.action.SHOW_TIMERS" />
|
|
1593
|
+
<category android:name="android.intent.category.DEFAULT" />
|
|
1594
|
+
</intent-filter>
|
|
1595
|
+
<intent-filter>
|
|
1596
|
+
<action android:name="android.intent.action.DISMISS_ALARM" />
|
|
1597
|
+
<category android:name="android.intent.category.DEFAULT" />
|
|
1598
|
+
</intent-filter>
|
|
1599
|
+
</activity>`,
|
|
1600
|
+
);
|
|
1601
|
+
// Calendar: replaces stripped Calendar.
|
|
1602
|
+
xml = appendMissingApplicationBlock(
|
|
1603
|
+
xml,
|
|
1604
|
+
`${androidPackage}.ElizaCalendarActivity`,
|
|
1605
|
+
`
|
|
1606
|
+
<activity
|
|
1607
|
+
android:name="${androidPackage}.ElizaCalendarActivity"
|
|
1608
|
+
android:exported="true"
|
|
1609
|
+
android:label="Calendar"
|
|
1610
|
+
android:theme="@style/AppTheme.NoActionBar">
|
|
1611
|
+
<intent-filter>
|
|
1612
|
+
<action android:name="android.intent.action.MAIN" />
|
|
1613
|
+
<category android:name="android.intent.category.LAUNCHER" />
|
|
1614
|
+
<category android:name="android.intent.category.APP_CALENDAR" />
|
|
1615
|
+
</intent-filter>
|
|
1616
|
+
<intent-filter>
|
|
1617
|
+
<action android:name="android.intent.action.VIEW" />
|
|
1618
|
+
<category android:name="android.intent.category.DEFAULT" />
|
|
1619
|
+
<data android:mimeType="vnd.android.cursor.item/event" />
|
|
1620
|
+
</intent-filter>
|
|
1621
|
+
<intent-filter>
|
|
1622
|
+
<action android:name="android.intent.action.INSERT" />
|
|
1623
|
+
<category android:name="android.intent.category.DEFAULT" />
|
|
1624
|
+
<data android:mimeType="vnd.android.cursor.dir/event" />
|
|
1625
|
+
</intent-filter>
|
|
1626
|
+
<intent-filter>
|
|
1627
|
+
<action android:name="android.intent.action.EDIT" />
|
|
1628
|
+
<category android:name="android.intent.category.DEFAULT" />
|
|
1629
|
+
<data android:mimeType="vnd.android.cursor.item/event" />
|
|
1630
|
+
</intent-filter>
|
|
1631
|
+
</activity>`,
|
|
1632
|
+
);
|
|
1633
|
+
dirty = true;
|
|
1634
|
+
for (const perm of ANDROID_PERMISSIONS) {
|
|
1635
|
+
const full = `android.permission.${perm}`;
|
|
1636
|
+
if (!xml.includes(full)) {
|
|
1637
|
+
xml = xml.replace(
|
|
1638
|
+
"</manifest>",
|
|
1639
|
+
` <uses-permission android:name="${full}" />\n</manifest>`,
|
|
1640
|
+
);
|
|
1641
|
+
dirty = true;
|
|
1642
|
+
}
|
|
1643
|
+
}
|
|
1644
|
+
// Storage permissions with maxSdkVersion
|
|
1645
|
+
if (!xml.includes("WRITE_EXTERNAL_STORAGE")) {
|
|
1646
|
+
xml = xml.replace(
|
|
1647
|
+
"</manifest>",
|
|
1648
|
+
' <uses-permission\n android:name="android.permission.WRITE_EXTERNAL_STORAGE"\n android:maxSdkVersion="28" />\n</manifest>',
|
|
1649
|
+
);
|
|
1650
|
+
dirty = true;
|
|
1651
|
+
}
|
|
1652
|
+
if (!xml.includes("READ_EXTERNAL_STORAGE")) {
|
|
1653
|
+
xml = xml.replace(
|
|
1654
|
+
"</manifest>",
|
|
1655
|
+
' <uses-permission\n android:name="android.permission.READ_EXTERNAL_STORAGE"\n android:maxSdkVersion="32" />\n</manifest>',
|
|
1656
|
+
);
|
|
1657
|
+
dirty = true;
|
|
1658
|
+
}
|
|
1659
|
+
if (dirty) {
|
|
1660
|
+
fs.writeFileSync(manifestPath, xml, "utf8");
|
|
1661
|
+
console.log(
|
|
1662
|
+
"[mobile-build] Merged permissions and service into AndroidManifest.xml.",
|
|
1663
|
+
);
|
|
1664
|
+
}
|
|
1665
|
+
}
|
|
1666
|
+
|
|
1667
|
+
// Copy ProGuard rules, rewriting the elizaOS default package to match the
|
|
1668
|
+
// app's actual namespace. Without this rewrite, R8 may strip Eliza-only
|
|
1669
|
+
// manifest-referenced classes (Dial/Assist/InCall/Boot) when the app is
|
|
1670
|
+
// namespaced as e.g. com.elizaai.eliza.
|
|
1671
|
+
const srcPro = path.join(
|
|
1672
|
+
platformsDir,
|
|
1673
|
+
"android",
|
|
1674
|
+
"app",
|
|
1675
|
+
"proguard-rules.pro",
|
|
1676
|
+
);
|
|
1677
|
+
if (fs.existsSync(srcPro)) {
|
|
1678
|
+
let proguardRules = fs.readFileSync(srcPro, "utf8");
|
|
1679
|
+
if (androidPackage && androidPackage !== "ai.elizaos.app") {
|
|
1680
|
+
proguardRules = proguardRules.replaceAll(
|
|
1681
|
+
"ai.elizaos.app.**",
|
|
1682
|
+
`${androidPackage}.**`,
|
|
1683
|
+
);
|
|
1684
|
+
}
|
|
1685
|
+
fs.writeFileSync(
|
|
1686
|
+
path.join(androidDir, "app", "proguard-rules.pro"),
|
|
1687
|
+
proguardRules,
|
|
1688
|
+
"utf8",
|
|
1689
|
+
);
|
|
1690
|
+
console.log("[mobile-build] Copied ProGuard rules.");
|
|
1691
|
+
}
|
|
1692
|
+
|
|
1693
|
+
// Enable release minification
|
|
1694
|
+
if (fs.existsSync(gradlePath)) {
|
|
1695
|
+
let g = fs.readFileSync(gradlePath, "utf8");
|
|
1696
|
+
if (g.includes("minifyEnabled false")) {
|
|
1697
|
+
g = g.replace(
|
|
1698
|
+
"minifyEnabled false",
|
|
1699
|
+
"minifyEnabled true\n shrinkResources true",
|
|
1700
|
+
);
|
|
1701
|
+
fs.writeFileSync(gradlePath, g, "utf8");
|
|
1702
|
+
console.log("[mobile-build] Enabled release minification.");
|
|
1703
|
+
}
|
|
1704
|
+
}
|
|
1705
|
+
}
|
|
1706
|
+
|
|
1707
|
+
// ── Phase 4: iOS native overlay ─────────────────────────────────────────
|
|
1708
|
+
|
|
1709
|
+
const IOS_PERMISSION_KEYS = [
|
|
1710
|
+
[
|
|
1711
|
+
"NSCameraUsageDescription",
|
|
1712
|
+
"This app uses your camera to capture photos and video when you ask it to.",
|
|
1713
|
+
],
|
|
1714
|
+
[
|
|
1715
|
+
"NSMicrophoneUsageDescription",
|
|
1716
|
+
"This app needs microphone access for voice wake, talk mode, and video capture.",
|
|
1717
|
+
],
|
|
1718
|
+
[
|
|
1719
|
+
"NSLocationWhenInUseUsageDescription",
|
|
1720
|
+
"This app uses your location to provide location-aware responses when you allow it.",
|
|
1721
|
+
],
|
|
1722
|
+
[
|
|
1723
|
+
"NSLocationAlwaysAndWhenInUseUsageDescription",
|
|
1724
|
+
"This app can share your location in the background so it stays up to date even when the app is not in use.",
|
|
1725
|
+
],
|
|
1726
|
+
[
|
|
1727
|
+
"NSPhotoLibraryUsageDescription",
|
|
1728
|
+
"This app accesses your photo library to attach and share photos or videos.",
|
|
1729
|
+
],
|
|
1730
|
+
[
|
|
1731
|
+
"NSPhotoLibraryAddUsageDescription",
|
|
1732
|
+
"This app saves captured photos and videos to your photo library.",
|
|
1733
|
+
],
|
|
1734
|
+
[
|
|
1735
|
+
"NSHealthShareUsageDescription",
|
|
1736
|
+
"This app reads your HealthKit sleep and biometric data to infer when you are asleep, awake, and ready for reminders.",
|
|
1737
|
+
],
|
|
1738
|
+
[
|
|
1739
|
+
"NSHealthUpdateUsageDescription",
|
|
1740
|
+
"This app does not write to HealthKit, but iOS requires this key when HealthKit capability is enabled.",
|
|
1741
|
+
],
|
|
1742
|
+
[
|
|
1743
|
+
"NSSpeechRecognitionUsageDescription",
|
|
1744
|
+
"This app uses on-device speech recognition to listen for voice commands and wake words.",
|
|
1745
|
+
],
|
|
1746
|
+
[
|
|
1747
|
+
"NSLocalNetworkUsageDescription",
|
|
1748
|
+
"This app discovers and connects to your elizaOS gateway on the local network.",
|
|
1749
|
+
],
|
|
1750
|
+
];
|
|
1751
|
+
|
|
1752
|
+
export const IOS_OFFICIAL_PODS = [
|
|
1753
|
+
["CapacitorApp", "@capacitor/app"],
|
|
1754
|
+
// Preferences is intentionally installed through CocoaPods on iOS because
|
|
1755
|
+
// Capacitor's generated SPM package is stripped below for this plugin.
|
|
1756
|
+
["CapacitorPreferences", "@capacitor/preferences"],
|
|
1757
|
+
["CapacitorKeyboard", "@capacitor/keyboard"],
|
|
1758
|
+
["CapacitorBrowser", "@capacitor/browser"],
|
|
1759
|
+
];
|
|
1760
|
+
|
|
1761
|
+
const IOS_INCOMPATIBLE_SPM_PLUGINS = new Set([
|
|
1762
|
+
"CapacitorApp",
|
|
1763
|
+
"CapacitorPreferences",
|
|
1764
|
+
"CapacitorStatusBar",
|
|
1765
|
+
]);
|
|
1766
|
+
|
|
1767
|
+
const IOS_COCOAPODS_OWNED_SPM_PLUGINS = new Set(["LlamaCppCapacitor"]);
|
|
1768
|
+
|
|
1769
|
+
const IOS_BONJOUR_SERVICES = [
|
|
1770
|
+
"_eliza-gw._tcp",
|
|
1771
|
+
"_elizaos-gw._tcp",
|
|
1772
|
+
"_eliza._tcp",
|
|
1773
|
+
];
|
|
1774
|
+
|
|
1775
|
+
function overlayIos() {
|
|
1776
|
+
const targetAppDir = path.join(appDir, "ios", "App", "App");
|
|
1777
|
+
|
|
1778
|
+
// Merge Info.plist permission strings
|
|
1779
|
+
const plistPath = path.join(targetAppDir, "Info.plist");
|
|
1780
|
+
if (fs.existsSync(plistPath)) {
|
|
1781
|
+
let plist = fs.readFileSync(plistPath, "utf8");
|
|
1782
|
+
let dirty = false;
|
|
1783
|
+
for (const [key, desc] of IOS_PERMISSION_KEYS) {
|
|
1784
|
+
if (!plist.includes(key)) {
|
|
1785
|
+
plist = plist.replace(
|
|
1786
|
+
"</dict>",
|
|
1787
|
+
`\t<key>${key}</key>\n\t<string>${desc}</string>\n</dict>`,
|
|
1788
|
+
);
|
|
1789
|
+
dirty = true;
|
|
1790
|
+
}
|
|
1791
|
+
}
|
|
1792
|
+
const nextPlist = ensurePlistUrlScheme(
|
|
1793
|
+
ensurePlistArrayStrings(
|
|
1794
|
+
ensurePlistArrayStrings(
|
|
1795
|
+
replaceOrInsertPlistString(
|
|
1796
|
+
plist,
|
|
1797
|
+
"CFBundleDisplayName",
|
|
1798
|
+
"$(ELIZA_DISPLAY_NAME)",
|
|
1799
|
+
),
|
|
1800
|
+
"NSBonjourServices",
|
|
1801
|
+
IOS_BONJOUR_SERVICES,
|
|
1802
|
+
),
|
|
1803
|
+
"UIBackgroundModes",
|
|
1804
|
+
["fetch"],
|
|
1805
|
+
),
|
|
1806
|
+
APP.urlScheme,
|
|
1807
|
+
);
|
|
1808
|
+
if (nextPlist !== plist) {
|
|
1809
|
+
plist = nextPlist;
|
|
1810
|
+
dirty = true;
|
|
1811
|
+
}
|
|
1812
|
+
if (dirty) {
|
|
1813
|
+
fs.writeFileSync(plistPath, plist, "utf8");
|
|
1814
|
+
console.log("[mobile-build] Merged iOS permission strings.");
|
|
1815
|
+
}
|
|
1816
|
+
}
|
|
1817
|
+
|
|
1818
|
+
// Copy entitlements with app group derived from appId
|
|
1819
|
+
const srcEnt = path.join(
|
|
1820
|
+
platformsDir,
|
|
1821
|
+
"ios",
|
|
1822
|
+
"App",
|
|
1823
|
+
"App",
|
|
1824
|
+
"App.entitlements",
|
|
1825
|
+
);
|
|
1826
|
+
if (fs.existsSync(srcEnt)) {
|
|
1827
|
+
let ent = fs.readFileSync(srcEnt, "utf8");
|
|
1828
|
+
ent = ent.replace("group.ai.elizaos.app", `group.${APP.appId}`);
|
|
1829
|
+
ent = ent.replace("group.app.eliza", `group.${APP.appId}`);
|
|
1830
|
+
fs.writeFileSync(path.join(targetAppDir, "App.entitlements"), ent, "utf8");
|
|
1831
|
+
console.log(
|
|
1832
|
+
`[mobile-build] Copied iOS entitlements (app group: group.${APP.appId}).`,
|
|
1833
|
+
);
|
|
1834
|
+
}
|
|
1835
|
+
|
|
1836
|
+
// Patch xcconfigs to include CocoaPods settings
|
|
1837
|
+
for (const cfg of ["debug", "release"]) {
|
|
1838
|
+
const xcPath = path.join(appDir, "ios", `${cfg}.xcconfig`);
|
|
1839
|
+
if (fs.existsSync(xcPath)) {
|
|
1840
|
+
const xc = fs.readFileSync(xcPath, "utf8");
|
|
1841
|
+
const inc = `#include "App/Pods/Target Support Files/Pods-App/Pods-App.${cfg}.xcconfig"`;
|
|
1842
|
+
if (!xc.includes(inc)) {
|
|
1843
|
+
fs.writeFileSync(xcPath, `${inc}\n${xc}`, "utf8");
|
|
1844
|
+
}
|
|
1845
|
+
}
|
|
1846
|
+
}
|
|
1847
|
+
|
|
1848
|
+
// Generate Podfile
|
|
1849
|
+
generatePodfile();
|
|
1850
|
+
applyIosAppIdentity();
|
|
1851
|
+
}
|
|
1852
|
+
|
|
1853
|
+
function isTruthyEnv(value) {
|
|
1854
|
+
return /^(1|true|yes|on)$/i.test(String(value ?? "").trim());
|
|
1855
|
+
}
|
|
1856
|
+
|
|
1857
|
+
function isIosSimulatorBuildTarget(buildTarget) {
|
|
1858
|
+
return (
|
|
1859
|
+
buildTarget?.sdk === "iphonesimulator" ||
|
|
1860
|
+
/\bSimulator\b/i.test(buildTarget?.destination ?? "")
|
|
1861
|
+
);
|
|
1862
|
+
}
|
|
1863
|
+
|
|
1864
|
+
export function prepareIosOverlay({ buildTarget = null } = {}) {
|
|
1865
|
+
const syncedFiles = syncPlatformTemplateFiles("ios");
|
|
1866
|
+
overlayIos();
|
|
1867
|
+
stripSpmIncompatiblePlugins();
|
|
1868
|
+
const includeLlama =
|
|
1869
|
+
isTruthyEnv(process.env.ELIZA_IOS_INCLUDE_LLAMA) ||
|
|
1870
|
+
isTruthyEnv(process.env.MILADY_IOS_INCLUDE_LLAMA);
|
|
1871
|
+
if (isIosSimulatorBuildTarget(buildTarget) || !includeLlama) {
|
|
1872
|
+
// Strip the SPM LlamaCppCapacitor entry whenever we're not bundling the
|
|
1873
|
+
// pod — either because the simulator build replaces it with a CocoaPod
|
|
1874
|
+
// (existing behavior) or because the build deliberately omits llama
|
|
1875
|
+
// (cloud-only / App Store thin client).
|
|
1876
|
+
stripSpmPlugins(IOS_COCOAPODS_OWNED_SPM_PLUGINS, {
|
|
1877
|
+
reason: includeLlama ? "CocoaPods-owned" : "llama excluded",
|
|
1878
|
+
});
|
|
1879
|
+
}
|
|
1880
|
+
return syncedFiles;
|
|
1881
|
+
}
|
|
1882
|
+
|
|
1883
|
+
function generatePodfile() {
|
|
1884
|
+
const podfileDir = path.join(appDir, "ios", "App");
|
|
1885
|
+
const iosPath = resolvePackagePath("@capacitor/ios", podfileDir);
|
|
1886
|
+
if (!iosPath) {
|
|
1887
|
+
console.warn(
|
|
1888
|
+
"[mobile-build] Could not resolve @capacitor/ios — skipping Podfile.",
|
|
1889
|
+
);
|
|
1890
|
+
return;
|
|
1891
|
+
}
|
|
1892
|
+
|
|
1893
|
+
// LlamaCppCapacitor ships an on-device llama.cpp xcframework. It is only
|
|
1894
|
+
// needed when the iOS build includes on-device inference. The default
|
|
1895
|
+
// App Store target is the `cloud` runtime mode, which is a thin HTTP
|
|
1896
|
+
// client and must NOT bundle the llama.cpp binary. Gate the pod on
|
|
1897
|
+
// ELIZA_IOS_INCLUDE_LLAMA / MILADY_IOS_INCLUDE_LLAMA — kept in sync with
|
|
1898
|
+
// `resolveIosBuildTarget()` so the pod, the xcframework path, and the
|
|
1899
|
+
// build destination all agree on a single inclusion decision.
|
|
1900
|
+
const includeLlama =
|
|
1901
|
+
isTruthyEnv(process.env.ELIZA_IOS_INCLUDE_LLAMA) ||
|
|
1902
|
+
isTruthyEnv(process.env.MILADY_IOS_INCLUDE_LLAMA);
|
|
1903
|
+
const customPods = [
|
|
1904
|
+
["ElizaosCapacitorAgent", "@elizaos/capacitor-agent"],
|
|
1905
|
+
["ElizaosCapacitorAppblocker", "@elizaos/capacitor-appblocker"],
|
|
1906
|
+
["ElizaosCapacitorCamera", "@elizaos/capacitor-camera"],
|
|
1907
|
+
["ElizaosCapacitorCanvas", "@elizaos/capacitor-canvas"],
|
|
1908
|
+
["ElizaosCapacitorGateway", "@elizaos/capacitor-gateway"],
|
|
1909
|
+
["ElizaosCapacitorLocation", "@elizaos/capacitor-location"],
|
|
1910
|
+
["ElizaosCapacitorMobileSignals", "@elizaos/capacitor-mobile-signals"],
|
|
1911
|
+
["ElizaosCapacitorScreencapture", "@elizaos/capacitor-screencapture"],
|
|
1912
|
+
["ElizaosCapacitorSwabble", "@elizaos/capacitor-swabble"],
|
|
1913
|
+
["ElizaosCapacitorTalkmode", "@elizaos/capacitor-talkmode"],
|
|
1914
|
+
["ElizaosCapacitorWebsiteblocker", "@elizaos/capacitor-websiteblocker"],
|
|
1915
|
+
...(includeLlama ? [["LlamaCppCapacitor", "llama-cpp-capacitor"]] : []),
|
|
1916
|
+
];
|
|
1917
|
+
if (!includeLlama) {
|
|
1918
|
+
console.log(
|
|
1919
|
+
"[mobile-build] iOS Podfile: omitting LlamaCppCapacitor (ELIZA_IOS_INCLUDE_LLAMA / MILADY_IOS_INCLUDE_LLAMA not set)",
|
|
1920
|
+
);
|
|
1921
|
+
}
|
|
1922
|
+
|
|
1923
|
+
const lines = [
|
|
1924
|
+
` pod 'Capacitor', :path => node_package_path('@capacitor/ios')`,
|
|
1925
|
+
` pod 'CapacitorCordova', :path => node_package_path('@capacitor/ios')`,
|
|
1926
|
+
];
|
|
1927
|
+
|
|
1928
|
+
for (const [name, pkg] of IOS_OFFICIAL_PODS) {
|
|
1929
|
+
const p = resolvePackagePath(pkg, podfileDir);
|
|
1930
|
+
if (p) lines.push(` pod '${name}', :path => node_package_path('${pkg}')`);
|
|
1931
|
+
}
|
|
1932
|
+
|
|
1933
|
+
for (const [name, pkg] of customPods) {
|
|
1934
|
+
const p = resolveNativePluginPackagePath(pkg, podfileDir);
|
|
1935
|
+
if (p) {
|
|
1936
|
+
lines.push(` pod '${name}', :path => '${p}'`);
|
|
1937
|
+
}
|
|
1938
|
+
}
|
|
1939
|
+
|
|
1940
|
+
fs.writeFileSync(
|
|
1941
|
+
path.join(podfileDir, "Podfile"),
|
|
1942
|
+
`\
|
|
1943
|
+
def node_package_path(package_name)
|
|
1944
|
+
package_json = \`node --print "require.resolve('#{package_name}/package.json')"\`.strip
|
|
1945
|
+
if package_json.empty?
|
|
1946
|
+
raise "Unable to resolve #{package_name}; run bun install before pod install"
|
|
1947
|
+
end
|
|
1948
|
+
File.dirname(package_json)
|
|
1949
|
+
end
|
|
1950
|
+
|
|
1951
|
+
capacitor_ios_path = node_package_path('@capacitor/ios')
|
|
1952
|
+
|
|
1953
|
+
require_relative File.join(capacitor_ios_path, 'scripts/pods_helpers')
|
|
1954
|
+
|
|
1955
|
+
platform :ios, '15.0'
|
|
1956
|
+
use_frameworks!
|
|
1957
|
+
|
|
1958
|
+
install! 'cocoapods', :disable_input_output_paths => true
|
|
1959
|
+
|
|
1960
|
+
def capacitor_pods
|
|
1961
|
+
${lines.join("\n")}
|
|
1962
|
+
end
|
|
1963
|
+
|
|
1964
|
+
target 'App' do
|
|
1965
|
+
capacitor_pods
|
|
1966
|
+
end
|
|
1967
|
+
|
|
1968
|
+
post_install do |installer|
|
|
1969
|
+
assertDeploymentTarget(installer)
|
|
1970
|
+
end
|
|
1971
|
+
`,
|
|
1972
|
+
"utf8",
|
|
1973
|
+
);
|
|
1974
|
+
console.log("[mobile-build] Generated Podfile.");
|
|
1975
|
+
}
|
|
1976
|
+
|
|
1977
|
+
// ── Phase 5: Platform patches ───────────────────────────────────────────
|
|
1978
|
+
|
|
1979
|
+
function stripSpmPlugins(
|
|
1980
|
+
pluginNames,
|
|
1981
|
+
{ reason = "incompatible SPM plugin" } = {},
|
|
1982
|
+
) {
|
|
1983
|
+
const pkgPath = path.join(
|
|
1984
|
+
appDir,
|
|
1985
|
+
"ios",
|
|
1986
|
+
"App",
|
|
1987
|
+
"CapApp-SPM",
|
|
1988
|
+
"Package.swift",
|
|
1989
|
+
);
|
|
1990
|
+
if (!fs.existsSync(pkgPath)) return;
|
|
1991
|
+
|
|
1992
|
+
let content = fs.readFileSync(pkgPath, "utf8");
|
|
1993
|
+
const lines = content.split("\n");
|
|
1994
|
+
const filtered = lines.filter((line) => {
|
|
1995
|
+
for (const name of pluginNames) {
|
|
1996
|
+
if (line.includes(`"${name}"`)) return false;
|
|
1997
|
+
}
|
|
1998
|
+
return true;
|
|
1999
|
+
});
|
|
2000
|
+
const changed = filtered.length !== lines.length;
|
|
2001
|
+
content = filtered.join("\n");
|
|
2002
|
+
|
|
2003
|
+
if (changed) {
|
|
2004
|
+
content = content.replace(/,(\s*[\])])/g, "$1").replace(/\n{3,}/g, "\n\n");
|
|
2005
|
+
fs.writeFileSync(pkgPath, content, "utf8");
|
|
2006
|
+
console.log(
|
|
2007
|
+
`[mobile-build] Stripped ${reason} SPM plugins: ${Array.from(
|
|
2008
|
+
pluginNames,
|
|
2009
|
+
).join(", ")}`,
|
|
2010
|
+
);
|
|
2011
|
+
}
|
|
2012
|
+
}
|
|
2013
|
+
|
|
2014
|
+
/** Strip incompatible official plugins from SPM Package.swift. */
|
|
2015
|
+
function stripSpmIncompatiblePlugins() {
|
|
2016
|
+
stripSpmPlugins(IOS_INCOMPATIBLE_SPM_PLUGINS, {
|
|
2017
|
+
reason: "incompatible",
|
|
2018
|
+
});
|
|
2019
|
+
}
|
|
2020
|
+
|
|
2021
|
+
function patchAndroidGradleWrapperForReleaseCompat() {
|
|
2022
|
+
const wrapperPath = path.join(
|
|
2023
|
+
androidDir,
|
|
2024
|
+
"gradle",
|
|
2025
|
+
"wrapper",
|
|
2026
|
+
"gradle-wrapper.properties",
|
|
2027
|
+
);
|
|
2028
|
+
if (!fs.existsSync(wrapperPath)) return;
|
|
2029
|
+
const current = fs.readFileSync(wrapperPath, "utf8");
|
|
2030
|
+
const patched = current.replace(
|
|
2031
|
+
/^distributionUrl=.*$/m,
|
|
2032
|
+
"distributionUrl=https\\://services.gradle.org/distributions/gradle-9.4.1-all.zip",
|
|
2033
|
+
);
|
|
2034
|
+
if (patched !== current) {
|
|
2035
|
+
fs.writeFileSync(wrapperPath, patched, "utf8");
|
|
2036
|
+
console.log("[mobile-build] Patched Android Gradle wrapper for AGP 9.");
|
|
2037
|
+
}
|
|
2038
|
+
}
|
|
2039
|
+
|
|
2040
|
+
// llama-cpp-capacitor 0.x ships Android Gradle DSL 8 syntax in its own
|
|
2041
|
+
// build.gradle. AGP 9 + Gradle 9 demand explicit `=` assignment for the
|
|
2042
|
+
// project-level DSL keys it uses (`namespace`, `version`, `ndkVersion`,
|
|
2043
|
+
// `lintOptions.abortOnError`) and rejects the legacy whitespace form, and
|
|
2044
|
+
// the legacy proguard file path is no longer shipped. Patch the installed
|
|
2045
|
+
// node_modules copy in place each build — modifying node_modules survives
|
|
2046
|
+
// the gradle invocation but a fresh `bun install` will re-clobber it,
|
|
2047
|
+
// which is fine because this function runs before every build.
|
|
2048
|
+
function patchInstalledLlamaCapacitorBuildGradle() {
|
|
2049
|
+
const candidates = [
|
|
2050
|
+
path.join(
|
|
2051
|
+
appDir,
|
|
2052
|
+
"node_modules",
|
|
2053
|
+
"llama-cpp-capacitor",
|
|
2054
|
+
"android",
|
|
2055
|
+
"build.gradle",
|
|
2056
|
+
),
|
|
2057
|
+
path.join(
|
|
2058
|
+
repoRoot,
|
|
2059
|
+
"node_modules",
|
|
2060
|
+
"llama-cpp-capacitor",
|
|
2061
|
+
"android",
|
|
2062
|
+
"build.gradle",
|
|
2063
|
+
),
|
|
2064
|
+
];
|
|
2065
|
+
const bunStores = [
|
|
2066
|
+
path.join(appDir, "node_modules", ".bun"),
|
|
2067
|
+
path.join(repoRoot, "node_modules", ".bun"),
|
|
2068
|
+
];
|
|
2069
|
+
for (const bunStore of bunStores) {
|
|
2070
|
+
if (!fs.existsSync(bunStore)) continue;
|
|
2071
|
+
for (const entry of fs.readdirSync(bunStore, { withFileTypes: true })) {
|
|
2072
|
+
if (!entry.isDirectory()) continue;
|
|
2073
|
+
if (!entry.name.startsWith("llama-cpp-capacitor@")) continue;
|
|
2074
|
+
candidates.push(
|
|
2075
|
+
path.join(
|
|
2076
|
+
bunStore,
|
|
2077
|
+
entry.name,
|
|
2078
|
+
"node_modules",
|
|
2079
|
+
"llama-cpp-capacitor",
|
|
2080
|
+
"android",
|
|
2081
|
+
"build.gradle",
|
|
2082
|
+
),
|
|
2083
|
+
);
|
|
2084
|
+
}
|
|
2085
|
+
}
|
|
2086
|
+
for (const gradlePath of candidates) {
|
|
2087
|
+
if (!fs.existsSync(gradlePath)) continue;
|
|
2088
|
+
const current = fs.readFileSync(gradlePath, "utf8");
|
|
2089
|
+
let patched = current
|
|
2090
|
+
.replaceAll(
|
|
2091
|
+
'namespace "ai.annadata.plugin.capacitor"',
|
|
2092
|
+
'namespace = "ai.annadata.plugin.capacitor"',
|
|
2093
|
+
)
|
|
2094
|
+
.replaceAll('version "3.22.1"', 'version = "3.22.1"')
|
|
2095
|
+
.replaceAll('ndkVersion "29.0.13113456"', 'ndkVersion = "29.0.13113456"')
|
|
2096
|
+
.replaceAll("abortOnError false", "abortOnError = false")
|
|
2097
|
+
.replaceAll(
|
|
2098
|
+
"getDefaultProguardFile('proguard-android.txt')",
|
|
2099
|
+
"getDefaultProguardFile('proguard-android-optimize.txt')",
|
|
2100
|
+
);
|
|
2101
|
+
patched = patched.replace(
|
|
2102
|
+
/\n\s*\/\/ Disable clean tasks[^\n]*\n\s*tasks\.whenTaskAdded\s*\{\s*task\s*->\s*\n\s*if\s*\(\s*task\.name\.contains\(["']Clean["']\)\s*&&\s*task\.name\.contains\(["']Debug["']\)\s*\)\s*\{\s*\n\s*task\.enabled\s*=\s*false\s*\n\s*\}\s*\n\s*\}\s*/g,
|
|
2103
|
+
"\n",
|
|
2104
|
+
);
|
|
2105
|
+
if (patched !== current) {
|
|
2106
|
+
fs.writeFileSync(gradlePath, patched, "utf8");
|
|
2107
|
+
console.log(
|
|
2108
|
+
`[mobile-build] Patched llama-cpp-capacitor build.gradle for AGP 9: ${path.relative(repoRoot, gradlePath)}`,
|
|
2109
|
+
);
|
|
2110
|
+
}
|
|
2111
|
+
}
|
|
2112
|
+
}
|
|
2113
|
+
|
|
2114
|
+
function patchAndroidGradle() {
|
|
2115
|
+
patchAndroidGradleWrapperForReleaseCompat();
|
|
2116
|
+
patchInstalledLlamaCapacitorBuildGradle();
|
|
2117
|
+
// Overwrite root build.gradle with our template (Maven mirrors, Kotlin version)
|
|
2118
|
+
const templateGradle = path.join(platformsDir, "android", "build.gradle");
|
|
2119
|
+
const targetGradle = path.join(androidDir, "build.gradle");
|
|
2120
|
+
if (fs.existsSync(templateGradle) && fs.existsSync(targetGradle)) {
|
|
2121
|
+
const current = fs.readFileSync(targetGradle, "utf8");
|
|
2122
|
+
const template = fs.readFileSync(templateGradle, "utf8");
|
|
2123
|
+
if (current !== template) {
|
|
2124
|
+
fs.writeFileSync(targetGradle, template, "utf8");
|
|
2125
|
+
console.log("[mobile-build] Patched android/build.gradle.");
|
|
2126
|
+
}
|
|
2127
|
+
}
|
|
2128
|
+
|
|
2129
|
+
// Keep generated Android projects aligned with current Capacitor/AndroidX requirements.
|
|
2130
|
+
const varsPath = path.join(androidDir, "variables.gradle");
|
|
2131
|
+
if (fs.existsSync(varsPath)) {
|
|
2132
|
+
const vars = fs.readFileSync(varsPath, "utf8");
|
|
2133
|
+
const patched = vars
|
|
2134
|
+
.replace(/minSdkVersion\s*=\s*\d+/, "minSdkVersion = 26")
|
|
2135
|
+
.replace(/compileSdkVersion\s*=\s*\d+/, "compileSdkVersion = 36");
|
|
2136
|
+
if (patched !== vars) {
|
|
2137
|
+
fs.writeFileSync(varsPath, patched, "utf8");
|
|
2138
|
+
console.log("[mobile-build] Patched Android SDK versions.");
|
|
2139
|
+
}
|
|
2140
|
+
}
|
|
2141
|
+
|
|
2142
|
+
const appGradlePath = path.join(androidDir, "app", "build.gradle");
|
|
2143
|
+
if (fs.existsSync(appGradlePath)) {
|
|
2144
|
+
const current = fs.readFileSync(appGradlePath, "utf8");
|
|
2145
|
+
let patched = replaceOrInsertGradleString(current, "namespace", APP.appId);
|
|
2146
|
+
patched = replaceOrInsertGradleString(patched, "applicationId", APP.appId);
|
|
2147
|
+
patched = appendMissingGradleDependency(
|
|
2148
|
+
patched,
|
|
2149
|
+
"com.google.code.gson:gson:2.13.2",
|
|
2150
|
+
);
|
|
2151
|
+
patched = appendMissingGradleDependency(
|
|
2152
|
+
patched,
|
|
2153
|
+
"com.google.firebase:firebase-common-ktx:21.0.0",
|
|
2154
|
+
);
|
|
2155
|
+
patched = patched.replace(
|
|
2156
|
+
/getDefaultProguardFile\('proguard-android\.txt'\)/g,
|
|
2157
|
+
"getDefaultProguardFile('proguard-android-optimize.txt')",
|
|
2158
|
+
);
|
|
2159
|
+
patched = injectBuildConfigAospField(patched);
|
|
2160
|
+
patched = injectNoCompressTarGz(patched);
|
|
2161
|
+
patched = injectNativeLibLegacyPackaging(patched);
|
|
2162
|
+
patched = injectAospAssetThinning(patched);
|
|
2163
|
+
patched = injectCopyForkLlamaLibTask(patched);
|
|
2164
|
+
if (patched !== current) {
|
|
2165
|
+
fs.writeFileSync(appGradlePath, patched, "utf8");
|
|
2166
|
+
console.log(
|
|
2167
|
+
`[mobile-build] Applied Android package identity ${APP.appId}.`,
|
|
2168
|
+
);
|
|
2169
|
+
}
|
|
2170
|
+
}
|
|
2171
|
+
|
|
2172
|
+
patchOfficialCapacitorGradleForAgp9();
|
|
2173
|
+
patchLlamaCppCapacitorGradle();
|
|
2174
|
+
patchNativePluginGradleForAgp9();
|
|
2175
|
+
|
|
2176
|
+
const stringsPath = path.join(
|
|
2177
|
+
androidDir,
|
|
2178
|
+
"app",
|
|
2179
|
+
"src",
|
|
2180
|
+
"main",
|
|
2181
|
+
"res",
|
|
2182
|
+
"values",
|
|
2183
|
+
"strings.xml",
|
|
2184
|
+
);
|
|
2185
|
+
if (fs.existsSync(stringsPath)) {
|
|
2186
|
+
const current = fs.readFileSync(stringsPath, "utf8");
|
|
2187
|
+
const appName = escapeXmlText(APP.appName);
|
|
2188
|
+
const appId = escapeXmlText(APP.appId);
|
|
2189
|
+
const urlScheme = escapeXmlText(APP.urlScheme);
|
|
2190
|
+
const patched = current
|
|
2191
|
+
.replace(
|
|
2192
|
+
/<string name="app_name">[^<]*<\/string>/,
|
|
2193
|
+
`<string name="app_name">${appName}</string>`,
|
|
2194
|
+
)
|
|
2195
|
+
.replace(
|
|
2196
|
+
/<string name="title_activity_main">[^<]*<\/string>/,
|
|
2197
|
+
`<string name="title_activity_main">${appName}</string>`,
|
|
2198
|
+
)
|
|
2199
|
+
.replace(
|
|
2200
|
+
/<string name="package_name">[^<]*<\/string>/,
|
|
2201
|
+
`<string name="package_name">${appId}</string>`,
|
|
2202
|
+
)
|
|
2203
|
+
.replace(
|
|
2204
|
+
/<string name="custom_url_scheme">[^<]*<\/string>/,
|
|
2205
|
+
`<string name="custom_url_scheme">${urlScheme}</string>`,
|
|
2206
|
+
);
|
|
2207
|
+
if (patched !== current) {
|
|
2208
|
+
fs.writeFileSync(stringsPath, patched, "utf8");
|
|
2209
|
+
console.log(
|
|
2210
|
+
`[mobile-build] Applied Android app strings for ${APP.appName}.`,
|
|
2211
|
+
);
|
|
2212
|
+
}
|
|
2213
|
+
}
|
|
2214
|
+
}
|
|
2215
|
+
|
|
2216
|
+
function sanitizeAndroidManifestWhenPlatformTemplatesMissing() {
|
|
2217
|
+
const srcJava = path.join(
|
|
2218
|
+
platformsDir,
|
|
2219
|
+
"android",
|
|
2220
|
+
"app",
|
|
2221
|
+
"src",
|
|
2222
|
+
"main",
|
|
2223
|
+
"java",
|
|
2224
|
+
"ai",
|
|
2225
|
+
"elizaos",
|
|
2226
|
+
"app",
|
|
2227
|
+
);
|
|
2228
|
+
if (fs.existsSync(srcJava)) return;
|
|
2229
|
+
|
|
2230
|
+
const manifestPath = path.join(
|
|
2231
|
+
androidDir,
|
|
2232
|
+
"app",
|
|
2233
|
+
"src",
|
|
2234
|
+
"main",
|
|
2235
|
+
"AndroidManifest.xml",
|
|
2236
|
+
);
|
|
2237
|
+
if (!fs.existsSync(manifestPath)) return;
|
|
2238
|
+
|
|
2239
|
+
let xml = fs.readFileSync(manifestPath, "utf8");
|
|
2240
|
+
const original = xml;
|
|
2241
|
+
const removeComponent = (source, className) => {
|
|
2242
|
+
const escapedName = escapeRegExp(className);
|
|
2243
|
+
const pairedRe = new RegExp(
|
|
2244
|
+
`\\n\\s*<(activity|service|receiver)\\b(?=[^>]*android:name="[^"]*\\.?${escapedName}")[\\s\\S]*?<\\/\\1>\\s*`,
|
|
2245
|
+
"g",
|
|
2246
|
+
);
|
|
2247
|
+
const selfClosingRe = new RegExp(
|
|
2248
|
+
`\\n\\s*<(activity|service|receiver)\\b(?=[^>]*android:name="[^"]*\\.?${escapedName}")[^>]*/>\\s*`,
|
|
2249
|
+
"g",
|
|
2250
|
+
);
|
|
2251
|
+
return source.replace(pairedRe, "\n").replace(selfClosingRe, "\n");
|
|
2252
|
+
};
|
|
2253
|
+
|
|
2254
|
+
for (const component of [
|
|
2255
|
+
"ElizaAgentService",
|
|
2256
|
+
"ElizaDialActivity",
|
|
2257
|
+
"ElizaAssistActivity",
|
|
2258
|
+
"ElizaInCallService",
|
|
2259
|
+
"ElizaSmsReceiver",
|
|
2260
|
+
"ElizaMmsReceiver",
|
|
2261
|
+
"ElizaRespondViaMessageService",
|
|
2262
|
+
"ElizaSmsComposeActivity",
|
|
2263
|
+
"ElizaBootReceiver",
|
|
2264
|
+
"ElizaBrowserActivity",
|
|
2265
|
+
"ElizaContactsActivity",
|
|
2266
|
+
"ElizaCameraActivity",
|
|
2267
|
+
"ElizaClockActivity",
|
|
2268
|
+
"ElizaCalendarActivity",
|
|
2269
|
+
]) {
|
|
2270
|
+
xml = removeComponent(xml, component);
|
|
2271
|
+
}
|
|
2272
|
+
if (xml !== original) {
|
|
2273
|
+
fs.writeFileSync(manifestPath, xml, "utf8");
|
|
2274
|
+
console.log(
|
|
2275
|
+
"[mobile-build] Removed Android components that need packaged platform templates.",
|
|
2276
|
+
);
|
|
2277
|
+
}
|
|
2278
|
+
}
|
|
2279
|
+
|
|
2280
|
+
const ANDROID_LAUNCHER_ICON_SIZES = {
|
|
2281
|
+
"mipmap-mdpi": 48,
|
|
2282
|
+
"mipmap-hdpi": 72,
|
|
2283
|
+
"mipmap-xhdpi": 96,
|
|
2284
|
+
"mipmap-xxhdpi": 144,
|
|
2285
|
+
"mipmap-xxxhdpi": 192,
|
|
2286
|
+
};
|
|
2287
|
+
|
|
2288
|
+
const ANDROID_SPLASH_SIZES = {
|
|
2289
|
+
drawable: [480, 320],
|
|
2290
|
+
"drawable-port-mdpi": [320, 480],
|
|
2291
|
+
"drawable-port-hdpi": [480, 720],
|
|
2292
|
+
"drawable-port-xhdpi": [640, 960],
|
|
2293
|
+
"drawable-port-xxhdpi": [960, 1440],
|
|
2294
|
+
"drawable-port-xxxhdpi": [1280, 1920],
|
|
2295
|
+
"drawable-land-mdpi": [480, 320],
|
|
2296
|
+
"drawable-land-hdpi": [720, 480],
|
|
2297
|
+
"drawable-land-xhdpi": [960, 640],
|
|
2298
|
+
"drawable-land-xxhdpi": [1440, 960],
|
|
2299
|
+
"drawable-land-xxxhdpi": [1920, 1280],
|
|
2300
|
+
};
|
|
2301
|
+
|
|
2302
|
+
async function loadImageToolForBrandAssets(platform) {
|
|
2303
|
+
try {
|
|
2304
|
+
return { kind: "sharp", sharp: (await import("sharp")).default };
|
|
2305
|
+
} catch (error) {
|
|
2306
|
+
const magick = resolveExecutable("magick");
|
|
2307
|
+
if (magick) {
|
|
2308
|
+
console.warn(
|
|
2309
|
+
`[mobile-build] sharp is unavailable for ${platform} brand assets; using ImageMagick fallback.`,
|
|
2310
|
+
);
|
|
2311
|
+
return { kind: "magick", magick };
|
|
2312
|
+
}
|
|
2313
|
+
throw new Error(
|
|
2314
|
+
`sharp is required to generate ${platform} brand assets for ${APP.appName}: ${
|
|
2315
|
+
error instanceof Error ? error.message : String(error)
|
|
2316
|
+
}`,
|
|
2317
|
+
);
|
|
2318
|
+
}
|
|
2319
|
+
}
|
|
2320
|
+
|
|
2321
|
+
async function writeCoverPng(
|
|
2322
|
+
tool,
|
|
2323
|
+
source,
|
|
2324
|
+
output,
|
|
2325
|
+
width,
|
|
2326
|
+
height,
|
|
2327
|
+
options = {},
|
|
2328
|
+
) {
|
|
2329
|
+
if (tool.kind === "sharp") {
|
|
2330
|
+
let image = tool.sharp(source).resize(width, height, {
|
|
2331
|
+
fit: "cover",
|
|
2332
|
+
position: "center",
|
|
2333
|
+
});
|
|
2334
|
+
if (options.flattenBackground) {
|
|
2335
|
+
image = image.flatten({ background: options.flattenBackground });
|
|
2336
|
+
}
|
|
2337
|
+
await image.png().toFile(output);
|
|
2338
|
+
return;
|
|
2339
|
+
}
|
|
2340
|
+
|
|
2341
|
+
const args = [
|
|
2342
|
+
source,
|
|
2343
|
+
"-resize",
|
|
2344
|
+
`${width}x${height}^`,
|
|
2345
|
+
"-gravity",
|
|
2346
|
+
"center",
|
|
2347
|
+
"-extent",
|
|
2348
|
+
`${width}x${height}`,
|
|
2349
|
+
];
|
|
2350
|
+
if (options.flattenBackground) {
|
|
2351
|
+
args.push(
|
|
2352
|
+
"-background",
|
|
2353
|
+
options.flattenBackground,
|
|
2354
|
+
"-alpha",
|
|
2355
|
+
"remove",
|
|
2356
|
+
"-alpha",
|
|
2357
|
+
"off",
|
|
2358
|
+
);
|
|
2359
|
+
}
|
|
2360
|
+
args.push(output);
|
|
2361
|
+
await run(tool.magick, args);
|
|
2362
|
+
}
|
|
2363
|
+
|
|
2364
|
+
async function writeAndroidForegroundPng(tool, source, output, size) {
|
|
2365
|
+
if (tool.kind === "sharp") {
|
|
2366
|
+
const foregroundSize = Math.round(size * 0.7);
|
|
2367
|
+
const padding = Math.round(size * 0.4);
|
|
2368
|
+
await tool
|
|
2369
|
+
.sharp(source)
|
|
2370
|
+
.resize(foregroundSize, foregroundSize, { fit: "contain" })
|
|
2371
|
+
.extend({
|
|
2372
|
+
top: padding,
|
|
2373
|
+
bottom: padding,
|
|
2374
|
+
left: padding,
|
|
2375
|
+
right: padding,
|
|
2376
|
+
background: { r: 0, g: 0, b: 0, alpha: 0 },
|
|
2377
|
+
})
|
|
2378
|
+
.resize(Math.round(size * 1.5), Math.round(size * 1.5), {
|
|
2379
|
+
fit: "contain",
|
|
2380
|
+
})
|
|
2381
|
+
.png()
|
|
2382
|
+
.toFile(output);
|
|
2383
|
+
return;
|
|
2384
|
+
}
|
|
2385
|
+
|
|
2386
|
+
await run(tool.magick, [
|
|
2387
|
+
source,
|
|
2388
|
+
"-resize",
|
|
2389
|
+
`${Math.round(size * 0.7)}x${Math.round(size * 0.7)}`,
|
|
2390
|
+
"-background",
|
|
2391
|
+
"none",
|
|
2392
|
+
"-gravity",
|
|
2393
|
+
"center",
|
|
2394
|
+
"-extent",
|
|
2395
|
+
`${Math.round(size * 1.5)}x${Math.round(size * 1.5)}`,
|
|
2396
|
+
output,
|
|
2397
|
+
]);
|
|
2398
|
+
}
|
|
2399
|
+
|
|
2400
|
+
function resolveBrandSources() {
|
|
2401
|
+
return {
|
|
2402
|
+
iconSource: firstExisting([
|
|
2403
|
+
path.join(appDir, "public", "android-chrome-512x512.png"),
|
|
2404
|
+
path.join(appDir, "public", "apple-touch-icon.png"),
|
|
2405
|
+
path.join(appDir, "public", "favicon-256x256.png"),
|
|
2406
|
+
]),
|
|
2407
|
+
splashSource: firstExisting([
|
|
2408
|
+
path.join(appDir, "public", "splash-bg.png"),
|
|
2409
|
+
path.join(appDir, "public", "splash-bg.jpg"),
|
|
2410
|
+
]),
|
|
2411
|
+
};
|
|
2412
|
+
}
|
|
2413
|
+
|
|
2414
|
+
async function generateIosBrandAssets() {
|
|
2415
|
+
const assetDir = path.join(iosDir, "App", "Assets.xcassets");
|
|
2416
|
+
if (!fs.existsSync(assetDir)) return;
|
|
2417
|
+
|
|
2418
|
+
const { iconSource, splashSource } = resolveBrandSources();
|
|
2419
|
+
if (!iconSource && !splashSource) return;
|
|
2420
|
+
|
|
2421
|
+
const imageTool = await loadImageToolForBrandAssets("iOS");
|
|
2422
|
+
|
|
2423
|
+
if (iconSource) {
|
|
2424
|
+
const iconSetDir = path.join(assetDir, "AppIcon.appiconset");
|
|
2425
|
+
const contentsPath = path.join(iconSetDir, "Contents.json");
|
|
2426
|
+
if (fs.existsSync(contentsPath)) {
|
|
2427
|
+
const contents = JSON.parse(fs.readFileSync(contentsPath, "utf8"));
|
|
2428
|
+
for (const image of contents.images ?? []) {
|
|
2429
|
+
if (!image.filename || !image.size || !image.scale) continue;
|
|
2430
|
+
const [width] = String(image.size).split("x");
|
|
2431
|
+
const scale = Number.parseFloat(String(image.scale));
|
|
2432
|
+
const pixels = Math.round(Number.parseFloat(width) * scale);
|
|
2433
|
+
if (!Number.isFinite(pixels) || pixels <= 0) continue;
|
|
2434
|
+
await writeCoverPng(
|
|
2435
|
+
imageTool,
|
|
2436
|
+
iconSource,
|
|
2437
|
+
path.join(iconSetDir, image.filename),
|
|
2438
|
+
pixels,
|
|
2439
|
+
pixels,
|
|
2440
|
+
{ flattenBackground: "#000000" },
|
|
2441
|
+
);
|
|
2442
|
+
}
|
|
2443
|
+
}
|
|
2444
|
+
}
|
|
2445
|
+
|
|
2446
|
+
if (splashSource) {
|
|
2447
|
+
const splashSetDir = path.join(assetDir, "Splash.imageset");
|
|
2448
|
+
const contentsPath = path.join(splashSetDir, "Contents.json");
|
|
2449
|
+
if (fs.existsSync(contentsPath)) {
|
|
2450
|
+
const contents = JSON.parse(fs.readFileSync(contentsPath, "utf8"));
|
|
2451
|
+
for (const image of contents.images ?? []) {
|
|
2452
|
+
if (!image.filename) continue;
|
|
2453
|
+
await writeCoverPng(
|
|
2454
|
+
imageTool,
|
|
2455
|
+
splashSource,
|
|
2456
|
+
path.join(splashSetDir, image.filename),
|
|
2457
|
+
2732,
|
|
2458
|
+
2732,
|
|
2459
|
+
);
|
|
2460
|
+
}
|
|
2461
|
+
}
|
|
2462
|
+
}
|
|
2463
|
+
|
|
2464
|
+
console.log(`[mobile-build] Generated iOS brand assets for ${APP.appName}.`);
|
|
2465
|
+
}
|
|
2466
|
+
|
|
2467
|
+
async function generateAndroidBrandAssets() {
|
|
2468
|
+
const resDir = path.join(androidDir, "app", "src", "main", "res");
|
|
2469
|
+
if (!fs.existsSync(resDir)) return;
|
|
2470
|
+
|
|
2471
|
+
const { iconSource, splashSource } = resolveBrandSources();
|
|
2472
|
+
if (!iconSource && !splashSource) return;
|
|
2473
|
+
|
|
2474
|
+
const imageTool = await loadImageToolForBrandAssets("Android");
|
|
2475
|
+
|
|
2476
|
+
if (iconSource) {
|
|
2477
|
+
for (const [dir, size] of Object.entries(ANDROID_LAUNCHER_ICON_SIZES)) {
|
|
2478
|
+
const out = path.join(resDir, dir);
|
|
2479
|
+
fs.mkdirSync(out, { recursive: true });
|
|
2480
|
+
await writeCoverPng(
|
|
2481
|
+
imageTool,
|
|
2482
|
+
iconSource,
|
|
2483
|
+
path.join(out, "ic_launcher.png"),
|
|
2484
|
+
size,
|
|
2485
|
+
size,
|
|
2486
|
+
);
|
|
2487
|
+
await writeCoverPng(
|
|
2488
|
+
imageTool,
|
|
2489
|
+
iconSource,
|
|
2490
|
+
path.join(out, "ic_launcher_round.png"),
|
|
2491
|
+
size,
|
|
2492
|
+
size,
|
|
2493
|
+
);
|
|
2494
|
+
await writeAndroidForegroundPng(
|
|
2495
|
+
imageTool,
|
|
2496
|
+
iconSource,
|
|
2497
|
+
path.join(out, "ic_launcher_foreground.png"),
|
|
2498
|
+
size,
|
|
2499
|
+
);
|
|
2500
|
+
}
|
|
2501
|
+
}
|
|
2502
|
+
|
|
2503
|
+
if (splashSource) {
|
|
2504
|
+
for (const [dir, [width, height]] of Object.entries(ANDROID_SPLASH_SIZES)) {
|
|
2505
|
+
const out = path.join(resDir, dir);
|
|
2506
|
+
fs.mkdirSync(out, { recursive: true });
|
|
2507
|
+
await writeCoverPng(
|
|
2508
|
+
imageTool,
|
|
2509
|
+
splashSource,
|
|
2510
|
+
path.join(out, "splash.png"),
|
|
2511
|
+
width,
|
|
2512
|
+
height,
|
|
2513
|
+
);
|
|
2514
|
+
}
|
|
2515
|
+
}
|
|
2516
|
+
|
|
2517
|
+
console.log(
|
|
2518
|
+
`[mobile-build] Generated Android brand assets for ${APP.appName}.`,
|
|
2519
|
+
);
|
|
2520
|
+
}
|
|
2521
|
+
|
|
2522
|
+
// ── Phase 6: Native builds ──────────────────────────────────────────────
|
|
2523
|
+
|
|
2524
|
+
export function patchLlamaCppCapacitorPodspecForXcframework(
|
|
2525
|
+
packageDir,
|
|
2526
|
+
{
|
|
2527
|
+
xcframeworkRelPath = "ios/Frameworks-xcframework/LlamaCpp.xcframework",
|
|
2528
|
+
} = {},
|
|
2529
|
+
) {
|
|
2530
|
+
const podspecPath = path.join(packageDir, "LlamaCppCapacitor.podspec");
|
|
2531
|
+
if (!fs.existsSync(podspecPath)) return;
|
|
2532
|
+
const current = fs.readFileSync(podspecPath, "utf8");
|
|
2533
|
+
let patched = current.replace(
|
|
2534
|
+
"s.vendored_frameworks = 'ios/Frameworks/llama-cpp.framework'",
|
|
2535
|
+
`s.vendored_frameworks = '${xcframeworkRelPath}'`,
|
|
2536
|
+
);
|
|
2537
|
+
patched = patched.replace(
|
|
2538
|
+
"s.vendored_frameworks = 'ios/Frameworks/LlamaCpp.framework'",
|
|
2539
|
+
`s.vendored_frameworks = '${xcframeworkRelPath}'`,
|
|
2540
|
+
);
|
|
2541
|
+
patched = patched.replace(
|
|
2542
|
+
"s.vendored_frameworks = 'ios/Frameworks/llama-cpp.xcframework'",
|
|
2543
|
+
`s.vendored_frameworks = '${xcframeworkRelPath}'`,
|
|
2544
|
+
);
|
|
2545
|
+
patched = patched.replace(
|
|
2546
|
+
"s.vendored_frameworks = 'ios/Frameworks/LlamaCpp.xcframework'",
|
|
2547
|
+
`s.vendored_frameworks = '${xcframeworkRelPath}'`,
|
|
2548
|
+
);
|
|
2549
|
+
patched = patched.replace(
|
|
2550
|
+
/\n\s*s\.pod_target_xcconfig\s*=\s*\{\s*\n\s*['"]FRAMEWORK_SEARCH_PATHS['"]\s*=>\s*['"]\$\(inherited\) "\$\(PODS_TARGET_SRCROOT\)\/ios\/Frameworks"['"]\s*\n\s*\}\s*/m,
|
|
2551
|
+
"\n",
|
|
2552
|
+
);
|
|
2553
|
+
// The published podspec also injects `ios/Frameworks` into
|
|
2554
|
+
// FRAMEWORK_SEARCH_PATHS, which contains the device-only
|
|
2555
|
+
// `llama-cpp.framework` next to the xcframework. The linker scans
|
|
2556
|
+
// -F paths in order and resolves `-framework llama-cpp` against the
|
|
2557
|
+
// device-only slice first, producing
|
|
2558
|
+
// ld: building for 'iOS-simulator', but linking in dylib (...
|
|
2559
|
+
// /llama-cpp.framework/llama-cpp) built for 'iOS'
|
|
2560
|
+
// on iphonesimulator builds. Drop the explicit search path so the
|
|
2561
|
+
// xcframework's per-platform slice is picked up via the standard
|
|
2562
|
+
// XCFrameworkIntermediates path the Xcode build system maintains.
|
|
2563
|
+
patched = patched.replace(
|
|
2564
|
+
/\s*s\.pod_target_xcconfig\s*=\s*\{[^}]*'FRAMEWORK_SEARCH_PATHS'\s*=>\s*'[^']*'[^}]*\}\s*/,
|
|
2565
|
+
"\n",
|
|
2566
|
+
);
|
|
2567
|
+
if (patched !== current) {
|
|
2568
|
+
fs.writeFileSync(podspecPath, patched, "utf8");
|
|
2569
|
+
console.log(
|
|
2570
|
+
"[mobile-build] Patched llama-cpp-capacitor podspec for xcframework + dropped FRAMEWORK_SEARCH_PATHS device-only override.",
|
|
2571
|
+
);
|
|
2572
|
+
}
|
|
2573
|
+
}
|
|
2574
|
+
|
|
2575
|
+
// Wave-4-F (iOS pipeline rewire): the iOS LlamaCpp.xcframework is now
|
|
2576
|
+
// produced by `build-llama-cpp-dflash.mjs --target ios-arm64-metal` +
|
|
2577
|
+
// `--target ios-arm64-simulator-metal` and assembled by
|
|
2578
|
+
// `ios-xcframework/build-xcframework.mjs --verify`. The previous in-process
|
|
2579
|
+
// cmake invocation that built `llama-cpp-capacitor`'s bundled `ios/`
|
|
2580
|
+
// source produced a STOCK llama.cpp framework with none of the milady
|
|
2581
|
+
// kernels (TurboQuant / QJL / PolarQuant / DFlash) and silently violated
|
|
2582
|
+
// AGENTS.md §3 on every iOS build. Delegating to the dflash builder
|
|
2583
|
+
// ensures the same kernel-set lands on iOS as on darwin/linux/android.
|
|
2584
|
+
//
|
|
2585
|
+
// AGENTS.md §3 enforcement: build-llama-cpp-dflash.mjs hard-throws on
|
|
2586
|
+
// missing kernels via writeCapabilities()/requiredKernelsMissing(); the
|
|
2587
|
+
// xcframework packaging --verify step additionally greps the static
|
|
2588
|
+
// archives for AGENTS.md §3 kernel symbols. Either failure aborts the
|
|
2589
|
+
// iOS build before the npm-bundled stock framework can be linked.
|
|
2590
|
+
const DFLASH_BUILD_SCRIPT = path.resolve(
|
|
2591
|
+
__dirname,
|
|
2592
|
+
"build-llama-cpp-dflash.mjs",
|
|
2593
|
+
);
|
|
2594
|
+
const IOS_XCFRAMEWORK_BUILD_SCRIPT = path.resolve(
|
|
2595
|
+
__dirname,
|
|
2596
|
+
"ios-xcframework",
|
|
2597
|
+
"build-xcframework.mjs",
|
|
2598
|
+
);
|
|
2599
|
+
|
|
2600
|
+
function elizaStateDirForBuild() {
|
|
2601
|
+
const env = process.env.ELIZA_STATE_DIR?.trim();
|
|
2602
|
+
if (env) return env;
|
|
2603
|
+
return path.join(os.homedir(), ".eliza");
|
|
2604
|
+
}
|
|
2605
|
+
|
|
2606
|
+
function dflashTargetOutDir(target) {
|
|
2607
|
+
return path.join(
|
|
2608
|
+
elizaStateDirForBuild(),
|
|
2609
|
+
"local-inference",
|
|
2610
|
+
"bin",
|
|
2611
|
+
"dflash",
|
|
2612
|
+
target,
|
|
2613
|
+
);
|
|
2614
|
+
}
|
|
2615
|
+
|
|
2616
|
+
async function ensureDflashIosTarget(target) {
|
|
2617
|
+
const outDir = dflashTargetOutDir(target);
|
|
2618
|
+
const capabilities = path.join(outDir, "CAPABILITIES.json");
|
|
2619
|
+
if (fs.existsSync(capabilities)) {
|
|
2620
|
+
console.log(
|
|
2621
|
+
`[mobile-build] Reusing existing dflash artifact for ${target} at ${outDir}`,
|
|
2622
|
+
);
|
|
2623
|
+
return outDir;
|
|
2624
|
+
}
|
|
2625
|
+
console.log(`[mobile-build] Building dflash artifact for ${target}`);
|
|
2626
|
+
await run("node", [DFLASH_BUILD_SCRIPT, "--target", target]);
|
|
2627
|
+
if (!fs.existsSync(capabilities)) {
|
|
2628
|
+
throw new Error(
|
|
2629
|
+
`[mobile-build] dflash build for ${target} did not produce CAPABILITIES.json at ${capabilities}. ` +
|
|
2630
|
+
`AGENTS.md §3 forbids shipping an iOS framework without the full kernel set; aborting.`,
|
|
2631
|
+
);
|
|
2632
|
+
}
|
|
2633
|
+
return outDir;
|
|
2634
|
+
}
|
|
2635
|
+
|
|
2636
|
+
async function ensureIosLlamaCppVendoredFramework({ buildTarget: _buildTarget }) {
|
|
2637
|
+
// When llama is excluded from the build (cloud-only / App Store thin
|
|
2638
|
+
// client), the pod is not generated and the vendored framework is not
|
|
2639
|
+
// referenced. Skipping here avoids spinning up xcodebuild for an
|
|
2640
|
+
// xcframework that nothing consumes.
|
|
2641
|
+
const includeLlama =
|
|
2642
|
+
isTruthyEnv(process.env.ELIZA_IOS_INCLUDE_LLAMA) ||
|
|
2643
|
+
isTruthyEnv(process.env.MILADY_IOS_INCLUDE_LLAMA);
|
|
2644
|
+
if (!includeLlama) return;
|
|
2645
|
+
|
|
2646
|
+
if (process.platform !== "darwin") {
|
|
2647
|
+
throw new Error(
|
|
2648
|
+
"[mobile-build] iOS llama.cpp xcframework build requires a macOS host with Xcode. " +
|
|
2649
|
+
"Either run on macOS or unset ELIZA_IOS_INCLUDE_LLAMA / MILADY_IOS_INCLUDE_LLAMA.",
|
|
2650
|
+
);
|
|
2651
|
+
}
|
|
2652
|
+
|
|
2653
|
+
const packageDir = resolvePackageAbsolutePath("llama-cpp-capacitor");
|
|
2654
|
+
if (!packageDir) {
|
|
2655
|
+
throw new Error(
|
|
2656
|
+
"[mobile-build] llama-cpp-capacitor package not found in node_modules; " +
|
|
2657
|
+
"either install it or unset ELIZA_IOS_INCLUDE_LLAMA / MILADY_IOS_INCLUDE_LLAMA.",
|
|
2658
|
+
);
|
|
2659
|
+
}
|
|
2660
|
+
|
|
2661
|
+
const frameworksDir = path.join(packageDir, "ios", "Frameworks");
|
|
2662
|
+
const xcframeworksDir = path.join(
|
|
2663
|
+
packageDir,
|
|
2664
|
+
"ios",
|
|
2665
|
+
"Frameworks-xcframework",
|
|
2666
|
+
);
|
|
2667
|
+
const xcframeworkDir = path.join(xcframeworksDir, "LlamaCpp.xcframework");
|
|
2668
|
+
patchLlamaCppCapacitorPodspecForXcframework(packageDir);
|
|
2669
|
+
|
|
2670
|
+
// Build (or reuse) both per-platform slices via the dflash builder so
|
|
2671
|
+
// the iOS xcframework carries the same milady kernel set as every
|
|
2672
|
+
// other supported backend. Per AGENTS.md §3, missing kernels here are
|
|
2673
|
+
// a hard error: build-llama-cpp-dflash.mjs already enforces that and
|
|
2674
|
+
// throws via writeCapabilities() before producing CAPABILITIES.json.
|
|
2675
|
+
await ensureDflashIosTarget("ios-arm64-metal");
|
|
2676
|
+
await ensureDflashIosTarget("ios-arm64-simulator-metal");
|
|
2677
|
+
|
|
2678
|
+
fs.mkdirSync(xcframeworksDir, { recursive: true });
|
|
2679
|
+
fs.rmSync(xcframeworkDir, { recursive: true, force: true });
|
|
2680
|
+
await run("node", [
|
|
2681
|
+
IOS_XCFRAMEWORK_BUILD_SCRIPT,
|
|
2682
|
+
"--output",
|
|
2683
|
+
xcframeworkDir,
|
|
2684
|
+
"--device-archive-dir",
|
|
2685
|
+
dflashTargetOutDir("ios-arm64-metal"),
|
|
2686
|
+
"--sim-archive-dir",
|
|
2687
|
+
dflashTargetOutDir("ios-arm64-simulator-metal"),
|
|
2688
|
+
"--verify",
|
|
2689
|
+
]);
|
|
2690
|
+
|
|
2691
|
+
// CocoaPods adds the parent directory of every `vendored_frameworks`
|
|
2692
|
+
// entry to FRAMEWORK_SEARCH_PATHS. The npm package ships a stock
|
|
2693
|
+
// device-only `LlamaCpp.framework` / `llama-cpp.framework` next to
|
|
2694
|
+
// the (now-replaced) xcframework slot. With both present the linker
|
|
2695
|
+
// resolves `-framework LlamaCpp` to the stock .framework first and
|
|
2696
|
+
// fails simulator builds with:
|
|
2697
|
+
// ld: building for 'iOS-simulator', but linking in dylib (...) built for 'iOS'
|
|
2698
|
+
// Move the npm-bundled stock frameworks out of the search path so the
|
|
2699
|
+
// xcframework's per-platform slice is the only resolvable target.
|
|
2700
|
+
for (const stale of [
|
|
2701
|
+
path.join(frameworksDir, "LlamaCpp.framework"),
|
|
2702
|
+
path.join(frameworksDir, "llama-cpp.framework"),
|
|
2703
|
+
]) {
|
|
2704
|
+
if (!fs.existsSync(stale)) continue;
|
|
2705
|
+
const archived = path.join(
|
|
2706
|
+
packageDir,
|
|
2707
|
+
"ios",
|
|
2708
|
+
`.${path.basename(stale, ".framework")}-stock-archive`,
|
|
2709
|
+
);
|
|
2710
|
+
fs.rmSync(archived, { recursive: true, force: true });
|
|
2711
|
+
fs.renameSync(stale, archived);
|
|
2712
|
+
console.log(
|
|
2713
|
+
`[mobile-build] Archived stock npm framework: ${stale} -> ${archived} ` +
|
|
2714
|
+
`(stock build has no Eliza-1 kernels — see AGENTS.md §3).`,
|
|
2715
|
+
);
|
|
2716
|
+
}
|
|
2717
|
+
console.log(
|
|
2718
|
+
"[mobile-build] iOS LlamaCpp.xcframework wired to milady-built kernels (device + simulator slices).",
|
|
2719
|
+
);
|
|
2720
|
+
}
|
|
2721
|
+
|
|
2722
|
+
export function shouldRunIosPodInstall(syncedFiles = []) {
|
|
2723
|
+
return syncedFiles.includes(path.join("App", "Podfile"));
|
|
2724
|
+
}
|
|
2725
|
+
|
|
2726
|
+
export function resolveIosBuildTarget({
|
|
2727
|
+
env = process.env,
|
|
2728
|
+
appDirValue = appDir,
|
|
2729
|
+
} = {}) {
|
|
2730
|
+
const explicitDestination = env.ELIZA_IOS_BUILD_DESTINATION;
|
|
2731
|
+
const explicitSdk = env.ELIZA_IOS_BUILD_SDK;
|
|
2732
|
+
|
|
2733
|
+
if (explicitDestination || explicitSdk) {
|
|
2734
|
+
return {
|
|
2735
|
+
destination: explicitDestination ?? "generic/platform=iOS Simulator",
|
|
2736
|
+
sdk: explicitSdk ?? "iphonesimulator",
|
|
2737
|
+
reason: "explicit environment override",
|
|
2738
|
+
};
|
|
2739
|
+
}
|
|
2740
|
+
|
|
2741
|
+
const includeDeviceOnlyLlama =
|
|
2742
|
+
isTruthyEnv(env.ELIZA_IOS_INCLUDE_LLAMA) ||
|
|
2743
|
+
isTruthyEnv(env.MILADY_IOS_INCLUDE_LLAMA);
|
|
2744
|
+
const llamaCppFramework = firstExisting([
|
|
2745
|
+
path.join(
|
|
2746
|
+
appDirValue,
|
|
2747
|
+
"node_modules",
|
|
2748
|
+
"llama-cpp-capacitor",
|
|
2749
|
+
"ios",
|
|
2750
|
+
"Frameworks",
|
|
2751
|
+
"LlamaCpp.framework",
|
|
2752
|
+
"LlamaCpp",
|
|
2753
|
+
),
|
|
2754
|
+
path.join(
|
|
2755
|
+
appDirValue,
|
|
2756
|
+
"node_modules",
|
|
2757
|
+
"llama-cpp-capacitor",
|
|
2758
|
+
"ios",
|
|
2759
|
+
"Frameworks",
|
|
2760
|
+
"llama-cpp.framework",
|
|
2761
|
+
"llama-cpp",
|
|
2762
|
+
),
|
|
2763
|
+
]);
|
|
2764
|
+
|
|
2765
|
+
if (includeDeviceOnlyLlama && llamaCppFramework) {
|
|
2766
|
+
return {
|
|
2767
|
+
destination: "generic/platform=iOS",
|
|
2768
|
+
sdk: "iphoneos",
|
|
2769
|
+
reason: "explicit device llama.cpp framework build",
|
|
2770
|
+
};
|
|
2771
|
+
}
|
|
2772
|
+
|
|
2773
|
+
return {
|
|
2774
|
+
destination: "generic/platform=iOS Simulator",
|
|
2775
|
+
sdk: "iphonesimulator",
|
|
2776
|
+
reason: "default cloud simulator build",
|
|
2777
|
+
};
|
|
2778
|
+
}
|
|
2779
|
+
|
|
2780
|
+
// ── Android cloud (Play-Store) strip set ────────────────────────────────
|
|
2781
|
+
//
|
|
2782
|
+
// The default Android target injects an on-device agent runtime, default
|
|
2783
|
+
// roles (dialer, SMS, browser, contacts, camera, calendar, clock,
|
|
2784
|
+
// assistant, in-call), a boot receiver, and the privileged appop /
|
|
2785
|
+
// usage-stats permissions that AOSP needs but Play Store rejects. The
|
|
2786
|
+
// `android-cloud` target produces a thin Capacitor client backed by Eliza
|
|
2787
|
+
// Cloud and must not ship any of those components.
|
|
2788
|
+
//
|
|
2789
|
+
// Components deleted from the manifest (and from app/src/main/java/...):
|
|
2790
|
+
const ANDROID_CLOUD_STRIPPED_COMPONENTS = [
|
|
2791
|
+
"ElizaAgentService",
|
|
2792
|
+
"ElizaDialActivity",
|
|
2793
|
+
"ElizaAssistActivity",
|
|
2794
|
+
"ElizaInCallService",
|
|
2795
|
+
"ElizaSmsReceiver",
|
|
2796
|
+
"ElizaMmsReceiver",
|
|
2797
|
+
"ElizaRespondViaMessageService",
|
|
2798
|
+
"ElizaSmsComposeActivity",
|
|
2799
|
+
"ElizaBootReceiver",
|
|
2800
|
+
"ElizaBrowserActivity",
|
|
2801
|
+
"ElizaContactsActivity",
|
|
2802
|
+
"ElizaCameraActivity",
|
|
2803
|
+
"ElizaClockActivity",
|
|
2804
|
+
"ElizaCalendarActivity",
|
|
2805
|
+
];
|
|
2806
|
+
|
|
2807
|
+
// Permissions removed from the manifest. Anything that triggers a Play
|
|
2808
|
+
// Store policy review (sensitive runtime perms, system-only signature
|
|
2809
|
+
// perms, default-role / call / SMS perms, background location) gets
|
|
2810
|
+
// dropped. The remainder — INTERNET, POST_NOTIFICATIONS, FOREGROUND_SERVICE
|
|
2811
|
+
// + FOREGROUND_SERVICE_DATA_SYNC for the Gateway sync service, WAKE_LOCK,
|
|
2812
|
+
// scoped storage SDK fallbacks, RECORD_AUDIO/CAMERA/LOCATION needed for
|
|
2813
|
+
// Capacitor plugins the cloud renderer still uses — stays in place.
|
|
2814
|
+
const ANDROID_CLOUD_STRIPPED_PERMISSIONS = [
|
|
2815
|
+
"READ_CONTACTS",
|
|
2816
|
+
"WRITE_CONTACTS",
|
|
2817
|
+
"CALL_PHONE",
|
|
2818
|
+
"READ_PHONE_STATE",
|
|
2819
|
+
"ANSWER_PHONE_CALLS",
|
|
2820
|
+
"MANAGE_OWN_CALLS",
|
|
2821
|
+
"READ_CALL_LOG",
|
|
2822
|
+
"WRITE_CALL_LOG",
|
|
2823
|
+
"READ_SMS",
|
|
2824
|
+
"SEND_SMS",
|
|
2825
|
+
"RECEIVE_SMS",
|
|
2826
|
+
"RECEIVE_MMS",
|
|
2827
|
+
"RECEIVE_WAP_PUSH",
|
|
2828
|
+
"ACCESS_BACKGROUND_LOCATION",
|
|
2829
|
+
"FOREGROUND_SERVICE_SPECIAL_USE",
|
|
2830
|
+
"RECEIVE_BOOT_COMPLETED",
|
|
2831
|
+
"SYSTEM_ALERT_WINDOW",
|
|
2832
|
+
"PACKAGE_USAGE_STATS",
|
|
2833
|
+
"MANAGE_APP_OPS_MODES",
|
|
2834
|
+
"BIND_DEVICE_ADMIN",
|
|
2835
|
+
];
|
|
2836
|
+
|
|
2837
|
+
// Java sources removed from the merged sources tree so they don't
|
|
2838
|
+
// reference manifest-stripped classes and break compilation.
|
|
2839
|
+
const ANDROID_CLOUD_STRIPPED_JAVA_FILES = [
|
|
2840
|
+
"ElizaAgentService.java",
|
|
2841
|
+
"ElizaAssistActivity.java",
|
|
2842
|
+
"ElizaBootReceiver.java",
|
|
2843
|
+
"ElizaBrowserActivity.java",
|
|
2844
|
+
"ElizaCalendarActivity.java",
|
|
2845
|
+
"ElizaCameraActivity.java",
|
|
2846
|
+
"ElizaClockActivity.java",
|
|
2847
|
+
"ElizaContactsActivity.java",
|
|
2848
|
+
"ElizaDialActivity.java",
|
|
2849
|
+
"ElizaInCallService.java",
|
|
2850
|
+
"ElizaMmsReceiver.java",
|
|
2851
|
+
"ElizaRespondViaMessageService.java",
|
|
2852
|
+
"ElizaSmsComposeActivity.java",
|
|
2853
|
+
"ElizaSmsReceiver.java",
|
|
2854
|
+
];
|
|
2855
|
+
|
|
2856
|
+
/**
|
|
2857
|
+
* Strip the Play-Store-noncompliant manifest components, permissions, and
|
|
2858
|
+
* Java sources, plus any previously-staged on-device agent runtime
|
|
2859
|
+
* artifacts (assets/agent + jniLibs/libeliza_*.so), from a freshly
|
|
2860
|
+
* overlaid Android project.
|
|
2861
|
+
*
|
|
2862
|
+
* Idempotent: safe to re-run on an already-stripped tree.
|
|
2863
|
+
*/
|
|
2864
|
+
function stripAndroidForCloud() {
|
|
2865
|
+
const androidPackage = APP.appId;
|
|
2866
|
+
|
|
2867
|
+
// 1. Strip manifest components, permissions, and BootReceiver/SMS/etc.
|
|
2868
|
+
const manifestPath = path.join(
|
|
2869
|
+
androidDir,
|
|
2870
|
+
"app",
|
|
2871
|
+
"src",
|
|
2872
|
+
"main",
|
|
2873
|
+
"AndroidManifest.xml",
|
|
2874
|
+
);
|
|
2875
|
+
if (fs.existsSync(manifestPath)) {
|
|
2876
|
+
let xml = fs.readFileSync(manifestPath, "utf8");
|
|
2877
|
+
const original = xml;
|
|
2878
|
+
|
|
2879
|
+
for (const component of ANDROID_CLOUD_STRIPPED_COMPONENTS) {
|
|
2880
|
+
xml = removeApplicationComponentBlock(
|
|
2881
|
+
xml,
|
|
2882
|
+
`${androidPackage}.${component}`,
|
|
2883
|
+
);
|
|
2884
|
+
xml = removeApplicationComponentClassBlock(xml, component);
|
|
2885
|
+
}
|
|
2886
|
+
|
|
2887
|
+
for (const perm of ANDROID_CLOUD_STRIPPED_PERMISSIONS) {
|
|
2888
|
+
const escaped = escapeRegExp(`android.permission.${perm}`);
|
|
2889
|
+
const re = new RegExp(
|
|
2890
|
+
`\\n\\s*<uses-permission\\b[^>]*android:name="${escaped}"[^>]*/>\\s*`,
|
|
2891
|
+
"g",
|
|
2892
|
+
);
|
|
2893
|
+
xml = xml.replace(re, "\n");
|
|
2894
|
+
}
|
|
2895
|
+
|
|
2896
|
+
if (xml !== original) {
|
|
2897
|
+
fs.writeFileSync(manifestPath, xml, "utf8");
|
|
2898
|
+
console.log(
|
|
2899
|
+
"[mobile-build] Stripped Play-Store-noncompliant components and permissions from AndroidManifest.xml.",
|
|
2900
|
+
);
|
|
2901
|
+
}
|
|
2902
|
+
}
|
|
2903
|
+
|
|
2904
|
+
// 2. Remove the matching Java sources so the build doesn't reference
|
|
2905
|
+
// manifest-stripped classes. The merged sources live under
|
|
2906
|
+
// app/src/main/java/<package-path>/, and overlayAndroid() may also
|
|
2907
|
+
// have left a legacy ai/elizaos/app copy if the Java rename ran on a
|
|
2908
|
+
// fresh tree — wipe both.
|
|
2909
|
+
const javaRoots = [
|
|
2910
|
+
path.join(
|
|
2911
|
+
androidDir,
|
|
2912
|
+
"app",
|
|
2913
|
+
"src",
|
|
2914
|
+
"main",
|
|
2915
|
+
"java",
|
|
2916
|
+
packageNameToPath(androidPackage),
|
|
2917
|
+
),
|
|
2918
|
+
path.join(androidDir, "app", "src", "main", "java", "ai", "elizaos", "app"),
|
|
2919
|
+
];
|
|
2920
|
+
let removedJavaCount = 0;
|
|
2921
|
+
for (const root of javaRoots) {
|
|
2922
|
+
if (!fs.existsSync(root)) continue;
|
|
2923
|
+
for (const file of ANDROID_CLOUD_STRIPPED_JAVA_FILES) {
|
|
2924
|
+
const target = path.join(root, file);
|
|
2925
|
+
if (fs.existsSync(target)) {
|
|
2926
|
+
fs.rmSync(target);
|
|
2927
|
+
removedJavaCount += 1;
|
|
2928
|
+
}
|
|
2929
|
+
}
|
|
2930
|
+
}
|
|
2931
|
+
if (removedJavaCount > 0) {
|
|
2932
|
+
console.log(
|
|
2933
|
+
`[mobile-build] Removed ${removedJavaCount} Play-Store-noncompliant Java source(s).`,
|
|
2934
|
+
);
|
|
2935
|
+
}
|
|
2936
|
+
|
|
2937
|
+
// 3. Wipe any previously-staged on-device agent runtime. These are
|
|
2938
|
+
// build artifacts (.gitignore covers them) — the cloud APK must not
|
|
2939
|
+
// embed bun, musl, libstdc++, libgcc, llama-server, or the
|
|
2940
|
+
// libeliza_*.so jniLibs disguise.
|
|
2941
|
+
const stagedAgentAssets = path.join(
|
|
2942
|
+
androidDir,
|
|
2943
|
+
"app",
|
|
2944
|
+
"src",
|
|
2945
|
+
"main",
|
|
2946
|
+
"assets",
|
|
2947
|
+
"agent",
|
|
2948
|
+
);
|
|
2949
|
+
if (fs.existsSync(stagedAgentAssets)) {
|
|
2950
|
+
fs.rmSync(stagedAgentAssets, { recursive: true, force: true });
|
|
2951
|
+
console.log(
|
|
2952
|
+
"[mobile-build] Removed staged on-device agent runtime under assets/agent/.",
|
|
2953
|
+
);
|
|
2954
|
+
}
|
|
2955
|
+
|
|
2956
|
+
const stagedJniLibs = path.join(androidDir, "app", "src", "main", "jniLibs");
|
|
2957
|
+
if (fs.existsSync(stagedJniLibs)) {
|
|
2958
|
+
let libelizaCount = 0;
|
|
2959
|
+
for (const abi of fs.readdirSync(stagedJniLibs)) {
|
|
2960
|
+
const abiDir = path.join(stagedJniLibs, abi);
|
|
2961
|
+
const stat = fs.statSync(abiDir);
|
|
2962
|
+
if (!stat.isDirectory()) continue;
|
|
2963
|
+
for (const lib of fs.readdirSync(abiDir)) {
|
|
2964
|
+
if (lib.startsWith("libeliza_") || lib === "libsigsys-handler.so") {
|
|
2965
|
+
fs.rmSync(path.join(abiDir, lib));
|
|
2966
|
+
libelizaCount += 1;
|
|
2967
|
+
}
|
|
2968
|
+
}
|
|
2969
|
+
}
|
|
2970
|
+
if (libelizaCount > 0) {
|
|
2971
|
+
console.log(
|
|
2972
|
+
`[mobile-build] Removed ${libelizaCount} disguised native runtime library(s) from jniLibs/.`,
|
|
2973
|
+
);
|
|
2974
|
+
}
|
|
2975
|
+
}
|
|
2976
|
+
}
|
|
2977
|
+
|
|
2978
|
+
async function buildAndroid() {
|
|
2979
|
+
const sdk = resolveAndroidSdkRoot();
|
|
2980
|
+
const jdk = resolveJavaHome();
|
|
2981
|
+
if (!sdk)
|
|
2982
|
+
throw new Error(
|
|
2983
|
+
"Android SDK not found. Set ANDROID_SDK_ROOT or ANDROID_HOME.",
|
|
2984
|
+
);
|
|
2985
|
+
if (!jdk) throw new Error("JDK 21 not found. Set JAVA_HOME.");
|
|
2986
|
+
|
|
2987
|
+
console.warn(
|
|
2988
|
+
"[mobile-build] WARNING: target `android` produces an APK that embeds " +
|
|
2989
|
+
"the on-device agent runtime (libeliza_bun.so disguise) and requests " +
|
|
2990
|
+
"system-only permissions (MANAGE_APP_OPS_MODES, PACKAGE_USAGE_STATS). " +
|
|
2991
|
+
"It is SIDELOAD-ONLY and will be rejected by the Play Store. Use " +
|
|
2992
|
+
"`build:android:cloud` for a Play-Store-compliant thin client, or " +
|
|
2993
|
+
"`build:android:system` for the AOSP privileged platform-signed APK.",
|
|
2994
|
+
);
|
|
2995
|
+
|
|
2996
|
+
await buildWeb("android");
|
|
2997
|
+
await ensurePlatform("android");
|
|
2998
|
+
await runCapacitor(["sync", "android"]);
|
|
2999
|
+
|
|
3000
|
+
patchAndroidGradle();
|
|
3001
|
+
await generateAndroidBrandAssets();
|
|
3002
|
+
overlayAndroid();
|
|
3003
|
+
sanitizeAndroidManifestWhenPlatformTemplatesMissing();
|
|
3004
|
+
await stageAndroidAgentRuntime({
|
|
3005
|
+
androidDir,
|
|
3006
|
+
spikeDir: androidAgentSpikeDir,
|
|
3007
|
+
});
|
|
3008
|
+
|
|
3009
|
+
const env = {
|
|
3010
|
+
...process.env,
|
|
3011
|
+
ANDROID_HOME: sdk,
|
|
3012
|
+
ANDROID_SDK_ROOT: sdk,
|
|
3013
|
+
JAVA_HOME: jdk,
|
|
3014
|
+
PATH: prependPath(process.env, [
|
|
3015
|
+
path.join(jdk, "bin"),
|
|
3016
|
+
path.join(sdk, "platform-tools"),
|
|
3017
|
+
]),
|
|
3018
|
+
};
|
|
3019
|
+
|
|
3020
|
+
// Mirror the AOSP gradle property forwarding from buildAndroidSystem so
|
|
3021
|
+
// a developer iterating with `bun run build:android` under ELIZA_AOSP_BUILD=1
|
|
3022
|
+
// gets BuildConfig.AOSP_BUILD=true in the debug APK as well.
|
|
3023
|
+
const settingsGradle = fs.readFileSync(
|
|
3024
|
+
path.join(androidDir, "capacitor.settings.gradle"),
|
|
3025
|
+
"utf8",
|
|
3026
|
+
);
|
|
3027
|
+
const gradleArgs = [];
|
|
3028
|
+
if (settingsGradle.includes(":elizaos-capacitor-websiteblocker")) {
|
|
3029
|
+
gradleArgs.push(":elizaos-capacitor-websiteblocker:testDebugUnitTest");
|
|
3030
|
+
}
|
|
3031
|
+
gradleArgs.push(":app:assembleDebug");
|
|
3032
|
+
if (
|
|
3033
|
+
process.env.ELIZA_GRADLE_AOSP_BUILD === "true" ||
|
|
3034
|
+
process.env.ELIZA_GRADLE_AOSP_BUILD === "1"
|
|
3035
|
+
) {
|
|
3036
|
+
gradleArgs.unshift("-PelizaAospBuild=true");
|
|
3037
|
+
}
|
|
3038
|
+
await run(
|
|
3039
|
+
"./gradlew",
|
|
3040
|
+
[":capacitor-cordova-android-plugins:writeDebugAarMetadata"],
|
|
3041
|
+
{
|
|
3042
|
+
cwd: androidDir,
|
|
3043
|
+
env,
|
|
3044
|
+
},
|
|
3045
|
+
);
|
|
3046
|
+
await run("./gradlew", gradleArgs, {
|
|
3047
|
+
cwd: androidDir,
|
|
3048
|
+
env,
|
|
3049
|
+
});
|
|
3050
|
+
}
|
|
3051
|
+
|
|
3052
|
+
async function buildAndroidCloud() {
|
|
3053
|
+
const sdk = resolveAndroidSdkRoot();
|
|
3054
|
+
const jdk = resolveJavaHome();
|
|
3055
|
+
if (!sdk)
|
|
3056
|
+
throw new Error(
|
|
3057
|
+
"Android SDK not found. Set ANDROID_SDK_ROOT or ANDROID_HOME.",
|
|
3058
|
+
);
|
|
3059
|
+
if (!jdk) throw new Error("JDK 21 not found. Set JAVA_HOME.");
|
|
3060
|
+
|
|
3061
|
+
await buildWeb("android-cloud");
|
|
3062
|
+
await ensurePlatform("android");
|
|
3063
|
+
await runCapacitor(["sync", "android"]);
|
|
3064
|
+
|
|
3065
|
+
patchAndroidGradle();
|
|
3066
|
+
await generateAndroidBrandAssets();
|
|
3067
|
+
overlayAndroid();
|
|
3068
|
+
sanitizeAndroidManifestWhenPlatformTemplatesMissing();
|
|
3069
|
+
// The cloud target is a thin Capacitor client backed by Eliza Cloud.
|
|
3070
|
+
// It must NOT embed the on-device agent runtime, NOT declare default
|
|
3071
|
+
// role activities (dialer, SMS, browser, contacts, camera, calendar,
|
|
3072
|
+
// clock, assistant, in-call), NOT register a BootReceiver, and NOT
|
|
3073
|
+
// request system-only permissions (MANAGE_APP_OPS_MODES,
|
|
3074
|
+
// PACKAGE_USAGE_STATS) or sensitive runtime permissions
|
|
3075
|
+
// (READ/SEND/RECEIVE_SMS, CALL_PHONE, ACCESS_BACKGROUND_LOCATION).
|
|
3076
|
+
// overlayAndroid() injects all of these unconditionally; we strip them
|
|
3077
|
+
// here as a post-overlay pass so the merge logic remains a single
|
|
3078
|
+
// source of truth across all three Android targets.
|
|
3079
|
+
stripAndroidForCloud();
|
|
3080
|
+
|
|
3081
|
+
const env = {
|
|
3082
|
+
...process.env,
|
|
3083
|
+
ANDROID_HOME: sdk,
|
|
3084
|
+
ANDROID_SDK_ROOT: sdk,
|
|
3085
|
+
JAVA_HOME: jdk,
|
|
3086
|
+
PATH: prependPath(process.env, [
|
|
3087
|
+
path.join(jdk, "bin"),
|
|
3088
|
+
path.join(sdk, "platform-tools"),
|
|
3089
|
+
]),
|
|
3090
|
+
};
|
|
3091
|
+
|
|
3092
|
+
// The Play-Store target intentionally builds without `-PelizaAospBuild`,
|
|
3093
|
+
// so BuildConfig.AOSP_BUILD = false at runtime — ElizaAgentService is
|
|
3094
|
+
// already stripped from the manifest and the related `assets/agent/`
|
|
3095
|
+
// tree is gone, but turning off the AOSP gradle flag also drops any
|
|
3096
|
+
// Soong/AOSP-only resource paths from the APK.
|
|
3097
|
+
const settingsGradle = fs.readFileSync(
|
|
3098
|
+
path.join(androidDir, "capacitor.settings.gradle"),
|
|
3099
|
+
"utf8",
|
|
3100
|
+
);
|
|
3101
|
+
const gradleArgs = [];
|
|
3102
|
+
if (settingsGradle.includes(":elizaos-capacitor-websiteblocker")) {
|
|
3103
|
+
gradleArgs.push(":elizaos-capacitor-websiteblocker:testDebugUnitTest");
|
|
3104
|
+
}
|
|
3105
|
+
gradleArgs.push(":app:assembleDebug");
|
|
3106
|
+
await run(
|
|
3107
|
+
"./gradlew",
|
|
3108
|
+
[":capacitor-cordova-android-plugins:writeDebugAarMetadata"],
|
|
3109
|
+
{
|
|
3110
|
+
cwd: androidDir,
|
|
3111
|
+
env,
|
|
3112
|
+
},
|
|
3113
|
+
);
|
|
3114
|
+
await run("./gradlew", gradleArgs, {
|
|
3115
|
+
cwd: androidDir,
|
|
3116
|
+
env,
|
|
3117
|
+
});
|
|
3118
|
+
}
|
|
3119
|
+
|
|
3120
|
+
function findAndroidSystemApk() {
|
|
3121
|
+
// Release-only. Staging a debug APK ships without R8 shrinking and
|
|
3122
|
+
// bypasses the release signing config — both invariants the AOSP
|
|
3123
|
+
// prebuilt path assumes hold. Soong re-signs with the platform key
|
|
3124
|
+
// either way, so a debug fallback is never an acceptable substitute.
|
|
3125
|
+
const candidates = [
|
|
3126
|
+
path.join(
|
|
3127
|
+
androidDir,
|
|
3128
|
+
"app",
|
|
3129
|
+
"build",
|
|
3130
|
+
"outputs",
|
|
3131
|
+
"apk",
|
|
3132
|
+
"release",
|
|
3133
|
+
"app-release-unsigned.apk",
|
|
3134
|
+
),
|
|
3135
|
+
path.join(
|
|
3136
|
+
androidDir,
|
|
3137
|
+
"app",
|
|
3138
|
+
"build",
|
|
3139
|
+
"outputs",
|
|
3140
|
+
"apk",
|
|
3141
|
+
"release",
|
|
3142
|
+
"app-release.apk",
|
|
3143
|
+
),
|
|
3144
|
+
];
|
|
3145
|
+
return firstExisting(candidates);
|
|
3146
|
+
}
|
|
3147
|
+
|
|
3148
|
+
function stageAndroidSystemApk() {
|
|
3149
|
+
const apk = findAndroidSystemApk();
|
|
3150
|
+
if (!apk) {
|
|
3151
|
+
throw new Error(
|
|
3152
|
+
"No release APK found at app/build/outputs/apk/release/. Run :app:assembleRelease before staging the ElizaOS prebuilt — debug APKs are not accepted.",
|
|
3153
|
+
);
|
|
3154
|
+
}
|
|
3155
|
+
fs.mkdirSync(elizaOsApkDir, { recursive: true });
|
|
3156
|
+
const target = path.join(elizaOsApkDir, elizaOsApkName);
|
|
3157
|
+
fs.copyFileSync(apk, target);
|
|
3158
|
+
console.log(`[mobile-build] Staged ${elizaOsApkName} at ${target}.`);
|
|
3159
|
+
}
|
|
3160
|
+
|
|
3161
|
+
async function buildAndroidSystem() {
|
|
3162
|
+
const sdk = resolveAndroidSdkRoot();
|
|
3163
|
+
const jdk = resolveJavaHome();
|
|
3164
|
+
if (!sdk)
|
|
3165
|
+
throw new Error(
|
|
3166
|
+
"Android SDK not found. Set ANDROID_SDK_ROOT or ANDROID_HOME.",
|
|
3167
|
+
);
|
|
3168
|
+
if (!jdk) throw new Error("JDK 21 not found. Set JAVA_HOME.");
|
|
3169
|
+
|
|
3170
|
+
await buildWeb("android-system");
|
|
3171
|
+
await ensurePlatform("android");
|
|
3172
|
+
await runCapacitor(["sync", "android"]);
|
|
3173
|
+
|
|
3174
|
+
patchAndroidGradle();
|
|
3175
|
+
await generateAndroidBrandAssets();
|
|
3176
|
+
overlayAndroid();
|
|
3177
|
+
sanitizeAndroidManifestWhenPlatformTemplatesMissing();
|
|
3178
|
+
await stageAndroidAgentRuntime({
|
|
3179
|
+
androidDir,
|
|
3180
|
+
spikeDir: androidAgentSpikeDir,
|
|
3181
|
+
});
|
|
3182
|
+
|
|
3183
|
+
const env = {
|
|
3184
|
+
...process.env,
|
|
3185
|
+
ANDROID_HOME: sdk,
|
|
3186
|
+
ANDROID_SDK_ROOT: sdk,
|
|
3187
|
+
JAVA_HOME: jdk,
|
|
3188
|
+
PATH: prependPath(process.env, [
|
|
3189
|
+
path.join(jdk, "bin"),
|
|
3190
|
+
path.join(sdk, "platform-tools"),
|
|
3191
|
+
]),
|
|
3192
|
+
};
|
|
3193
|
+
|
|
3194
|
+
// This target always produces the privileged AOSP APK, so bake the local
|
|
3195
|
+
// agent flag into BuildConfig and preserve assets/agent. The regular
|
|
3196
|
+
// Capacitor target leaves this property unset and strips those assets.
|
|
3197
|
+
const gradleArgs = ["-PelizaAospBuild=true", ":app:assembleRelease"];
|
|
3198
|
+
await run(
|
|
3199
|
+
"./gradlew",
|
|
3200
|
+
[":capacitor-cordova-android-plugins:writeReleaseAarMetadata"],
|
|
3201
|
+
{
|
|
3202
|
+
cwd: androidDir,
|
|
3203
|
+
env,
|
|
3204
|
+
},
|
|
3205
|
+
);
|
|
3206
|
+
await run("./gradlew", gradleArgs, {
|
|
3207
|
+
cwd: androidDir,
|
|
3208
|
+
env,
|
|
3209
|
+
});
|
|
3210
|
+
stageAndroidSystemApk();
|
|
3211
|
+
}
|
|
3212
|
+
|
|
3213
|
+
async function buildIos() {
|
|
3214
|
+
if (process.platform !== "darwin")
|
|
3215
|
+
throw new Error("iOS builds require macOS and Xcode.");
|
|
3216
|
+
|
|
3217
|
+
const cocoapodsScript = path.join(
|
|
3218
|
+
appCoreRoot,
|
|
3219
|
+
"scripts",
|
|
3220
|
+
"prepare-ios-cocoapods.sh",
|
|
3221
|
+
);
|
|
3222
|
+
|
|
3223
|
+
await buildWeb("ios");
|
|
3224
|
+
await ensurePlatform("ios");
|
|
3225
|
+
if (fs.existsSync(cocoapodsScript)) {
|
|
3226
|
+
await run("bash", [cocoapodsScript], { cwd: repoRoot });
|
|
3227
|
+
}
|
|
3228
|
+
await runCapacitor(["sync", "ios"]);
|
|
3229
|
+
|
|
3230
|
+
const buildTarget = resolveIosBuildTarget();
|
|
3231
|
+
console.log(
|
|
3232
|
+
`[mobile-build] iOS build target: ${buildTarget.destination} (${buildTarget.sdk}; ${buildTarget.reason})`,
|
|
3233
|
+
);
|
|
3234
|
+
const syncedFiles = prepareIosOverlay({ buildTarget });
|
|
3235
|
+
await generateIosBrandAssets();
|
|
3236
|
+
await ensureIosLlamaCppVendoredFramework({ buildTarget });
|
|
3237
|
+
|
|
3238
|
+
// CocoaPods compiles Capacitor from source, avoiding SPM binary API issues
|
|
3239
|
+
if (
|
|
3240
|
+
fs.existsSync(path.join(iosDir, "Podfile")) ||
|
|
3241
|
+
shouldRunIosPodInstall(syncedFiles)
|
|
3242
|
+
) {
|
|
3243
|
+
await run("pod", ["install"], { cwd: iosDir });
|
|
3244
|
+
}
|
|
3245
|
+
|
|
3246
|
+
const wsPath = path.join(iosDir, "App.xcworkspace");
|
|
3247
|
+
const projectArgs = fs.existsSync(wsPath)
|
|
3248
|
+
? ["-workspace", "App.xcworkspace"]
|
|
3249
|
+
: ["-project", "App.xcodeproj"];
|
|
3250
|
+
await run(
|
|
3251
|
+
"xcodebuild",
|
|
3252
|
+
[
|
|
3253
|
+
...projectArgs,
|
|
3254
|
+
"-scheme",
|
|
3255
|
+
"App",
|
|
3256
|
+
"-configuration",
|
|
3257
|
+
"Debug",
|
|
3258
|
+
"-destination",
|
|
3259
|
+
buildTarget.destination,
|
|
3260
|
+
"-sdk",
|
|
3261
|
+
buildTarget.sdk,
|
|
3262
|
+
"CODE_SIGNING_ALLOWED=NO",
|
|
3263
|
+
...(isIosSimulatorBuildTarget(buildTarget)
|
|
3264
|
+
? ["ARCHS=arm64", "ONLY_ACTIVE_ARCH=YES", "EXCLUDED_ARCHS=x86_64"]
|
|
3265
|
+
: []),
|
|
3266
|
+
"build",
|
|
3267
|
+
],
|
|
3268
|
+
{ cwd: iosDir },
|
|
3269
|
+
);
|
|
3270
|
+
}
|
|
3271
|
+
|
|
3272
|
+
// ── Entry point ─────────────────────────────────────────────────────────
|
|
3273
|
+
|
|
3274
|
+
export async function main(argv = process.argv.slice(2)) {
|
|
3275
|
+
const target = argv[0];
|
|
3276
|
+
if (
|
|
3277
|
+
target !== "android" &&
|
|
3278
|
+
target !== "android-cloud" &&
|
|
3279
|
+
target !== "android-system" &&
|
|
3280
|
+
target !== "ios" &&
|
|
3281
|
+
target !== "ios-overlay"
|
|
3282
|
+
) {
|
|
3283
|
+
console.error(
|
|
3284
|
+
"Usage: node scripts/run-mobile-build.mjs <android|android-cloud|android-system|ios|ios-overlay>",
|
|
3285
|
+
);
|
|
3286
|
+
process.exit(1);
|
|
3287
|
+
}
|
|
3288
|
+
if (target === "android") {
|
|
3289
|
+
await buildAndroid();
|
|
3290
|
+
} else if (target === "android-cloud") {
|
|
3291
|
+
await buildAndroidCloud();
|
|
3292
|
+
} else if (target === "android-system") {
|
|
3293
|
+
await buildAndroidSystem();
|
|
3294
|
+
} else if (target === "ios") {
|
|
3295
|
+
await buildIos();
|
|
3296
|
+
} else {
|
|
3297
|
+
prepareIosOverlay();
|
|
3298
|
+
await generateIosBrandAssets();
|
|
3299
|
+
}
|
|
3300
|
+
}
|
|
3301
|
+
|
|
3302
|
+
const isMain =
|
|
3303
|
+
process.argv[1] &&
|
|
3304
|
+
path.resolve(process.argv[1]) === fileURLToPath(import.meta.url);
|
|
3305
|
+
|
|
3306
|
+
if (isMain) {
|
|
3307
|
+
await main();
|
|
3308
|
+
}
|