UniClipboard

Full-text search

Where to query encrypted history, what syntax it accepts, and how the index is managed.

Edit on GitHub

UniClipboard keeps an encrypted full-text index of local clipboard history, so "stored locally" and "stored safely" hold at the same time. The index is encrypted at rest and shares its key material with the history database — see What syncs — Local storage.

SurfaceStatus / when to use it
History pagePrimary in-app surface. The History view is the landing page; its search box mixes free text with content-type / source-device / time filters, all wired to the query service described below.
Quick PanelGlobal hotkey, keyboard-first quick access. Live filtering with composite filter chips. See Quick Panel
uniclip search CLIScripts, SSH, remote sessions. See CLI — Search

Query syntax

In History, combine free text with structured filters: / selects a content type, @ a source device, # a tag, on: a time preset, and ext: a file extension. The CLI exposes filters through flags such as --type, --ext, and --tag; see the CLI reference. For the Quick Panel's controls, see Quick Panel.

Add a filter after text

Type pix /, pix @, or pix # to open suggestions at the caret. Choose an option with the arrow keys and Enter or Tab, or click it. History keeps pix and any text after the selected filter word. You can combine conditions, move the caret to edit a filter word, and remove a selected filter chip. Escape dismisses suggestions without selecting a condition.

Shortcuts start at the beginning of the input or after whitespace. A path such as /tmp/docs, a URL, or an email address is not converted into a filter. Quoting the whole word ("/text") or escaping its leading character (\/text) also keeps it as query text. This does not add phrase-search semantics to the search engine. Unknown conditions remain query text with an explanation; an unfinished shortcut prompts you to choose a filter.

If the query is rejected, History asks you to revise it instead of showing an empty result. Use ordinary search words or one consistent AND or OR operator; mixing AND and OR is rejected. A successful query with no matches remains distinct from an unavailable index or failed request.

Substring matching

Any token without a prefix is a case-insensitive substring filter. Multiple tokens are AND-ed:

report v2
project meeting notes

Results are ranked by BM25 relevance, not by time. For chronological output, combine substring search with the time filter below.

Type filter /

/text invite
/richtext newsletter
/image screenshot
/file invoice

Equivalent to the type chips in the Quick Panel and the CLI's --type. Allowed values: text / richtext / image / file. richtext covers HTML / rich-text clips, which form their own physical content class. Web links and source-like snippets are not physical types — they are tags (#link / #code, see below).

Extension filter ext:

ext:pdf contract
ext:ts useReducer

Only meaningful for file payloads (matches the filename suffix). CLI equivalent: --ext.

Time range

In the Quick Panel, pick a preset from the dropdown (Today / Last 7 days / This month / …). In the CLI, pass millisecond timestamps to --from-ms / --to-ms:

uniclip search "report" \
    --from-ms 1710000000000 \
    --to-ms 1710100000000

Source-device filter

Narrow results to clips that arrived from one device — a paired computer or a mobile-sync phone. In History, pick a device from the filter bar or type @ and choose from the list. In the CLI, pass --source-device with a device name (case-insensitive) or a device id; repeat it to match several devices. Run uniclip member list to see the available device names.

Tag filter #

Narrow results to clips carrying a content tag. Tags are derived automatically as items are indexed:

  • #link — the clip contains a web URL.
  • #code — the clip is plain text that looks like source code. Rich text / HTML is a physical type (/richtext), not this tag.

The History search box and the Quick Panel both support # tags — type # and pick a tag from the list. The CLI exposes the same tags via uniclip search --tag.

What's not supported

Several conventions you might expect from other search boxes don't work here:

  • Quoted phrases ("exact phrase") — quotes are treated as ordinary characters.
  • Mixing AND and OR in the same query — revise the query to use one operator consistently.
  • Wildcards / regex — same.
  • Boolean combinations across content types (e.g. "text or link").

For more elaborate queries, export --detailed --json from the CLI and post-process in a script.

Index lifecycle

The index opens with the daemon. Newly copied items are tokenized and indexed at the same moment they're encrypted into history, so they become searchable near-instantly. There are still a few moments where you'll deal with it explicitly:

Fresh install / after a major upgrade

The index may be in a "rebuilding" state.

  • GUI: Settings → Storage → Search index shows the current status (Ready / Rebuilding / Unavailable), the last rebuild timestamp, and a Rebuild button.
  • CLI: uniclip search status reports the same fields.

Manual rebuild

Occasionally the index drifts out of sync with history (most often when the process was SIGKILL-ed mid-write).

An interrupted rebuild now resumes automatically the next time the daemon starts (for example when you reopen the app), so a manual rebuild is usually only needed when you'd rather not wait for a restart.

  • GUI: that Rebuild button. After clicking, the state shifts to "Rebuilding" and the UI polls every 2 s until completion.
  • CLI: uniclip search rebuild is synchronous — it doesn't return until the rebuild finishes, which is convenient for snapshot scripts.

Queries continue to work during a rebuild; the result set just isn't complete until it finishes.

Corruption recovery

If the index file itself is structurally damaged (very rare — usually a disk error), a plain rebuild may not start. Delete the index subdirectory under the data folder, then run rebuild to recreate it from history. The clipboard history lives in a separate file and isn't affected.

See Troubleshooting — Search & index.

Privacy

  • The index file is encrypted at rest, with keys held by the OS keyring (shared KEK / MasterKey with the history database).
  • The index never leaves this machine and is not part of cross- device sync. Each device searches only what it has seen locally.
  • That means a newly joined device cannot search history from before it joined — a direct consequence of the no-backfill design noted in Quick start — Add a second device.

When you can't find what you expected

Most likely first:

  1. Spelling or casing — try a shorter token. Substring matching is noisy by nature.
  2. Time filter is too tight. Reset the time dropdown to "All".
  3. The entry was GC'd by the retention policy. Check the limits under Settings — Storage and confirm the entry is still inside the window.
  4. The entry never synced over — check Devices — Content-type allowlist on the sender side.
  5. The index isn't ready. Look at the GUI status pill or run uniclip search status.

On this page