# @elizaos/capacitor-eliza-tasks Capacitor plugin that bridges iOS `BGTaskScheduler` background-wake events into the elizaOS Capacitor runtime. ## What it does iOS suspends apps when they leave the foreground. This plugin registers two background task identifiers with `BGTaskScheduler` so the elizaOS iOS app can be woken by the OS on a schedule: - **`BGAppRefreshTask`** (`ai.eliza.tasks.refresh`) — short wake (~25s budget), network available. Used for polling the agent's loopback `/api/internal/wake` route. - **`BGProcessingTask`** (`ai.eliza.tasks.processing`) — long-running wake (~120s budget), requires device to be charging and idle. Used for local-LLM warmup passes. - **Silent APNs push** (`remote-push`) — optional; gated on `ELIZA_APNS_ENABLED` in `Info.plist`. Forwarded through `AppDelegate` via `ElizaCompanionRemotePush` `NSNotification`. All three wake paths emit the same `wake` event to the JS layer, so a single handler can drain them: ```ts import { ElizaTasks } from "@elizaos/capacitor-eliza-tasks"; await ElizaTasks.addListener("wake", (event) => { console.log(event.kind, event.deadlineSec, event.firedAtMs); // event.kind: "refresh" | "processing" | "remote-push" }); // Arm the first wake await ElizaTasks.scheduleNext({ earliestBeginSec: 900 }); ``` On web and non-iOS platforms the plugin returns `supported: false`; scheduling reports no iOS wake path, and cancellation reports that no web wake requests were cancelled. The app should call `getStatus()` and fall back to `@capacitor/background-runner` polling when `supported` is false. ## Installation ```bash npm install @elizaos/capacitor-eliza-tasks npx cap sync ``` ### iOS setup Add both identifiers to `Info.plist`: ```xml BGTaskSchedulerPermittedIdentifiers ai.eliza.tasks.refresh ai.eliza.tasks.processing ``` For silent-push support also add: ```xml ELIZA_APNS_ENABLED 1 ``` And enable the **Background Modes** capability in Xcode: check `Background fetch` and `Remote notifications`. ## API ### `scheduleNext(options?)` Enqueues the next `BGAppRefreshTask`. Idempotent — replaces any pending request. ```ts interface ElizaTasksScheduleOptions { earliestBeginSec?: number; // default 900 (15 min), floor 1 alsoProcessing?: boolean; // also schedule a BGProcessingTask } ``` Returns `ElizaTasksScheduleResult` with `{ scheduled, identifier, earliestBeginAtMs, reason }`. ### `getStatus()` Returns the plugin's view of `BGTaskScheduler` state: ```ts interface ElizaTasksStatus { supported: boolean; platform: "ios" | "android" | "web"; refreshScheduled: boolean; processingScheduled: boolean; lastWakeFiredAtMs: number | null; lastWakeKind: ElizaTaskKind | null; reason: string | null; } ``` ### `cancelAll()` Cancels all pending refresh and processing task requests. ### `addListener("wake", fn)` Registers a listener for `ElizaTasksWakeEvent`: ```ts interface ElizaTasksWakeEvent { kind: "refresh" | "processing" | "remote-push"; identifier: string; deadlineSec: number; firedAtMs: number; payload: Record; } ``` ### `removeAllListeners()` Removes all `wake` listeners. ## Platform support | Platform | Support | |---|---| | iOS 15+ | Full — `BGTaskScheduler` + optional APNs | | Android | Unsupported in this iOS BGTaskScheduler bridge | | Web / Electron | Unsupported fallback (`supported: false`) |