项目文件夹

文件
wehub-resource-sync 426e9eeabd
Voice Workbench / headless workbench (mocked backends) (push) Has been cancelled
Voice Workbench / real acoustic lane (nightly, provisioned only) (push) Has been cancelled
ci / test (push) Has been cancelled
ci / lint-and-format (push) Has been cancelled
ci / build (push) Has been cancelled
ci / dev-startup (push) Has been cancelled
gitleaks / gitleaks (push) Has been cancelled
Markdown Links / Relative Markdown Links (push) Has been cancelled
Quality (Extended) / Homepage Build (PR smoke) (push) Has been cancelled
Quality (Extended) / Comment-only diff guard (push) Has been cancelled
Quality (Extended) / Format + Type Safety Ratchet (push) Has been cancelled
Quality (Extended) / Develop Gate (secret scan + UI determinism) (push) Has been cancelled
Quality (Extended) / Develop Gate (lint) (push) Has been cancelled
Chat shell gestures / Chat shell gesture + parity e2e (push) Has been cancelled
Cloud Gateway Discord / Test (push) Has been cancelled
Benchmark Bridge Tests / benchmark (bunx @biomejs/biome check packages/lifeops-bench/src, benchmark-lint) (push) Has been cancelled
Benchmark Bridge Tests / benchmark (bunx vitest run --config packages/lifeops-bench/vitest.config.ts --root packages/lifeops-bench --passWithNoTests, benchmark-tests) (push) Has been cancelled
Build Agent Image / build-and-push (push) Has been cancelled
Dev Smoke / bun run dev onboarding chat (push) Has been cancelled
Dev Smoke / Vite HMR dependency-level smoke (push) Has been cancelled
Electrobun Submodule Guard / electrobun gitlink is fetchable (push) Has been cancelled
Publish @elizaos/example-code / check_npm (push) Has been cancelled
Publish @elizaos/example-code / publish_npm (push) Has been cancelled
Publish @elizaos/plugin-elizacloud / verify_version (push) Has been cancelled
Publish @elizaos/plugin-elizacloud / publish_npm (push) Has been cancelled
Sandbox Live Smoke / Sandbox live smoke (push) Has been cancelled
Snap Build & Test / Build Snap (amd64) (push) Has been cancelled
Snap Build & Test / Build Snap (arm64) (push) Has been cancelled
Test Packaging / elizaos CLI global-install smoke (node + bun) (push) Has been cancelled
Cloud Gateway Webhook / Test (push) Has been cancelled
Cloud Tests / lint-and-types (push) Has been cancelled
Cloud Tests / unit-tests (push) Has been cancelled
Cloud Tests / integration-tests (push) Has been cancelled
Cloud Tests / e2e-tests (push) Has been cancelled
CodeQL Advanced / Analyze (javascript-typescript) (push) Has been cancelled
Deploy Apps Worker (Product 2) / Determine environment (push) Has been cancelled
Deploy Apps Worker (Product 2) / Deploy apps worker to apps-control host (${{ needs.determine-env.outputs.environment }}) (push) Has been cancelled
Deploy Eliza Provisioning Worker / Determine environment (push) Has been cancelled
Deploy Eliza Provisioning Worker / Deploy worker to Hetzner host (${{ needs.determine-env.outputs.environment }} @ ${{ needs.determine-env.outputs.deployment_sha }}) (push) Has been cancelled
Dev Smoke / Classify changed paths (push) Has been cancelled
supply-chain / sbom (push) Has been cancelled
supply-chain / vulnerability-scan (push) Has been cancelled
Build, Push & Deploy to Phala Cloud / build-and-push (push) Has been cancelled
Test Packaging / Validate Packaging Configs (push) Has been cancelled
Test Packaging / Build & Test PyPI Package (push) Has been cancelled
Test Packaging / PyPI on Python ${{ matrix.python }} (push) Has been cancelled
Test Packaging / Pack & Test JS Tarballs (push) Has been cancelled
UI Fixture E2E / ui-fixture-e2e (push) Has been cancelled
UI Fixture E2E / fixture-e2e (push) Has been cancelled
UI Story Gate / story-gate (push) Has been cancelled
vault-ci / test (macos-latest) (push) Has been cancelled
vault-ci / test (ubuntu-latest) (push) Has been cancelled
vault-ci / test (windows-latest) (push) Has been cancelled
vault-ci / app-core wiring tests (push) Has been cancelled
verify-patches / verify patches/CHECKSUMS.sha256 (push) Has been cancelled
Voice Benchmark Smoke / voice-emotion fixture smoke (push) Has been cancelled
Voice Benchmark Smoke / voiceagentbench fixture smoke (push) Has been cancelled
Voice Benchmark Smoke / voicebench-quality unit smoke (push) Has been cancelled
Voice Benchmark Smoke / voicebench TypeScript unit (no audio) (push) Has been cancelled
Voice Benchmark Smoke / voice bench smoke summary (push) Has been cancelled
Windows CI / windows ([bun run --cwd packages/app-core test bun run --cwd packages/elizaos test bun run --cwd packages/cloud/shared test], app-and-cli) (push) Has been cancelled
Windows CI / windows ([bun run --cwd packages/scenario-runner test bun run --cwd packages/vault test bun run --cwd packages/security test bun run --cwd plugins/plugin-coding-tools test], framework-packages) (push) Has been cancelled
Windows CI / windows ([bun run --cwd plugins/plugin-elizacloud test bun run --cwd plugins/plugin-discord test bun run --cwd plugins/plugin-anthropic test bun run --cwd plugins/plugin-openai test bun run --cwd plugins/plugin-app-control test bun run --cwd plugins/pl… (push) Has been cancelled
Windows CI / windows ([node packages/scripts/run-turbo.mjs run build --filter=@elizaos/core --filter=@elizaos/shared --filter=@elizaos/agent --concurrency=4 node packages/scripts/run-bash-linux-only.mjs scripts/verify-riscv64-buildpaths.sh node packages/scripts/run… (push) Has been cancelled
Windows CI / windows ([node packages/scripts/run-turbo.mjs run typecheck --filter=@elizaos/core --filter=@elizaos/shared --filter=@elizaos/cloud-shared --concurrency=4 bun run --cwd packages/core test bun run --cwd packages/shared test], core-runtime, 75) (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:43:05 +08:00

12 KiB

@elizaos/capacitor-mobile-signals

Capacitor plugin that bridges mobile wake, lock, battery, and protected-data state into Eliza agents via the MobileSignals Capacitor plugin interface.

Purpose / role

This is a Capacitor plugin (not an elizaOS runtime plugin with actions/providers). It exposes a cross-platform MobileSignals API surface that an Eliza mobile app (iOS or Android) installs and calls. On iOS it uses HealthKit, FamilyControls, and DeviceActivity; on Android it uses Health Connect and PACKAGE_USAGE_STATS. A web fallback uses document.visibilityState, window.focus/blur, and the Battery Status API. The plugin is opt-in — it must be explicitly registered with the Capacitor app and its native permissions must be granted by the user.

Plugin surface

This package registers one Capacitor plugin: MobileSignals.

Method Description
checkPermissions() Returns current permission status, capabilities, screen-time status, and required setup actions.
requestPermissions(options?) Triggers native permission request flows (health, screen time, notifications).
openSettings(options?) Opens a specific native settings page (app, health, battery optimization, etc.).
startMonitoring(options?) Starts event streaming; returns initial device + health snapshots.
stopMonitoring() Stops event streaming and removes all native listeners.
getSnapshot() One-shot async read of current device + health state without streaming.
scheduleBackgroundRefresh() Background refresh is unavailable on the current native implementations (iOS uses foreground monitoring and routes background work elsewhere; web cannot schedule). Always resolves scheduled: false with a reason.
cancelBackgroundRefresh() No native background-refresh task is registered to cancel. Always resolves cancelled: false with a reason.
addListener("signal", fn) Subscribes to MobileSignalsSignal events (device snapshot or health snapshot).
removeAllListeners() Removes all registered event listeners.

Two snapshot types are emitted on "signal":

  • MobileSignalsSnapshot (source: "mobile_device") — state, idle/locked status, battery.
  • MobileSignalsHealthSnapshot (source: "mobile_health") — sleep, biometrics, screen-time status.

Layout

src/
  definitions.ts   All exported TypeScript types and the MobileSignalsPlugin interface
  index.ts         Capacitor registerPlugin call — entry point for the JS/TS consumer
  web.ts           MobileSignalsWeb: browser fallback using visibility, focus, Battery API

android/
  src/main/java/ai/eliza/plugins/mobilesignals/
    MobileSignalsPlugin.kt   Android Capacitor plugin implementation

ios/Sources/MobileSignalsPlugin/
  MobileSignalsPlugin.swift  iOS Capacitor plugin implementation (HealthKit, FamilyControls)
  ScreenTimeSupport.swift    iOS Screen Time / DeviceActivity helpers

scripts/
  validate-ios-screen-time.mjs        Build-time wiring validator (exports validateIosScreenTimeBuildWiring, assertIosScreenTimeBuildWiring)
  validate-ios-screen-time.test.mjs   Tests for the validator

ElizaosCapacitorMobileSignals.podspec  CocoaPods spec (links FamilyControls + DeviceActivity frameworks)
rollup.config.mjs                      Rollup config for CJS bundle
tsconfig.json                          TypeScript config (emits to dist/esm/)

Commands

Scripts are defined in package.json; run them from the repo root with bun run --cwd:

bun run --cwd plugins/plugin-native-mobile-signals clean                     # remove build output
bun run --cwd plugins/plugin-native-mobile-signals build                     # build package artifacts
bun run --cwd plugins/plugin-native-mobile-signals typecheck                 # TypeScript typecheck
bun run --cwd plugins/plugin-native-mobile-signals lint                      # mutating Biome check
bun run --cwd plugins/plugin-native-mobile-signals lint:check                # read-only Biome check
bun run --cwd plugins/plugin-native-mobile-signals format                    # write formatting
bun run --cwd plugins/plugin-native-mobile-signals format:check              # read-only formatting check
bun run --cwd plugins/plugin-native-mobile-signals test                      # run package tests
bun run --cwd plugins/plugin-native-mobile-signals prepublishOnly            # publish-time build hook
bun run --cwd plugins/plugin-native-mobile-signals watch                     # watch TypeScript sources
bun run --cwd plugins/plugin-native-mobile-signals build:unlocked            # bun run clean && bunx tsc -p tsconfig.json && bunx rollup -c rollup.config.mjs
bun run --cwd plugins/plugin-native-mobile-signals validate:ios-screen-time  # node scripts/validate-ios-screen-time.mjs

Config / env vars

Variable Required Description
MOBILE_SIGNALS_IOS_PROVISIONING_PROFILE No Path to the .mobileprovision file used by validate:ios-screen-time to verify Screen Time entitlements in the provisioning profile.
MOBILE_SIGNALS_REQUIRE_IOS_PROVISIONING_PROFILE No Set to "1" to make validate:ios-screen-time fail if no provisioning profile is supplied.

No runtime environment variables are read by the plugin itself. Permission state and capabilities are determined at runtime by querying native APIs.

iOS requirements

Screen Time / DeviceActivity features require additional entitlements and Xcode targets. The validate:ios-screen-time script checks:

  1. App.entitlements contains com.apple.developer.family-controls.
  2. Xcode project sets CODE_SIGN_ENTITLEMENTS = App/App.entitlements.
  3. DeviceActivityMonitorExtension and DeviceActivityReportExtension app-extension targets exist and are embedded.
  4. ElizaosCapacitorMobileSignals.podspec links FamilyControls and DeviceActivity frameworks.

Without these, screenTime.supported will be false and screenTime.authorization.status will be "unavailable".

Android requirements

The Android implementation uses PACKAGE_USAGE_STATS permission (requires the user to grant Usage Access in system settings — cannot be requested via a normal permission dialog). On Android the screen-time equivalent is Health Connect and UsageStatsManager. The plugin exposes openSettings({ target: "usageAccess" }) to direct the user to the correct settings page.

How to extend

Add a new method to the plugin:

  1. Add the method signature to MobileSignalsPlugin interface in src/definitions.ts.
  2. Add any new input/output types to src/definitions.ts.
  3. Implement the method in src/web.ts (MobileSignalsWeb class) — return a graceful fallback for web.
  4. Implement in ios/Sources/MobileSignalsPlugin/MobileSignalsPlugin.swift.
  5. Implement in android/src/main/java/ai/eliza/plugins/mobilesignals/MobileSignalsPlugin.kt.
  6. Rebuild: bun run --cwd plugins/plugin-native-mobile-signals build.

Add a new signal field:

Extend MobileSignalsSnapshot or MobileSignalsHealthSnapshot in src/definitions.ts, then propagate through the native implementations and the web fallback's buildSnapshot / buildHealthSnapshot helpers in src/web.ts.

Conventions / gotchas

  • Instrumented test (issue #9967). The PACKAGE_USAGE_STATS reads (AppOps GET_USAGE_STATS check + UsageStatsManager.queryUsageStats) live in UsageStatsReader; the plugin delegates to it (single source) so an on-device androidTest can drive the real provider. The permission is special-access, so the harness grants it host-side (appops set <pkg> android:get_usage_stats allow) and the usage tests Assume-skip when absent — verified positive on an API-34 emulator (real foreground-usage history).
  • This is a Capacitor plugin, not an elizaOS action/provider/service plugin. There is no Plugin object registered with AgentRuntime. It is consumed by a Capacitor-enabled mobile/web app.
  • The web fallback (src/web.ts) always returns status: "not-applicable" for checkPermissions and false for health capabilities. Do not add health data to the web path.
  • rawUsageExportAvailable is permanently false in MobileSignalsScreenTimeStatus — this is intentional (Apple does not expose raw usage export).
  • On iOS, Screen Time features require Apple's restricted com.apple.developer.family-controls entitlement, which must be provisioned by Apple. The validate:ios-screen-time script is the canonical check.
  • dist/ is committed for publishing but should be regenerated via build before any release.
  • The package uses three outputs: ESM (dist/esm/) for tree-shaking consumers, CJS (dist/plugin.cjs.js) for CommonJS hosts, and IIFE (dist/plugin.js) for unpkg/browser script-tag use. The bun/development export condition resolves directly to src/index.ts for local dev.
  • See root AGENTS.md for repo-wide conventions (logging, ESM, naming, architecture rules).

NON-NEGOTIABLE — evidence, trajectories & real end-to-end tests

The binding, repo-wide standard is AGENTS.md. Read it. Nothing in this package is done until it is proven done — a reviewer must confirm it works without reading the code, from the artifacts you attach. This applies to every feature, fix, refactor, and chore here. "Tests pass" is not proof; "CI is green" is not proof.

  • Record AND read model trajectories. Capture the actual inputs and outputs of the model from a live LLM — not the deterministic proxy, not a mock: the prompt, the providers/context, the raw model output, every tool/action call, and the result. Then open the trajectory and review it by hand. A captured-but-unread trajectory is not evidence (packages/scenario-runner/bin/eliza-scenarios run <scenario> --report <out>).
  • Real, full-featured E2E — no larp. Every feature ships detailed end-to-end tests that drive the real path end to end. Not the happy "front door" only: cover error paths, edge/empty/invalid input, concurrency, roles/permissions, and adversarial input. A test that asserts against a mock/stub/fixture standing in for the thing under test does not count. If the real model/device/chain/connector/account is hard to reach, make it reachable — that is the work, not an excuse to mock. If the existing tests here are shallow or mocked, fixing them is part of your change.
  • Screenshots + logs at every phase, plus a complete walkthrough video/run-through of the entire feature or view, start to finish (bun run test:e2e:record).
  • Manually review every artifact the change touches — never just the green check: client logs (console + network), server logs ([ClassName] …), the model trajectories in and out, before/after full-page screenshots, and the domain artifacts listed below for this package.
  • No residuals. No shortcuts. The goal is not "done" — it is everything done. Clear every blocker by the hard path: build the real architecture, stand up the real model/device/service, actually test it. Never leave a TODO, a stub, a stepping-stone, or a "follow-up." When unsure, research thoroughly, weigh the options, and ship the best, highest-effort, production-ready version. Keep going until every possibility is exhausted.

Artifacts → attached inline in the PR (MP4 video, JPG screenshots, logs in <details>); attach each evidence type or explicitly mark it N/A with a reason — never leave it blank. If develop moved and changed behavior, re-capture evidence; stale proof is worse than none.

Capture & manually review for this package — native / on-device bridge:

  • The capability run on a real device or simulator — not desktop Chromium against a mocked bridge (see #9967/#9580): device logs + the captured output (photo, OCR text, detection boxes, transcript, sensor reading).
  • Parity vs the reference implementation where one exists (e.g. the Python/Ultralytics reference), with the numeric tolerances actually met.
  • Permission-denied, no-hardware, and background/foreground lifecycle paths.
  • A short recording of the on-device run; confirm the build under test is yours (versionName / a known on-screen change), not a stale install.