Repository navigation
Pantry Host 0.6.0 — Publish to Bluesky from any self-hosted origin
The round trip is now open to every tier. 0.5.0 let you publish recipes and menus to your PDS — but only from origins that could complete AT Protocol OAuth. 0.6.0 removes that constraint and closes the loop on cross-device identity.
Publish broker (#38)
Self-hosted instances (LAN, Tailscale, plain HTTP — any origin that can't do AT OAuth itself) now publish through a popup on the hosted origin, my.pantryhost.app/publish-broker:
- The popup shows which origin is asking, the exact record JSON, and a dry-run badge when applicable; nothing is written without your confirm click inside the popup (real URL bar — no clickjacking).
- OAuth tokens and DPoP keys never leave the broker origin — only record payloads go in, only receipts come out, with
targetOrigin-locked replies. - One request per popup lifetime; the payload can't be swapped after the review renders.
- Records still travel browser → PDS. Pantry Host infrastructure stores nothing.
- Sign-in inside the broker runs in a nested popup (
signInPopup+ BroadcastChannel) because PDS auth pages send COOP headers that would sever the popup's link to your app on a redirect.
Adopt-own-records (#40)
Importing your own published recipe used to disconnect it from its record — re-publishing minted a duplicate. Now, when a recipe or menu's sourceUrl is an at:// record owned by the signed-in DID:
- Publish targets the original's rkey —
putRecordupdates it in place. The broker review screen says so explicitly: "Updates your existing record<rkey>in place." - On OAuth-capable origins, the CTA reflects it immediately: import your own record and it shows "View on Bluesky" without ever publishing from that device.
- Menu children you own get the same treatment — local edits land on the originals instead of freezing as strongRefs.
- Re-publish also preserves photos: when a fresh photo fetch fails (CORS-blocked CDNs), the existing record's embed is carried forward — a re-publish never loses a photo.
Fixes
- Hosted-origin sign-in worked for the first time (#41):
client-metadata.jsonwas served without CORS headers, somy.pantryhost.appcould never fetch it and sign-in died before OAuth started. All prior sign-ins had been on loopback. - Stale localStorage cache seeds no longer white-screen detail pages (#39): a cached recipe/menu shape missing its load-bearing arrays is discarded instead of trusted, at both the cache layer and the render layer.
- Deterministic rkeys + PDS reconcile (#36): publish state is derived from the PDS, not localStorage — a second device or a cleared cache resolves the same record. (Merged pre-0.6.0, ships here.)
#stagescroll restored on Tier 1 navigation (#35).- Leftover dry-run receipts no longer render a published CTA in real mode; shared Modal panel no longer transparent on the web tier.
Known gaps
- First publish of a CORS-blocked external photo (including
cdn.bsky.app) is still photoless —com.atproto.sync.getBlobfallback tracked as follow-up. - Fully sovereign alternatives to the broker (own-domain OAuth, app passwords) tracked in #37.
🤖 Generated with Claude Code