Skip to content

feat(plugin): add privacy-first text clipboard history and pinned snippets #306

Description

@xcv58

Summary

Add an official clipboard-history plugin that stores a searchable, local history of copied text and supports pinned snippets.

The first version should be privacy-first and intentionally limited to text. Images, files, cloud synchronization, OCR, and cross-device sharing are out of scope.

Related: #95

Motivation

MacTools currently provides Clipboard Clear but does not help users recover previously copied text or maintain reusable snippets.

Clipboard history is most valuable when it is:

  • Easy to invoke from anywhere
  • Clearly local
  • Predictable about retention
  • Easy to pause or erase
  • Integrated with MacTools actions and shortcuts
  • Explicit about what it observes and stores

Product principles

  1. Local by default

    • Clipboard content must not be uploaded.
    • No account or network service is required.
  2. Collect the minimum

    • Capture text only in the MVP.
    • Ignore unsupported pasteboard types.
  3. User-controlled retention

    • Users choose maximum item count and expiration.
    • Clearing history is immediate and verifiable.
  4. No hidden global search exposure

    • Transient clipboard entries must not be added to the static Unified Search index.
    • Clipboard search happens inside the plugin's dedicated panel.
  5. Clear pause state

    • The UI must visibly indicate when history collection is paused.

MVP functionality

History collection

Observe changes to the general pasteboard while the plugin is active.

Capture plain text when:

  • The value is non-empty.
  • The value is below the configured size limit.
  • The same normalized value is not already the newest item.
  • Collection is not paused.
  • The likely source application is not excluded.

Store:

  • Stable item ID
  • Captured text
  • Capture date
  • Best-effort source application bundle identifier and name
  • Pin state
  • Last-used date

Source-application attribution is best effort. It should use the shared system-context service when available and must not be represented as guaranteed provenance.

History browser

Provide a searchable floating panel or workspace with:

  • Recent items
  • Pinned snippets
  • Search
  • Copy
  • Delete
  • Pin/unpin
  • Clear unpinned history
  • Clear all history
  • Pause/resume collection

Keyboard navigation should be supported.

Selecting an item should copy it back to the pasteboard.

Automatically synthesizing Command-V is not required for the MVP.

Retention settings

Support:

  • Maximum item count
  • Expiration period
  • Maximum text size
  • Excluded applications
  • Capture pause
  • Clear history
  • Clear pinned snippets separately

Suggested default behavior:

  • Modest bounded history size
  • Expiration enabled
  • Oversized values ignored
  • Pinned snippets exempt from ordinary expiration

Final defaults should be reviewed during implementation.

Storage and privacy

Use a dedicated plugin store rather than UserDefaults for clipboard payloads.

Requirements:

  • Encrypt clipboard payloads at rest using a key stored in Keychain.
  • Do not write clipboard text to logs, crash breadcrumbs, analytics, or action-history details.
  • Store only metadata needed by the product.
  • Delete expired items from persistent storage rather than merely hiding them.
  • Ensure uninstall removes the plugin database and associated encryption key.
  • Redact content from diagnostics and support exports.

If encrypted storage cannot be completed in the initial implementation, the feature should not silently fall back to plaintext. The product must either block release or explicitly redesign the storage contract.

Application exclusions

Allow users to exclude applications by bundle identifier.

Collection filtering should happen before clipboard content is persisted.

Because the pasteboard does not provide guaranteed source-application identity, the UI and documentation must state that exclusion uses the frontmost application observed at capture time.

The implementation should never claim that exclusions provide the same guarantees as a secure-input field or password manager.

Proposed canonical actions

Action ID Behavior
open-history Open the searchable clipboard-history panel
pause-collection Pause future history capture
resume-collection Resume capture
toggle-collection Toggle capture state
clear-unpinned-history Clear non-pinned history with confirmation
clear-all-history Clear all history and snippets with stronger confirmation

Do not create one canonical action or Unified Search result for every transient history item.

Pinned-snippet actions can be considered later after privacy, portability, and catalog-size behavior are defined.

Proposed architecture

  • ClipboardChangeMonitoring
    • Detects pasteboard ownership/change transitions.
  • ClipboardCaptureCoordinator
    • Applies pause, exclusion, type, deduplication, and size policies.
  • ClipboardHistoryStore
    • Owns encrypted persistence, retention, and deletion.
  • ClipboardHistoryQuerying
    • Provides bounded search and pagination.
  • ClipboardSourceContextProviding
    • Supplies best-effort frontmost-application context.
  • ClipboardHistoryPanelController
    • Owns presentation and keyboard interaction.
  • ClipboardHistoryPlugin
    • Publishes settings, state, permissions, and canonical actions.

Keep pasteboard monitoring separate from persistence so both can be tested independently.

Implementation plan

  • Define the history and retention data model.
  • Implement an encrypted local store.
  • Implement text-only pasteboard monitoring.
  • Add deduplication and size limits.
  • Integrate best-effort source-application context.
  • Add application exclusions.
  • Add retention cleanup.
  • Build the searchable history panel.
  • Add pin/unpin and snippet storage.
  • Add pause/resume and clear controls.
  • Publish canonical actions.
  • Add uninstall cleanup.
  • Add privacy documentation and Marketplace metadata.
  • Add unit, integration, and manual tests.

Test coverage

Include tests for:

  • Empty clipboard
  • Unsupported types
  • Duplicate consecutive values
  • Oversized text
  • Rapid clipboard changes
  • Clipboard ownership changing during capture
  • Pause/resume
  • Excluded applications
  • Missing source-application context
  • Retention expiration
  • Maximum-count pruning
  • Pinned-item retention
  • Encryption-key loss
  • Store corruption
  • Uninstall cleanup
  • No clipboard content appearing in logs

Acceptance criteria

  • The plugin captures supported text while enabled.
  • Users can search, copy, delete, pin, and unpin entries.
  • Collection can be paused and its state is clearly visible.
  • Transient entries are not added to global Unified Search.
  • History is bounded by count, age, and item size.
  • Clipboard payloads are encrypted at rest.
  • Clearing history removes persistent payloads.
  • Excluded applications are filtered before persistence when source context is available.
  • Uninstall removes clipboard data and cryptographic material.
  • No clipboard text is written to application logs.

Non-goals

  • Images
  • Files
  • Rich-text previews
  • OCR
  • Cloud sync
  • Cross-device clipboard
  • AI classification
  • Automatic secret detection
  • Guaranteed password-manager protection
  • Automatically typing or pasting into applications
  • Exposing every history item as a canonical action

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions