Skip to content

Clipboard

On-device clipboard history — search, favorite and paste back

Overview

Clipboard keeps an on-device history of what you copy. As you copy text (or, optionally, images) on any site, each item is saved into your own clipboard history — so you can search it, favorite the entries worth keeping, tag them, and paste them back into any field without switching tabs. It is part of the kimtos new-tab app suite.

Everything is fully on-device. There is no backend, no account, and no network: every clip lives in your browser's local storage and never leaves the machine. Password fields are never captured — that is a hard rule, not a setting.

Clipboard is a Pro app. Its capture pipeline runs only when the app is installed and the account is on the Pro plan; otherwise nothing is captured.

This app is under active development. This booklet describes what the code currently supports.

Highlights

  • Automatic capture — a content script watches copy/cut on every https page and forwards the copied text to the extension, where it is saved. Reading the copied text inside the copy event needs no clipboard-read permission.
  • Types — clips are auto-classified as text, link (a bare http(s) URL), color (a #hex/rgb()/hsl() value), or image (opt-in).
  • Source chip — text clips remember the page title/URL (and favicon) they were copied from.
  • Search, sort, favorite, tag — filter by substring, sort by recency or A–Z, star entries to protect them, and add colored tags for quick filtering.
  • Merge — combine two or more clips into one new clip.
  • In-page picker — a search overlay you open on any page (Alt+Shift+V, the right-click menu, or the on-field button) to paste a past clip straight into the field you were in, without leaving the page.
  • Quick pasteAlt+Shift+1/2/3 pastes the 1st/2nd/3rd most-recent clip directly into the focused field.
  • Side panel — open the history in Chrome's side panel, beside the tab.
  • Manage & housekeeping — edit clip text, delete, batch-delete, export/import the history as JSON, and clear everything except your favorites.
  • Agent tools — the HomeAI assistant can list, search, read, create, copy, favorite, tag, merge, and delete clips on your behalf, all on-device.

Privacy model

Clipboard writes only to local browser storage:

  • Clips (type, text, one-line preview, byte size, favorite flag, tags, timestamps, use count, and the source page) are records in the shared IndexedDB, in the clipboard-items collection.
  • Image clips keep their bytes in the local blob store, keyed clipboard:<id>.
  • Tags (name + color) live in the local key/value store under clipboard:tags.
  • Capture settings live in chrome.storage.local so the page, the background worker, and the content script share one source of truth.

Nothing is uploaded, and there are no analytics or third-party calls. A hard rule skips password fields; long pastes (over 100,000 characters) and large images (over 5 MB) are skipped so local storage stays reasonable. Duplicate copies are de-duplicated rather than stored twice, and the history is trimmed to a maximum count (default 500) — but favorites are never evicted.

Getting Started

Open Clipboard from the dock. Once the app is installed on a Pro account, capture starts automatically: copy some text on any site and it appears in the list. If you have not copied anything yet, the list reads "Nothing copied yet."

The clipboard window

The window is a single list of your clips, most-recently-used first, with a toolbar on top and a stats/housekeeping footer at the bottom.

  • Search — type in the search box to filter clips by substring.
  • Sort — the Recent / A–Z button toggles between most-recent-first and alphabetical order.
  • Monitoring — the ● Monitoring / ○ Paused button turns capture on or off everywhere (this setting is shared with the background worker and the content script).
  • Settings — the sliders button opens a drawer (see below).
  • Add an item — type into the "Add an item…" box and press Enter (or the + button) to save a clip manually.

Working with a clip

Each row shows the clip's preview (or a thumbnail for image clips), its last-used time, and the source page it came from, plus its tags.

  • Copy it back — click the preview text (or thumbnail), or the copy icon. A brief "Copied" note confirms. Copying updates the clip's last-used time and use count. (Copying needs a focused window; if it fails, click the window first.)
  • Favorite — click the star. Favorites are protected from auto-cleanup and from "Clear".
  • Edit — the pencil icon opens an inline editor; Save rewrites the text (and its preview, type, and size).
  • Tag — the tag icon prompts for a tag name; a new tag gets the next color from the palette automatically. Remove a tag by clicking its #tag × chip.
  • Delete — the trash icon removes the clip.

Filter chips

Below the toolbar, chips filter the list: All, ★ Favorites, and one chip per tag (#tagname). Click a chip to filter; click it again to clear.

Batch actions

Enter multi-select from the list header to tick several clips at once, then delete them in one step. With two or more selected, a Merge (N) button appears that combines them into a single new clip.

Capture settings

The settings drawer (the sliders button) controls how capture behaves. These settings are stored in chrome.storage.local so they apply across the page, the background worker, and every tab's content script:

  • Keep at most — the maximum number of clips to retain (10–5000, default 500). When you exceed it, the oldest non-favorite clips are evicted.
  • Never capture from — a comma-separated list of hosts to exclude; a copy on a matching site is ignored.
  • Show a note on the page when I copy — toggles the small "Saved to KimtOS Clipboard" toast that appears on the page after a captured copy.
  • Also capture copied images — off by default; when on, copying an image file saves it as an image clip (subject to the 5 MB cap).

Password fields are always skipped regardless of these settings.

Pasting on any page

You do not need to switch to the kimtos tab to reuse a clip. On any https page:

  • Open the picker — press Alt+Shift+V, choose Paste from KimtOS Clipboard… from the right-click menu, or click the small kimtos button that appears at the corner of a focused text field. A search overlay opens; type to filter, use ↑ ↓ to move, Enter to paste, Esc to close. The clip is inserted into the field you were in — or copied to the system clipboard if no field is focused.
  • Quick pasteAlt+Shift+1, Alt+Shift+2, or Alt+Shift+3 pastes the 1st, 2nd, or 3rd most-recent clip straight into the focused field.
  • Save a selection explicitly — right-click a selection and choose Save selection to Clipboard History. This is deliberate, so it bypasses the monitor toggle and exclusions.
  • Open the side panel — right-click and choose Open KimtOS Clipboard panel to keep the history open beside the tab.

The Alt+Shift+V shortcut is editable at chrome://extensions/shortcuts.

Import, export, and clearing

The footer shows a live count, total size, and favorite count, plus:

  • Export JSON — downloads your whole history (image clips inlined as data URLs) as kimtos-clipboard.json.
  • Import JSON — loads clips from a previous export or a compatible { items: [{ text }] } file. Imports merge by content — duplicates are not re-added.
  • Clear… — after a confirm, removes every clip except your favorites.

Architecture

Clipboard spans three browser contexts that a normal app does not: the new-tab page (the UI + agent tools), a background service worker (added to the extension specifically for this app), and two content scripts injected into every page. A content script cannot reach the extension's IndexedDB, so all persistence happens in the service worker; the contexts coordinate through message passing and chrome.storage.local.

Modules

FileRole
apps/clipboard/index.tsThe app descriptor and browse/search/manage UI: toolbar, filter chips, the clip list (star/copy/edit/tag/delete), batch-select + merge, the settings drawer, and the stats/export/import/clear footer. Also declares the HomeAI agent tools. All data ops go through the local API (getApi/jsonApi).
apps/clipboard/meta.tsApp metadata — id, accent, order, plan: 'pro', and marketing copy.
lib/clipboardShared.tsDOM-free, storage-free primitives shared by all three contexts: the ClipItem/CaptureState types, collection/key constants, the FNV-1a hashText, classifyText, previewOf, the cross-context capture-state accessors (get/setCaptureState), change signals, and the Pro/installed entitlement gate.
lib/clipboardStore.tsThe persistence layer over the shared dataStore (IndexedDB): add/patch/remove clips and image clips, hash-based dedupe, trim to maxItems (never evicting favorites), merge, stats, tags, and JSON import/export. Used by both the service worker and the app's local routes so behavior is identical everywhere. The capture content script must not import this.
background/index.tsThe MV3 service worker: receives captured copies from content scripts and persists them via clipboardStore, serves history to the in-page picker, and owns the context-menu items and the paste-history hotkey.
content/clipboardCapture.tsCapture content script (every https page). Listens for copy/cut, honors monitor/pause/exclusions and the password-field rule, and forwards the copied text (or opt-in image) to the service worker. Stores nothing itself.
content/clipboardPicker.tsThe in-page history picker (shadow-DOM search overlay), the Alt+Shift+V / quick-paste key handling, and the on-field floating paste button. Fetches history from the service worker and inserts the chosen clip into the focused field.

The UI never touches storage directly: it calls getApi / jsonApi (the suite's local router, dispatched to the app's clipboard.local routes), the same path the agent tools use — so UI and tools stay in sync.

Capture → store → paste flow

Cross-context coordination

  • Capture settings (CaptureState) live in chrome.storage.local under clipboard:capture. The UI edits them; the content script and worker read them. The content script keeps a synchronous local copy and live-reloads it when the key changes (onCaptureChanged), starting from monitor-on defaults so no copy is dropped while the async read is in flight.
  • Change signal — the worker cannot reach the page's dataStore listeners, so after a capture it bumps clipboard:changed in chrome.storage.local; open app windows listen (onClipsChanged) and reload. The UI also refreshes on its own edits (dataStore.onChange) and on window focus.
  • Entitlement gate — because the capture content script is always injected, it checks a cached "installed + Pro" flag (clipboardActiveCached) before doing anything; the worker re-checks clipboardActive() before storing. A free or non-installed user's clipboard is never captured.

Messages, menus, and commands

The worker's chrome.runtime.onMessage handles clip:add, clip:add-image, clip:list (up to 200 recent, for the picker), and clip:nth (quick-paste). It registers three context-menu items (save selection, open picker, open side panel) via the contextMenus permission, opens the picker in the active tab on the open-clipboard-picker command (Alt+Shift+V), and opens Chrome's side panel on request.

Data model

One record type, ClipItem, in the clipboard-items collection:

  • { id, type, text, preview, hash, bytes, favorite, tags, createdAt, lastUsedAt, useCount, source?, mime? }.
  • type is text | link | color | image, assigned by classifyText.
  • preview is a single-line, 200-char-capped display string.
  • hash is a fast FNV-1a hash used only for dedupe — a hash hit is confirmed by an exact text compare, so a collision can never merge two different clips.
  • source records the originating page's { url, title, favicon }.
  • Image clips carry a mime and store their bytes in the blob store at clipboard:<id> (the record's text is empty).

Tags are stored separately as { name, color } in the key/value store under clipboard:tags, auto-assigned the next color from a fixed palette; items reference tags by name.