Metadata-Version: 2.4
Name: clippal
Version: 0.1.0
Summary: Power-user macOS clipboard manager with menu bar, global hotkeys, and search
Author: Vineet Kumar
License-Expression: MIT
Project-URL: Homepage, https://github.com/naxatar/clippal
Project-URL: Repository, https://github.com/naxatar/clippal
Project-URL: Issues, https://github.com/naxatar/clippal/issues
Keywords: clipboard,macos,clipboard-manager,menu-bar,pyobjc
Classifier: Development Status :: 3 - Alpha
Classifier: Environment :: MacOS X
Classifier: Intended Audience :: End Users/Desktop
Classifier: Operating System :: MacOS :: MacOS X
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Desktop Environment
Classifier: Topic :: Utilities
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: pyobjc-framework-Cocoa
Requires-Dist: pyobjc-framework-Quartz
Requires-Dist: pyyaml
Provides-Extra: dev
Requires-Dist: pytest; extra == "dev"
Dynamic: license-file

# clipmon (clippal)

[![PyPI](https://img.shields.io/pypi/v/clippal)](https://pypi.org/project/clippal/)
[![Python](https://img.shields.io/pypi/pyversions/clippal)](https://pypi.org/project/clippal/)
[![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
[![CI](https://github.com/naxatar/clippal/actions/workflows/ci.yml/badge.svg)](https://github.com/naxatar/clippal/actions/workflows/ci.yml)

A power-user macOS clipboard manager. Monitors your clipboard, stores history in SQLite with full-text search, and provides a menu bar app with a floating overlay and keyboard-driven search panel. The goal: a clipboard manager so useful it becomes an extension of your keyboard.

## Quick start

```bash
brew install clippal          # or: pip install clippal
clippal ui                    # starts in background, look for 📋 in menu bar
```

macOS will ask for **Accessibility permission** on first launch — grant it for global hotkeys to work. Then:
- **Ctrl+Opt+F** — open search panel (browse, search, edit, create clips)
- **Ctrl+Opt+V** — peek at clipboard (hold to browse history)

## Features

- **Clipboard monitoring** -- polls `NSPasteboard.changeCount` at 500ms, stores text with metadata (source app, content type, timestamps)
- **Duplicate handling** -- same text bumps copy count + moves to top instead of creating a new entry
- **Smart filtering** -- skips password managers (`ConcealedType`), transient content, auto-generated clipboard writes
- **Full-text search** -- FTS5-powered search across all clipboard history
- **Menu bar app** -- browse recent clips, click to copy back, pin/unpin items
- **Search panel** -- floating split-pane with live typeahead, history (left) + favourites (right), inline editing, right-click context menu, hover preview, and scrollable help
- **Floating overlay** -- hold-to-peek panel showing current clipboard content with history cycling
- **Global hotkeys** -- configurable shortcuts (Ctrl+Option+V for overlay, Ctrl+Option+F for search). Requires Accessibility permission
- **Singleton process** -- only one instance runs at a time, `clipmon stop` to shut down
- **File logging** -- logs to `~/.config/clipmon/clipmon.log`, view with `clipmon logs`
- **CLI tools** -- list, search, stats, export (JSON/CSV), clear, stop, logs

## Requirements

- macOS (tested on macOS 26 Tahoe)
- Python >= 3.9
- Accessibility permission (for global hotkeys)

## Installation

### From PyPI (recommended)

```bash
pip install clippal
```

### From Homebrew

```bash
brew tap naxatar/tap
brew install clippal
```

### From source (development)

```bash
git clone https://github.com/naxatar/clippal.git && cd clippal
python3 -m venv venv && source venv/bin/activate
pip install -e ".[dev]"
```

### Post-install

clipmon requires **Accessibility permission** for global hotkeys (Ctrl+Opt+V overlay, Ctrl+Opt+F search). macOS will prompt on first launch, or grant manually in **System Settings > Privacy & Security > Accessibility**.

## Usage

### Menu bar app (recommended)

```bash
clipmon ui
```

Launches the menu bar app in the background and exits immediately. If already running, shows status with PID, uptime, and clip stats:

```
clipmon: running (pid 12345, uptime 2h 15m)
  Clips: 142  Pinned: 5  Apps: 12
```

Features:
- Dropdown showing recent clips (click to copy back)
- Pinned clips section
- Search (Ctrl+Option+F)
- Floating overlay toggle (Ctrl+Option+V)
- Copy count badges on frequently copied items

### Managing the process

```bash
clipmon ui                      # Start (background) or show status
clipmon stop                    # Stop the running instance
clipmon logs                    # Show last 50 log lines
clipmon logs -f                 # Follow logs live (tail -f)
clipmon logs -n 100             # Show last 100 lines
```

### Uninstalling

```bash
clipmon uninstall               # Stops clipmon, removes all data (~/.config/clipmon/)
pip uninstall clippal           # or: brew uninstall clippal
```

This removes your clipboard history database, config file, and logs. Use `clipmon uninstall -y` to skip the confirmation prompt.

### CLI commands

```bash
clipmon list                    # Show recent clipboard history
clipmon list --limit 50 -v      # 50 items, verbose (timestamps, source app)
clipmon search "query"          # Full-text search
clipmon stats                   # Total clips, top copied, top apps
clipmon export                  # JSON to stdout
clipmon export --format csv     # CSV to stdout
clipmon clear                   # Clear history (with confirmation)
clipmon clear -y                # Clear without confirmation
```

## Search panel

Open with **Ctrl+Option+F**. A floating split-pane with History (left, 60%) and Favourites (right, 40%).

### Navigation

| Key | Action |
|-----|--------|
| `↓` / `↑` | Move through list (down enters table, up from row 0 returns to search) |
| `← →` | Switch between History and Favourites |
| `Enter` | Copy selected clip to clipboard |
| `Cmd+Enter` | Paste directly into the active app (simulates Cmd+V) |
| `Esc` | Close panel / cancel edit |
| `?` | Toggle scrollable help overlay |

### Actions (select a clip first)

| Key | Action |
|-----|--------|
| `E` | Edit clip in preview area |
| `F` | Toggle favourite (pin/unpin) |
| `O` | Open -- URL opens in browser, short text opens as Google search |
| `D` | Delete clip |

### Edit mode

The preview area at the bottom is always editable. Click it or press `E` to start editing. Changes are auto-detected.

| Key | Action |
|-----|--------|
| `Cmd+S` | Save edit (overwrite original) |
| `Cmd+Shift+S` | Save as new clip (keep original) |
| `Esc` | Cancel and revert |

Navigation is blocked while editing to prevent accidental data loss.

### Mouse interactions

| Action | Effect |
|--------|--------|
| **Hover** | Highlights row and shows preview (reverts on mouse leave) |
| **Click** | Selects row |
| **Double-click** | Pastes clip and closes panel |
| **Cmd+click** | Opens clip (same as `O` key) |
| **Right-click** | Context menu (Paste, Edit, Favourite, Open, Delete) |
| **Click ⋯** | Same context menu via three-dot button on each row |

Keyboard always takes priority over mouse hover -- pressing any arrow key clears the hover state and resumes from the keyboard's last position.

## Overlay

Toggle with **Ctrl+Option+V**. A translucent hold-to-peek panel showing clipboard content.

| Key | Action |
|-----|--------|
| `Ctrl+Opt+V` | Show overlay / cycle back through history |
| `Shift+Ctrl+Opt+V` | Cycle forward (rewind) through history |
| Release `Ctrl` | Close overlay |

## Configuration

Config file: `~/.config/clipmon/config.yml` (auto-created on first run)

| Setting | Default | Description |
|---------|---------|-------------|
| `polling_interval` | `0.5` | Clipboard poll frequency (seconds) |
| `max_history` | `1000` | Maximum clips to keep |
| `db_path` | `~/.config/clipmon/clipmon.db` | SQLite database location |
| `skip_concealed` | `true` | Skip password manager entries |
| `skip_transient` | `true` | Skip transient clipboard items |
| `log_level` | `INFO` | Logging level |
| `hotkey_toggle_overlay` | `ctrl+alt+v` | Overlay toggle shortcut |
| `hotkey_open_search` | `ctrl+alt+f` | Search shortcut |
| `overlay_x` / `overlay_y` | `100` | Overlay panel position (saved automatically) |
| `overlay_visible` | `false` | Restore overlay on launch |
| `suggestion_threshold` | `5` | Copies before suggesting a shortcut |

## Architecture

```
src/clipmon/
  cli.py            CLI entry point (argparse)
  config.py         YAML config with defaults
  db.py             SQLite + FTS5 storage layer
  watcher.py        Clipboard polling (daemon thread)
  menubar.py        Menu bar app + clipboard integration (pure PyObjC)
  overlay.py        Floating NSPanel overlay
  search_window.py  Search panel with split tables, inline editing, context menus
  hotkeys.py        Global keyboard shortcuts (NSEvent monitors)
  pidfile.py        Singleton process management
```

### Storage

- **SQLite with WAL mode** for concurrent read/write
- **SHA-256 dedup** -- O(1) duplicate detection via content hash index
- **FTS5 virtual table** synced via triggers for instant full-text search
- **Schema**: `clips` table with id, content_text, content_hash, content_type, source_app, created_at, updated_at, copy_count, pinned

### UI

- **Menu bar** via pure PyObjC (`NSStatusItem` + `NSMenu`) -- runs on main NSRunLoop, no thread-safety issues
- **Overlay** via PyObjC `NSPanel` -- borderless, non-activating, vibrancy HUD material, hold-to-peek with history cycling
- **Search panel** via PyObjC `NSPanel` -- floating split-pane with live typeahead, inline preview editing, right-click context menu with ⋯ button, hover highlight, double-click paste, Cmd+click open
- **Hotkeys** via `NSEvent` global/local monitors -- requires Accessibility permission

## Tests

```bash
pytest          # 305 tests, ~2.5s
pytest -v       # verbose output
```

All PyObjC code is tested via fake AppKit classes (FakePanel, FakeNSEvent, FakeTableView, etc.) with module reload + namespace patching. No real NSApplication needed.

## Project status

| Milestone | Status |
|-----------|--------|
| 1. Core Clipboard Monitor | Complete |
| 2. Menu Bar App + Floating UI | Complete |
| 3. Smart Clipboard (search panel, inline editing, keyboard-driven paste) | Complete |

See [docs/MILESTONES.md](docs/MILESTONES.md) for details, [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md) for system overview, and [docs/VISION.md](docs/VISION.md) for where this is headed.
