Build PastePal

YESback to the verdict

0%0 of 17 items done

Saved on this device only. Tick prerequisites first, then work the phases in order · do not start one until the checks above it pass.

A clipboard manager whose interesting engineering is capturing everything fast and searchably, and whose entire design constraint is that a meaningful fraction of what passes through a clipboard must never be written down.

estimated effort weekendthe files for this build are in the project pack

CaptureA platform clipboard observer honouring the sensitive-content markerExclusionSource application and content shape rules applied before writingStorageEncrypted local database with a bounded historySearchFull text over decrypted content in memoryRuntimeA local application with a global hotkey

Before step 1

Everything below is assumed from the first step. Tick each one when you actually have it, not when you plan to.

  1. installfree

    Why Runs the local application.

    Get it nodejs.org, or nvm install 22. open ↗

    Verify node --version prints v22 or higher

  2. installfree

    Why The marker is how a password manager tells you not to record something, and reading it is platform-specific and easy to miss entirely.

    Get it Your platform's clipboard interface, and find the marker's name in its documentation before writing the capture path.

    Verify Content copied from a password manager is identifiable as marked

  3. installfree

    Why The database encryption key has to live somewhere better than beside the database.

    Get it Your platform's credential store interface.

    Verify A key stores and retrieves and is not readable from a plain file

  4. decidefree

    Why Deciding what never to record after a month of recording is deciding it too late, since the data already exists.

    Get it List applications to exclude and the content shapes that must never be stored, erring wide.

    Verify The list is loaded by the capture path before the first run

  5. have readyfree

    Why The single most important behaviour is not recording what a password manager copies, and that is only verifiable against a real one.

    Get it Any password manager that sets the sensitivity marker.

    Verify Copying a password from it produces no stored item

Data model

Create these before the first phase that stores anything. Changing a table later is the expensive kind of change.

- items(id, kind, content, source_app, copied_at, pinned, collection_id) · kind is text, image, file_ref or rich
- collections(id, name, ordinal) · saved snippets, kept indefinitely unlike history
- exclusions(id, rule_kind, pattern, created_at) · rule_kind is app, shape or marker
- skipped(at, reason, source_app) · that something was excluded, never what it was
- settings(key, value) · hotkey, retention, encryption state
- The skipped table records that an exclusion fired and why, and deliberately never records the content it excluded, because that record would be exactly the thing being protected.

Environment variables

These go in a .env file the app reads at startup. The pack's .env.example is this table as a file · copy it, never commit the filled-in version.

VariableNeededExampleWhere the value comes from
DB_PATHrequired~/.local/share/pastepal/history.dbEncrypted history and collections.
DB_KEY_REFsecretrequireda keychain item referenceThe encryption key lives in the platform keychain, not beside the database.
HISTORY_LIMITrequired200Bounded. An unbounded clipboard log is a growing liability.
EXCLUSIONS_PATHrequired./config/exclusions.txtApplied in the capture path, before anything is written.
HONOUR_SENSITIVITY_MARKERrequiredalwaysPresent as a constant. It is how a password manager says do not record this.
SYNC_HISTORYrequiredneverPresent as a constant. Only deliberately saved collections sync.

The build, in order

  1. Not capturing what must not be captured

    Sensitive content never reaches disk in the first place.

    1. Password managers set it. Ignoring it is the first failure.

      Files src/capture.ts

    2. Card numbers, keys and tokens, checked in the capture path.

      Files src/exclusions.tstests/exclusions.test.ts

    3. The record would otherwise be the thing you were protecting.

      Files src/skipped.ts

    done when · tick each as it passes
    watch out
    • Filtering sensitive items when the history is displayed leaves them in the database, the backups and any crash report, so the protection exists only in the interface. Apply exclusions in the capture path, and record that something was skipped without recording what it was.
  2. A history that is faster than not having one

    Reaching an item from three copies ago takes under a second.

    1. The first use of the day is the one that decides the habit.

      Files src/window.ts

    2. A rich text item pasted as plain text is a lost item.

      Files src/formats.ts

    3. An unbounded clipboard log is a growing liability.

      Files src/retention.ts

    done when · tick each as it passes
    watch out
    • A clipboard manager that takes two seconds to open is slower than scrolling back in the application you copied from, and people stop using it within a week. Pre-warm the window, and measure from keypress to pasted rather than to displayed.
  3. Encrypted at rest, searchable in memory

    The stored history is unreadable without the key, and still searchable.

    1. So the key is not sitting beside the database.

      Files src/crypto.ts

    2. A plaintext index makes the encryption decorative.

      Files src/search.tstests/no-index.test.ts

    3. Decrypted history resident indefinitely defeats the lock.

      Files src/lock.ts

    done when · tick each as it passes
    watch out
    • Building a search index for speed writes the content in plaintext beside the encrypted database, which makes the encryption decorative. Search in memory over the decrypted set, and accept the performance cost, which at a bounded history size is negligible.
  4. Things worth keeping

    Snippets you use often are saved separately from the rolling history.

    1. A saved snippet should not roll out of history.

      Files src/collections.ts

    2. Otherwise the sensitive item persists indefinitely rather than briefly.

      Files src/collections.ts

    3. The whole tool exists to avoid reaching for a mouse.

      Files src/collections.ts

    done when · tick each as it passes
    watch out
    • Allowing a user to pin an item that the exclusion rules would have blocked reintroduces exactly the risk, and the item then persists indefinitely rather than rolling out of history. Apply the same rules to collections and explain the refusal rather than silently allowing it.
what this build does not replace
after v1, if you want it

Need the files? The project pack on the verdict page hands your agent the whole brief · more productivity utilities.