ilia b643f50d76 Initial commit: macOS clipboard manager menu bar app
Tauri 2 + React 18 + TypeScript + Tailwind CSS v4 + SQLite (rusqlite)

Features:
- Menu bar app with tray icon (no dock icon)
- Global hotkey Cmd+Shift+V
- Clipboard polling every 500ms (text, images, file paths)
- SQLite FTS5 full-text search
- Pin/unpin entries, auto-trim, context menu
- Settings panel (launch at login, show images, max history, clear all)
- Dark/light mode following macOS system preference
- Frameless floating window, closes on blur

Testing:
- 27 Rust unit tests (db, clipboard, FTS5, trim, settings)
- 31 TypeScript component tests (vitest + @testing-library/react)

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-12 12:55:56 -04:00

maCopy

A lightweight macOS clipboard manager that lives in your menu bar. Built with Tauri 2, React, TypeScript, and SQLite.

macOS Tauri License

Features

  • Menu bar app — no dock icon, stays out of your way
  • Global hotkeyCmd+Shift+V opens the window from anywhere
  • Clipboard monitoring — polls every 500ms for text, images, and file paths
  • Full-text search — instant filtering via SQLite FTS5
  • Quick pasteCmd+1 through Cmd+9 to paste the Nth item
  • Pin entries — pinned items stay at the top and are never auto-deleted
  • Context menu — right-click for Copy, Pin/Unpin, Delete
  • Auto-trim — keeps the last 500 entries by default (configurable: 100/500/1000)
  • Dark/light mode — follows macOS system appearance
  • Privacy — whitespace-only entries are ignored; pause monitoring from the tray

Prerequisites

  • macOS 10.15+
  • Rust 1.77+ — install via rustup
  • Node.js 18+ and npm
  • Xcode Command Line Toolsxcode-select --install

Quick Start

git clone <your-repo-url> maCopy
cd maCopy
npm install
npm run tauri dev

The app will compile the Rust backend, start the Vite dev server, and launch the menu bar app.

Development

Project Structure

maCopy/
├── src/                        # React + TypeScript frontend
│   ├── main.tsx                # Entry point
│   ├── App.tsx                 # Main app: routing, keyboard nav, polling
│   ├── index.css               # Tailwind v4 + custom theme tokens
│   ├── types.ts                # Shared TypeScript types
│   ├── test/                   # Test setup and factories
│   │   ├── setup.ts
│   │   └── factories.ts
│   └── components/
│       ├── SearchBar.tsx       # Auto-focused search input
│       ├── ClipboardList.tsx   # Entry list with time-ago, pin badges
│       ├── ContextMenu.tsx     # Right-click: Copy / Pin / Delete
│       └── SettingsPanel.tsx   # Toggles + max history + clear all
├── src-tauri/                  # Rust backend
│   ├── Cargo.toml
│   ├── tauri.conf.json         # Tauri config, permissions, window
│   └── src/
│       ├── main.rs             # Binary entry point
│       ├── lib.rs              # App setup: tray, hotkey, window behavior
│       ├── clipboard.rs        # Background polling thread (500ms)
│       ├── db.rs               # SQLite CRUD + FTS5 + auto-trim
│       └── commands.rs         # Tauri IPC commands
├── package.json
├── vite.config.ts
├── vitest.config.ts
└── tsconfig.json

Scripts

Command Description
npm run tauri dev Run the app in development mode with hot reload
npm run tauri build Build a release .app bundle
npm test Run frontend tests (vitest)
npm run test:watch Run frontend tests in watch mode
npm run test:rust Run Rust backend tests
npm run test:all Run all tests (frontend + backend)

Tech Stack

Layer Technology
Framework Tauri 2
Frontend React 18, TypeScript, Tailwind CSS v4
Backend Rust, rusqlite (bundled SQLite)
Clipboard arboard for cross-platform access
Search SQLite FTS5 with content-sync triggers
Hotkey tauri-plugin-global-shortcut
Autostart tauri-plugin-autostart
Testing vitest + @testing-library/react (frontend), cargo test (backend)

Architecture

Clipboard Polling

A dedicated Rust thread polls the system clipboard every 500ms using the arboard crate. Each new clipboard value is hashed (SHA-256) and compared against the last known hash to avoid duplicates. Text, images (stored as base64 PNG data URIs), and file paths are all captured.

SQLite + FTS5

The database uses a content-synced FTS5 virtual table with triggers that automatically keep the full-text index in sync with the main clipboard_entries table. This enables instant prefix search as you type.

Window Behavior

The window is frameless, always-on-top, and hides when it loses focus — behaving like a native macOS popover. Clicking the tray icon or pressing Cmd+Shift+V toggles visibility.

Data Storage

The SQLite database is stored at:

~/Library/Application Support/maCopy/clipboard.db

Testing

Frontend (31 tests)

npm test

Tests cover all four UI components: SearchBar, ClipboardList, ContextMenu, and SettingsPanel. Tauri APIs are mocked so tests run in jsdom without the native runtime.

Backend (27 tests)

npm run test:rust

Tests use in-memory SQLite databases and cover: CRUD operations, FTS5 search, auto-trim with pin preservation, settings persistence, SHA-256 hashing, and PNG encoding.

All tests

npm run test:all

Building for Release

npm run tauri build

The built .app bundle will be in src-tauri/target/release/bundle/macos/.

License

MIT

Description
No description provided
Readme MIT 351 KiB
Languages
TypeScript 52.3%
Rust 45.6%
CSS 1.8%
HTML 0.3%