Skip to content

Add Discord and iMessage channel adapters - #3

Merged
Peyton-Spencer merged 1 commit into
feat/local-chat-foundationfrom
feat/discord-imessage-adapters
Aug 30, 2026
Merged

Add Discord and iMessage channel adapters#3
Peyton-Spencer merged 1 commit into
feat/local-chat-foundationfrom
feat/discord-imessage-adapters

Conversation

@Peyton-Spencer

@Peyton-Spencer Peyton-Spencer commented Aug 28, 2026

Copy link
Copy Markdown

What changed

  • adds a channel-adapter SPI and runtime registry backed by the existing supervised server
  • exposes typed, authorization-scoped RPCs to list accounts, conversations, and messages and to send when a transport supports it
  • adds a Discrawl adapter for local Discord status, guild/DM discovery, and archived message reads
  • adds a macOS iMessage adapter for Messages database reads and AppleScript sends with Full Disk Access and Apple Events diagnostics
  • adds focused adapter tests, including command-argument isolation for iMessage text

Capability and safety behavior

  • Discrawl is explicitly archive-only: personal Discord sending fails with capability_unavailable
  • bot and device Discord modes remain distinct transports; bot API sending is the next adapter, not a silent fallback
  • iMessage is macOS-only, does not read history without Full Disk Access, and requires Apple Automation consent to send
  • user message text is passed as an osascript argument, never interpolated into the AppleScript program
  • no Ditto account or cloud sync is required

Current slice

This establishes the server/RPC vertical slice. It expects a locally available discrawl binary and uses the system sqlite3/osascript tools on macOS. Bundling/supervision, the SQLite normalized event/outbox store, bot transport, and unified inbox UI are intentionally follow-up layers.

Validation

  • vp check (passes; repository has pre-existing warnings)
  • vp run typecheck
  • vp test run apps/server/src/channels/DiscrawlAdapter.test.ts apps/server/src/channels/IMessageAdapter.test.ts apps/server/src/dittoHarness/DittoHarnessRuntime.test.ts packages/contracts/src/settings.test.ts (64 tests)

Stack

Depends on #2, which depends on #1.

Note

Add Discord and iMessage channel adapters with ChannelRegistry and channels.* RPC endpoints

  • Introduces ChannelAdapter interface and ChannelRegistry service that routes calls across registered adapters, with multi-account discovery and conversation aggregation when no accountId is given
  • Implements DiscrawlAdapter for read-only Discord history via the Discrawl CLI (status, channels list, dms, messages); sendMessage always fails with capability_unavailable
  • Implements IMessageAdapter for macOS iMessage via sqlite3 against chat.db for reads and osascript for sends; reports unavailable off macOS and permission_required when chat.db access fails
  • Adds four WebSocket RPCs (channelsListAccounts, channelsListConversations, channelsListMessages, channelsSendMessage) with contract schemas in channels.ts and rpc.ts, plus authorization scopes in RpcAuthorization.ts: list endpoints require read scope, send requires operate scope
  • Risk: iMessage send uses osascript with handle:-prefixed conversation IDs; verify argument escaping in IMessageAdapter.ts prevents injection. iMessage SQL query against chat.db requires Full Disk Access on macOS.

Macroscope summarized 1632af6.

@github-actions github-actions Bot added size:XL vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. labels Aug 28, 2026
@github-actions

github-actions Bot commented Aug 28, 2026

Copy link
Copy Markdown

Thread transfer impact

✅ Thread transfer remains within every enforced ceiling.

ℹ️ No successful main baseline artifact is available yet. This run establishes the initial measurement.

Provider Metric Main baseline This PR Impact PR ceiling
Codex Total thread wire 13.5 KiB 15.1 KiB
Codex Thread snapshot wire 6.9 KiB 7.3 KiB
Codex Live turn WebSocket wire 6.6 KiB 7.8 KiB
Codex Live turn WebSocket decoded 57.0 KiB 66.4 KiB
Codex Live turn messages 11 21
Claude Total thread wire 13.5 KiB 15.1 KiB
Claude Thread snapshot wire 6.9 KiB 7.3 KiB
Claude Live turn WebSocket wire 6.6 KiB 7.8 KiB
Claude Live turn WebSocket decoded 57.9 KiB 66.4 KiB
Claude Live turn messages 11 21

Baseline: unavailable · PR result: 1632af6 · Source CI: success

Scenario and decoded snapshot size

10 historical turns, 5 command tools per turn, 878.9 KiB retained MCP result per historical turn, and a 1.05 MiB retained result in the measured turn.

  • Codex decoded thread snapshot: 109.4 KiB
  • Claude decoded thread snapshot: 110.1 KiB

Updated in place by a trusted workflow. PR artifacts are strictly validated and never executed.

@Peyton-Spencer
Peyton-Spencer force-pushed the feat/discord-imessage-adapters branch from 205fd1f to 420faab Compare August 28, 2026 22:17
@Peyton-Spencer
Peyton-Spencer force-pushed the feat/discord-imessage-adapters branch from 420faab to 1632af6 Compare August 28, 2026 22:22
@Peyton-Spencer
Peyton-Spencer marked this pull request as ready for review August 30, 2026 20:19
@Peyton-Spencer
Peyton-Spencer merged commit 19059fe into main Aug 30, 2026
28 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XL vouch:trusted PR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant