Skip to content

fix(paperbell): re-handshake with the host on every PaperBell ready event - #36

Merged
SongshGeo merged 1 commit into
mainfrom
dev
Aug 18, 2026
Merged

SongshGeo merged 1 commit into
mainfrom
dev

Conversation

@SongshGeo

Copy link
Copy Markdown

Follow-up to the PaperBell main plugin's MIGRATION-0.4.7.md.

The bug this fixes

0.4.7 invalidates any PPBClient handle from a previous host load: every request* on it resolves to null and its config push is gone. Our ready listener guarded on !this.client, so once PaperBell updated we kept holding that dead handle — language following and account status silently stopped working until the user disabled and re-enabled this plugin by hand.

attach() now runs on every paperbell:ready: it releases the old handle (unsubscribe + unregister, both wrapped), registers again, re-reads capabilities, and re-subscribes. Two details keep the recovery invisible:

  • the last known config survives a reconnect and a failed re-register, so the UI never flips back to the fallback language;
  • on a reconnect only, we refetch the config when listGrants() says config is already granted — the grant outlived the reload, so this prompts for nothing. A first connect stays scope-free by design.

There is deliberately no "same host object, skip the handshake" shortcut: whether a reloaded host hands back a fresh api is its business, and guessing wrong would leave us on a dead handle forever.

Contract re-vendored to 0.4.7

PPB_SCHEMA_VERSION 1 → 2, so the "host schema is newer than vendored" console warning stops firing spuriously for every user who has PaperBell installed. Type names now match the host's published contract appendix verbatim (PaperBellRestrictedConfig + deprecated alias, PaperBellLLMCredentials, PaperBellActivationInfo, PPBProtectedDownload*), plus the optional profile / cimpoFolders / completion-quota fields 0.4.7 added. The proposed projects scope stays marked as ours, not upstream's.

The rest of the migration

Host change Us
Only api + settings remain on the plugin instance Nothing to do — we only ever read .api
Four keys gone from settings; pluginGrants no longer forgeable Nothing to do — we never read them, never forged a grant
llm.baseUrl / llm.model are now effective values Nothing to do — no feature builds a URL from them yet
Only plugins holding a scope get a settings card Accepted deliberately; documented under "Deferred consent"

Tests

MockPaperBellHost.reload() models a 0.4.7 zombie handle (every request*null, subscribers dropped) so a test can't pass against a dead handle. Nine new tests cover re-registration, re-subscription, config retention (including the failed-re-register path), the grant-gated refetch, a scope-free first connect, and the "never two live registrations" invariant.

npm run lint clean; 447 tests pass.

PaperBell 0.4.7 invalidates any PPBClient handle from a previous host load:
every request* on it resolves to null and its config push is gone. Our ready
listener guarded on `!this.client`, so once the host updated we kept holding
that dead handle — language following and account status silently stopped
working until the user disabled and re-enabled this plugin by hand.

attach() now runs on every paperbell:ready, not just the first: it releases the
old handle, registers again, re-reads capabilities and re-subscribes. The last
known config survives a reconnect (and a failed re-register), so the UI never
flips back to the fallback language; on a reconnect only, we refetch the config
when listGrants() says the scope is already granted, which prompts for nothing.
A first connect stays scope-free by design.

Also re-vendors the contract against 0.4.7: PPB_SCHEMA_VERSION 1 -> 2, so the
"host schema is newer than vendored" warning stops firing spuriously, with type
names aligned to the host's published contract appendix.

Nothing else in the migration applies to us: we never reached past `.api` into
the host's internals, never read plugin.settings, and no feature builds a URL
from llm.baseUrl yet. Our settings card in PaperBell now appears only once a
scope is granted — accepted deliberately, documented under "Deferred consent".

Refs: MIGRATION-0.4.7.md in PaperBell-Org/Obsidian-PaperBell-Plugin

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@SongshGeo
SongshGeo merged commit 9578be6 into main Aug 18, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant