Make Prompt Stash server-authoritative across clients
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 23k
- Forks
- 5.9k
- Avg merge
- 11h 14m
- Merged PRs (30d)
- 357
Description
Summary
Move Prompt Stash from browser-local state to durable state owned by the target T3 execution environment, so stashed prompts follow the same environment across desktop, web, mobile, or another controlling machine.
This should happen after #6276 because that PR establishes the server-side attachment model this design should reuse instead of inventing another blob-sync path.
Depends on: #6276
Why
Today the stash is globally provider-agnostic, but apps/web/src/promptStashStore.ts still treats browser localStorage as the authoritative store. That means the same execution environment can have different stash queues depending on which client/browser is connected.
#6276 fixes the harder attachment half by uploading attachment bytes to the server and persisting references by ID. Once that lands, stash metadata can move server-side while continuing to reference those existing attachment IDs.
Proposed architecture
The target execution environment/server should be the single source of truth for Prompt Stash.
- Persist stash metadata durably on the server, scoped to the environment rather than a thread or provider.
- Add idempotent mutations for creating, taking, and deleting stash entries.
takeshould be atomic so two clients cannot restore the same entry. - Expose a dedicated environment-level stash snapshot/subscription rather than piggybacking on
subscribeThread, because stash is intentionally thread- and provider-agnostic. - Put replicated client state in
packages/client-runtimeso web and mobile consume the same canonical model. - Reuse the attachment IDs introduced by #6276. Sync references, not base64/blob payloads.
- Keep client storage only as an optional offline pending-outbox layer, not as canonical stash state.
- Clear the composer only after the target server acknowledges a durable stash write.
- Keep T3 Connect as transport to the execution environment, not a second state authority.
Possible RPC/command shape, names illustrative:
prompt-stash.createprompt-stash.takeprompt-stash.deleteprompt-stash.subscribe/ snapshot
Correctness requirements
- Two connected clients see the same stash ordering and updates.
- Taking an entry from one client removes it everywhere exactly once.
- Concurrent restore attempts cannot duplicate a stash entry.
- Server restart preserves the queue.
- Attachment references remain valid after stash/create/take flows.
- A failed durable write leaves the composer and attachments unchanged.
- Existing local-only stash data has an explicit migration or retirement policy.
- Offline behavior cannot overwrite newer canonical server state silently.
Out of scope
- Making T3 Connect the canonical storage layer.
- Reworking the attachment upload protocol already covered by #6276.
- Making stash thread- or provider-scoped again.
Implementation order
Do not start this until #6276 is merged or its attachment contract is otherwise stable enough to build against. The implementation should then be a focused follow-up PR rather than expanding #6276 further.
Related discussion: https://github.com/pingdotgg/t3code/pull/6276#issuecomment-5350255834
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Wait for #6276 and review its server-side attachment contract first. Then inspect apps/web/src/promptStashStore.ts and the shared packages/client-runtime model, tracing how stash state and T3 Connect calls currently flow. Done means durable environment-scoped stash state, shared client updates, atomic take behavior, restart persistence, and attachment references that remain valid.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- backend, full-stack
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100