#20732: fix(signal): forward replyTo as quoteTimestamp/quoteAuthor for native threading
channel: signal
size: M
Cluster:
Slack and Signal Enhancements
## Summary
- Problem: Signal reply threading (quote bubbles) doesn’t work because `replyToId` is never mapped to signal-cli’s `quoteTimestamp`/`quoteAuthor` JSON-RPC fields.
- Why it matters: without native quote bubbles, replies in busy threads are ambiguous and the UX regresses to plain-text quoting.
- What changed: thread `replyToId` + new `replyToAuthor` through the outbound pipeline and forward them as `quoteTimestamp`/`quoteAuthor` for Signal.
- What did NOT change: no config defaults, no gateway routing changes, no behavior changes for other channels.
## Root cause
The outbound pipeline already carries `replyToId`, but Signal didn’t implement any mapping.
- Telegram/Discord/Slack map `replyToId` in their outbound adapters.
- Signal’s outbound adapter ignored `replyToId`.
- Additionally, Signal’s primary send path in `deliver.ts` bypasses the outbound adapter for markdown→Signal styled-text formatting, so fixing only the adapter is insufficient.
Signal also requires the quoted message author (`quoteAuthor`) in addition to the quoted message timestamp (`quoteTimestamp`). The pipeline didn’t carry this, so this PR adds `replyToAuthor` as an additive optional field.
## Behavior details
- Quote params are only included when both are present:
- `replyToId` parses as a positive integer timestamp
- `replyToAuthor` is provided (non-empty)
- If `replyToAuthor` is missing, we send a normal message (no partial quote payload).
- For chunked Signal sends, the quote bubble is attached only to the first chunk.
## Changes
- Add `quoteTimestamp`/`quoteAuthor` to `SignalSendOpts` and include them in the Signal `send` JSON-RPC call
- Add `replyToAuthor` to `ChannelOutboundContext` and thread it through:
- message-action-runner → outbound-send-service → message → deliver
- Update Signal’s inline send path in `deliver.ts` to forward quote params
- Update Signal outbound adapter to map `replyToId`/`replyToAuthor` → `quoteTimestamp`/`quoteAuthor`
- Accept `replyToAuthor` or `quoteAuthor` as the message tool param name (alias)
## Usage
```
message action=send channel=signal target=<recipient> message="exactly" replyTo=<message_timestamp> replyToAuthor=<sender_uuid>
```
## Test plan
- `pnpm check`
- `npx vitest run src/infra/outbound/deliver.test.ts src/infra/outbound/outbound-send-service.test.ts src/infra/outbound/message.test.ts`
## Manual verification (not in CI)
Not run against a live Signal account/daemon in this PR.
Suggested quick check:
1. Send a Signal DM or group message.
2. Reply with `replyTo=<ts>` + `replyToAuthor=<uuid>`.
3. Confirm the recipient UI shows a native quote bubble.
4. Send a multi-paragraph reply that chunks and confirm only the first chunk is quoted.
## Security impact
- New permissions/capabilities? No
- Secrets/tokens handling changed? No
- New/changed network calls? No (same signal-cli daemon)
- Command/tool execution surface changed? Yes (additive `replyToAuthor` param for Signal quote bubbles)
## AI assistance
AI-assisted (Cursor). I reviewed the full outbound pipeline and added unit tests to lock the parameter forwarding behavior.
Most Similar PRs
#8271: feat(signal): Add full quoted message context support
by ProofOfReach · 2026-02-03
73.4%
#15956: feat(signal): enhanced inbound message handling
by heyhudson · 2026-02-14
71.2%
#23723: feat(message): improve send param ergonomics and actionable routing...
by SmithLabsLLC · 2026-02-22
68.0%
#22485: fix(slack): use threadId from delivery context as threadTs fallback...
by dorukardahan · 2026-02-21
67.0%
#20722: fix(signal): use correct JSON-RPC param names for sendReaction
by arjunblj · 2026-02-19
66.7%
#15994: feat(signal): add unsend, poll create, poll vote, and poll terminat...
by heyhudson · 2026-02-14
66.7%
#19274: feat(mattermost): enable threaded replies in channels
by rockinyp · 2026-02-17
66.4%
#20186: fix(discord): thread mediaLocalRoots through reply delivery path
by pvoo · 2026-02-18
66.2%
#17453: fix(signal): make group reactions deterministic from inbound sender...
by akalypse · 2026-02-15
65.5%
#17818: Fix Signal reaction notification missing sender (support legacy 'so...
by Clawborn · 2026-02-16
65.0%