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
-
Local by default
- Clipboard content must not be uploaded.
- No account or network service is required.
-
Collect the minimum
- Capture text only in the MVP.
- Ignore unsupported pasteboard types.
-
User-controlled retention
- Users choose maximum item count and expiration.
- Clearing history is immediate and verifiable.
-
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.
-
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
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
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
Summary
Add an official
clipboard-historyplugin 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:
Product principles
Local by default
Collect the minimum
User-controlled retention
No hidden global search exposure
Clear pause state
MVP functionality
History collection
Observe changes to the general pasteboard while the plugin is active.
Capture plain text when:
Store:
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:
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:
Suggested default behavior:
Final defaults should be reviewed during implementation.
Storage and privacy
Use a dedicated plugin store rather than
UserDefaultsfor clipboard payloads.Requirements:
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
open-historypause-collectionresume-collectiontoggle-collectionclear-unpinned-historyclear-all-historyDo 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
ClipboardChangeMonitoringClipboardCaptureCoordinatorClipboardHistoryStoreClipboardHistoryQueryingClipboardSourceContextProvidingClipboardHistoryPanelControllerClipboardHistoryPluginKeep pasteboard monitoring separate from persistence so both can be tested independently.
Implementation plan
Test coverage
Include tests for:
Acceptance criteria
Non-goals