Files
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

9.8 KiB

@elizaos/macosalarm

macOS native alarm scheduling via UNUserNotificationCenter, driven by a self-contained Swift CLI helper invoked from the Eliza runtime.

Purpose / role

Adds the ALARM action to an Eliza agent so it can schedule, cancel, and list macOS calendar-trigger notifications without any third-party dependencies. The plugin is auto-enabled on darwin ("autoEnable": "darwin" in package.json); on non-darwin platforms the action's validate hook returns false and nothing runs. Load it by name "macosalarm" or import macosAlarmPlugin from @elizaos/macosalarm.

Plugin surface

Kind Name Description
Action ALARM Schedule (set), remove (cancel), or enumerate (list) macOS alarms. Subaction comes from structured parameters (action / subaction / op) or from the structured parameter shape. Role-gated to ADMIN.

No providers, services, evaluators, routes, or events are registered.

Layout

plugins/plugin-native-macosalarm/
  src/
    index.ts        Re-exports everything; default export = macosAlarmPlugin
    plugin.ts       createMacosAlarmPlugin(deps?) → Plugin; macosAlarmPlugin singleton
    actions.ts      createAlarmAction(deps?) → Action; runSet/runCancel/runList helpers
    helper.ts       runHelper(request, options?) — spawns the Swift binary via stdin/stdout JSON IPC
    types.ts        All request/response/param types for the IPC protocol
  swift-helper/
    main.swift      Self-contained Swift CLI; reads JSON from stdin, writes JSON to stdout
  scripts/
    build-helper.mjs  Compiles main.swift → bin/macosalarm-helper via swiftc (skips on non-darwin)
  bin/
    macosalarm-helper  Compiled Swift binary (darwin only, produced by build:helper)
  __tests__/
    helper.test.ts               Unit tests for runHelper IPC layer (mock spawn, no binary needed)
    integration.macos.test.ts    Integration tests (darwin only)

Commands

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

bun run --cwd plugins/plugin-native-macosalarm clean           # remove build output
bun run --cwd plugins/plugin-native-macosalarm build           # build package artifacts
bun run --cwd plugins/plugin-native-macosalarm typecheck       # TypeScript typecheck
bun run --cwd plugins/plugin-native-macosalarm lint            # mutating Biome check
bun run --cwd plugins/plugin-native-macosalarm lint:check      # read-only Biome check
bun run --cwd plugins/plugin-native-macosalarm format          # write formatting
bun run --cwd plugins/plugin-native-macosalarm format:check    # read-only formatting check
bun run --cwd plugins/plugin-native-macosalarm test            # run package tests
bun run --cwd plugins/plugin-native-macosalarm prepublishOnly  # publish-time build hook
bun run --cwd plugins/plugin-native-macosalarm build:helper    # node scripts/build-helper.mjs
bun run --cwd plugins/plugin-native-macosalarm build:ts        # tsc --noCheck -p tsconfig.json

Config / env vars

Variable Required Default Purpose
ELIZA_MACOSALARM_HELPER_BIN No bin/macosalarm-helper relative to package root Override path to the compiled Swift binary
ELIZA_MACOSALARM_FORCE_HELPER_BUILD No unset Set to 1 to force recompiling the tracked Swift helper binary even when it is newer than the source
ELIZA_VERBOSE_PLUGIN_BUILD No unset Set to 1 to log the binary output path during build:helper

No runtime config keys are read from the agent runtime settings object. The only env var consumed at runtime is ELIZA_MACOSALARM_HELPER_BIN.

ALARM action parameters

Parameter Required for Description
action / subaction / op set, cancel, or list (if absent, inferred from structured parameter shape: schedule payload → set, id → cancel, otherwise list)
timeIso set ISO-8601 timestamp for the alarm
title set Notification title
body set (optional) Notification body
sound set (optional) Sound name ("default" = critical sound; any named system sound)
id cancel (required), set (optional) Alarm identifier; auto-generated as alarm-<UUID> if omitted on set

How to extend

Add a new Swift action (e.g., permission check exposed to the agent):

  1. The Swift binary already handles "permission" — add a corresponding TS subaction in src/actions.ts alongside runSet/runCancel/runList.
  2. Extend ALARM_SUBACTIONS and the switch in the handler.
  3. Add a matching typed response interface in src/types.ts and include it in the MacosAlarmHelperResponse union.

Add a new action (e.g., a separate ALARM_SNOOZE action):

  1. Create a new function in src/actions.ts returning an Action object.
  2. Export it and add it to the actions array in src/plugin.ts.
  3. Use runHelper from src/helper.ts for all IPC with the binary.

Conventions / gotchas

  • darwin-only at runtime. helper.ts throws MacosAlarmHelperUnavailableError (reason "macos-only") on non-darwin unless a custom spawnImpl is provided (used in tests to mock the binary).
  • Binary must be compiled before use. build:helper runs swiftc and writes to bin/macosalarm-helper. If the binary is missing at runtime, runHelper throws MacosAlarmHelperUnavailableError with reason "helper-binary-missing".
  • IPC protocol is line-delimited JSON. The Swift process reads one JSON object from stdin and writes exactly one JSON object to stdout. The TS layer takes the last non-empty line of stdout as the response.
  • Notification permission. schedule calls ensureAuthorization() in Swift, which requests the UNUserNotificationCenter permission prompt on first use. If the user has denied notifications, the binary exits with code 3 and returns { "success": false, "error": "permission-denied: ..." }.
  • Role gate. The ALARM action has roleGate: { minRole: "ADMIN" }, so only admin-role users can trigger it.
  • Context gate. The action matches the tasks, calendar, and automation contexts from canonical turn routing plus legacy activeContexts / selectedContexts signals. It does not validate from alarm keywords in raw message text.
  • Testing the Swift layer. Use the spawnImpl and binPathOverride options in HelperRunOptions to inject a mock process in tests without needing a compiled binary.

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.