Feature request: bounded persistent storage for local provider plugins (`ctx.storage`)

Open
#3,170 2 comments 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
5/5
Estimated time
Over a week
Newbie friendliness
35/100
Issue type
Feature
Clarity
Needs clarification
Activity status
Active

Research direction

No source file, test, or entry point is named. Start by resolving the API shape, capability requirement, storage limits, deletion semantics, and runtime parity questions; done means a bounded, isolated persistent-storage design with coverage for the listed app, CLI, QuickJS, JavaScriptCore, validation, cleanup, and approval behaviors.

Written by the indexing model from the issue text.

Description

clawsweeper:needs-maintainer-review clawsweeper:needs-product-decision clawsweeper:no-new-fix-pr issue-rating: 🌊 off-meta tidepool P3

Problem

Local provider plugins currently have ctx.cache, but it is an in-memory,
per-runtime cache. Its contents are lost when CodexBar or the plugin runtime
restarts.

Plugins are intentionally sandboxed and cannot access local files, databases,
Node APIs, or subprocesses. This is a good security boundary, but it also means
that a plugin cannot preserve a small amount of non-secret state without
running a separate local service.

A concrete example is a quota-planning plugin:

  • The provider exposes only a cumulative weekly usage percentage.
  • To calculate "usage today", the plugin records the cumulative value at the
    beginning of each quota day.
  • After CodexBar restarts, that baseline disappears and the calculated daily
    usage resets or has to be estimated again.

This cannot be solved accurately with the current provider response alone.

Other possible use cases include:

  • Incremental synchronization cursors
  • Last-seen provider counters
  • Derived rate-window baselines
  • Small checkpoints needed to recover after a runtime restart
  • Provider state that should be isolated between multiple plugin instances

Proposed API

Would CodexBar be open to a small, host-managed persistent storage API for local
provider plugins?

For example:

ctx.storage.get(key) // JSON value | undefined
ctx.storage.set(key, value)
ctx.storage.remove(key)

Possible TypeScript contract:

interface CodexBarPluginStorage {
  get<T extends CodexBarJSONValue = CodexBarJSONValue>(
    key: string
  ): T | undefined;

  set(key: string, value: CodexBarJSONValue): void;

  remove(key: string): void;
}

The API would be synchronous, similar to ctx.cache, while the host would be
responsible for durable storage.

Suggested constraints

To preserve the existing plugin sandbox, the storage could be:

  • Namespaced per plugin instance
  • Limited to JSON-serializable values
  • Small and bounded, for example 64 KiB per instance
  • Written atomically
  • Available consistently in QuickJS and the JavaScriptCore fallback
  • Available to both the app and CLI runtimes
  • Deleted when the plugin instance is removed
  • Inaccessible to other plugin instances
  • Unable to expose arbitrary file paths or local filesystem access

This should not be treated as a secret store. Plugins should continue using
secure settings for credentials, tokens, and cookies.

It may also make sense to require an explicit manifest capability such as:

capabilities: ["persistent-storage"]

That would make the new authority visible during plugin approval and keep
storage access fail-closed for plugins that do not request it.

Why not persist ctx.cache automatically?

ctx.cache currently has clear temporary-cache semantics, including a bounded
TTL. Changing it into durable storage could surprise existing plugins.

A separate ctx.storage API would keep the distinction explicit:

  • ctx.cache: temporary runtime cache
  • ctx.storage: small persistent plugin state

Testing expectations

The externally visible behavior should cover:

  • Values surviving runtime destruction and recreation
  • get, set, overwrite, missing-key, and idempotent remove
  • Plugin-instance isolation
  • JSON and capacity validation
  • Safe handling of corrupt or incompatible stored data
  • Cleanup when a plugin instance is deleted
  • QuickJS and JavaScriptCore behavior parity
  • App and CLI access to the same instance state
  • Capability and approval enforcement, if a capability is required

Questions for maintainers and plugin authors

  1. Does a bounded persistent plugin-state API fit CodexBar's plugin model?
  2. Would other plugin authors use this for checkpoints, cursors, or derived
    usage windows?
  3. Should access require an explicit persistent-storage capability?
  4. Is ctx.storage.get/set/remove the right API shape?
  5. Would a read-only previous-snapshot API be preferable for some use cases?
  6. What storage limit and deletion semantics would be most appropriate?

If the direction is welcome, I would be happy to prepare a tested implementation
and documentation in a follow-up PR.

Dominant language
Swift
Stars
21.6k
Forks
2k
Avg merge
1d 9h
Merged PRs (30d)
385

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from steipete/CodexBar

All issues in steipete/CodexBar

Similar issues

More Swift issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.