Skip to content

v0.9.0 — write-on-demand sharing and live cross-surface sync

Latest

Choose a tag to compare

@abiddotdev abiddotdev released this 06 Sep 00:31
· 6 commits to master since this release
489d215

Changed

  • Sharing is now write-on-demand instead of automatic. Every render used to mirror to disk the moment it settled, whether or not anyone ever intended to share it; the accumulated directory only bounded itself by artifactRetentionDays. Nothing is written now until a card's Export control asks for it — and that request names only the call ({callId}), never document bytes: the host reads title/html straight out of the call's own durable session log, verifies it settled successfully as a visualizer call, and only then writes it. The write is idempotent (exporting the same call twice reproduces the same file) and rate-limited (30 requests/minute) against a scripted loop.
    • The card's Share button is now two states in one slot: Export until the write confirms, then Share (open) once it has — kept as two separate clicks rather than write-then-open in one, specifically to avoid a popup blocker on the tab window.open would otherwise have to make after an awaited network call. Copy share link and a new Unshare control (arm-then-confirm, like the gallery's own Delete, removing the export and returning the card to Export) only ever appear once something is actually exported — there is nothing to copy or unshare before that, so Copy-link no longer needs to trigger an export of its own the way it briefly did.
    • New host dependency on @deepseek-ai/dsh-session (ctx.sessions), replacing the loosely-typed session/event listener the streaming mirror used — this plugin previously named that package only in a comment explaining why it deliberately avoided depending on it; the export-on-demand read needs a real, durable, replayable log lookup (Session.snapshotEvents()) that a live event listener cannot provide after the fact.
    • The streaming .partial sidecar mirror is gone entirely — it wrote to disk every ~120ms for every render whether or not it was ever shared, and nothing had ever read it back.
    • The system prompt's sharing note changed from "every render is saved automatically" to pointing the model at the Share control instead — the underlying reason to avoid a duplicate file-tool write is unchanged (the conversation log was always the actual durable copy), only the description of what the export route does changed.
    • The rendered document's own bridge gained a read-only window.share ({exported, url}), requested at boot and re-pushed on every change, with a dsh-share-status window event alongside it for a document that wants to react rather than poll. Deliberately read-only — there is no bridge call to trigger a share from inside the document, since that would recreate the automatic-write behavior this whole change removed, just moved one layer down into model-authored script.
    • A page reload remounts every card at "not exported," since export status was pure in-memory React state with no way to tell a genuinely-unexported call apart from an already-shared one whose page just happened to reload. useExportControl now checks once on mount against the current artifact listing — the client already computes the exact name an export would carry, so finding it in the listing recovers the correct state instead of showing Export again for something already on disk. Every card reconciling at once (a transcript reload) shares one listing request rather than firing one each. A user's own click always wins over a slower-resolving check: the reconciliation only ever moves a card out of idle, never overwrites an in-progress or already-settled one.
    • Exporting or unsharing from one surface now updates every other open surface holding the same file live, not just at its own next mount: a dsh-artifact-changed window event fires on a confirmed export or delete, and both a card's useExportControl and the gallery tab listen for it. Deleting a file from the gallery drops it out of an open card's Share/Copy-link/Unshare immediately instead of leaving those controls pointed at a 404 until the page reloads; unsharing from a card drops its row from an open gallery tab the same way.