Originally created by: kristofferR
Carrier now appears in the macOS share sheet as a target: pick a photo in Finder or Photos, hit Share, choose Carrier, and it lands as an attachment in the open Messenger conversation.
This implements [#211], [#213], and [#214]:
share-extension/macos/ is a minimal sandboxed Share Extension built directly with clang. It handles the request in beginRequestWithExtensionContext:, serializes the complete selection onto a one-time UUID-named private pasteboard, and opens carrier://share-pasteboard/<uuid> so the main app can take over.macos/share_intake.rs accepts only that exact capability URL, consumes and globally releases the named pasteboard, validates the whole payload before delivery, parks one fresh share across cold start or page load, and raises the active Messenger window. No filesystem path crosses into the page.share-intake.ts reconstructs File objects and delivers them to the visible conversation composer through Messenger's paste handler with a drop fallback. Delivery requires the exact transfer to be inspected and acknowledged; ambiguous delivery is never retried into a duplicate attachment. A share with no composer waits for up to two minutes.The extension bounds file reads before allocating, handles security-scoped URLs, refuses partial selections, and enforces a 100 MB aggregate cap. The native and page sides independently validate file counts, UTF-8 name lengths, traversal-free names, payload size, and freshness.
Release-pipeline bundling, nested signing, and notarization are handled separately by [#212]. The Windows share target remains [#215]/#216.
Verified on macOS 27 through the real Finder share sheet with a PNG: Carrier came to the front and the image rendered as an unsent attachment in the open conversation's composer. The same run logged extension beginRequest, collection, pasteboard handoff, native acceptance, and page attachment.
The private named pasteboard is intentional. App-group containers reject ad-hoc-signed builds when the group prefix cannot match a signing team, while the sandboxed extension can use the pasteboard in both development and release builds. The capability is unguessable, consumed once, bounded, and treated as untrusted by the receiver.
Part of [#217].
Tickets: #211
Tickets: #212
Tickets: #213
Tickets: #214
Tickets: #215
Tickets: #217
Originally posted by: kristofferR
@coderabbitai review
Originally posted by: kristofferR
@codex review
Originally posted by: coderabbitai[bot]
⚠️ Action not completed
Review rate limited. > Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.Originally posted by: coderabbitai[bot]
📝 Walkthrough
## Walkthrough The PR adds a macOS Share Services extension. It transfers validated attachments through a tokenized pasteboard and `carrier://` URL. Native code parks and forwards shares to Messenger. Messenger decodes files and attaches them to the composer. ### Changes **macOS share intake** |Layer / File(s)|Summary| |---|---| |**Share extension payload creation**`share-extension/macos/*`|The extension collects ordered attachments, enforces size limits, writes base64 JSON to a named pasteboard, and opens the `carrier://` handoff URL.| |**Native handoff and pending delivery**
`src-tauri/Info.plist`, `src-tauri/src/lib.rs`, `src-tauri/src/macos/*`, `src-tauri/src/settings.rs`, `src-tauri/src/window.rs`|The app validates handoffs, clears pasteboard data, stores pending shares, and delivers them when a Messenger page is available.| |**Messenger validation and composer delivery**
`inject/src/messenger/features/share-intake.ts`, `inject/src/messenger/lib/share-intake.ts`, `inject/src/messenger/lib/share-intake.test.ts`, `inject/src/messenger/index.ts`, `inject/src/types.d.ts`, `src-tauri/inject/messenger.js`|Messenger sanitizes payloads, reconstructs `File` objects, waits for the composer, dispatches paste or drop events, and reports delivery states through diagnostics or toasts.| **Estimated code review effort:** 4 (Complex) | ~60 minutes **Possibly related issues** - Carrier issue 214 — Covers the Messenger share-intake hook, file reconstruction, pending delivery, and expiry implemented here. - Carrier issue 217 — Covers the macOS share-sheet intake and Messenger composer delivery path. - Carrier issue 213 — Covers the `carrier://share-pasteboard` handoff, native validation, pending delivery, and Messenger intake. - Carrier issue 211 — Covers the macOS share extension, pasteboard handoff, URL handling, and Messenger delivery. - Carrier issue 212 — Covers packaging and signing for the macOS share extension added by this PR. **Possibly related PRs** - [[kristofferR/Carrier#165](https://github.com/kristofferR/Carrier/issues/165)](https://github.com/kristofferR/Carrier/pull/165) — Both PRs initialize a new Messenger feature from `inject/src/messenger/index.ts`.
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
| Check name | Status | Explanation | | :------------------------: | :------- | :--------------------------------------------------------------------------------------------------------------- | | Description Check | ✅ Passed | Check skipped - CodeRabbit’s high-level summary is enabled. | | Title check | ✅ Passed | The title clearly describes the primary change: adding a macOS share extension that shares content into Carrier. | | Docstring Coverage | ✅ Passed | Docstring coverage is 86.21% which is sufficient. The required threshold is 80.00%. | | Linked Issues check | ✅ Passed | Check skipped because no linked issues were found for this pull request. | | Out of Scope Changes check | ✅ Passed | Check skipped because no linked issues were found for this pull request. |✨ Finishing Touches 💡 1
🛠️ Fix failing CI checks 💡
- [ ] Create stacked PR - [ ] Commit on current branch📝 Generate docstrings
- [ ] Create stacked PR - [ ] Commit on current branch🧪 Generate unit tests (beta)
- [ ] Create PR with unit tests - [ ] Commit unit tests in branch `feat/macos-share-target`Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.
❤️ Share
- [X](https://twitter.com/intent/tweet?text=I%20just%20used%20%40coderabbitai%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20the%20proprietary%20code.%20Check%20it%20out%3A&url=https%3A//coderabbit.ai) - [Mastodon](https://mastodon.social/share?text=I%20just%20used%20%40coderabbitai%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20the%20proprietary%20code.%20Check%20it%20out%3A%20https%3A%2F%2Fcoderabbit.ai) - [Reddit](https://www.reddit.com/submit?title=Great%20tool%20for%20code%20review%20-%20CodeRabbit&text=I%20just%20used%20CodeRabbit%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20proprietary%20code.%20Check%20it%20out%3A%20https%3A//coderabbit.ai) - [LinkedIn](https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Fcoderabbit.ai&mini=true&title=Great%20tool%20for%20code%20review%20-%20CodeRabbit&summary=I%20just%20used%20CodeRabbit%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20proprietary%20code)Comment
@coderabbitai helpto get the list of available commands.Related
Commit: [b66f90]
Originally posted by: kristofferR
@codex review
Originally posted by: kristofferR
@codex review
Originally posted by: kristofferR
@codex review
Originally posted by: kristofferR
@codex review
Originally posted by: kristofferR
@codex review
Originally posted by: kristofferR
@codex review
Originally posted by: kristofferR
@coderabbitai review
Originally posted by: coderabbitai[bot]
⚠️ Action not completed
Review rate limited. > Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.Originally posted by: kristofferR
@coderabbitai review
Originally posted by: coderabbitai[bot]
✅ Action performed
Review finished. > Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.Originally posted by: kristofferR
@codex review
Originally posted by: kristofferR
@coderabbitai review
Originally posted by: coderabbitai[bot]
✅ Action performed
Review finished. > Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.Originally posted by: kristofferR
@codex review
Originally posted by: kristofferR
@coderabbitai review
Originally posted by: coderabbitai[bot]
⚠️ Action not completed
Review rate limited. > Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.Originally posted by: kristofferR
@codex review
Ticket changed by: kristofferR