@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,2510 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import { createServer as createNetServer } from "node:net";
|
|
3
|
+
import os from "node:os";
|
|
4
|
+
import path from "node:path";
|
|
5
|
+
import { resolveApiToken, resolveDesktopApiPort } from "@elizaos/shared";
|
|
6
|
+
import Electrobun, {
|
|
7
|
+
ApplicationMenu,
|
|
8
|
+
BrowserView,
|
|
9
|
+
BrowserWindow,
|
|
10
|
+
BuildConfig,
|
|
11
|
+
Updater,
|
|
12
|
+
Utils,
|
|
13
|
+
WGPU,
|
|
14
|
+
webgpu,
|
|
15
|
+
} from "electrobun/bun";
|
|
16
|
+
import {
|
|
17
|
+
resolveDesktopRuntimeMode,
|
|
18
|
+
resolveInitialApiBase,
|
|
19
|
+
resolveRendererFacingApiBase,
|
|
20
|
+
} from "./api-base";
|
|
21
|
+
import {
|
|
22
|
+
buildApplicationMenu,
|
|
23
|
+
findAppMenuEntryBySlug,
|
|
24
|
+
getAppMenuEntries,
|
|
25
|
+
parseSettingsWindowAction,
|
|
26
|
+
} from "./application-menu";
|
|
27
|
+
import { setApplicationMenuActionHandler } from "./application-menu-action-registry";
|
|
28
|
+
import { showBackgroundNoticeOnce } from "./background-notice";
|
|
29
|
+
import { getBrandConfig } from "./brand-config";
|
|
30
|
+
import { startBrowserWorkspaceBridgeServer } from "./browser-workspace-bridge-server";
|
|
31
|
+
import { readNavigationEventUrl } from "./cloud-auth-window";
|
|
32
|
+
import { startDesktopTestBridgeServer } from "./desktop-test-bridge-server";
|
|
33
|
+
import { scheduleDevtoolsLayoutRefresh } from "./devtools-layout";
|
|
34
|
+
import { getFloatingChatManager } from "./floating-chat-window";
|
|
35
|
+
import * as apiBaseOwner from "./lifecycle/api-base-owner";
|
|
36
|
+
import {
|
|
37
|
+
markDesktopSessionStale,
|
|
38
|
+
primeDesktopSessionAuth,
|
|
39
|
+
} from "./lifecycle/desktop-session-prime";
|
|
40
|
+
import { logger } from "./logger";
|
|
41
|
+
import {
|
|
42
|
+
resolveBootstrapShellRenderer,
|
|
43
|
+
resolveBootstrapViewRenderer,
|
|
44
|
+
resolveMainWindowPartition,
|
|
45
|
+
shouldForceMainWindowCef,
|
|
46
|
+
} from "./main-window-session";
|
|
47
|
+
import {
|
|
48
|
+
buildMainMenuResetApiCandidates,
|
|
49
|
+
pickReachableMenuResetApiBase,
|
|
50
|
+
runMainMenuResetAfterApiBaseResolved,
|
|
51
|
+
} from "./menu-reset-from-main";
|
|
52
|
+
import {
|
|
53
|
+
configureDesktopLocalApiAuth,
|
|
54
|
+
getAgentManager,
|
|
55
|
+
getDiagnosticLogPath,
|
|
56
|
+
getStartupDiagnosticLogTail,
|
|
57
|
+
getStartupDiagnosticsSnapshot,
|
|
58
|
+
getStartupStatusPath,
|
|
59
|
+
} from "./native/agent";
|
|
60
|
+
import { getDesktopManager } from "./native/desktop";
|
|
61
|
+
import { disposeNativeModules, initializeNativeModules } from "./native/index";
|
|
62
|
+
import {
|
|
63
|
+
enableVibrancy,
|
|
64
|
+
ensureShadow,
|
|
65
|
+
setNativeDragRegion,
|
|
66
|
+
setTrafficLightsPosition,
|
|
67
|
+
} from "./native/mac-window-effects";
|
|
68
|
+
import { getPermissionManager } from "./native/permissions";
|
|
69
|
+
import { checkWebGpuSupport } from "./native/webgpu-browser-support";
|
|
70
|
+
import { printElectrobunDevSettingsBanner } from "./print-electrobun-dev-settings-banner";
|
|
71
|
+
import { resolveRendererAsset } from "./renderer-static";
|
|
72
|
+
import {
|
|
73
|
+
buildBunRpcHandlers,
|
|
74
|
+
wireBrowserWorkspaceCaller,
|
|
75
|
+
} from "./rpc-handlers";
|
|
76
|
+
import type { ElizaDesktopRPCSchema } from "./rpc-schema";
|
|
77
|
+
import {
|
|
78
|
+
readResolvedPreloadScript,
|
|
79
|
+
resolveRendererAssetDir,
|
|
80
|
+
} from "./runtime-layout";
|
|
81
|
+
import { mergeRuntimePermissionStates } from "./runtime-permissions";
|
|
82
|
+
import { startScreenshotDevServer } from "./screenshot-dev-server";
|
|
83
|
+
import { recordStartupPhase, resolveStartupBundlePath } from "./startup-trace";
|
|
84
|
+
import {
|
|
85
|
+
type BoundsStore,
|
|
86
|
+
isDetachedSurface,
|
|
87
|
+
type ManagedWindowFrame,
|
|
88
|
+
type ManagedWindowLike,
|
|
89
|
+
SurfaceWindowManager,
|
|
90
|
+
} from "./surface-windows";
|
|
91
|
+
import type { SendToWebview } from "./types.js";
|
|
92
|
+
import {
|
|
93
|
+
resolveDesktopBundleVersion,
|
|
94
|
+
shouldResetWindowsCefProfile,
|
|
95
|
+
shouldWriteWindowsCefProfileMarker,
|
|
96
|
+
} from "./windows-cef-profile";
|
|
97
|
+
|
|
98
|
+
const BRAND = getBrandConfig();
|
|
99
|
+
const CONFIG_EXPORT_FILE_NAME = BRAND.configExportFileName;
|
|
100
|
+
const STARTUP_CRASH_REPORT_FILE = "startup-crash-report-latest.md";
|
|
101
|
+
const STARTUP_CRASH_PROMPT_MARKER_FILE = "startup-crash-last-prompted.txt";
|
|
102
|
+
|
|
103
|
+
import {
|
|
104
|
+
isAgentReady,
|
|
105
|
+
onAgentReadyChange,
|
|
106
|
+
setAgentReady,
|
|
107
|
+
} from "./agent-ready-state";
|
|
108
|
+
import {
|
|
109
|
+
clearCurrentMainWindow,
|
|
110
|
+
setCurrentMainWindow,
|
|
111
|
+
updateCurrentMainWindowEffectsState,
|
|
112
|
+
} from "./main-window-runtime";
|
|
113
|
+
import {
|
|
114
|
+
isStewardLocalEnabled,
|
|
115
|
+
onStewardStatusChange,
|
|
116
|
+
resetSteward,
|
|
117
|
+
restartSteward,
|
|
118
|
+
setStewardSendToWebview,
|
|
119
|
+
startSteward,
|
|
120
|
+
stopSteward,
|
|
121
|
+
} from "./native/steward";
|
|
122
|
+
|
|
123
|
+
function resolveDesktopAppIconPath(): string {
|
|
124
|
+
return path.join(
|
|
125
|
+
import.meta.dir,
|
|
126
|
+
process.platform === "win32"
|
|
127
|
+
? "../assets/appIcon.ico"
|
|
128
|
+
: "../assets/appIcon.png",
|
|
129
|
+
);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
function shouldUseBrowserDevtoolsFallback(): boolean {
|
|
133
|
+
return false;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
function setupApplicationMenu(): void {
|
|
137
|
+
const isMac = process.platform === "darwin";
|
|
138
|
+
const menu = buildApplicationMenu({
|
|
139
|
+
isMac,
|
|
140
|
+
browserEnabled: false,
|
|
141
|
+
detachedWindows: surfaceWindowManager?.listWindows() ?? [],
|
|
142
|
+
agentReady: isAgentReady(),
|
|
143
|
+
});
|
|
144
|
+
ApplicationMenu.setApplicationMenu(
|
|
145
|
+
menu as Parameters<typeof ApplicationMenu.setApplicationMenu>[0],
|
|
146
|
+
);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
onAgentReadyChange(() => setupApplicationMenu());
|
|
150
|
+
|
|
151
|
+
function summarizeDesktopActionError(error: unknown, fallback: string): string {
|
|
152
|
+
const message = error instanceof Error ? error.message : fallback;
|
|
153
|
+
const trimmed = message.trim();
|
|
154
|
+
if (!trimmed) return fallback;
|
|
155
|
+
return trimmed.length > 80 ? `${trimmed.slice(0, 77)}...` : trimmed;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
function buildApiRequestHeaders(contentType?: string): Record<string, string> {
|
|
159
|
+
const headers: Record<string, string> = {
|
|
160
|
+
Accept: "application/json",
|
|
161
|
+
};
|
|
162
|
+
if (contentType) {
|
|
163
|
+
headers["Content-Type"] = contentType;
|
|
164
|
+
}
|
|
165
|
+
let apiToken = resolveApiToken(process.env);
|
|
166
|
+
if (!apiToken) {
|
|
167
|
+
const rt = resolveDesktopRuntimeMode(
|
|
168
|
+
process.env as Record<string, string | undefined>,
|
|
169
|
+
);
|
|
170
|
+
if (rt.mode === "local") {
|
|
171
|
+
apiToken = configureDesktopLocalApiAuth().trim();
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
if (apiToken) {
|
|
175
|
+
headers.Authorization = `Bearer ${apiToken}`;
|
|
176
|
+
}
|
|
177
|
+
return headers;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
function resolveLoopbackApiBase(): string | null {
|
|
181
|
+
const port = getAgentManager().getStatus().port;
|
|
182
|
+
if (typeof port === "number" && port > 0) {
|
|
183
|
+
return `http://127.0.0.1:${port}`;
|
|
184
|
+
}
|
|
185
|
+
return resolveInitialApiBase(process.env);
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* Picks a loopback API base the main process can actually reach.
|
|
190
|
+
*
|
|
191
|
+
* **WHY:** `resolveLoopbackApiBase()` falls back to `resolveInitialApiBase`,
|
|
192
|
+
* which in **external** mode is `ELIZA_DESKTOP_API_BASE` (often :31337). If that
|
|
193
|
+
* dev server is down but the **embedded** agent is still running on a dynamic
|
|
194
|
+
* port, menu Reset must not blindly POST to the dead env URL.
|
|
195
|
+
*/
|
|
196
|
+
async function resolveReachableApiBaseForMainReset(): Promise<string | null> {
|
|
197
|
+
const candidates = buildMainMenuResetApiCandidates({
|
|
198
|
+
embeddedPort: getAgentManager().getStatus().port,
|
|
199
|
+
configuredBase: resolveInitialApiBase(process.env),
|
|
200
|
+
});
|
|
201
|
+
if (candidates.length === 0) {
|
|
202
|
+
return null;
|
|
203
|
+
}
|
|
204
|
+
const base = await pickReachableMenuResetApiBase({
|
|
205
|
+
candidates,
|
|
206
|
+
fetchImpl: fetch,
|
|
207
|
+
buildHeaders: buildApiRequestHeaders,
|
|
208
|
+
});
|
|
209
|
+
if (base) {
|
|
210
|
+
logger.info(
|
|
211
|
+
`[Main][reset] Using reachable API base ${base} (tried: ${candidates.join(", ")})`,
|
|
212
|
+
);
|
|
213
|
+
} else {
|
|
214
|
+
logger.warn(
|
|
215
|
+
`[Main][reset] No reachable API base among candidates (tried: ${candidates.join(", ")})`,
|
|
216
|
+
);
|
|
217
|
+
}
|
|
218
|
+
return base;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
/**
|
|
222
|
+
* App menu "Reset the app…" — confirm + HTTP reset + restart in the **main process**.
|
|
223
|
+
*
|
|
224
|
+
* **WHY not renderer `fetch`:** after native `showMessageBox`, WKWebView may not run
|
|
225
|
+
* network/bridge work on the same turn, so reset appeared hung. **WHY push
|
|
226
|
+
* `menu-reset-app-applied`:** renderer must still run the same local wipe as
|
|
227
|
+
* Settings (`completeResetLocalStateAfterServerWipe`); main only supplies a fresh
|
|
228
|
+
* `/api/status` snapshot as `agentStatus`. Orchestration core: `menu-reset-from-main.ts`.
|
|
229
|
+
*
|
|
230
|
+
* @see `docs/apps/desktop-main-process-reset.md`
|
|
231
|
+
*/
|
|
232
|
+
async function resetTheAppFromApplicationMenu(): Promise<void> {
|
|
233
|
+
logger.info(
|
|
234
|
+
`[Main][reset] App menu: Reset ${BRAND.appName} — confirm + POST /api/agent/reset + restart (main process)`,
|
|
235
|
+
);
|
|
236
|
+
await getDesktopManager()
|
|
237
|
+
.showWindow()
|
|
238
|
+
.catch((err: unknown) => {
|
|
239
|
+
logger.warn(
|
|
240
|
+
`[Main][reset] showWindow failed (continuing): ${err instanceof Error ? err.message : String(err)}`,
|
|
241
|
+
);
|
|
242
|
+
});
|
|
243
|
+
|
|
244
|
+
const autoConfirm =
|
|
245
|
+
process.env.ELIZA_DESKTOP_TEST_AUTO_CONFIRM_DIALOGS === "1" ||
|
|
246
|
+
process.env.ELIZA_DESKTOP_TEST_AUTO_CONFIRM_RESET === "1";
|
|
247
|
+
const response = autoConfirm
|
|
248
|
+
? 0
|
|
249
|
+
: await Utils.showMessageBox({
|
|
250
|
+
type: "warning",
|
|
251
|
+
title: "Reset Agent",
|
|
252
|
+
message:
|
|
253
|
+
"This will reset the agent: config, cloud keys, and local agent database (conversations / memory).",
|
|
254
|
+
detail:
|
|
255
|
+
"Downloaded GGUF embedding models are kept. You will return to the onboarding wizard.",
|
|
256
|
+
buttons: ["Reset", "Cancel"],
|
|
257
|
+
defaultId: 0,
|
|
258
|
+
cancelId: 1,
|
|
259
|
+
}).then((box) =>
|
|
260
|
+
box && typeof box === "object" && "response" in box
|
|
261
|
+
? (box as { response: number }).response
|
|
262
|
+
: typeof box === "number"
|
|
263
|
+
? box
|
|
264
|
+
: 1,
|
|
265
|
+
);
|
|
266
|
+
if (response !== 0) {
|
|
267
|
+
logger.info("[Main][reset] User cancelled native confirm");
|
|
268
|
+
return;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
const apiBase = await resolveReachableApiBaseForMainReset();
|
|
272
|
+
if (!apiBase) {
|
|
273
|
+
Utils.showNotification({
|
|
274
|
+
title: "Reset Failed",
|
|
275
|
+
body: `Could not reach the ${BRAND.appName} API (tried embedded port and ELIZA_DESKTOP_API_BASE / defaults). Start the agent or dev server, or fix your API base env.`,
|
|
276
|
+
});
|
|
277
|
+
return;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
try {
|
|
281
|
+
const runtimeMode = resolveDesktopRuntimeMode(
|
|
282
|
+
process.env as Record<string, string | undefined>,
|
|
283
|
+
);
|
|
284
|
+
|
|
285
|
+
await runMainMenuResetAfterApiBaseResolved({
|
|
286
|
+
apiBase,
|
|
287
|
+
fetchImpl: fetch,
|
|
288
|
+
buildHeaders: buildApiRequestHeaders,
|
|
289
|
+
useEmbeddedRestart: runtimeMode.mode === "local",
|
|
290
|
+
restartEmbeddedClearingLocalDb: async () => {
|
|
291
|
+
const status = await getAgentManager().restartClearingLocalDb();
|
|
292
|
+
return { port: status.port ?? undefined };
|
|
293
|
+
},
|
|
294
|
+
pushEmbeddedApiBaseToRenderer: (port, apiToken) => {
|
|
295
|
+
if (currentWindow) {
|
|
296
|
+
const base = port
|
|
297
|
+
? resolveRendererFacingApiBase(
|
|
298
|
+
process.env as Record<string, string | undefined>,
|
|
299
|
+
port,
|
|
300
|
+
)
|
|
301
|
+
: (resolveLoopbackApiBase() ??
|
|
302
|
+
resolveInitialApiBase(
|
|
303
|
+
process.env as Record<string, string | undefined>,
|
|
304
|
+
) ??
|
|
305
|
+
apiBase);
|
|
306
|
+
if (base) {
|
|
307
|
+
apiBaseOwner.notifyChange(currentWindow, base, apiToken);
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
},
|
|
311
|
+
getLocalApiAuthToken: () => configureDesktopLocalApiAuth(),
|
|
312
|
+
postExternalAgentRestart: async () => {
|
|
313
|
+
try {
|
|
314
|
+
await fetch(`${apiBase}/api/agent/restart`, {
|
|
315
|
+
method: "POST",
|
|
316
|
+
headers: buildApiRequestHeaders(),
|
|
317
|
+
});
|
|
318
|
+
} catch {
|
|
319
|
+
/* 409 / race while restarting — poll below */
|
|
320
|
+
}
|
|
321
|
+
},
|
|
322
|
+
resolveApiBaseForStatusPoll: () => resolveLoopbackApiBase() ?? apiBase,
|
|
323
|
+
sendMenuResetAppliedToRenderer: (payload) => {
|
|
324
|
+
sendToActiveRenderer("desktopTrayMenuClick", payload);
|
|
325
|
+
},
|
|
326
|
+
});
|
|
327
|
+
logger.info(
|
|
328
|
+
"[Main][reset] Pushed menu-reset-app-applied to renderer with /api/status snapshot",
|
|
329
|
+
);
|
|
330
|
+
} catch (err) {
|
|
331
|
+
logger.error(
|
|
332
|
+
`[Main][reset] Main-process reset failed: ${err instanceof Error ? err.message : String(err)}`,
|
|
333
|
+
);
|
|
334
|
+
Utils.showNotification({
|
|
335
|
+
title: "Reset Failed",
|
|
336
|
+
body: summarizeDesktopActionError(err, "Reset failed"),
|
|
337
|
+
});
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
const MAC_TRAFFIC_LIGHTS_X = 14;
|
|
342
|
+
const MAC_TRAFFIC_LIGHTS_Y = 12;
|
|
343
|
+
/** Left inset of the drag strip so it clears the traffic lights. */
|
|
344
|
+
const MAC_NATIVE_DRAG_REGION_X = 92;
|
|
345
|
+
/**
|
|
346
|
+
* Native titlebar drag height. The native layer keeps resize bands thin
|
|
347
|
+
* separately and only installs drag views in safe title/empty zones so
|
|
348
|
+
* titlebar buttons continue to receive clicks.
|
|
349
|
+
*/
|
|
350
|
+
const MAC_NATIVE_DRAG_REGION_HEIGHT = 38;
|
|
351
|
+
|
|
352
|
+
/**
|
|
353
|
+
* Vibrancy, shadow, traffic lights, and native chrome layout. Re-calls native
|
|
354
|
+
* layout whenever the window or webview subtree may have reordered so the drag
|
|
355
|
+
* view stays above WKWebView.
|
|
356
|
+
*/
|
|
357
|
+
function applyMacOSWindowEffects(win: BrowserWindow): void {
|
|
358
|
+
if (process.platform !== "darwin") return;
|
|
359
|
+
|
|
360
|
+
const ptr = (win as { ptr?: unknown }).ptr;
|
|
361
|
+
if (!ptr) {
|
|
362
|
+
logger.warn("[MacEffects] win.ptr unavailable — skipping native effects");
|
|
363
|
+
return;
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
const vibrancyEnabled = enableVibrancy(
|
|
367
|
+
ptr as Parameters<typeof enableVibrancy>[0],
|
|
368
|
+
);
|
|
369
|
+
const shadowEnabled = ensureShadow(ptr as Parameters<typeof ensureShadow>[0]);
|
|
370
|
+
updateCurrentMainWindowEffectsState({
|
|
371
|
+
vibrancyEnabled,
|
|
372
|
+
shadowEnabled,
|
|
373
|
+
});
|
|
374
|
+
|
|
375
|
+
const alignButtons = () =>
|
|
376
|
+
setTrafficLightsPosition(
|
|
377
|
+
ptr as Parameters<typeof setTrafficLightsPosition>[0],
|
|
378
|
+
MAC_TRAFFIC_LIGHTS_X,
|
|
379
|
+
MAC_TRAFFIC_LIGHTS_Y,
|
|
380
|
+
);
|
|
381
|
+
const alignDragRegion = () =>
|
|
382
|
+
setNativeDragRegion(
|
|
383
|
+
ptr as Parameters<typeof setNativeDragRegion>[0],
|
|
384
|
+
MAC_NATIVE_DRAG_REGION_X,
|
|
385
|
+
MAC_NATIVE_DRAG_REGION_HEIGHT,
|
|
386
|
+
);
|
|
387
|
+
|
|
388
|
+
const alignChrome = () => {
|
|
389
|
+
alignButtons();
|
|
390
|
+
alignDragRegion();
|
|
391
|
+
};
|
|
392
|
+
|
|
393
|
+
alignChrome();
|
|
394
|
+
setTimeout(alignChrome, 120);
|
|
395
|
+
const chromeRefreshTimer = setInterval(alignChrome, 1000);
|
|
396
|
+
|
|
397
|
+
win.on("resize", alignChrome);
|
|
398
|
+
win.on("focus", alignChrome);
|
|
399
|
+
win.on("blur", () => {
|
|
400
|
+
alignChrome();
|
|
401
|
+
setTimeout(alignChrome, 80);
|
|
402
|
+
setTimeout(alignChrome, 240);
|
|
403
|
+
setTimeout(alignChrome, 700);
|
|
404
|
+
});
|
|
405
|
+
// Display (NSScreen) changes without a resize edge case — depth uses window.screen.
|
|
406
|
+
win.on("move", alignChrome);
|
|
407
|
+
win.on("close", () => clearInterval(chromeRefreshTimer));
|
|
408
|
+
|
|
409
|
+
// WKWebView is often inserted or reordered after first layout; restack native
|
|
410
|
+
// views so drag/resize strips stay hit-testable above the page.
|
|
411
|
+
try {
|
|
412
|
+
win.webview.on("dom-ready", () => {
|
|
413
|
+
alignChrome();
|
|
414
|
+
setTimeout(alignChrome, 50);
|
|
415
|
+
setTimeout(alignChrome, 300);
|
|
416
|
+
});
|
|
417
|
+
} catch {
|
|
418
|
+
// webview may not accept listeners yet in some embed paths
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
interface WindowState {
|
|
423
|
+
x: number;
|
|
424
|
+
y: number;
|
|
425
|
+
width: number;
|
|
426
|
+
height: number;
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
/**
|
|
430
|
+
* Fresh-install default: a generous 1440x900 window centered-ish
|
|
431
|
+
* near the top-left of the primary display. Maximize-on-launch (see
|
|
432
|
+
* createMainWindow) then expands this to fill the screen on every
|
|
433
|
+
* boot, so this default only matters for brand-new installs on
|
|
434
|
+
* systems where maximize() hasn't registered yet.
|
|
435
|
+
*/
|
|
436
|
+
const DEFAULT_WINDOW_STATE: WindowState = {
|
|
437
|
+
x: 60,
|
|
438
|
+
y: 60,
|
|
439
|
+
width: 1440,
|
|
440
|
+
height: 900,
|
|
441
|
+
};
|
|
442
|
+
|
|
443
|
+
/**
|
|
444
|
+
* Marker value we stamp into the saved state when we'd like the next
|
|
445
|
+
* launch to open maximized. Kept as a synthetic "pending-maximize" flag
|
|
446
|
+
* rather than a real bool so it piggybacks on the existing
|
|
447
|
+
* width/height/x/y schema without a migration.
|
|
448
|
+
*/
|
|
449
|
+
const MAXIMIZE_ON_LAUNCH_SENTINEL = 1;
|
|
450
|
+
|
|
451
|
+
interface PersistedWindowState extends WindowState {
|
|
452
|
+
/** When truthy, call win.maximize() right after creation. */
|
|
453
|
+
shouldMaximize?: number;
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
function loadWindowState(statePath: string): PersistedWindowState {
|
|
457
|
+
try {
|
|
458
|
+
if (fs.existsSync(statePath)) {
|
|
459
|
+
const data = JSON.parse(fs.readFileSync(statePath, "utf8"));
|
|
460
|
+
if (typeof data.width === "number" && typeof data.height === "number") {
|
|
461
|
+
const state = { ...DEFAULT_WINDOW_STATE, ...data };
|
|
462
|
+
// Discard state saved while the window was minimized. On Windows,
|
|
463
|
+
// minimized windows report position (-32000, -32000) and a tiny
|
|
464
|
+
// size, which makes the window invisible on next launch.
|
|
465
|
+
if (state.width < 200 || state.height < 200 || state.x < -16000) {
|
|
466
|
+
return {
|
|
467
|
+
...DEFAULT_WINDOW_STATE,
|
|
468
|
+
shouldMaximize: MAXIMIZE_ON_LAUNCH_SENTINEL,
|
|
469
|
+
};
|
|
470
|
+
}
|
|
471
|
+
return state;
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
} catch {}
|
|
475
|
+
// No saved state → first launch. Open at the default 1440×900 window
|
|
476
|
+
// size (centered-ish near top-left) instead of maximizing. Maximizing on
|
|
477
|
+
// first launch buries the welcome content in a vast empty workspace and
|
|
478
|
+
// gives a "this is overwhelming" impression. The user can always
|
|
479
|
+
// maximize themselves; subsequent launches restore their last size.
|
|
480
|
+
return { ...DEFAULT_WINDOW_STATE };
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
let saveTimer: ReturnType<typeof setTimeout> | null = null;
|
|
484
|
+
|
|
485
|
+
function scheduleStateSave(statePath: string, win: BrowserWindow): void {
|
|
486
|
+
if (saveTimer) clearTimeout(saveTimer);
|
|
487
|
+
saveTimer = setTimeout(() => {
|
|
488
|
+
try {
|
|
489
|
+
const { x, y } = win.getPosition();
|
|
490
|
+
const { width, height } = win.getSize();
|
|
491
|
+
// Skip saving when the window is minimized — Windows reports
|
|
492
|
+
// position (-32000, -32000) and a collapsed size, which would make
|
|
493
|
+
// the window invisible on next launch.
|
|
494
|
+
if (width < 200 || height < 200 || x < -16000) return;
|
|
495
|
+
const dir = path.dirname(statePath);
|
|
496
|
+
if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
|
|
497
|
+
fs.writeFileSync(
|
|
498
|
+
statePath,
|
|
499
|
+
JSON.stringify({ x, y, width, height }),
|
|
500
|
+
"utf8",
|
|
501
|
+
);
|
|
502
|
+
} catch {}
|
|
503
|
+
}, 500);
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
/**
|
|
507
|
+
* Per-slug app-window bounds persistence. Survives across launches so an
|
|
508
|
+
* app re-opened later restores to the user's last position+size.
|
|
509
|
+
*
|
|
510
|
+
* **WHY a separate file from `window-state.json`**: the main window is
|
|
511
|
+
* singleton (one record); app windows are slug-keyed (one record per app).
|
|
512
|
+
* Mixing them would couple unrelated lifecycles.
|
|
513
|
+
*/
|
|
514
|
+
function createAppWindowBoundsStore(): BoundsStore {
|
|
515
|
+
const storePath = path.join(Utils.paths.userData, "app-window-bounds.json");
|
|
516
|
+
type Blob = Record<string, ManagedWindowFrame>;
|
|
517
|
+
let cache: Blob | null = null;
|
|
518
|
+
|
|
519
|
+
function isFrame(value: unknown): value is ManagedWindowFrame {
|
|
520
|
+
if (!value || typeof value !== "object") return false;
|
|
521
|
+
const f = value as Record<string, unknown>;
|
|
522
|
+
return (
|
|
523
|
+
typeof f.x === "number" &&
|
|
524
|
+
typeof f.y === "number" &&
|
|
525
|
+
typeof f.width === "number" &&
|
|
526
|
+
typeof f.height === "number" &&
|
|
527
|
+
f.width >= 200 &&
|
|
528
|
+
f.height >= 200 &&
|
|
529
|
+
f.x > -16000 &&
|
|
530
|
+
f.y > -16000
|
|
531
|
+
);
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
function readCache(): Blob {
|
|
535
|
+
if (cache) return cache;
|
|
536
|
+
try {
|
|
537
|
+
if (fs.existsSync(storePath)) {
|
|
538
|
+
const raw = JSON.parse(fs.readFileSync(storePath, "utf8")) as unknown;
|
|
539
|
+
if (raw && typeof raw === "object") {
|
|
540
|
+
const next: Blob = {};
|
|
541
|
+
for (const [slug, frame] of Object.entries(raw)) {
|
|
542
|
+
if (isFrame(frame)) next[slug] = frame;
|
|
543
|
+
}
|
|
544
|
+
cache = next;
|
|
545
|
+
return next;
|
|
546
|
+
}
|
|
547
|
+
}
|
|
548
|
+
} catch {
|
|
549
|
+
/* ignore — corrupt or missing file just yields empty cache */
|
|
550
|
+
}
|
|
551
|
+
cache = {};
|
|
552
|
+
return cache;
|
|
553
|
+
}
|
|
554
|
+
|
|
555
|
+
function writeCache(): void {
|
|
556
|
+
if (!cache) return;
|
|
557
|
+
try {
|
|
558
|
+
const dir = path.dirname(storePath);
|
|
559
|
+
if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
|
|
560
|
+
fs.writeFileSync(storePath, JSON.stringify(cache), "utf8");
|
|
561
|
+
} catch {
|
|
562
|
+
/* ignore — bounds save must never break the window */
|
|
563
|
+
}
|
|
564
|
+
}
|
|
565
|
+
|
|
566
|
+
return {
|
|
567
|
+
load: (slug) => {
|
|
568
|
+
const blob = readCache();
|
|
569
|
+
return blob[slug] ?? null;
|
|
570
|
+
},
|
|
571
|
+
save: (slug, frame) => {
|
|
572
|
+
if (!isFrame(frame)) return;
|
|
573
|
+
const blob = readCache();
|
|
574
|
+
blob[slug] = frame;
|
|
575
|
+
writeCache();
|
|
576
|
+
},
|
|
577
|
+
};
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
let currentWindow: BrowserWindow | null = null;
|
|
581
|
+
let currentSendToWebview: SendToWebview | null = null;
|
|
582
|
+
let surfaceWindowManager: SurfaceWindowManager | null = null;
|
|
583
|
+
let rendererUrlPromise: Promise<string> | null = null;
|
|
584
|
+
let backgroundWindowPromise: Promise<void> | null = null;
|
|
585
|
+
let isQuitting = false;
|
|
586
|
+
|
|
587
|
+
function requestAppQuit(): void {
|
|
588
|
+
isQuitting = true;
|
|
589
|
+
Utils.quit();
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
const cleanupFns: Array<() => void | Promise<void>> = [];
|
|
593
|
+
let lastFocusedWindow: ManagedWindowLike | null = null;
|
|
594
|
+
const macOpenedDevtoolsWindowIds = new Set<number>();
|
|
595
|
+
|
|
596
|
+
async function openBrowserDevtoolsFallback(
|
|
597
|
+
targetWindow: ManagedWindowLike | BrowserWindow | null,
|
|
598
|
+
): Promise<void> {
|
|
599
|
+
const currentUrl = (
|
|
600
|
+
targetWindow?.webview as { url?: string | null } | undefined
|
|
601
|
+
)?.url;
|
|
602
|
+
const url = currentUrl?.trim() || (await resolveRendererUrl());
|
|
603
|
+
|
|
604
|
+
if (!/^https?:\/\//i.test(url)) {
|
|
605
|
+
Utils.showNotification({
|
|
606
|
+
title: "Developer Tools Unavailable",
|
|
607
|
+
body: "Native macOS Electrobun devtools are disabled, and the renderer URL is not browser-openable.",
|
|
608
|
+
});
|
|
609
|
+
return;
|
|
610
|
+
}
|
|
611
|
+
|
|
612
|
+
Utils.openExternal(url);
|
|
613
|
+
Utils.showNotification({
|
|
614
|
+
title: "Opened Renderer in Browser",
|
|
615
|
+
body: "Native macOS Electrobun devtools are disabled due to a WKWebView crash/layout bug. Use browser devtools instead.",
|
|
616
|
+
});
|
|
617
|
+
}
|
|
618
|
+
|
|
619
|
+
function sendToActiveRenderer(message: string, payload?: unknown): void {
|
|
620
|
+
currentSendToWebview?.(message, payload);
|
|
621
|
+
if (!currentSendToWebview) {
|
|
622
|
+
const level =
|
|
623
|
+
message === "desktopTrayMenuClick" ? console.warn : console.debug;
|
|
624
|
+
level.call(
|
|
625
|
+
console,
|
|
626
|
+
"[Main] Dropped renderer message (no window):",
|
|
627
|
+
message,
|
|
628
|
+
);
|
|
629
|
+
}
|
|
630
|
+
}
|
|
631
|
+
|
|
632
|
+
function sendManagedWindowsChanged(): void {
|
|
633
|
+
sendToActiveRenderer("desktopManagedWindowsChanged", {
|
|
634
|
+
windows: surfaceWindowManager?.listWindows() ?? [],
|
|
635
|
+
});
|
|
636
|
+
}
|
|
637
|
+
|
|
638
|
+
function shouldRestoreWindowBeforeMenuAction(
|
|
639
|
+
action: string | undefined,
|
|
640
|
+
): boolean {
|
|
641
|
+
if (!action || action.startsWith("focus-window:")) {
|
|
642
|
+
return false;
|
|
643
|
+
}
|
|
644
|
+
return action !== "quit";
|
|
645
|
+
}
|
|
646
|
+
|
|
647
|
+
/**
|
|
648
|
+
* Serve the renderer dist over HTTP so WKWebView can load it without
|
|
649
|
+
* file:// CORS restrictions (crossorigin ES modules break over file://).
|
|
650
|
+
* Returns the base URL e.g. "http://localhost:5174".
|
|
651
|
+
*/
|
|
652
|
+
async function startRendererServer(): Promise<string> {
|
|
653
|
+
const rendererDir = resolveRendererAssetDir(import.meta.dir);
|
|
654
|
+
if (!fs.existsSync(rendererDir)) {
|
|
655
|
+
logger.warn("[Renderer] renderer dir not found:", rendererDir);
|
|
656
|
+
return "";
|
|
657
|
+
}
|
|
658
|
+
|
|
659
|
+
// Find a free port starting at 5174 (5173 reserved for Vite dev)
|
|
660
|
+
const getPort = (start: number): Promise<number> =>
|
|
661
|
+
new Promise((resolve) => {
|
|
662
|
+
const srv = createNetServer();
|
|
663
|
+
srv.listen(start, "127.0.0.1", () => {
|
|
664
|
+
const { port } = srv.address() as { port: number };
|
|
665
|
+
srv.close(() => resolve(port));
|
|
666
|
+
});
|
|
667
|
+
srv.on("error", () => resolve(getPort(start + 1)));
|
|
668
|
+
});
|
|
669
|
+
|
|
670
|
+
const port = await getPort(5174);
|
|
671
|
+
|
|
672
|
+
const mimeTypes: Record<string, string> = {
|
|
673
|
+
".html": "text/html; charset=utf-8",
|
|
674
|
+
".js": "application/javascript",
|
|
675
|
+
".mjs": "application/javascript",
|
|
676
|
+
".css": "text/css",
|
|
677
|
+
".png": "image/png",
|
|
678
|
+
".jpg": "image/jpeg",
|
|
679
|
+
".svg": "image/svg+xml",
|
|
680
|
+
".ico": "image/x-icon",
|
|
681
|
+
".json": "application/json",
|
|
682
|
+
".gz": "application/octet-stream",
|
|
683
|
+
".wasm": "application/wasm",
|
|
684
|
+
".glb": "model/gltf-binary",
|
|
685
|
+
".gltf": "model/gltf+json",
|
|
686
|
+
".vrm": "model/gltf-binary",
|
|
687
|
+
};
|
|
688
|
+
|
|
689
|
+
// Seed the api-base-owner singleton with the initial value so the
|
|
690
|
+
// HTML-inject path and the RPC push path both read the same source of
|
|
691
|
+
// truth. Without this seeding, the static server would inject one value
|
|
692
|
+
// into HTML before the renderer mounts and the RPC bridge would push a
|
|
693
|
+
// different value moments later — the renderer racing two answers is
|
|
694
|
+
// what produced the port-shift disconnect documented in MASTER.md §0.
|
|
695
|
+
const initialApiBase = resolveInitialApiBase(
|
|
696
|
+
process.env as Record<string, string | undefined>,
|
|
697
|
+
);
|
|
698
|
+
const initialApiToken =
|
|
699
|
+
resolveDesktopRuntimeMode(process.env as Record<string, string | undefined>)
|
|
700
|
+
.mode === "local"
|
|
701
|
+
? configureDesktopLocalApiAuth()
|
|
702
|
+
: (resolveApiToken(process.env) ?? "");
|
|
703
|
+
apiBaseOwner.setCurrent(initialApiBase, initialApiToken);
|
|
704
|
+
|
|
705
|
+
const resolveRendererCacheControl = (
|
|
706
|
+
pathname: string,
|
|
707
|
+
mimeExt: string,
|
|
708
|
+
): string => {
|
|
709
|
+
if (pathname.startsWith("/assets/")) {
|
|
710
|
+
return "public, max-age=31536000, immutable";
|
|
711
|
+
}
|
|
712
|
+
if (
|
|
713
|
+
mimeExt === ".vrm" ||
|
|
714
|
+
pathname.endsWith(".vrm.gz") ||
|
|
715
|
+
pathname.startsWith("/vrms/previews/") ||
|
|
716
|
+
pathname.startsWith("/vrms/backgrounds/") ||
|
|
717
|
+
[
|
|
718
|
+
".png",
|
|
719
|
+
".jpg",
|
|
720
|
+
".jpeg",
|
|
721
|
+
".gif",
|
|
722
|
+
".webp",
|
|
723
|
+
".avif",
|
|
724
|
+
".svg",
|
|
725
|
+
".mp3",
|
|
726
|
+
".wav",
|
|
727
|
+
".ogg",
|
|
728
|
+
".m4a",
|
|
729
|
+
".aac",
|
|
730
|
+
".flac",
|
|
731
|
+
".glb",
|
|
732
|
+
].includes(mimeExt)
|
|
733
|
+
) {
|
|
734
|
+
return "public, max-age=86400";
|
|
735
|
+
}
|
|
736
|
+
return "public, max-age=0, must-revalidate";
|
|
737
|
+
};
|
|
738
|
+
|
|
739
|
+
Bun.serve({
|
|
740
|
+
port,
|
|
741
|
+
hostname: "127.0.0.1",
|
|
742
|
+
async fetch(req) {
|
|
743
|
+
const url = new URL(req.url);
|
|
744
|
+
const pathname = url.pathname;
|
|
745
|
+
|
|
746
|
+
// Proxy /api/*, /ws, /music-player to the agent port. Mirrors the Vite
|
|
747
|
+
// dev-server proxy in apps/app/vite.config.ts so the renderer can rely
|
|
748
|
+
// on same-origin /api fetches whether it's loaded via Vite (watch mode)
|
|
749
|
+
// or this static server (non-watch dev:desktop). Without this, every
|
|
750
|
+
// /api/* call returned SPA HTML and Settings sat on "Loading…" forever.
|
|
751
|
+
if (
|
|
752
|
+
initialApiBase &&
|
|
753
|
+
(pathname.startsWith("/api/") ||
|
|
754
|
+
pathname === "/ws" ||
|
|
755
|
+
pathname.startsWith("/music-player"))
|
|
756
|
+
) {
|
|
757
|
+
const target = new URL(pathname + url.search, initialApiBase);
|
|
758
|
+
const headers = new Headers(req.headers);
|
|
759
|
+
headers.set("host", target.host);
|
|
760
|
+
try {
|
|
761
|
+
const upstream = await fetch(target, {
|
|
762
|
+
method: req.method,
|
|
763
|
+
headers,
|
|
764
|
+
body: req.body,
|
|
765
|
+
// @ts-expect-error Bun fetch supports duplex for streaming bodies
|
|
766
|
+
duplex: "half",
|
|
767
|
+
redirect: "manual",
|
|
768
|
+
});
|
|
769
|
+
return new Response(upstream.body, {
|
|
770
|
+
status: upstream.status,
|
|
771
|
+
statusText: upstream.statusText,
|
|
772
|
+
headers: upstream.headers,
|
|
773
|
+
});
|
|
774
|
+
} catch (err) {
|
|
775
|
+
return new Response(
|
|
776
|
+
JSON.stringify({
|
|
777
|
+
error: "API server unavailable",
|
|
778
|
+
detail: err instanceof Error ? err.message : String(err),
|
|
779
|
+
}),
|
|
780
|
+
{
|
|
781
|
+
status: 502,
|
|
782
|
+
headers: { "Content-Type": "application/json" },
|
|
783
|
+
},
|
|
784
|
+
);
|
|
785
|
+
}
|
|
786
|
+
}
|
|
787
|
+
|
|
788
|
+
const { filePath, isGzipped, mimeExt } = resolveRendererAsset({
|
|
789
|
+
rendererDir,
|
|
790
|
+
urlPath: pathname,
|
|
791
|
+
existsSync: fs.existsSync,
|
|
792
|
+
statSync: fs.statSync,
|
|
793
|
+
});
|
|
794
|
+
|
|
795
|
+
try {
|
|
796
|
+
const content = fs.readFileSync(filePath);
|
|
797
|
+
// Inject API base into HTML responses
|
|
798
|
+
if (mimeExt === ".html" || filePath.endsWith("index.html")) {
|
|
799
|
+
const html = apiBaseOwner.injectIntoHtml(content.toString("utf8"));
|
|
800
|
+
return new Response(html, {
|
|
801
|
+
headers: {
|
|
802
|
+
"Content-Type": "text/html; charset=utf-8",
|
|
803
|
+
"Access-Control-Allow-Origin": "*",
|
|
804
|
+
"Cache-Control": "public, max-age=0, must-revalidate",
|
|
805
|
+
},
|
|
806
|
+
});
|
|
807
|
+
}
|
|
808
|
+
|
|
809
|
+
const headers: Record<string, string> = {
|
|
810
|
+
"Content-Type": mimeTypes[mimeExt] ?? "application/octet-stream",
|
|
811
|
+
"Access-Control-Allow-Origin": "*",
|
|
812
|
+
"Cache-Control": resolveRendererCacheControl(pathname, mimeExt),
|
|
813
|
+
};
|
|
814
|
+
|
|
815
|
+
if (isGzipped) {
|
|
816
|
+
headers["Content-Encoding"] = "gzip";
|
|
817
|
+
}
|
|
818
|
+
|
|
819
|
+
return new Response(content, { headers });
|
|
820
|
+
} catch {
|
|
821
|
+
return new Response("Not found", { status: 404 });
|
|
822
|
+
}
|
|
823
|
+
},
|
|
824
|
+
});
|
|
825
|
+
|
|
826
|
+
console.log(`[Renderer] Static server on http://127.0.0.1:${port}`);
|
|
827
|
+
return `http://127.0.0.1:${port}`;
|
|
828
|
+
}
|
|
829
|
+
|
|
830
|
+
async function resolveRendererUrl(): Promise<string> {
|
|
831
|
+
// Prefer ELIZA_RENDERER_URL / VITE_DEV_SERVER_URL when set (e.g. dev-platform.mjs watch mode).
|
|
832
|
+
// Why: Vite HMR only works against the dev server; serving pre-built dist from this static
|
|
833
|
+
// server would force a full rebuild for every UI change.
|
|
834
|
+
let rendererUrl =
|
|
835
|
+
process.env.ELIZA_RENDERER_URL ?? process.env.VITE_DEV_SERVER_URL ?? "";
|
|
836
|
+
|
|
837
|
+
if (!rendererUrl) {
|
|
838
|
+
rendererUrlPromise ??= startRendererServer();
|
|
839
|
+
rendererUrl = await rendererUrlPromise;
|
|
840
|
+
}
|
|
841
|
+
|
|
842
|
+
if (!rendererUrl) {
|
|
843
|
+
// Last resort: file:// (may have CORS issues with crossorigin module scripts)
|
|
844
|
+
rendererUrl = `file://${path.join(resolveRendererAssetDir(import.meta.dir), "index.html")}`;
|
|
845
|
+
logger.warn(
|
|
846
|
+
"[Main] Falling back to file:// renderer URL — CORS issues possible",
|
|
847
|
+
);
|
|
848
|
+
}
|
|
849
|
+
|
|
850
|
+
return rendererUrl;
|
|
851
|
+
}
|
|
852
|
+
|
|
853
|
+
async function createMainWindow(rpc: ElizaDesktopRpc): Promise<BrowserWindow> {
|
|
854
|
+
const rendererUrl = await resolveRendererUrl();
|
|
855
|
+
const mainWindowPartition = resolveMainWindowPartition(process.env);
|
|
856
|
+
if (mainWindowPartition) {
|
|
857
|
+
logger.info(
|
|
858
|
+
`[Main] Using isolated main window partition ${mainWindowPartition}`,
|
|
859
|
+
);
|
|
860
|
+
}
|
|
861
|
+
|
|
862
|
+
const statePath = path.join(Utils.paths.userData, "window-state.json");
|
|
863
|
+
const state = loadWindowState(statePath);
|
|
864
|
+
|
|
865
|
+
let preload: string;
|
|
866
|
+
try {
|
|
867
|
+
preload = readResolvedPreloadScript(import.meta.dir);
|
|
868
|
+
} catch (err) {
|
|
869
|
+
logger.error(
|
|
870
|
+
`[Main] Failed to read preload script: ${err instanceof Error ? err.message : String(err)}`,
|
|
871
|
+
);
|
|
872
|
+
preload = "// preload unavailable";
|
|
873
|
+
}
|
|
874
|
+
|
|
875
|
+
const windowFrame = {
|
|
876
|
+
width: state.width,
|
|
877
|
+
height: state.height,
|
|
878
|
+
x: state.x,
|
|
879
|
+
y: state.y,
|
|
880
|
+
};
|
|
881
|
+
const titleBarStyle =
|
|
882
|
+
process.platform === "darwin" ? "hiddenInset" : "default";
|
|
883
|
+
const transparent = process.platform === "darwin";
|
|
884
|
+
const buildInfo = await BuildConfig.get();
|
|
885
|
+
const forceMainWindowCef = shouldForceMainWindowCef(process.env);
|
|
886
|
+
const canUseCefView = buildInfo.availableRenderers.includes("cef");
|
|
887
|
+
const useIsolatedMainView =
|
|
888
|
+
(process.platform === "win32" && mainWindowPartition) ||
|
|
889
|
+
(forceMainWindowCef && canUseCefView && !!mainWindowPartition);
|
|
890
|
+
|
|
891
|
+
if (forceMainWindowCef && !canUseCefView) {
|
|
892
|
+
logger.warn(
|
|
893
|
+
"[Main] ELIZA_DESKTOP_FORCE_CEF=1 requested, but this Electrobun build does not bundle the CEF renderer. Falling back to the native renderer.",
|
|
894
|
+
);
|
|
895
|
+
}
|
|
896
|
+
|
|
897
|
+
let win: BrowserWindow;
|
|
898
|
+
if (useIsolatedMainView) {
|
|
899
|
+
// Shell window with the empty default webview. The actual content
|
|
900
|
+
// (and therefore the RPC channel) is hosted on the separate mainView
|
|
901
|
+
// BrowserView constructed below — that's what we attach `rpc` to.
|
|
902
|
+
win = new BrowserWindow({
|
|
903
|
+
title: BRAND.appName,
|
|
904
|
+
// @ts-expect-error: Electrobun doesn't expose icon in JS typings yet
|
|
905
|
+
icon: resolveDesktopAppIconPath(),
|
|
906
|
+
url: null,
|
|
907
|
+
preload: null,
|
|
908
|
+
frame: windowFrame,
|
|
909
|
+
renderer: resolveBootstrapShellRenderer(buildInfo),
|
|
910
|
+
titleBarStyle,
|
|
911
|
+
transparent,
|
|
912
|
+
});
|
|
913
|
+
win.webview.remove();
|
|
914
|
+
const mainView = new BrowserView({
|
|
915
|
+
url: rendererUrl,
|
|
916
|
+
preload,
|
|
917
|
+
renderer: forceMainWindowCef
|
|
918
|
+
? "cef"
|
|
919
|
+
: resolveBootstrapViewRenderer(buildInfo),
|
|
920
|
+
partition: mainWindowPartition,
|
|
921
|
+
frame: {
|
|
922
|
+
x: 0,
|
|
923
|
+
y: 0,
|
|
924
|
+
width: state.width,
|
|
925
|
+
height: state.height,
|
|
926
|
+
},
|
|
927
|
+
windowId: win.id,
|
|
928
|
+
rpc,
|
|
929
|
+
});
|
|
930
|
+
win.webviewId = mainView.id;
|
|
931
|
+
if (forceMainWindowCef) {
|
|
932
|
+
logger.info(
|
|
933
|
+
`[Main] Using CEF main-window workaround with persistent partition ${mainWindowPartition}`,
|
|
934
|
+
);
|
|
935
|
+
}
|
|
936
|
+
} else {
|
|
937
|
+
win = new BrowserWindow({
|
|
938
|
+
title: BRAND.appName,
|
|
939
|
+
// @ts-expect-error: Electrobun doesn't expose icon in JS typings yet
|
|
940
|
+
icon: resolveDesktopAppIconPath(),
|
|
941
|
+
url: rendererUrl,
|
|
942
|
+
preload,
|
|
943
|
+
frame: windowFrame,
|
|
944
|
+
titleBarStyle,
|
|
945
|
+
transparent,
|
|
946
|
+
rpc,
|
|
947
|
+
});
|
|
948
|
+
}
|
|
949
|
+
|
|
950
|
+
applyMacOSWindowEffects(win);
|
|
951
|
+
win.on("resize", () => scheduleStateSave(statePath, win));
|
|
952
|
+
win.on("move", () => scheduleStateSave(statePath, win));
|
|
953
|
+
|
|
954
|
+
// First-launch ergonomics: when there's no saved state (or the
|
|
955
|
+
// saved state was garbage and we're falling back to defaults), open
|
|
956
|
+
// the window maximized so the user gets a full workspace instead of
|
|
957
|
+
// a 1440x900 rectangle in the corner they have to resize by hand.
|
|
958
|
+
// Subsequent launches skip this because loadWindowState returns the
|
|
959
|
+
// real persisted dimensions without the shouldMaximize sentinel.
|
|
960
|
+
if (state.shouldMaximize === MAXIMIZE_ON_LAUNCH_SENTINEL) {
|
|
961
|
+
try {
|
|
962
|
+
(win as typeof win & { maximize?: () => void }).maximize?.();
|
|
963
|
+
} catch (err) {
|
|
964
|
+
// Non-fatal — if maximize() isn't available on this electrobun
|
|
965
|
+
// build, the window still opens at the default dimensions.
|
|
966
|
+
logger.warn(
|
|
967
|
+
`[main-window] maximize() failed: ${err instanceof Error ? err.message : String(err)}`,
|
|
968
|
+
);
|
|
969
|
+
}
|
|
970
|
+
}
|
|
971
|
+
|
|
972
|
+
return win;
|
|
973
|
+
}
|
|
974
|
+
|
|
975
|
+
function attachMainWindow(
|
|
976
|
+
win: BrowserWindow,
|
|
977
|
+
rpc: ElizaDesktopRpc,
|
|
978
|
+
sendToWebview: SendToWebview,
|
|
979
|
+
): BrowserWindow {
|
|
980
|
+
wireMainWindowAfterCreate(win, rpc, sendToWebview);
|
|
981
|
+
currentWindow = win;
|
|
982
|
+
currentSendToWebview = sendToWebview;
|
|
983
|
+
setCurrentMainWindow(win, {
|
|
984
|
+
titleBarStyle: process.platform === "darwin" ? "hiddenInset" : "default",
|
|
985
|
+
transparent: process.platform === "darwin",
|
|
986
|
+
});
|
|
987
|
+
trackFocusedWindow(win);
|
|
988
|
+
|
|
989
|
+
win.webview.on("dom-ready", () => {
|
|
990
|
+
injectApiBase(win);
|
|
991
|
+
});
|
|
992
|
+
|
|
993
|
+
// Prevent the main webview from navigating to external URLs.
|
|
994
|
+
// The renderer is always served from localhost — any other navigation
|
|
995
|
+
// (e.g. from a compromised plugin) should open in the default browser.
|
|
996
|
+
win.webview.on("will-navigate", (event: unknown) => {
|
|
997
|
+
const e = event as {
|
|
998
|
+
url?: string;
|
|
999
|
+
data?: { detail?: string };
|
|
1000
|
+
preventDefault?: () => void;
|
|
1001
|
+
};
|
|
1002
|
+
const url = readNavigationEventUrl(e);
|
|
1003
|
+
try {
|
|
1004
|
+
const parsed = new URL(url);
|
|
1005
|
+
const isAllowed =
|
|
1006
|
+
parsed.protocol === "file:" ||
|
|
1007
|
+
parsed.hostname === "localhost" ||
|
|
1008
|
+
parsed.hostname === "127.0.0.1" ||
|
|
1009
|
+
parsed.protocol === "views:";
|
|
1010
|
+
if (!isAllowed) {
|
|
1011
|
+
e.preventDefault?.();
|
|
1012
|
+
void import("electrobun/bun")
|
|
1013
|
+
.then(({ Utils }) => {
|
|
1014
|
+
try {
|
|
1015
|
+
Utils.openExternal(url);
|
|
1016
|
+
} catch {
|
|
1017
|
+
// Ignore external open failures during navigation blocking.
|
|
1018
|
+
}
|
|
1019
|
+
})
|
|
1020
|
+
.catch(() => {});
|
|
1021
|
+
}
|
|
1022
|
+
} catch {
|
|
1023
|
+
// Unparseable URL — block it.
|
|
1024
|
+
e.preventDefault?.();
|
|
1025
|
+
}
|
|
1026
|
+
});
|
|
1027
|
+
|
|
1028
|
+
win.on("close", () => {
|
|
1029
|
+
if (currentWindow?.id === win.id) {
|
|
1030
|
+
currentWindow = null;
|
|
1031
|
+
currentSendToWebview = null;
|
|
1032
|
+
}
|
|
1033
|
+
clearCurrentMainWindow(win);
|
|
1034
|
+
getDesktopManager().clearMainWindow(win);
|
|
1035
|
+
|
|
1036
|
+
if (!isQuitting) {
|
|
1037
|
+
void ensureBackgroundWindow();
|
|
1038
|
+
}
|
|
1039
|
+
});
|
|
1040
|
+
|
|
1041
|
+
return win;
|
|
1042
|
+
}
|
|
1043
|
+
|
|
1044
|
+
async function ensureBackgroundWindow(): Promise<void> {
|
|
1045
|
+
if (isQuitting || currentWindow) {
|
|
1046
|
+
return;
|
|
1047
|
+
}
|
|
1048
|
+
|
|
1049
|
+
// Don't recreate the window — just keep the process alive in the
|
|
1050
|
+
// background (exitOnLastWindowClosed is false in electrobun.config.ts).
|
|
1051
|
+
// The dock icon click fires the "reopen" event which restores the window.
|
|
1052
|
+
logger.info("[Main] Window closed — agent continues in background");
|
|
1053
|
+
showBackgroundRunNoticeOnce();
|
|
1054
|
+
}
|
|
1055
|
+
|
|
1056
|
+
/** Restore or recreate the main window (called on dock icon click). */
|
|
1057
|
+
async function restoreWindow(): Promise<void> {
|
|
1058
|
+
if (currentWindow) {
|
|
1059
|
+
try {
|
|
1060
|
+
currentWindow.unminimize();
|
|
1061
|
+
currentWindow.focus();
|
|
1062
|
+
} catch {
|
|
1063
|
+
// unminimize/focus may not be available
|
|
1064
|
+
}
|
|
1065
|
+
return;
|
|
1066
|
+
}
|
|
1067
|
+
if (backgroundWindowPromise) {
|
|
1068
|
+
await backgroundWindowPromise;
|
|
1069
|
+
return;
|
|
1070
|
+
}
|
|
1071
|
+
backgroundWindowPromise = (async () => {
|
|
1072
|
+
const { rpc, sendToWebview } = createDesktopRpc("main");
|
|
1073
|
+
const win = attachMainWindow(
|
|
1074
|
+
await createMainWindow(rpc),
|
|
1075
|
+
rpc,
|
|
1076
|
+
sendToWebview,
|
|
1077
|
+
);
|
|
1078
|
+
injectApiBase(win);
|
|
1079
|
+
logger.info("[Main] Restored window from dock click");
|
|
1080
|
+
})().finally(() => {
|
|
1081
|
+
backgroundWindowPromise = null;
|
|
1082
|
+
});
|
|
1083
|
+
await backgroundWindowPromise;
|
|
1084
|
+
}
|
|
1085
|
+
|
|
1086
|
+
function showBackgroundRunNoticeOnce(): void {
|
|
1087
|
+
try {
|
|
1088
|
+
showBackgroundNoticeOnce({
|
|
1089
|
+
fileSystem: fs,
|
|
1090
|
+
userDataDir: Utils.paths.userData,
|
|
1091
|
+
showNotification: (options) => {
|
|
1092
|
+
Utils.showNotification(options);
|
|
1093
|
+
},
|
|
1094
|
+
});
|
|
1095
|
+
} catch (error) {
|
|
1096
|
+
logger.warn(
|
|
1097
|
+
`[Main] Failed to persist background notice marker: ${error instanceof Error ? error.message : String(error)}`,
|
|
1098
|
+
);
|
|
1099
|
+
}
|
|
1100
|
+
}
|
|
1101
|
+
|
|
1102
|
+
async function createSettingsWindow(tabHint?: string): Promise<void> {
|
|
1103
|
+
if (!surfaceWindowManager) return;
|
|
1104
|
+
await surfaceWindowManager.openSettingsWindow(tabHint);
|
|
1105
|
+
}
|
|
1106
|
+
|
|
1107
|
+
async function showMainSurface(surface: string): Promise<void> {
|
|
1108
|
+
if (!currentWindow) {
|
|
1109
|
+
await restoreWindow();
|
|
1110
|
+
}
|
|
1111
|
+
void getDesktopManager().showWindow();
|
|
1112
|
+
sendToActiveRenderer("desktopTrayMenuClick", {
|
|
1113
|
+
itemId: `show-main:${surface}`,
|
|
1114
|
+
});
|
|
1115
|
+
}
|
|
1116
|
+
|
|
1117
|
+
function resolveDefaultDialogPath(): string {
|
|
1118
|
+
const downloadsPath = path.join(os.homedir(), "Downloads");
|
|
1119
|
+
return fs.existsSync(downloadsPath) ? downloadsPath : os.homedir();
|
|
1120
|
+
}
|
|
1121
|
+
|
|
1122
|
+
async function exportConfigFromMenu(): Promise<void> {
|
|
1123
|
+
const apiBase = resolveLoopbackApiBase();
|
|
1124
|
+
if (!apiBase) {
|
|
1125
|
+
Utils.showNotification({
|
|
1126
|
+
title: "Config Export Failed",
|
|
1127
|
+
body: "Agent unavailable",
|
|
1128
|
+
});
|
|
1129
|
+
return;
|
|
1130
|
+
}
|
|
1131
|
+
|
|
1132
|
+
try {
|
|
1133
|
+
const response = await fetch(`${apiBase}/api/config`, {
|
|
1134
|
+
headers: buildApiRequestHeaders(),
|
|
1135
|
+
});
|
|
1136
|
+
if (!response.ok) {
|
|
1137
|
+
throw new Error(`Config fetch failed (${response.status})`);
|
|
1138
|
+
}
|
|
1139
|
+
|
|
1140
|
+
const config = await response.json();
|
|
1141
|
+
const dialog = await getDesktopManager().showSaveDialog({
|
|
1142
|
+
defaultPath: resolveDefaultDialogPath(),
|
|
1143
|
+
allowedFileTypes: "json",
|
|
1144
|
+
});
|
|
1145
|
+
if (dialog.canceled || dialog.filePaths.length === 0) {
|
|
1146
|
+
return;
|
|
1147
|
+
}
|
|
1148
|
+
|
|
1149
|
+
const outputPath = path.join(dialog.filePaths[0], CONFIG_EXPORT_FILE_NAME);
|
|
1150
|
+
fs.writeFileSync(
|
|
1151
|
+
outputPath,
|
|
1152
|
+
`${JSON.stringify(config, null, 2)}\n`,
|
|
1153
|
+
"utf8",
|
|
1154
|
+
);
|
|
1155
|
+
|
|
1156
|
+
Utils.showNotification({
|
|
1157
|
+
title: "Config Exported",
|
|
1158
|
+
body: `Saved to ${outputPath}`,
|
|
1159
|
+
});
|
|
1160
|
+
} catch (error) {
|
|
1161
|
+
Utils.showNotification({
|
|
1162
|
+
title: "Config Export Failed",
|
|
1163
|
+
body: summarizeDesktopActionError(error, "Config export failed"),
|
|
1164
|
+
});
|
|
1165
|
+
}
|
|
1166
|
+
}
|
|
1167
|
+
|
|
1168
|
+
async function importConfigFromMenu(): Promise<void> {
|
|
1169
|
+
const apiBase = resolveLoopbackApiBase();
|
|
1170
|
+
if (!apiBase) {
|
|
1171
|
+
Utils.showNotification({
|
|
1172
|
+
title: "Config Import Failed",
|
|
1173
|
+
body: "Agent unavailable",
|
|
1174
|
+
});
|
|
1175
|
+
return;
|
|
1176
|
+
}
|
|
1177
|
+
|
|
1178
|
+
try {
|
|
1179
|
+
const dialog = await getDesktopManager().showOpenDialog({
|
|
1180
|
+
defaultPath: resolveDefaultDialogPath(),
|
|
1181
|
+
allowedFileTypes: "json",
|
|
1182
|
+
canChooseFiles: true,
|
|
1183
|
+
canChooseDirectory: false,
|
|
1184
|
+
allowsMultipleSelection: false,
|
|
1185
|
+
});
|
|
1186
|
+
if (dialog.canceled || dialog.filePaths.length === 0) {
|
|
1187
|
+
return;
|
|
1188
|
+
}
|
|
1189
|
+
|
|
1190
|
+
const inputPath = dialog.filePaths[0];
|
|
1191
|
+
const rawConfig = fs.readFileSync(inputPath, "utf8");
|
|
1192
|
+
const parsedConfig = JSON.parse(rawConfig) as unknown;
|
|
1193
|
+
if (
|
|
1194
|
+
typeof parsedConfig !== "object" ||
|
|
1195
|
+
parsedConfig === null ||
|
|
1196
|
+
Array.isArray(parsedConfig)
|
|
1197
|
+
) {
|
|
1198
|
+
throw new Error("Config file must contain a JSON object");
|
|
1199
|
+
}
|
|
1200
|
+
|
|
1201
|
+
const response = await fetch(`${apiBase}/api/config`, {
|
|
1202
|
+
method: "PUT",
|
|
1203
|
+
headers: buildApiRequestHeaders("application/json"),
|
|
1204
|
+
body: JSON.stringify(parsedConfig),
|
|
1205
|
+
});
|
|
1206
|
+
if (!response.ok) {
|
|
1207
|
+
throw new Error(`Config import failed (${response.status})`);
|
|
1208
|
+
}
|
|
1209
|
+
|
|
1210
|
+
Utils.showNotification({
|
|
1211
|
+
title: "Config Imported",
|
|
1212
|
+
body: `Loaded ${path.basename(inputPath)}`,
|
|
1213
|
+
});
|
|
1214
|
+
} catch (error) {
|
|
1215
|
+
Utils.showNotification({
|
|
1216
|
+
title: "Config Import Failed",
|
|
1217
|
+
body: summarizeDesktopActionError(error, "Config import failed"),
|
|
1218
|
+
});
|
|
1219
|
+
}
|
|
1220
|
+
}
|
|
1221
|
+
|
|
1222
|
+
function trackFocusedWindow(window: ManagedWindowLike): void {
|
|
1223
|
+
lastFocusedWindow = window;
|
|
1224
|
+
window.on("focus", () => {
|
|
1225
|
+
lastFocusedWindow = window;
|
|
1226
|
+
const windowId = (window as { id?: number }).id;
|
|
1227
|
+
if (
|
|
1228
|
+
process.platform === "darwin" &&
|
|
1229
|
+
typeof windowId === "number" &&
|
|
1230
|
+
macOpenedDevtoolsWindowIds.has(windowId)
|
|
1231
|
+
) {
|
|
1232
|
+
scheduleDevtoolsLayoutRefresh(
|
|
1233
|
+
window as Parameters<typeof scheduleDevtoolsLayoutRefresh>[0],
|
|
1234
|
+
);
|
|
1235
|
+
}
|
|
1236
|
+
});
|
|
1237
|
+
window.on("close", () => {
|
|
1238
|
+
const windowId = (window as { id?: number }).id;
|
|
1239
|
+
if (typeof windowId === "number") {
|
|
1240
|
+
macOpenedDevtoolsWindowIds.delete(windowId);
|
|
1241
|
+
}
|
|
1242
|
+
});
|
|
1243
|
+
}
|
|
1244
|
+
|
|
1245
|
+
function toggleFocusedWindowDevTools(): void {
|
|
1246
|
+
const targetWindow = lastFocusedWindow ?? currentWindow;
|
|
1247
|
+
const webview = targetWindow?.webview as
|
|
1248
|
+
| {
|
|
1249
|
+
toggleDevTools?: () => void;
|
|
1250
|
+
openDevTools?: () => void;
|
|
1251
|
+
}
|
|
1252
|
+
| undefined;
|
|
1253
|
+
|
|
1254
|
+
if (shouldUseBrowserDevtoolsFallback()) {
|
|
1255
|
+
void openBrowserDevtoolsFallback(targetWindow);
|
|
1256
|
+
return;
|
|
1257
|
+
}
|
|
1258
|
+
|
|
1259
|
+
if (typeof webview?.toggleDevTools === "function") {
|
|
1260
|
+
webview.toggleDevTools();
|
|
1261
|
+
scheduleDevtoolsLayoutRefresh(
|
|
1262
|
+
targetWindow as Parameters<typeof scheduleDevtoolsLayoutRefresh>[0],
|
|
1263
|
+
);
|
|
1264
|
+
return;
|
|
1265
|
+
}
|
|
1266
|
+
|
|
1267
|
+
if (typeof webview?.openDevTools === "function") {
|
|
1268
|
+
webview.openDevTools();
|
|
1269
|
+
scheduleDevtoolsLayoutRefresh(
|
|
1270
|
+
targetWindow as Parameters<typeof scheduleDevtoolsLayoutRefresh>[0],
|
|
1271
|
+
);
|
|
1272
|
+
return;
|
|
1273
|
+
}
|
|
1274
|
+
|
|
1275
|
+
Utils.showNotification({
|
|
1276
|
+
title: "Developer Tools Unavailable",
|
|
1277
|
+
body: "The focused window does not expose Electrobun devtools controls.",
|
|
1278
|
+
});
|
|
1279
|
+
}
|
|
1280
|
+
|
|
1281
|
+
/**
|
|
1282
|
+
* The exact rpc object that BrowserView.defineRPC<ElizaDesktopRPCSchema>
|
|
1283
|
+
* returns. Carries the schema generic so call sites get typed `request`
|
|
1284
|
+
* and `send` proxies.
|
|
1285
|
+
*/
|
|
1286
|
+
type ElizaDesktopRpc = ReturnType<
|
|
1287
|
+
typeof BrowserView.defineRPC<ElizaDesktopRPCSchema>
|
|
1288
|
+
>;
|
|
1289
|
+
|
|
1290
|
+
/**
|
|
1291
|
+
* Internal: type-erased view of the rpc shape that
|
|
1292
|
+
* `wireBrowserWorkspaceCaller` consumes. The handler module declares its
|
|
1293
|
+
* own structural type with `params: any`, so we widen here at the
|
|
1294
|
+
* boundary instead of forcing every consumer to import that internal.
|
|
1295
|
+
*/
|
|
1296
|
+
// biome-ignore lint/suspicious/noExplicitAny: bridges typed rpc.request to the handler-module's any-params signature
|
|
1297
|
+
type RpcRequestProxy = Record<string, (params: any) => Promise<any>>;
|
|
1298
|
+
|
|
1299
|
+
const MAX_RPC_REQUEST_TIME_MS = 600_000;
|
|
1300
|
+
|
|
1301
|
+
/**
|
|
1302
|
+
* Build a typed RPC instance plus its `sendToWebview` companion, ready to
|
|
1303
|
+
* be passed to a `BrowserWindow` / `BrowserView` constructor via the `rpc`
|
|
1304
|
+
* option.
|
|
1305
|
+
*
|
|
1306
|
+
* This is the constructor-time injection pattern required by the
|
|
1307
|
+
* Electrobun rules: handlers are declared up front and bound when the
|
|
1308
|
+
* webview is created, not patched in post-hoc via `setRequestHandler`.
|
|
1309
|
+
*
|
|
1310
|
+
* `sendToWebview` closes over the RPC by reference so it can be passed
|
|
1311
|
+
* into `buildBunRpcHandlers` before `defineRPC` returns — we only need
|
|
1312
|
+
* the actual `send` proxy at call time, after the webview is alive.
|
|
1313
|
+
*
|
|
1314
|
+
* @param label Diagnostic tag included in the "no RPC method" warning so
|
|
1315
|
+
* main / settings / surface windows are distinguishable.
|
|
1316
|
+
*/
|
|
1317
|
+
function createDesktopRpc(label: string): {
|
|
1318
|
+
rpc: ElizaDesktopRpc;
|
|
1319
|
+
sendToWebview: SendToWebview;
|
|
1320
|
+
} {
|
|
1321
|
+
let rpc: ElizaDesktopRpc | undefined;
|
|
1322
|
+
|
|
1323
|
+
const sendToWebview: SendToWebview = (message, payload) => {
|
|
1324
|
+
if (!rpc) {
|
|
1325
|
+
logger.warn(
|
|
1326
|
+
`[sendToWebview:${label}] RPC not yet initialised; dropping message: ${message}`,
|
|
1327
|
+
);
|
|
1328
|
+
return;
|
|
1329
|
+
}
|
|
1330
|
+
try {
|
|
1331
|
+
// `rpc.send` is a Proxy<sendFn> from defineElectrobunRPC: both
|
|
1332
|
+
// `rpc.send(message, payload)` and `rpc.send.<message>(payload)`
|
|
1333
|
+
// dispatch through the same underlying sendFn. Cast to a plain
|
|
1334
|
+
// function signature to call it dynamically by name without the
|
|
1335
|
+
// schema-typed overloads narrowing the message string.
|
|
1336
|
+
(rpc.send as unknown as (m: string, p?: unknown) => void)(
|
|
1337
|
+
message,
|
|
1338
|
+
payload ?? null,
|
|
1339
|
+
);
|
|
1340
|
+
} catch (err) {
|
|
1341
|
+
logger.warn(
|
|
1342
|
+
`[sendToWebview:${label}] send(${message}) failed: ${err instanceof Error ? err.message : String(err)}`,
|
|
1343
|
+
);
|
|
1344
|
+
}
|
|
1345
|
+
};
|
|
1346
|
+
|
|
1347
|
+
type BunRpcRequestsHandlers = NonNullable<
|
|
1348
|
+
Parameters<typeof BrowserView.defineRPC<ElizaDesktopRPCSchema>>[0]["handlers"]
|
|
1349
|
+
>["requests"];
|
|
1350
|
+
|
|
1351
|
+
rpc = BrowserView.defineRPC<ElizaDesktopRPCSchema>({
|
|
1352
|
+
maxRequestTime: MAX_RPC_REQUEST_TIME_MS,
|
|
1353
|
+
handlers: {
|
|
1354
|
+
requests: buildBunRpcHandlers({
|
|
1355
|
+
sendToWebview,
|
|
1356
|
+
}) as BunRpcRequestsHandlers,
|
|
1357
|
+
},
|
|
1358
|
+
});
|
|
1359
|
+
|
|
1360
|
+
return { rpc, sendToWebview };
|
|
1361
|
+
}
|
|
1362
|
+
|
|
1363
|
+
/**
|
|
1364
|
+
* Wire main-window-only side effects after the BrowserWindow has been
|
|
1365
|
+
* constructed with its pre-built RPC.
|
|
1366
|
+
*
|
|
1367
|
+
* Does NOT register request handlers — those are baked into the rpc by
|
|
1368
|
+
* `createDesktopRpc` at construction time. This function only wires
|
|
1369
|
+
* post-hoc concerns that need a live `win` and `rpc.request` proxy:
|
|
1370
|
+
*
|
|
1371
|
+
* - native module singletons (DesktopManager, AgentManager, …) get
|
|
1372
|
+
* bound to the main window + sendToWebview
|
|
1373
|
+
* - browser workspace's renderer-side caller is set so bun-side tab
|
|
1374
|
+
* code can `rpc.request.browserWorkspaceRendererEvaluate(...)`
|
|
1375
|
+
* - steward sidecar's send-to-webview is wired
|
|
1376
|
+
*/
|
|
1377
|
+
function wireMainWindowAfterCreate(
|
|
1378
|
+
win: BrowserWindow,
|
|
1379
|
+
rpc: ElizaDesktopRpc,
|
|
1380
|
+
sendToWebview: SendToWebview,
|
|
1381
|
+
): void {
|
|
1382
|
+
initializeNativeModules(win, sendToWebview);
|
|
1383
|
+
setStewardSendToWebview(sendToWebview);
|
|
1384
|
+
wireBrowserWorkspaceCaller({
|
|
1385
|
+
request: rpc.request as unknown as RpcRequestProxy,
|
|
1386
|
+
});
|
|
1387
|
+
}
|
|
1388
|
+
|
|
1389
|
+
/**
|
|
1390
|
+
* Wire RPC for a secondary window (e.g. settings) after constructor-time
|
|
1391
|
+
* injection. Does NOT call `initializeNativeModules` — that would
|
|
1392
|
+
* overwrite the main window reference on DesktopManager and other
|
|
1393
|
+
* singletons.
|
|
1394
|
+
*
|
|
1395
|
+
* This keeps the call site symmetric with the main window even though
|
|
1396
|
+
* settings windows don't need most of the wiring.
|
|
1397
|
+
*/
|
|
1398
|
+
function wireSettingsRpcAfterCreate(rpc: ElizaDesktopRpc): void {
|
|
1399
|
+
wireBrowserWorkspaceCaller({
|
|
1400
|
+
request: rpc.request as unknown as RpcRequestProxy,
|
|
1401
|
+
});
|
|
1402
|
+
}
|
|
1403
|
+
|
|
1404
|
+
function injectApiBase(win: BrowserWindow): void {
|
|
1405
|
+
const runtimeResolution = resolveDesktopRuntimeMode(
|
|
1406
|
+
process.env as Record<string, string | undefined>,
|
|
1407
|
+
);
|
|
1408
|
+
|
|
1409
|
+
if (runtimeResolution.externalApi.invalidSources.length > 0) {
|
|
1410
|
+
logger.warn(
|
|
1411
|
+
`[Main] Invalid API base env vars: ${runtimeResolution.externalApi.invalidSources.join(", ")}`,
|
|
1412
|
+
);
|
|
1413
|
+
}
|
|
1414
|
+
|
|
1415
|
+
if (
|
|
1416
|
+
runtimeResolution.mode === "external" &&
|
|
1417
|
+
runtimeResolution.externalApi.base
|
|
1418
|
+
) {
|
|
1419
|
+
apiBaseOwner.notifyChange(
|
|
1420
|
+
win,
|
|
1421
|
+
runtimeResolution.externalApi.base,
|
|
1422
|
+
resolveApiToken(process.env) ?? "",
|
|
1423
|
+
);
|
|
1424
|
+
setAgentReady(true);
|
|
1425
|
+
return;
|
|
1426
|
+
}
|
|
1427
|
+
|
|
1428
|
+
const agent = getAgentManager();
|
|
1429
|
+
const port = agent.getPort() ?? resolveDesktopApiPort(process.env);
|
|
1430
|
+
const apiToken = configureDesktopLocalApiAuth();
|
|
1431
|
+
apiBaseOwner.notifyChange(
|
|
1432
|
+
win,
|
|
1433
|
+
resolveRendererFacingApiBase(
|
|
1434
|
+
process.env as Record<string, string | undefined>,
|
|
1435
|
+
port,
|
|
1436
|
+
),
|
|
1437
|
+
apiToken,
|
|
1438
|
+
);
|
|
1439
|
+
setAgentReady(true);
|
|
1440
|
+
}
|
|
1441
|
+
|
|
1442
|
+
/**
|
|
1443
|
+
* Push real OS permission states into the agent REST API so the renderer's
|
|
1444
|
+
* PermissionsSection shows correct statuses and capability toggles unlock.
|
|
1445
|
+
*/
|
|
1446
|
+
async function syncPermissionsToRestApi(
|
|
1447
|
+
port: number,
|
|
1448
|
+
startup = false,
|
|
1449
|
+
): Promise<void> {
|
|
1450
|
+
try {
|
|
1451
|
+
const permissions = await mergeRuntimePermissionStates(
|
|
1452
|
+
port,
|
|
1453
|
+
await getPermissionManager().checkAllPermissions(),
|
|
1454
|
+
);
|
|
1455
|
+
await fetch(`http://127.0.0.1:${port}/api/permissions/state`, {
|
|
1456
|
+
method: "PUT",
|
|
1457
|
+
headers: { "Content-Type": "application/json" },
|
|
1458
|
+
body: JSON.stringify({ permissions, startup }),
|
|
1459
|
+
});
|
|
1460
|
+
} catch (err) {
|
|
1461
|
+
logger.warn(
|
|
1462
|
+
`[Main] Permission sync failed: ${err instanceof Error ? err.message : String(err)}`,
|
|
1463
|
+
);
|
|
1464
|
+
}
|
|
1465
|
+
}
|
|
1466
|
+
|
|
1467
|
+
async function _startAgent(win: BrowserWindow): Promise<void> {
|
|
1468
|
+
const runtimeResolution = resolveDesktopRuntimeMode(
|
|
1469
|
+
process.env as Record<string, string | undefined>,
|
|
1470
|
+
);
|
|
1471
|
+
|
|
1472
|
+
if (runtimeResolution.mode !== "local") {
|
|
1473
|
+
logger.info(
|
|
1474
|
+
`[Main] Skipping embedded agent startup (${runtimeResolution.mode} mode)`,
|
|
1475
|
+
);
|
|
1476
|
+
injectApiBase(win);
|
|
1477
|
+
return;
|
|
1478
|
+
}
|
|
1479
|
+
|
|
1480
|
+
const agent = getAgentManager();
|
|
1481
|
+
recordStartupPhase("autostart_requested", {
|
|
1482
|
+
pid: process.pid,
|
|
1483
|
+
exec_path: process.execPath,
|
|
1484
|
+
bundle_path: resolveStartupBundlePath(process.execPath),
|
|
1485
|
+
});
|
|
1486
|
+
|
|
1487
|
+
try {
|
|
1488
|
+
const status = await agent.start();
|
|
1489
|
+
|
|
1490
|
+
if (status.state === "running" && status.port) {
|
|
1491
|
+
const apiBase = `http://127.0.0.1:${status.port}`;
|
|
1492
|
+
const rendererBase = resolveRendererFacingApiBase(
|
|
1493
|
+
process.env as Record<string, string | undefined>,
|
|
1494
|
+
status.port,
|
|
1495
|
+
);
|
|
1496
|
+
// Mint or reload the loopback desktop session and install the
|
|
1497
|
+
// session+csrf cookies on the webview's cookie jar BEFORE we tell the
|
|
1498
|
+
// renderer to start hitting /api. This is the desktop trust path: if
|
|
1499
|
+
// the bridge succeeds, the renderer skips the login UI; if it fails,
|
|
1500
|
+
// the renderer behaves like a remote browser (password-required).
|
|
1501
|
+
await primeDesktopSessionAuth(apiBase, rendererBase);
|
|
1502
|
+
const apiToken = resolveApiToken(process.env) ?? "";
|
|
1503
|
+
apiBaseOwner.notifyChange(win, rendererBase, apiToken);
|
|
1504
|
+
setAgentReady(true);
|
|
1505
|
+
// Sync real OS permission states to the REST API so the renderer
|
|
1506
|
+
// can display them and capability toggles can unlock.
|
|
1507
|
+
// Pass startup=true so the backend skips scheduling a restart for
|
|
1508
|
+
// capabilities that are being auto-enabled for the first time.
|
|
1509
|
+
syncPermissionsToRestApi(status.port, true);
|
|
1510
|
+
}
|
|
1511
|
+
} catch (err) {
|
|
1512
|
+
logger.error(
|
|
1513
|
+
`[Main] Agent start failed: ${err instanceof Error ? err.message : String(err)}`,
|
|
1514
|
+
);
|
|
1515
|
+
}
|
|
1516
|
+
}
|
|
1517
|
+
|
|
1518
|
+
async function setupUpdater(): Promise<void> {
|
|
1519
|
+
const runUpdateCheck = async (notifyOnNoUpdate = false): Promise<void> => {
|
|
1520
|
+
try {
|
|
1521
|
+
const updaterState = await getDesktopManager().getUpdaterState();
|
|
1522
|
+
if (!updaterState.canAutoUpdate) {
|
|
1523
|
+
if (updaterState.autoUpdateDisabledReason) {
|
|
1524
|
+
logger.info(
|
|
1525
|
+
`[Updater] Skipping auto-update check: ${updaterState.autoUpdateDisabledReason}`,
|
|
1526
|
+
);
|
|
1527
|
+
if (notifyOnNoUpdate) {
|
|
1528
|
+
Utils.showNotification({
|
|
1529
|
+
title: "Updates Unavailable",
|
|
1530
|
+
body: updaterState.autoUpdateDisabledReason,
|
|
1531
|
+
});
|
|
1532
|
+
}
|
|
1533
|
+
}
|
|
1534
|
+
return;
|
|
1535
|
+
}
|
|
1536
|
+
|
|
1537
|
+
const updateResult = await Updater.checkForUpdate();
|
|
1538
|
+
if (updateResult?.updateAvailable) {
|
|
1539
|
+
Updater.downloadUpdate().catch((err: unknown) => {
|
|
1540
|
+
logger.warn(
|
|
1541
|
+
`[Updater] Download failed: ${err instanceof Error ? err.message : String(err)}`,
|
|
1542
|
+
);
|
|
1543
|
+
});
|
|
1544
|
+
return;
|
|
1545
|
+
}
|
|
1546
|
+
|
|
1547
|
+
if (notifyOnNoUpdate) {
|
|
1548
|
+
Utils.showNotification({
|
|
1549
|
+
title: `${BRAND.appName} Up To Date`,
|
|
1550
|
+
body: "You already have the latest release installed.",
|
|
1551
|
+
});
|
|
1552
|
+
}
|
|
1553
|
+
} catch (err) {
|
|
1554
|
+
logger.warn(
|
|
1555
|
+
`[Updater] Update check failed: ${err instanceof Error ? err.message : String(err)}`,
|
|
1556
|
+
);
|
|
1557
|
+
if (notifyOnNoUpdate) {
|
|
1558
|
+
Utils.showNotification({
|
|
1559
|
+
title: "Update Check Failed",
|
|
1560
|
+
body: `${BRAND.appName} could not reach the update server.`,
|
|
1561
|
+
});
|
|
1562
|
+
}
|
|
1563
|
+
}
|
|
1564
|
+
};
|
|
1565
|
+
|
|
1566
|
+
try {
|
|
1567
|
+
// Subscribe to update status changes so we can notify the renderer
|
|
1568
|
+
// at the right lifecycle points.
|
|
1569
|
+
Updater.onStatusChange((entry: { status: string; message?: string }) => {
|
|
1570
|
+
if (entry.status === "update-available") {
|
|
1571
|
+
// checkForUpdate found a new version — notify renderer
|
|
1572
|
+
const info = Updater.updateInfo();
|
|
1573
|
+
sendToActiveRenderer("desktopUpdateAvailable", {
|
|
1574
|
+
version: info.version,
|
|
1575
|
+
});
|
|
1576
|
+
} else if (entry.status === "download-complete") {
|
|
1577
|
+
// downloadUpdate finished — update is ready to apply
|
|
1578
|
+
const info = Updater.updateInfo();
|
|
1579
|
+
sendToActiveRenderer("desktopUpdateReady", { version: info.version });
|
|
1580
|
+
Utils.showNotification({
|
|
1581
|
+
title: `${BRAND.appName} Update Ready`,
|
|
1582
|
+
body: `Version ${info.version} is ready. Restart to apply.`,
|
|
1583
|
+
});
|
|
1584
|
+
}
|
|
1585
|
+
});
|
|
1586
|
+
|
|
1587
|
+
const triggerManualUpdateCheck = () => {
|
|
1588
|
+
Utils.showNotification({
|
|
1589
|
+
title: "Checking for Updates",
|
|
1590
|
+
body: `${BRAND.appName} is checking for a newer release.`,
|
|
1591
|
+
});
|
|
1592
|
+
void runUpdateCheck(true);
|
|
1593
|
+
};
|
|
1594
|
+
|
|
1595
|
+
const handleApplicationMenuAction = async (
|
|
1596
|
+
action: string | undefined,
|
|
1597
|
+
): Promise<void> => {
|
|
1598
|
+
if (!currentWindow && shouldRestoreWindowBeforeMenuAction(action)) {
|
|
1599
|
+
await restoreWindow();
|
|
1600
|
+
}
|
|
1601
|
+
if (action === "check-for-updates") {
|
|
1602
|
+
triggerManualUpdateCheck();
|
|
1603
|
+
} else if (action === "open-about") {
|
|
1604
|
+
const updaterState = await getDesktopManager().getUpdaterState();
|
|
1605
|
+
const version = updaterState.currentVersion || "unknown";
|
|
1606
|
+
Utils.showNotification({
|
|
1607
|
+
title: `About ${BRAND.appName}`,
|
|
1608
|
+
body: `Version ${version} (${process.platform}/${process.arch})`,
|
|
1609
|
+
});
|
|
1610
|
+
void createSettingsWindow("updates");
|
|
1611
|
+
} else if (action === "export-config") {
|
|
1612
|
+
void exportConfigFromMenu();
|
|
1613
|
+
} else if (action === "import-config") {
|
|
1614
|
+
void importConfigFromMenu();
|
|
1615
|
+
} else if (action === "toggle-devtools") {
|
|
1616
|
+
toggleFocusedWindowDevTools();
|
|
1617
|
+
} else if (action === "relaunch") {
|
|
1618
|
+
void getDesktopManager().relaunch();
|
|
1619
|
+
} else if (action === "reset-app") {
|
|
1620
|
+
void resetTheAppFromApplicationMenu();
|
|
1621
|
+
} else if (action === "open-secrets-manager") {
|
|
1622
|
+
// The Secrets Storage modal lives in the renderer. Make sure
|
|
1623
|
+
// the main window is visible, then notify the renderer to
|
|
1624
|
+
// show the modal. The keyboard accelerator
|
|
1625
|
+
// (⌘⌥⌃V on Mac / Ctrl+Alt+Shift+V on Win/Linux) flows
|
|
1626
|
+
// through this same path; the renderer's `keydown` listener
|
|
1627
|
+
// also dispatches the same toggle directly when a Eliza
|
|
1628
|
+
// window is already focused.
|
|
1629
|
+
void restoreWindow();
|
|
1630
|
+
sendToActiveRenderer("openSecretsManager", {});
|
|
1631
|
+
} else if (
|
|
1632
|
+
action === "open-settings" ||
|
|
1633
|
+
action?.startsWith("open-settings-")
|
|
1634
|
+
) {
|
|
1635
|
+
void createSettingsWindow(parseSettingsWindowAction(action));
|
|
1636
|
+
} else if (action?.startsWith("new-window:")) {
|
|
1637
|
+
const surface = action.slice("new-window:".length);
|
|
1638
|
+
if (surfaceWindowManager && isDetachedSurface(surface)) {
|
|
1639
|
+
void surfaceWindowManager.openSurfaceWindow(surface);
|
|
1640
|
+
}
|
|
1641
|
+
} else if (action?.startsWith("focus-window:")) {
|
|
1642
|
+
const windowId = action.slice("focus-window:".length);
|
|
1643
|
+
surfaceWindowManager?.focusWindow(windowId);
|
|
1644
|
+
} else if (action?.startsWith("show-main:")) {
|
|
1645
|
+
const surface = action.slice("show-main:".length);
|
|
1646
|
+
showMainSurface(surface);
|
|
1647
|
+
} else if (action === "focus-main-window") {
|
|
1648
|
+
void getDesktopManager().focusWindow();
|
|
1649
|
+
} else if (action === "hide-main-window") {
|
|
1650
|
+
void getDesktopManager().hideWindow();
|
|
1651
|
+
} else if (action === "maximize-main-window") {
|
|
1652
|
+
void getDesktopManager().maximizeWindow();
|
|
1653
|
+
} else if (action === "restore-main-window") {
|
|
1654
|
+
void getDesktopManager().unmaximizeWindow();
|
|
1655
|
+
} else if (action === "desktop-notify") {
|
|
1656
|
+
void getDesktopManager().showNotification({
|
|
1657
|
+
title: `${BRAND.appName} Desktop`,
|
|
1658
|
+
body: `${BRAND.appName} native application menu actions are wired and responding.`,
|
|
1659
|
+
urgency: "normal",
|
|
1660
|
+
});
|
|
1661
|
+
} else if (action === "restart-steward") {
|
|
1662
|
+
if (isStewardLocalEnabled()) {
|
|
1663
|
+
restartSteward().catch((err: unknown) => {
|
|
1664
|
+
logger.error(
|
|
1665
|
+
`[Main] Steward restart failed: ${err instanceof Error ? err.message : String(err)}`,
|
|
1666
|
+
);
|
|
1667
|
+
Utils.showNotification({
|
|
1668
|
+
title: "Steward Restart Failed",
|
|
1669
|
+
body: err instanceof Error ? err.message : "Unknown error",
|
|
1670
|
+
});
|
|
1671
|
+
});
|
|
1672
|
+
}
|
|
1673
|
+
} else if (action === "reset-steward") {
|
|
1674
|
+
if (isStewardLocalEnabled()) {
|
|
1675
|
+
resetSteward().catch((err: unknown) => {
|
|
1676
|
+
logger.error(
|
|
1677
|
+
`[Main] Steward reset failed: ${err instanceof Error ? err.message : String(err)}`,
|
|
1678
|
+
);
|
|
1679
|
+
Utils.showNotification({
|
|
1680
|
+
title: "Steward Reset Failed",
|
|
1681
|
+
body: err instanceof Error ? err.message : "Unknown error",
|
|
1682
|
+
});
|
|
1683
|
+
});
|
|
1684
|
+
}
|
|
1685
|
+
} else if (
|
|
1686
|
+
action?.startsWith("apps:") ||
|
|
1687
|
+
action?.startsWith("tray-app-")
|
|
1688
|
+
) {
|
|
1689
|
+
// Both shapes resolve to the same flow:
|
|
1690
|
+
// 1. Look up the app entry by slug.
|
|
1691
|
+
// 2. If the app declares hasDetailsPage, focus the main window
|
|
1692
|
+
// and tell the renderer to navigate to /apps/<slug>/details
|
|
1693
|
+
// (where the user can review config + click Launch).
|
|
1694
|
+
// 3. Otherwise, open or focus its dedicated native window
|
|
1695
|
+
// directly (zero-config viewers / overlays).
|
|
1696
|
+
// WHY two prefixes: `apps:<slug>` is what `buildAppsMenu` emits
|
|
1697
|
+
// for the OS menu bar; `tray-app-<slug>` is what the tray icons
|
|
1698
|
+
// emit. Both arrive here.
|
|
1699
|
+
const slug = action.startsWith("apps:")
|
|
1700
|
+
? action.slice("apps:".length)
|
|
1701
|
+
: action.slice("tray-app-".length);
|
|
1702
|
+
const entry = findAppMenuEntryBySlug(slug);
|
|
1703
|
+
if (entry) {
|
|
1704
|
+
if (entry.hasDetailsPage) {
|
|
1705
|
+
// Restore main window first so the renderer route is visible.
|
|
1706
|
+
void restoreWindow();
|
|
1707
|
+
sendToActiveRenderer("desktopAppDetailsRequested", {
|
|
1708
|
+
slug: entry.slug,
|
|
1709
|
+
});
|
|
1710
|
+
} else {
|
|
1711
|
+
void getDesktopManager().openAppWindow({
|
|
1712
|
+
slug: entry.slug,
|
|
1713
|
+
title: entry.displayName,
|
|
1714
|
+
path: entry.windowPath,
|
|
1715
|
+
alwaysOnTop: false,
|
|
1716
|
+
});
|
|
1717
|
+
}
|
|
1718
|
+
}
|
|
1719
|
+
} else if (action === "restart-agent") {
|
|
1720
|
+
getAgentManager()
|
|
1721
|
+
.restart()
|
|
1722
|
+
.catch((err: unknown) => {
|
|
1723
|
+
logger.error(
|
|
1724
|
+
`[Main] Agent restart failed: ${err instanceof Error ? err.message : String(err)}`,
|
|
1725
|
+
);
|
|
1726
|
+
});
|
|
1727
|
+
} else if (action === "quit") {
|
|
1728
|
+
void getDesktopManager().quit();
|
|
1729
|
+
} else if (action === "show") {
|
|
1730
|
+
void getDesktopManager().showWindow();
|
|
1731
|
+
} else if (action?.startsWith("navigate-")) {
|
|
1732
|
+
void getDesktopManager().showWindow();
|
|
1733
|
+
sendToActiveRenderer("desktopTrayMenuClick", { itemId: action });
|
|
1734
|
+
}
|
|
1735
|
+
};
|
|
1736
|
+
|
|
1737
|
+
setApplicationMenuActionHandler(handleApplicationMenuAction);
|
|
1738
|
+
|
|
1739
|
+
Electrobun.events.on(
|
|
1740
|
+
"application-menu-clicked",
|
|
1741
|
+
(e: { data?: { action?: string } }) => {
|
|
1742
|
+
void handleApplicationMenuAction(e?.data?.action);
|
|
1743
|
+
},
|
|
1744
|
+
);
|
|
1745
|
+
|
|
1746
|
+
// Route tray app entries (`tray-app-<slug>`) into the same handler as the
|
|
1747
|
+
// OS menu bar. WHY: the desktop manager forwards every tray click to the
|
|
1748
|
+
// renderer, but spawning native windows must happen on the bun side.
|
|
1749
|
+
Electrobun.events.on(
|
|
1750
|
+
"tray-clicked",
|
|
1751
|
+
(e: { data?: { action?: string } }) => {
|
|
1752
|
+
const action = e?.data?.action;
|
|
1753
|
+
if (typeof action === "string" && action.startsWith("tray-app-")) {
|
|
1754
|
+
void handleApplicationMenuAction(action);
|
|
1755
|
+
}
|
|
1756
|
+
},
|
|
1757
|
+
);
|
|
1758
|
+
|
|
1759
|
+
Electrobun.events.on("context-menu-clicked", (action: string) => {
|
|
1760
|
+
if (action === "check-for-updates") {
|
|
1761
|
+
triggerManualUpdateCheck();
|
|
1762
|
+
} else if (action === "relaunch") {
|
|
1763
|
+
void getDesktopManager().relaunch();
|
|
1764
|
+
}
|
|
1765
|
+
});
|
|
1766
|
+
|
|
1767
|
+
await runUpdateCheck(false);
|
|
1768
|
+
} catch (err) {
|
|
1769
|
+
logger.warn(
|
|
1770
|
+
`[Updater] Update check failed: ${err instanceof Error ? err.message : String(err)}`,
|
|
1771
|
+
);
|
|
1772
|
+
}
|
|
1773
|
+
}
|
|
1774
|
+
|
|
1775
|
+
/**
|
|
1776
|
+
* Handle a `<scheme>://...` deep link. Recognized routes:
|
|
1777
|
+
* - `<scheme>://apps/<slug>` → open or focus the matching app window
|
|
1778
|
+
* - anything else → forward to renderer as a generic share target so
|
|
1779
|
+
* in-app handlers (share-into-chat, etc.) can react.
|
|
1780
|
+
*
|
|
1781
|
+
* The URL scheme itself is configured at build time (electrobun.config.ts:
|
|
1782
|
+
* `urlSchemes`, sourced from `ELIZA_URL_SCHEME`) — this handler does not
|
|
1783
|
+
* care which scheme is used; it only routes by host + pathname.
|
|
1784
|
+
*/
|
|
1785
|
+
function handleDeepLink(url: string): void {
|
|
1786
|
+
let parsed: URL;
|
|
1787
|
+
try {
|
|
1788
|
+
parsed = new URL(url);
|
|
1789
|
+
} catch {
|
|
1790
|
+
sendToActiveRenderer("shareTargetReceived", { url });
|
|
1791
|
+
return;
|
|
1792
|
+
}
|
|
1793
|
+
|
|
1794
|
+
// `<scheme>://apps/<slug>` → URL parses host="apps", pathname="/<slug>"
|
|
1795
|
+
if (parsed.host === "apps") {
|
|
1796
|
+
const slug = parsed.pathname
|
|
1797
|
+
.replace(/^\/+/, "")
|
|
1798
|
+
.replace(/[?#].*$/, "")
|
|
1799
|
+
.split("/")[0];
|
|
1800
|
+
if (slug) {
|
|
1801
|
+
const entry = findAppMenuEntryBySlug(slug);
|
|
1802
|
+
if (entry) {
|
|
1803
|
+
// Mirror the menu/tray handler: apps with a details page get a config
|
|
1804
|
+
// review screen instead of a direct window so deep links and clicks
|
|
1805
|
+
// produce identical UX.
|
|
1806
|
+
if (entry.hasDetailsPage) {
|
|
1807
|
+
void restoreWindow();
|
|
1808
|
+
sendToActiveRenderer("desktopAppDetailsRequested", {
|
|
1809
|
+
slug: entry.slug,
|
|
1810
|
+
});
|
|
1811
|
+
} else {
|
|
1812
|
+
void getDesktopManager().openAppWindow({
|
|
1813
|
+
slug: entry.slug,
|
|
1814
|
+
title: entry.displayName,
|
|
1815
|
+
path: entry.windowPath,
|
|
1816
|
+
alwaysOnTop: false,
|
|
1817
|
+
});
|
|
1818
|
+
}
|
|
1819
|
+
return;
|
|
1820
|
+
}
|
|
1821
|
+
}
|
|
1822
|
+
}
|
|
1823
|
+
|
|
1824
|
+
sendToActiveRenderer("shareTargetReceived", { url });
|
|
1825
|
+
}
|
|
1826
|
+
|
|
1827
|
+
function setupDeepLinks(): void {
|
|
1828
|
+
Electrobun.events.on("open-url", (url: string) => {
|
|
1829
|
+
handleDeepLink(url);
|
|
1830
|
+
});
|
|
1831
|
+
}
|
|
1832
|
+
|
|
1833
|
+
function setupDockReopen(): void {
|
|
1834
|
+
Electrobun.events.on("reopen", () => {
|
|
1835
|
+
void restoreWindow();
|
|
1836
|
+
});
|
|
1837
|
+
}
|
|
1838
|
+
|
|
1839
|
+
async function runShutdownCleanup(reason: string): Promise<void> {
|
|
1840
|
+
logger.info(`[Main] App quitting (${reason}), disposing native modules...`);
|
|
1841
|
+
isQuitting = true;
|
|
1842
|
+
sendToActiveRenderer("desktopShutdownStarted", { reason });
|
|
1843
|
+
for (const cleanupFn of cleanupFns) {
|
|
1844
|
+
await Promise.resolve(cleanupFn());
|
|
1845
|
+
}
|
|
1846
|
+
await disposeNativeModules();
|
|
1847
|
+
}
|
|
1848
|
+
|
|
1849
|
+
function setupShutdown(): void {
|
|
1850
|
+
Electrobun.events.on("before-quit", () => {
|
|
1851
|
+
void runShutdownCleanup("before-quit");
|
|
1852
|
+
});
|
|
1853
|
+
}
|
|
1854
|
+
|
|
1855
|
+
/**
|
|
1856
|
+
* Load repo-root and ~/.eliza/.env into `process.env` (non-destructive) so the
|
|
1857
|
+
* main process can send the same `ELIZA_API_TOKEN` as `dev-server.ts` when
|
|
1858
|
+
* calling loopback APIs (app menu reset, export, etc.). The dev API child
|
|
1859
|
+
* already loads dotenv; Electrobun did not until this ran.
|
|
1860
|
+
*
|
|
1861
|
+
* Packaged desktop builds must not load these files. On machines that also
|
|
1862
|
+
* have a the app/Eliza dev checkout, ~/.eliza/.env can contain
|
|
1863
|
+
* ELIZA_DESKTOP_API_BASE and related overrides that switch the packaged app
|
|
1864
|
+
* into external mode and make launcher startup appear dead.
|
|
1865
|
+
*/
|
|
1866
|
+
async function loadTheAppEnvFilesForMain(): Promise<void> {
|
|
1867
|
+
const normalizedModuleDir = import.meta.dir.replaceAll("\\", "/");
|
|
1868
|
+
const isPackagedBuild = !normalizedModuleDir.includes("/src/");
|
|
1869
|
+
if (isPackagedBuild) {
|
|
1870
|
+
return;
|
|
1871
|
+
}
|
|
1872
|
+
|
|
1873
|
+
try {
|
|
1874
|
+
const { config } = await import("dotenv");
|
|
1875
|
+
const repoRootGuess = path.resolve(
|
|
1876
|
+
normalizedModuleDir,
|
|
1877
|
+
"..",
|
|
1878
|
+
"..",
|
|
1879
|
+
"..",
|
|
1880
|
+
"..",
|
|
1881
|
+
);
|
|
1882
|
+
for (const envPath of [
|
|
1883
|
+
path.join(repoRootGuess, ".env"),
|
|
1884
|
+
path.join(os.homedir(), ".eliza", ".env"),
|
|
1885
|
+
]) {
|
|
1886
|
+
if (fs.existsSync(envPath)) {
|
|
1887
|
+
config({ path: envPath, override: false });
|
|
1888
|
+
}
|
|
1889
|
+
}
|
|
1890
|
+
} catch {
|
|
1891
|
+
/* dotenv may be unavailable in minimal installs */
|
|
1892
|
+
}
|
|
1893
|
+
}
|
|
1894
|
+
|
|
1895
|
+
function initializeBundledWebGPU(): void {
|
|
1896
|
+
if (!WGPU.native.available) {
|
|
1897
|
+
logger.info(
|
|
1898
|
+
"[WebGPU] Native Dawn runtime not bundled for this run; renderer-side WebGPU remains available through the webview/browser path.",
|
|
1899
|
+
);
|
|
1900
|
+
return;
|
|
1901
|
+
}
|
|
1902
|
+
|
|
1903
|
+
webgpu.install();
|
|
1904
|
+
logger.info(`[WebGPU] Native Dawn runtime ready at ${WGPU.native.path}`);
|
|
1905
|
+
}
|
|
1906
|
+
|
|
1907
|
+
/**
|
|
1908
|
+
* Check WebGPU availability in the webview browser and push status to renderer.
|
|
1909
|
+
*
|
|
1910
|
+
* **WHY not inline `os.release() - 9`:** that was wrong on macOS 26 (Darwin 25);
|
|
1911
|
+
* see `checkWebGpuSupport` / `getMacOSMajorVersion` in `webgpu-browser-support.ts`
|
|
1912
|
+
* and `docs/apps/electrobun-darwin-macos-webgpu-version.md`.
|
|
1913
|
+
*
|
|
1914
|
+
* On macOS 26+ with native renderer, WebGPU is expected via WKWebView.
|
|
1915
|
+
* On Linux/Windows with CEF, upstream Electrobun flag support is still needed.
|
|
1916
|
+
*/
|
|
1917
|
+
function checkWebGpuBrowserSupport(): void {
|
|
1918
|
+
const status = checkWebGpuSupport();
|
|
1919
|
+
if (status.available) {
|
|
1920
|
+
logger.info(`[WebGPU Browser] ${status.reason}`);
|
|
1921
|
+
} else {
|
|
1922
|
+
logger.warn(`[WebGPU Browser] ${status.reason}`);
|
|
1923
|
+
if (status.chromeBetaPath) {
|
|
1924
|
+
logger.info(
|
|
1925
|
+
`[WebGPU Browser] Chrome Beta found at: ${status.chromeBetaPath}`,
|
|
1926
|
+
);
|
|
1927
|
+
} else if (status.downloadUrl) {
|
|
1928
|
+
logger.info(
|
|
1929
|
+
`[WebGPU Browser] Download Chrome Beta: ${status.downloadUrl}`,
|
|
1930
|
+
);
|
|
1931
|
+
}
|
|
1932
|
+
}
|
|
1933
|
+
|
|
1934
|
+
// Push status to renderer after a short delay to allow window creation.
|
|
1935
|
+
setTimeout(() => {
|
|
1936
|
+
sendToActiveRenderer("webgpu:browserStatus", status);
|
|
1937
|
+
}, 2000);
|
|
1938
|
+
}
|
|
1939
|
+
|
|
1940
|
+
async function main(): Promise<void> {
|
|
1941
|
+
recordStartupPhase("main_start", {
|
|
1942
|
+
pid: process.pid,
|
|
1943
|
+
exec_path: process.execPath,
|
|
1944
|
+
bundle_path: resolveStartupBundlePath(process.execPath),
|
|
1945
|
+
});
|
|
1946
|
+
await loadTheAppEnvFilesForMain();
|
|
1947
|
+
recordStartupPhase("env_loaded", {
|
|
1948
|
+
pid: process.pid,
|
|
1949
|
+
});
|
|
1950
|
+
console.log(`[Main] Starting ${BRAND.appName} (Electrobun)`);
|
|
1951
|
+
const normalizedModuleDir = import.meta.dir.replaceAll("\\", "/");
|
|
1952
|
+
const runtimeResolution = resolveDesktopRuntimeMode(
|
|
1953
|
+
process.env as Record<string, string | undefined>,
|
|
1954
|
+
);
|
|
1955
|
+
// Structured startup environment block — visible in CI logs and eliza-startup.log
|
|
1956
|
+
console.log(
|
|
1957
|
+
`[Env] platform=${process.platform} arch=${process.arch} bun=${Bun.version} ` +
|
|
1958
|
+
`execPath=${process.execPath} cwd=${process.cwd()} moduleDir=${import.meta.dir} ` +
|
|
1959
|
+
`packaged=${!normalizedModuleDir.includes("/src/")} argv=${process.argv.slice(1).join(" ")}`,
|
|
1960
|
+
);
|
|
1961
|
+
console.log(
|
|
1962
|
+
`[Env] desktopRuntimeMode=${runtimeResolution.mode} externalApi=${runtimeResolution.externalApi.base ?? "none"}`,
|
|
1963
|
+
);
|
|
1964
|
+
|
|
1965
|
+
printElectrobunDevSettingsBanner(
|
|
1966
|
+
process.env as Record<string, string | undefined>,
|
|
1967
|
+
);
|
|
1968
|
+
|
|
1969
|
+
await maybePromptStartupCrashReport();
|
|
1970
|
+
recordStartupPhase("crash_prompt_checked", {
|
|
1971
|
+
pid: process.pid,
|
|
1972
|
+
});
|
|
1973
|
+
// On Windows (CEF renderer), clear stale CEF profile data when the app
|
|
1974
|
+
// version changes. A leftover Partitions/default profile from a previous
|
|
1975
|
+
// install causes "Cannot create profile at path" errors that cascade into
|
|
1976
|
+
// GPU process crashes, rendering the UI unusable. Clearing the CEF cache
|
|
1977
|
+
// is safe — it only contains browser session state (cookies, caches,
|
|
1978
|
+
// LevelDB stores) that CEF recreates on next launch.
|
|
1979
|
+
if (process.platform === "win32") {
|
|
1980
|
+
try {
|
|
1981
|
+
const cefDir = path.join(Utils.paths.userData, "CEF");
|
|
1982
|
+
const cefVersionMarker = path.join(
|
|
1983
|
+
cefDir,
|
|
1984
|
+
BRAND.cefVersionMarkerFileName,
|
|
1985
|
+
);
|
|
1986
|
+
const currentVersion =
|
|
1987
|
+
resolveDesktopBundleVersion(import.meta.dir) ?? "unknown";
|
|
1988
|
+
let previousVersion: string | null = null;
|
|
1989
|
+
try {
|
|
1990
|
+
previousVersion = fs.readFileSync(cefVersionMarker, "utf-8").trim();
|
|
1991
|
+
} catch {
|
|
1992
|
+
// No marker — first run or pre-fix install.
|
|
1993
|
+
}
|
|
1994
|
+
if (
|
|
1995
|
+
shouldResetWindowsCefProfile({
|
|
1996
|
+
currentVersion,
|
|
1997
|
+
previousVersion,
|
|
1998
|
+
cefDirExists: fs.existsSync(cefDir),
|
|
1999
|
+
})
|
|
2000
|
+
) {
|
|
2001
|
+
logger.info(
|
|
2002
|
+
`[Main] CEF version mismatch (${previousVersion ?? "none"} → ${currentVersion}), clearing stale CEF profile`,
|
|
2003
|
+
);
|
|
2004
|
+
// Remove everything except the version marker we're about to write.
|
|
2005
|
+
for (const entry of fs.readdirSync(cefDir)) {
|
|
2006
|
+
if (entry === BRAND.cefVersionMarkerFileName) continue;
|
|
2007
|
+
const entryPath = path.join(cefDir, entry);
|
|
2008
|
+
try {
|
|
2009
|
+
fs.rmSync(entryPath, { recursive: true, force: true });
|
|
2010
|
+
} catch (err) {
|
|
2011
|
+
logger.warn(
|
|
2012
|
+
`[Main] Could not remove ${entryPath}: ${err instanceof Error ? err.message : String(err)}`,
|
|
2013
|
+
);
|
|
2014
|
+
}
|
|
2015
|
+
}
|
|
2016
|
+
}
|
|
2017
|
+
// Write/update version marker so we don't clear again on next launch.
|
|
2018
|
+
if (shouldWriteWindowsCefProfileMarker(currentVersion)) {
|
|
2019
|
+
fs.mkdirSync(cefDir, { recursive: true });
|
|
2020
|
+
fs.writeFileSync(cefVersionMarker, currentVersion);
|
|
2021
|
+
}
|
|
2022
|
+
} catch (err) {
|
|
2023
|
+
logger.warn(
|
|
2024
|
+
`[Main] CEF profile cleanup failed (non-fatal): ${err instanceof Error ? err.message : String(err)}`,
|
|
2025
|
+
);
|
|
2026
|
+
}
|
|
2027
|
+
}
|
|
2028
|
+
|
|
2029
|
+
initializeBundledWebGPU();
|
|
2030
|
+
recordStartupPhase("webgpu_initialized", {
|
|
2031
|
+
pid: process.pid,
|
|
2032
|
+
});
|
|
2033
|
+
checkWebGpuBrowserSupport();
|
|
2034
|
+
cleanupFns.length = 0;
|
|
2035
|
+
cleanupFns.push(await startBrowserWorkspaceBridgeServer());
|
|
2036
|
+
recordStartupPhase("browser_workspace_bridge_ready", {
|
|
2037
|
+
pid: process.pid,
|
|
2038
|
+
});
|
|
2039
|
+
const stopDesktopTestBridgeServer = await startDesktopTestBridgeServer();
|
|
2040
|
+
recordStartupPhase("desktop_test_bridge_ready", {
|
|
2041
|
+
pid: process.pid,
|
|
2042
|
+
});
|
|
2043
|
+
if (stopDesktopTestBridgeServer) {
|
|
2044
|
+
cleanupFns.push(stopDesktopTestBridgeServer);
|
|
2045
|
+
}
|
|
2046
|
+
|
|
2047
|
+
// WHY push API base on every status tick with a port: embedded startup can
|
|
2048
|
+
// settle on a different loopback port than env/static HTML (allocation + stdout).
|
|
2049
|
+
// Detached surfaces must not keep a stale __ELIZA_API_BASE__ while the main
|
|
2050
|
+
// window was already updated—menu reset, chat, and settings each own a webview.
|
|
2051
|
+
cleanupFns.push(
|
|
2052
|
+
getAgentManager().onStatusChange((status) => {
|
|
2053
|
+
if (status.port) {
|
|
2054
|
+
// The agent rebound to a different loopback port (or recovered from a
|
|
2055
|
+
// crash) — the cookies we installed during _startAgent were scoped to
|
|
2056
|
+
// the old origin. Re-prime so the renderer's next /api request stays
|
|
2057
|
+
// authenticated.
|
|
2058
|
+
markDesktopSessionStale();
|
|
2059
|
+
const apiBase = `http://127.0.0.1:${status.port}`;
|
|
2060
|
+
const rendererBase = resolveRendererFacingApiBase(
|
|
2061
|
+
process.env as Record<string, string | undefined>,
|
|
2062
|
+
status.port,
|
|
2063
|
+
);
|
|
2064
|
+
void primeDesktopSessionAuth(apiBase, rendererBase);
|
|
2065
|
+
if (currentWindow) {
|
|
2066
|
+
injectApiBase(currentWindow);
|
|
2067
|
+
}
|
|
2068
|
+
surfaceWindowManager?.forEachWindow((w) => {
|
|
2069
|
+
injectApiBase(w as BrowserWindow);
|
|
2070
|
+
});
|
|
2071
|
+
}
|
|
2072
|
+
}),
|
|
2073
|
+
);
|
|
2074
|
+
|
|
2075
|
+
// Create window first — on Windows (CEF) the UI message loop must be
|
|
2076
|
+
// running before any synchronous FFI calls like setApplicationMenu().
|
|
2077
|
+
// Calling setupApplicationMenu() before createMainWindow() deadlocks.
|
|
2078
|
+
recordStartupPhase("creating_window", {
|
|
2079
|
+
pid: process.pid,
|
|
2080
|
+
});
|
|
2081
|
+
const { rpc: mainRpc, sendToWebview: mainSendToWebview } =
|
|
2082
|
+
createDesktopRpc("main");
|
|
2083
|
+
const mainWin = attachMainWindow(
|
|
2084
|
+
await createMainWindow(mainRpc),
|
|
2085
|
+
mainRpc,
|
|
2086
|
+
mainSendToWebview,
|
|
2087
|
+
);
|
|
2088
|
+
recordStartupPhase("window_ready", {
|
|
2089
|
+
pid: process.pid,
|
|
2090
|
+
});
|
|
2091
|
+
|
|
2092
|
+
// Configure the floating chat manager now that the renderer URL is resolved.
|
|
2093
|
+
// This must run after createMainWindow() so rendererUrlPromise is already set.
|
|
2094
|
+
void resolveRendererUrl().then((url) => {
|
|
2095
|
+
let preload = "";
|
|
2096
|
+
try {
|
|
2097
|
+
preload = readResolvedPreloadScript(import.meta.dir);
|
|
2098
|
+
} catch {
|
|
2099
|
+
/* non-fatal */
|
|
2100
|
+
}
|
|
2101
|
+
getFloatingChatManager().configure(url, preload);
|
|
2102
|
+
});
|
|
2103
|
+
|
|
2104
|
+
// Per-window RPC tracking: surface windows each get their own typed
|
|
2105
|
+
// RPC built up front via createDesktopRpc, baked into the BrowserWindow
|
|
2106
|
+
// constructor, then "wired" post-hoc by wireSettingsRpcAfterCreate.
|
|
2107
|
+
const surfaceRpcs = new WeakMap<ManagedWindowLike, ElizaDesktopRpc>();
|
|
2108
|
+
|
|
2109
|
+
surfaceWindowManager = new SurfaceWindowManager({
|
|
2110
|
+
createWindow: (options) => {
|
|
2111
|
+
const { rpc } = createDesktopRpc("surface");
|
|
2112
|
+
const window = new BrowserWindow({
|
|
2113
|
+
...options,
|
|
2114
|
+
rpc,
|
|
2115
|
+
}) as BrowserWindow & ManagedWindowLike;
|
|
2116
|
+
surfaceRpcs.set(window, rpc);
|
|
2117
|
+
return window;
|
|
2118
|
+
},
|
|
2119
|
+
resolveRendererUrl,
|
|
2120
|
+
readPreload: () => readResolvedPreloadScript(import.meta.dir),
|
|
2121
|
+
wireRpc: (window) => {
|
|
2122
|
+
const rpc = surfaceRpcs.get(window);
|
|
2123
|
+
if (!rpc) {
|
|
2124
|
+
logger.warn(
|
|
2125
|
+
"[surface-windows] wireRpc called for window with no tracked rpc; skipping browser-workspace caller setup",
|
|
2126
|
+
);
|
|
2127
|
+
return;
|
|
2128
|
+
}
|
|
2129
|
+
wireSettingsRpcAfterCreate(rpc);
|
|
2130
|
+
},
|
|
2131
|
+
injectApiBase: (window) =>
|
|
2132
|
+
injectApiBase(window as BrowserWindow & ManagedWindowLike),
|
|
2133
|
+
onWindowFocused: (window) => {
|
|
2134
|
+
lastFocusedWindow = window;
|
|
2135
|
+
},
|
|
2136
|
+
onRegistryChanged: () => {
|
|
2137
|
+
sendManagedWindowsChanged();
|
|
2138
|
+
setupApplicationMenu();
|
|
2139
|
+
},
|
|
2140
|
+
boundsStore: createAppWindowBoundsStore(),
|
|
2141
|
+
});
|
|
2142
|
+
// Set up app menu after the window (and its message loop) exists.
|
|
2143
|
+
setupApplicationMenu();
|
|
2144
|
+
const stopScreenshotDevServer = startScreenshotDevServer();
|
|
2145
|
+
if (stopScreenshotDevServer) {
|
|
2146
|
+
cleanupFns.push(stopScreenshotDevServer);
|
|
2147
|
+
}
|
|
2148
|
+
|
|
2149
|
+
// Wire detached window callbacks so menus and RPC can open them.
|
|
2150
|
+
getDesktopManager().setOpenSettingsCallback((tabHint) => {
|
|
2151
|
+
void createSettingsWindow(tabHint);
|
|
2152
|
+
});
|
|
2153
|
+
getDesktopManager().setRestoreMainWindowCallback(() => restoreWindow());
|
|
2154
|
+
getDesktopManager().setRequestQuitCallback(() => {
|
|
2155
|
+
requestAppQuit();
|
|
2156
|
+
});
|
|
2157
|
+
getDesktopManager().setOpenSurfaceWindowCallback(
|
|
2158
|
+
(surface, browse, alwaysOnTop) => {
|
|
2159
|
+
if (!surfaceWindowManager) {
|
|
2160
|
+
throw new Error("Surface window manager is not ready.");
|
|
2161
|
+
}
|
|
2162
|
+
return surfaceWindowManager.openSurfaceWindow(
|
|
2163
|
+
surface,
|
|
2164
|
+
browse,
|
|
2165
|
+
alwaysOnTop === true,
|
|
2166
|
+
);
|
|
2167
|
+
},
|
|
2168
|
+
);
|
|
2169
|
+
getDesktopManager().setOpenAppWindowCallback((options) => {
|
|
2170
|
+
if (!surfaceWindowManager) {
|
|
2171
|
+
throw new Error("Surface window manager is not ready.");
|
|
2172
|
+
}
|
|
2173
|
+
return surfaceWindowManager.openAppWindow(options);
|
|
2174
|
+
});
|
|
2175
|
+
getDesktopManager().setManagedWindowAlwaysOnTopCallback((id, flag) => {
|
|
2176
|
+
return surfaceWindowManager?.setWindowAlwaysOnTop(id, flag) ?? false;
|
|
2177
|
+
});
|
|
2178
|
+
|
|
2179
|
+
// If launched with --hidden (e.g. auto-launch with openAsHidden), minimize immediately.
|
|
2180
|
+
if (process.argv.includes("--hidden")) {
|
|
2181
|
+
try {
|
|
2182
|
+
mainWin.minimize();
|
|
2183
|
+
} catch (err) {
|
|
2184
|
+
logger.warn(
|
|
2185
|
+
`[Main] Failed to minimize window on --hidden startup: ${err instanceof Error ? err.message : String(err)}`,
|
|
2186
|
+
);
|
|
2187
|
+
}
|
|
2188
|
+
}
|
|
2189
|
+
|
|
2190
|
+
setupDeepLinks();
|
|
2191
|
+
setupDockReopen();
|
|
2192
|
+
|
|
2193
|
+
const desktop = getDesktopManager();
|
|
2194
|
+
try {
|
|
2195
|
+
await desktop.createTray({
|
|
2196
|
+
icon: resolveDesktopAppIconPath(),
|
|
2197
|
+
tooltip: BRAND.appName,
|
|
2198
|
+
title: BRAND.appName,
|
|
2199
|
+
menu: [
|
|
2200
|
+
{ id: "tray-show-window", label: "Show Window", type: "normal" },
|
|
2201
|
+
{ id: "sep-apps", type: "separator" },
|
|
2202
|
+
// One entry per known app — clicks dispatch to handleApplicationMenuAction
|
|
2203
|
+
// via the bun-side `tray-clicked` listener below, which then opens (or
|
|
2204
|
+
// focuses) the dedicated native window for that app.
|
|
2205
|
+
...getAppMenuEntries().map((entry) => ({
|
|
2206
|
+
id: `tray-app-${entry.slug}`,
|
|
2207
|
+
label: entry.displayName,
|
|
2208
|
+
type: "normal" as const,
|
|
2209
|
+
})),
|
|
2210
|
+
{ id: "sep-lifecycle", type: "separator" },
|
|
2211
|
+
{
|
|
2212
|
+
id: "tray-toggle-lifecycle",
|
|
2213
|
+
label: "Start/Stop Agent",
|
|
2214
|
+
type: "normal",
|
|
2215
|
+
},
|
|
2216
|
+
{
|
|
2217
|
+
id: "tray-restart",
|
|
2218
|
+
label: "Restart Agent",
|
|
2219
|
+
type: "normal",
|
|
2220
|
+
},
|
|
2221
|
+
{ id: "sep-quit", type: "separator" },
|
|
2222
|
+
{ id: "quit", label: "Quit", type: "normal" },
|
|
2223
|
+
],
|
|
2224
|
+
});
|
|
2225
|
+
} catch (err) {
|
|
2226
|
+
logger.warn(
|
|
2227
|
+
`[Main] Tray creation failed: ${err instanceof Error ? err.message : String(err)}`,
|
|
2228
|
+
);
|
|
2229
|
+
}
|
|
2230
|
+
|
|
2231
|
+
// ── Steward sidecar startup (must happen BEFORE agent) ────────────
|
|
2232
|
+
// When STEWARD_LOCAL=true, start the steward sidecar first so it can
|
|
2233
|
+
// set STEWARD_API_URL / STEWARD_AGENT_TOKEN env vars. The the app agent's
|
|
2234
|
+
// steward-bridge.ts reads these on boot to discover local steward.
|
|
2235
|
+
if (isStewardLocalEnabled()) {
|
|
2236
|
+
logger.info("[Main] STEWARD_LOCAL=true — starting steward sidecar...");
|
|
2237
|
+
cleanupFns.push(() => stopSteward());
|
|
2238
|
+
|
|
2239
|
+
// Listen for steward status changes and push to renderer
|
|
2240
|
+
cleanupFns.push(
|
|
2241
|
+
onStewardStatusChange((status) => {
|
|
2242
|
+
sendToActiveRenderer("stewardStatusUpdate", status);
|
|
2243
|
+
}),
|
|
2244
|
+
);
|
|
2245
|
+
|
|
2246
|
+
try {
|
|
2247
|
+
const stewardResult = await startSteward();
|
|
2248
|
+
if (stewardResult.state === "running") {
|
|
2249
|
+
logger.info(
|
|
2250
|
+
`[Main] Steward sidecar ready on port ${stewardResult.port}, wallet: ${stewardResult.walletAddress ?? "pending"}`,
|
|
2251
|
+
);
|
|
2252
|
+
} else {
|
|
2253
|
+
logger.warn(
|
|
2254
|
+
`[Main] Steward sidecar in state "${stewardResult.state}": ${stewardResult.error ?? "unknown"}`,
|
|
2255
|
+
);
|
|
2256
|
+
sendToActiveRenderer("stewardStartupFailed", {
|
|
2257
|
+
error: stewardResult.error ?? "Steward failed to start",
|
|
2258
|
+
canRetry: true,
|
|
2259
|
+
});
|
|
2260
|
+
}
|
|
2261
|
+
} catch (err) {
|
|
2262
|
+
const error = err instanceof Error ? err.message : String(err);
|
|
2263
|
+
logger.error(`[Main] Steward sidecar startup failed: ${error}`);
|
|
2264
|
+
sendToActiveRenderer("stewardStartupFailed", {
|
|
2265
|
+
error,
|
|
2266
|
+
canRetry: true,
|
|
2267
|
+
});
|
|
2268
|
+
// Don't block agent startup — steward is optional
|
|
2269
|
+
}
|
|
2270
|
+
}
|
|
2271
|
+
|
|
2272
|
+
// Agent startup: in external mode, push the API base via the
|
|
2273
|
+
// api-base-owner (the agent is already running externally). In local
|
|
2274
|
+
// mode, start the embedded agent first — apiBaseOwner.injectIntoHtml()
|
|
2275
|
+
// already set the initial window.__ELIZA_API_BASE__ from the seed value
|
|
2276
|
+
// in main(), but _startAgent will push the actual port once the agent
|
|
2277
|
+
// reports it.
|
|
2278
|
+
if (currentWindow) {
|
|
2279
|
+
const rt = resolveDesktopRuntimeMode(
|
|
2280
|
+
process.env as Record<string, string | undefined>,
|
|
2281
|
+
);
|
|
2282
|
+
if (rt.mode === "external") {
|
|
2283
|
+
injectApiBase(currentWindow);
|
|
2284
|
+
} else if (rt.mode === "local") {
|
|
2285
|
+
logger.info("[Main] Starting embedded agent (local mode).");
|
|
2286
|
+
_startAgent(currentWindow).catch((err) => {
|
|
2287
|
+
logger.error(
|
|
2288
|
+
`[Main] Agent auto-start failed: ${err instanceof Error ? err.message : String(err)}`,
|
|
2289
|
+
);
|
|
2290
|
+
const error = err instanceof Error ? err.message : String(err);
|
|
2291
|
+
sendToActiveRenderer("agentStartupFailed", { error });
|
|
2292
|
+
console.error(`title: "${BRAND.appName} startup failed"`);
|
|
2293
|
+
});
|
|
2294
|
+
}
|
|
2295
|
+
}
|
|
2296
|
+
|
|
2297
|
+
void setupUpdater();
|
|
2298
|
+
cleanupFns.push(() => getAgentManager().stop());
|
|
2299
|
+
setupShutdown();
|
|
2300
|
+
}
|
|
2301
|
+
|
|
2302
|
+
function resolveStartupCrashReportPath(): string {
|
|
2303
|
+
return path.join(
|
|
2304
|
+
path.dirname(getDiagnosticLogPath()),
|
|
2305
|
+
STARTUP_CRASH_REPORT_FILE,
|
|
2306
|
+
);
|
|
2307
|
+
}
|
|
2308
|
+
|
|
2309
|
+
function resolveStartupCrashPromptMarkerPath(): string {
|
|
2310
|
+
return path.join(
|
|
2311
|
+
path.dirname(getDiagnosticLogPath()),
|
|
2312
|
+
STARTUP_CRASH_PROMPT_MARKER_FILE,
|
|
2313
|
+
);
|
|
2314
|
+
}
|
|
2315
|
+
|
|
2316
|
+
function buildStartupCrashDiscordReport(options: {
|
|
2317
|
+
source: "startup-recovery" | "fatal-startup";
|
|
2318
|
+
error: string | null;
|
|
2319
|
+
}): string {
|
|
2320
|
+
const diagnostics = getStartupDiagnosticsSnapshot();
|
|
2321
|
+
const startupLogTail = getStartupDiagnosticLogTail(8_000).trim();
|
|
2322
|
+
const appVersion = process.env.npm_package_version?.trim() || "unknown";
|
|
2323
|
+
const appRuntime = `electrobun/${Bun.version}`;
|
|
2324
|
+
const reportLines = [
|
|
2325
|
+
`${BRAND.appName} startup crash report`,
|
|
2326
|
+
"",
|
|
2327
|
+
"Share this report in Discord and ping @iono.",
|
|
2328
|
+
"",
|
|
2329
|
+
`Source: ${options.source}`,
|
|
2330
|
+
`Timestamp: ${new Date().toISOString()}`,
|
|
2331
|
+
`App Version: ${appVersion}`,
|
|
2332
|
+
`Runtime: ${appRuntime}`,
|
|
2333
|
+
`Platform: ${process.platform} ${process.arch}`,
|
|
2334
|
+
`State: ${diagnostics.state}`,
|
|
2335
|
+
`Phase: ${diagnostics.phase}`,
|
|
2336
|
+
`Last Error: ${options.error ?? diagnostics.lastError ?? "unknown"}`,
|
|
2337
|
+
`Updated At: ${diagnostics.updatedAt}`,
|
|
2338
|
+
`Log Path: ${diagnostics.logPath}`,
|
|
2339
|
+
`Status Path: ${diagnostics.statusPath}`,
|
|
2340
|
+
"",
|
|
2341
|
+
startupLogTail ? "Startup Log Tail:" : "Startup Log Tail: unavailable",
|
|
2342
|
+
];
|
|
2343
|
+
|
|
2344
|
+
if (startupLogTail) {
|
|
2345
|
+
reportLines.push("```");
|
|
2346
|
+
reportLines.push(startupLogTail);
|
|
2347
|
+
reportLines.push("```");
|
|
2348
|
+
}
|
|
2349
|
+
return `${reportLines.join("\n")}\n`;
|
|
2350
|
+
}
|
|
2351
|
+
|
|
2352
|
+
function persistStartupCrashReport(options: {
|
|
2353
|
+
source: "startup-recovery" | "fatal-startup";
|
|
2354
|
+
error: string | null;
|
|
2355
|
+
}): { report: string; reportPath: string } {
|
|
2356
|
+
const report = buildStartupCrashDiscordReport(options);
|
|
2357
|
+
const primaryReportPath = resolveStartupCrashReportPath();
|
|
2358
|
+
const fallbackReportPath = path.join(os.tmpdir(), STARTUP_CRASH_REPORT_FILE);
|
|
2359
|
+
let reportPath = primaryReportPath;
|
|
2360
|
+
try {
|
|
2361
|
+
fs.mkdirSync(path.dirname(primaryReportPath), { recursive: true });
|
|
2362
|
+
fs.writeFileSync(primaryReportPath, report, "utf8");
|
|
2363
|
+
} catch (err) {
|
|
2364
|
+
logger.warn(
|
|
2365
|
+
`[Main] Failed to write startup crash report: ${err instanceof Error ? err.message : String(err)}`,
|
|
2366
|
+
);
|
|
2367
|
+
try {
|
|
2368
|
+
fs.mkdirSync(path.dirname(fallbackReportPath), { recursive: true });
|
|
2369
|
+
fs.writeFileSync(fallbackReportPath, report, "utf8");
|
|
2370
|
+
reportPath = fallbackReportPath;
|
|
2371
|
+
} catch (fallbackErr) {
|
|
2372
|
+
logger.warn(
|
|
2373
|
+
`[Main] Failed to write fallback startup crash report: ${fallbackErr instanceof Error ? fallbackErr.message : String(fallbackErr)}`,
|
|
2374
|
+
);
|
|
2375
|
+
}
|
|
2376
|
+
}
|
|
2377
|
+
return { report, reportPath };
|
|
2378
|
+
}
|
|
2379
|
+
|
|
2380
|
+
function wasStartupCrashAlreadyPrompted(updatedAt: string): boolean {
|
|
2381
|
+
try {
|
|
2382
|
+
const markerPath = resolveStartupCrashPromptMarkerPath();
|
|
2383
|
+
return fs.readFileSync(markerPath, "utf8").trim() === updatedAt;
|
|
2384
|
+
} catch {
|
|
2385
|
+
return false;
|
|
2386
|
+
}
|
|
2387
|
+
}
|
|
2388
|
+
|
|
2389
|
+
function markStartupCrashPrompted(updatedAt: string): void {
|
|
2390
|
+
try {
|
|
2391
|
+
fs.writeFileSync(resolveStartupCrashPromptMarkerPath(), updatedAt, "utf8");
|
|
2392
|
+
} catch {}
|
|
2393
|
+
}
|
|
2394
|
+
|
|
2395
|
+
async function maybePromptStartupCrashReport(): Promise<void> {
|
|
2396
|
+
if (
|
|
2397
|
+
process.env.ELIZA_DESKTOP_SKIP_STARTUP_CRASH_PROMPT === "1" ||
|
|
2398
|
+
process.env.ELIZA_DESKTOP_TEST_AUTO_CONFIRM_DIALOGS === "1"
|
|
2399
|
+
) {
|
|
2400
|
+
return;
|
|
2401
|
+
}
|
|
2402
|
+
|
|
2403
|
+
const diagnostics = getStartupDiagnosticsSnapshot();
|
|
2404
|
+
const looksLikeStartupFailure =
|
|
2405
|
+
diagnostics.state === "error" &&
|
|
2406
|
+
diagnostics.phase !== "ready" &&
|
|
2407
|
+
diagnostics.phase !== "stopped";
|
|
2408
|
+
if (!looksLikeStartupFailure) {
|
|
2409
|
+
return;
|
|
2410
|
+
}
|
|
2411
|
+
if (wasStartupCrashAlreadyPrompted(diagnostics.updatedAt)) {
|
|
2412
|
+
return;
|
|
2413
|
+
}
|
|
2414
|
+
|
|
2415
|
+
const { report, reportPath } = persistStartupCrashReport({
|
|
2416
|
+
source: "startup-recovery",
|
|
2417
|
+
error: diagnostics.lastError,
|
|
2418
|
+
});
|
|
2419
|
+
markStartupCrashPrompted(diagnostics.updatedAt);
|
|
2420
|
+
|
|
2421
|
+
const dialog = await Utils.showMessageBox({
|
|
2422
|
+
type: "warning",
|
|
2423
|
+
title: `${BRAND.appName} recovered after a startup failure`,
|
|
2424
|
+
message:
|
|
2425
|
+
"The previous launch failed. A crash report is ready to share with support.",
|
|
2426
|
+
detail:
|
|
2427
|
+
"Choose Copy Report, paste into Discord, and ping @iono. You can also open logs.",
|
|
2428
|
+
buttons: ["Copy Report", "Open Logs Folder", "Continue"],
|
|
2429
|
+
defaultId: 0,
|
|
2430
|
+
cancelId: 2,
|
|
2431
|
+
});
|
|
2432
|
+
const response =
|
|
2433
|
+
dialog && typeof dialog === "object" && "response" in dialog
|
|
2434
|
+
? (dialog as { response: number }).response
|
|
2435
|
+
: typeof dialog === "number"
|
|
2436
|
+
? dialog
|
|
2437
|
+
: 2;
|
|
2438
|
+
|
|
2439
|
+
if (response === 0) {
|
|
2440
|
+
try {
|
|
2441
|
+
Utils.clipboardWriteText(report);
|
|
2442
|
+
Utils.showNotification({
|
|
2443
|
+
title: "Crash report copied",
|
|
2444
|
+
body: "Paste in Discord and ping @iono.",
|
|
2445
|
+
});
|
|
2446
|
+
} catch (err) {
|
|
2447
|
+
logger.warn(
|
|
2448
|
+
`[Main] Failed to copy startup crash report: ${err instanceof Error ? err.message : String(err)}`,
|
|
2449
|
+
);
|
|
2450
|
+
}
|
|
2451
|
+
} else if (response === 1) {
|
|
2452
|
+
try {
|
|
2453
|
+
Utils.openPath(path.dirname(reportPath));
|
|
2454
|
+
} catch (err) {
|
|
2455
|
+
logger.warn(
|
|
2456
|
+
`[Main] Failed to open startup logs folder: ${err instanceof Error ? err.message : String(err)}`,
|
|
2457
|
+
);
|
|
2458
|
+
}
|
|
2459
|
+
}
|
|
2460
|
+
}
|
|
2461
|
+
|
|
2462
|
+
main().catch((err) => {
|
|
2463
|
+
const msg = `[Main] Fatal error during startup: ${err?.stack ?? err}`;
|
|
2464
|
+
console.error(msg);
|
|
2465
|
+
recordStartupPhase("fatal", {
|
|
2466
|
+
pid: process.pid,
|
|
2467
|
+
exec_path: process.execPath,
|
|
2468
|
+
bundle_path: resolveStartupBundlePath(process.execPath),
|
|
2469
|
+
error: err instanceof Error ? err.stack || err.message : String(err),
|
|
2470
|
+
});
|
|
2471
|
+
persistStartupCrashReport({
|
|
2472
|
+
source: "fatal-startup",
|
|
2473
|
+
error: msg,
|
|
2474
|
+
});
|
|
2475
|
+
recordStartupPhase("fatal", {
|
|
2476
|
+
pid: process.pid,
|
|
2477
|
+
exec_path: process.execPath,
|
|
2478
|
+
bundle_path: resolveStartupBundlePath(process.execPath),
|
|
2479
|
+
error: err instanceof Error ? err.stack || err.message : String(err),
|
|
2480
|
+
});
|
|
2481
|
+
// Write to startup log so it's visible even without a console
|
|
2482
|
+
try {
|
|
2483
|
+
const logPath = getDiagnosticLogPath();
|
|
2484
|
+
fs.mkdirSync(path.dirname(logPath), { recursive: true });
|
|
2485
|
+
fs.appendFileSync(logPath, `[${new Date().toISOString()}] ${msg}\n`);
|
|
2486
|
+
fs.writeFileSync(
|
|
2487
|
+
getStartupStatusPath(),
|
|
2488
|
+
`${JSON.stringify(
|
|
2489
|
+
{
|
|
2490
|
+
state: "error",
|
|
2491
|
+
phase: "fatal_startup",
|
|
2492
|
+
updatedAt: new Date().toISOString(),
|
|
2493
|
+
lastError: msg,
|
|
2494
|
+
platform: process.platform,
|
|
2495
|
+
arch: process.arch,
|
|
2496
|
+
logPath,
|
|
2497
|
+
statusPath: getStartupStatusPath(),
|
|
2498
|
+
},
|
|
2499
|
+
null,
|
|
2500
|
+
2,
|
|
2501
|
+
)}\n`,
|
|
2502
|
+
"utf8",
|
|
2503
|
+
);
|
|
2504
|
+
} catch {}
|
|
2505
|
+
void runShutdownCleanup("fatal-startup").finally(shutdownAfterFatalError);
|
|
2506
|
+
});
|
|
2507
|
+
|
|
2508
|
+
import { shutdownAfterFatalError } from "./fatal-shutdown";
|
|
2509
|
+
|
|
2510
|
+
export { shutdownAfterFatalError };
|