feat: remote-editor invite handshake + "Shared with me" (#62, part 2) #70

Merged
claude-bot merged 3 commits from feat/v7-remote-invite-handshake into main 2026-06-30 13:52:37 +00:00
Contributor

Part 2 of #62. The host now tells the editor's instance about an invite, and the editor records it.

What it does

  • Host send: POST /api/projects/:id/invite-remote delivers a signed AP Invite to the remote actor's inbox (object = the project's AP collection URL + name, target = the actor), fire-and-forget so a delivery failure never fails the invite. New services/apOutbound.ts getSigningIdentity() resolves (and lazily creates) the owner's AP keypair for signing.
  • Editor receive: the inbox handles Invite — when target is this inbox's actor, it records a row in remote_project_invitations (migration 043).
  • Editor surface: GET /api/remote-projects lists active invitations; a new Shared with me page (/remote-projects, linked from Settings → Projects) shows them.

Verification (dev server)

remoteInviteHandshake.test.ts2 tests (signed Invite): an Invite addressed to this user is recorded and listed (title + host actor); an Invite addressed to a different actor is ignored.

api tsc clean; app build clean (fixed a react-router v8 import); full API suite 213 passed (was 211).

The host→editor Invite delivery is fire-and-forget outbound, so it's exercised end-to-end only across two live instances; the receive + list paths are fully tested here.

Next

PR 3 (final): editor remote-view (signed-fetch the host's entries via #62-part-1's endpoint) + compose/edit → signed Create/Update delivery — closing #62 and the v7 milestone.

🤖 Generated with Claude Code

Part 2 of **#62**. The host now *tells* the editor's instance about an invite, and the editor records it. ## What it does - **Host send:** `POST /api/projects/:id/invite-remote` delivers a signed AP `Invite` to the remote actor's inbox (`object` = the project's AP collection URL + name, `target` = the actor), fire-and-forget so a delivery failure never fails the invite. New `services/apOutbound.ts` `getSigningIdentity()` resolves (and lazily creates) the owner's AP keypair for signing. - **Editor receive:** the inbox handles `Invite` — when `target` is this inbox's actor, it records a row in **`remote_project_invitations`** (migration `043`). - **Editor surface:** `GET /api/remote-projects` lists active invitations; a new **Shared with me** page (`/remote-projects`, linked from Settings → Projects) shows them. ## Verification (dev server) `remoteInviteHandshake.test.ts` — **2 tests** (signed Invite): an Invite addressed to this user is recorded and listed (title + host actor); an Invite addressed to a *different* actor is ignored. api `tsc` clean; app build clean (fixed a `react-router` v8 import); full API suite **213 passed** (was 211). The host→editor `Invite` delivery is fire-and-forget outbound, so it's exercised end-to-end only across two live instances; the receive + list paths are fully tested here. ## Next PR 3 (final): editor remote-view (signed-fetch the host's entries via #62-part-1's endpoint) + compose/edit → signed `Create`/`Update` delivery — closing #62 and the v7 milestone. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
The host notifies the editor's instance, which records the invitation.

- Host: POST /api/projects/:id/invite-remote now delivers a signed AP Invite
  (object = the project's AP collection URL + name, target = the remote actor)
  to the actor's inbox, fire-and-forget. New services/apOutbound.ts
  getSigningIdentity() resolves/lazily-creates the owner's AP keypair.
- Editor: the inbox handles Invite — when addressed to this user's actor, it
  records a row in remote_project_invitations (migration 043).
- Editor: GET /api/remote-projects lists active invitations; a "Shared with
  me" page (linked from Settings → Projects) shows them.

PR3 adds reading the host's entries and delivering edits.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
docs(p62): changelog for invite handshake (#62 part 2)
Some checks failed
CI / App — typecheck, test & build (push) Failing after 59s
CI / API — typecheck & tests (push) Has been cancelled
e253547508
fix(p62): import Link from react-router (v8), not react-router-dom
All checks were successful
CI / App — typecheck, test & build (push) Successful in 1m35s
CI / API — typecheck & tests (push) Successful in 2m37s
CI / App — typecheck, test & build (pull_request) Successful in 1m33s
CI / API — typecheck & tests (pull_request) Successful in 2m55s
834c000a6e
claude-bot scheduled this pull request to auto merge when all checks succeed 2026-06-30 13:49:46 +00:00
claude-bot deleted branch feat/v7-remote-invite-handshake 2026-06-30 13:52:37 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
rbrooks/TeaLeaves!70
No description provided.