Skip to content

feat(imessage): add native imsg message actions#79234

Merged
steipete merged 1 commit into
mainfrom
feat/imessage-native-actions
May 8, 2026
Merged

feat(imessage): add native imsg message actions#79234
steipete merged 1 commit into
mainfrom
feat/imessage-native-actions

Conversation

@steipete

@steipete steipete commented May 8, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Problem: the iMessage plugin could send/receive through imsg, but the shared message tool had no native action surface for private-API bridge capabilities.
  • Why it matters: agents could not reliably react, edit, unsend, reply with effects/attachments, or manage groups through the bundled iMessage channel.
  • What changed: added iMessage-owned message actions, lightweight message-tool discovery, private-API status cache sharing, config gates enforced at discovery and execution, target aliases, reaction watch payload support, and regression coverage.
  • What did NOT change (scope boundary): no fallback to unsupported imsg RPC methods; actions are advertised from cached imsg status --json bridge capability/selector status and probed lazily at execution.

Change Type (select all)

  • Bug fix
  • Feature
  • Refactor required for the fix
  • Docs
  • Security hardening
  • Chore/infra

Scope (select all touched areas)

  • Gateway / orchestration
  • Skills / tool execution
  • Auth / tokens
  • Memory / storage
  • Integrations
  • API / contracts
  • UI / DX
  • CI/CD / infra

Linked Issue/PR

  • Closes #
  • Related #
  • This PR fixes a bug or regression

Real behavior proof (required for external PRs)

  • Behavior or issue addressed: iMessage shared message-tool actions and bridge capability gating.
  • Real environment tested: local OpenClaw checkout on macOS with Node 22.22.2.
  • Exact steps or command run after this patch: targeted Vitest shard bundle and pnpm tsgo:extensions.
  • Evidence after fix: local command output showed all targeted tests green and extension typecheck exit 0.
  • Observed result after fix: discovery/dispatch tests cover unavailable bridge gating, disabled action rejection, upload asVoice/as_voice, target aliases, inbound GUID handling, and reaction watch parsing.
  • What was not tested: live Messages.app private-API bridge execution in this checkout.
  • Before evidence (optional but encouraged): reviewer comments identified unsupported discovery, unchecked aliases, and stale guardrails.

Root Cause (if applicable)

  • Root cause: N/A for the feature; review fixes covered drift between discovery, config gates, shared normalization, and the actual imsg status --json bridge capability surface.
  • Missing detection / guardrail: no lightweight iMessage message-tool artifact and no execution-time config gate regression coverage.
  • Contributing context (if known): origin/main already had a newer private-API implementation, so this PR rebases onto that and preserves its status/selector model.

Regression Test Plan (if applicable)

  • Coverage level that should have caught this:
    • Unit test
    • Seam / integration test
    • End-to-end test
    • Existing coverage already sufficient
  • Target test or file: extensions/imessage/src/actions.test.ts, extensions/imessage/src/message-tool-api.test.ts, src/infra/outbound/message-action-spec.test.ts, src/plugins/contracts/plugin-sdk-runtime-api-guardrails.test.ts.
  • Scenario the test should lock in: discovery stays lightweight and capability-gated; disabled actions cannot execute; upload voice flag aliases work; iMessage target aliases survive shared normalization.
  • Why this is the smallest reliable guardrail: these are adapter/schema contracts around the shared message tool, not full live bridge behavior.
  • Existing test that already covers this (if any): iMessage monitor/parse tests cover inbound reaction payload and GUID/short-id context behavior.
  • If no new test is added, why not: N/A.

User-visible / Behavior Changes

The iMessage plugin can advertise and execute private-API message actions for reactions, edits, unsends, replies, rich sends, attachments, and group management when the configured imsg bridge reports support.

Diagram (if applicable)

Before:
message tool -> iMessage send only / no native private actions

After:
imsg status cache -> lightweight discovery -> message action -> config gate -> private API bridge

Security Impact (required)

  • New permissions/capabilities? Yes
  • Secrets/tokens handling changed? No
  • New/changed network calls? No
  • Command/tool execution surface changed? Yes
  • Data access scope changed? No
  • If any Yes, explain risk + mitigation: exposes iMessage private-API actions only through the existing channel action surface, with config gates enforced at discovery and execution and attachment input still flowing through shared media normalization.

Repro + Verification

Environment

  • OS: macOS
  • Runtime/container: Node 22.22.2 via mise, pnpm
  • Model/provider: N/A
  • Integration/channel (if any): iMessage / imsg
  • Relevant config (redacted): channels.imessage.cliPath="imsg"

Steps

  1. Run focused iMessage/message-tool test bundle.
  2. Run extension typecheck.
  3. Run whitespace diff check.

Expected

  • Tests and typecheck pass.

Actual

  • Passed.

Evidence

  • Failing test/log before + passing after
  • Trace/log snippets
  • Screenshot/recording
  • Perf numbers (if relevant)

Human Verification (required)

  • Verified scenarios: focused tests for action discovery/dispatch gates, upload voice aliases, target aliases, inbound GUID/short-id handling, reaction parsing/watch options, metadata guardrails.
  • Edge cases checked: unavailable bridge cache, disabled action execution, group-only discovery filtering, sendAttachment mapped to upload-file without exposing the internal action name.
  • What you did not verify: live Messages.app private-API calls on a SIP-disabled host.

Review Conversations

  • I replied to or resolved every bot review conversation I addressed in this PR.
  • I left unresolved only the conversations that still need reviewer or maintainer judgment.

Compatibility / Migration

  • Backward compatible? Yes
  • Config/env changes? Yes
  • Migration needed? No
  • If yes, exact upgrade steps: optional channels.imessage.actions.* gates can disable individual private-API actions.

Risks and Mitigations

  • Risk: action discovery could advertise methods unsupported by the installed imsg bridge.
    • Mitigation: discovery reads cached private-API availability/selectors and execution lazily probes before calling the bridge.
  • Risk: destructive actions bypass config gates through stale schemas or manual calls.
    • Mitigation: handleAction rejects disabled actions before dispatch.

@openclaw-barnacle openclaw-barnacle Bot added channel: imessage Channel integration: imessage size: L maintainer Maintainer-authored PR labels May 8, 2026
@steipete steipete added the proof: override Maintainer override for the external PR real behavior proof gate. label May 8, 2026
@steipete
steipete merged commit fe79d85 into main May 8, 2026
11 of 18 checks passed
@steipete
steipete deleted the feat/imessage-native-actions branch May 8, 2026 04:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

channel: imessage Channel integration: imessage maintainer Maintainer-authored PR proof: override Maintainer override for the external PR real behavior proof gate. size: L

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant