Stash
<a alt="CI Status" href="https://github.com/NotAShelf/stash/actions">
<img
src="https://github.com/NotAShelf/stash/actions/workflows/rust.yml/badge.svg"
alt="Build Status"
/>
</a>
<a alt="Dependencies" href="https://deps.rs/repo/github/notashelf/stash">
<img
src="https://deps.rs/repo/github/notashelf/stash/status.svg"
alt="Dependency Status"
/>
</a>
Lightweight & feature-rich Wayland clipboard "manager" with fast persistent history and robust multi-media support. Stores and previews clipboard entries (text, images) on the clipboard with a neat TUI and advanced scripting capabilities.
Installation | Usage | Motivation Tips and Tricks
Stash is a feature-rich, yet simple and lightweight clipboard management utility with many features such as but not necessarily limited to:
cliphist list)stash watchwl-clipboard tools (wl-copy and wl-paste)See usage section for more details.
Nix is the recommended way of downloading Stash. You can install it using Nix
flakes using nix profile add if on non-nixos or add Stash as a flake input if
you are on NixOS.
{
# Add Stash to your inputs like so
inputs.stash.url = "github:NotAShelf/stash";
outputs = { /* ... */ };
}
Then you can get the package from your flake input, and add it to your packages
to make stash available in your system.
{inputs, pkgs, ...}: let
stashPkg = inputs.stash.packages.${pkgs.stdenv.hostPlatform}.stash;
in {
environment.systemPackages = [stashPkg];
# Additionally feel free to add the Stash package in `systemd.packages` to
# automatically run the Stash watch daemon, which will watch your primary
# clipboard for changes and persist them.
systemd.packages = [stashPkg];
}
If you want to give Stash a try before you switch to it, you may also run it one
time with nix run.
nix run github:NotAShelf/stash -- watch # start the watch daemon
You can also install Stash on any of your systems without using Nix. New releases are made when a version gets tagged, and are available under GitHub Releases. To install Stash on your system without Nix, either:
$PATH. Instructions may differ based on your
distribution, but generally you want to download the built binary from
releases and put it somewhere like /usr/bin or ~/.local/bin depending on
your distribution.bash
cargo install --git https://github.com/notashelf/stash
[!NOTE] It is not a priority to provide 1:1 backwards compatibility with Cliphist. While the interface is almost identical, Stash chooses to build upon Cliphist's design and extend existing design choices. See Migrating from Cliphist for more details.
The command interface of Stash is only slightly different from Cliphist. In
most cases, you may simply replace cliphist with stash and your commands,
aliases or scripts will continue to work as intended.
Some of the commands allow further fine-graining with flags such as --type or
--format to allow specific input and output specifiers. See --help for
individual subcommands if in doubt.
$ stash help
Wayland clipboard manager
Usage: stash [OPTIONS] [COMMAND]
Commands:
store Store clipboard contents
list List clipboard history
decode Decode and output clipboard entry by id
delete Delete clipboard entry by id (if numeric), or entries matching a query (if not). Numeric arguments are treated as ids. Use --type to specify explicitly
db Database management operations
import Import clipboard data from stdin (default: TSV format)
watch Start a process to watch clipboard for changes and store automatically
help Print this message or the help of the given subcommand(s)
Options:
--max-items <MAX_ITEMS>
Maximum number of clipboard entries to keep [default: 18446744073709551615]
--max-dedupe-search <MAX_DEDUPE_SEARCH>
Number of recent entries to check for duplicates when storing new clipboard data [default: 20]
--preview-width <PREVIEW_WIDTH>
Maximum width (in characters) for clipboard entry previews in list output [default: 100]
--db-path <DB_PATH>
Path to the `SQLite` clipboard database file [env: STASH_DB_PATH=]
--excluded-apps <EXCLUDED_APPS>
Application names to exclude from clipboard history [env: STASH_EXCLUDED_APPS=]
--ask
Ask for confirmation before destructive operations
-v, --verbose...
Increase logging verbosity
-q, --quiet...
Decrease logging verbosity
-h, --help
Print help
-V, --version
Print version
echo "some clipboard text" | stash store
stash list
Stash list will list all entries in an interactive TUI that allows navigation
and copying/deleting entries. This behaviour is EXCLUSIVE TO TTYs and Stash will
display entries in Cliphist-compatible TSV format in Bash scripts. You may also
enforce the output format with stash list --format <tsv | json>.
You may also view your clipboard with the addition of expired entries, i.e.,
entries that have reached their TTL and are marked as expired, using the
--expired flag as stash list --expired. Expired entries are not cleaned up
when using this flag, allowing you to inspect them before running cleanup.
stash decode <input ID>
[!TIP] Decoding from dmenu-compatible tools:
bash stash list | tofi | stash decode
stash delete --type [id | query] <text or ID>
By default stash will try to guess the type of an entry, but this may not be
desirable for all users. If you wish to be explicit, pass --type to
stash delete.
stash delete --type id < ids.txt
[!WARNING] This command is deprecated, and will be removed in v0.4.0. Use
stash db wipeinstead.
stash wipe
Stash provides a db subcommand for database maintenance operations:
stash db wipe [--expired] [--ask]
stash db vacuum
stash db stats
stash db wipe: Remove all entries from the database. Use --expired to only
wipe expired entries instead of all entries. Requires --ask confirmation by
default.stash db vacuum: Optimize the database using SQLite's VACUUM command,
reclaiming space and improving performance.stash db stats: Display database statistics including total/active/expired
entry counts, storage size, and page information. This is provided purely for
convenience and the rule of the cool.stash watch
This runs a daemon that monitors the clipboard and stores new entries
automatically. This is designed as an alternative to shelling out to
wl-paste --watch inside a Systemd service or XDG autostart. You may find a
premade Systemd service in contrib/. Packagers are encouraged to vendor the
service unless adding their own.
When stash watch is running and a clipboard entry expires, Stash will detect
if the current clipboard still contains that expired content and automatically
clear it. This prevents stale data from remaining in your clipboard after an
entry has expired from history.
[!NOTE] This behavior only applies when the watch daemon is actively running. Manual expiration or deletion of entries will not clear the clipboard.
stash watch supports a --mime-type (short -t) option that lets you
prioritise which MIME type the daemon should request from the clipboard when
multiple representations are available.
any (default): Request any available representation (current behaviour).text: Prefer text representations (e.g. text/plain, text/html).image: Prefer image representations (e.g. image/png, image/jpeg) so that
image copies from browsers or file managers are stored as images rather than
HTML fragments.Example: prefer images when running the watch daemon
stash watch --mime-type image
This is useful when copying images from browsers or file managers where the
clipboard may offer both HTML and image representations; selecting image will
ask the compositor for image data first. Most users will be fine using the
default value (any) but in the case your browser (or other applications!)
regularly misrepresent data, you might wish to prioritize a different type.
Some commands take additional flags to modify Stash's behavior. See each
commands --help text for more details. The following are generally standard:
--db-path <path>: Custom database path--max-items <N>: Maximum number of entries to keep (oldest trimmed)--max-dedupe-search <N>: Deduplication window size--preview-width <N>: Text preview max width for list--version: Print the current version and exitStash can be configured to avoid storing clipboard entries that match a sensitive pattern, using a regular expression. This is useful for preventing accidental storage of secrets, passwords, or other sensitive data. You don't want sensitive data ending up in your persistent clipboard, right?
The filter can be configured in one of three ways, as part of two separate features.
This can be configured in one of two ways. You can use the environment
variable STASTH_SENSITIVE_REGEX to a valid regex pattern, and if the
clipboard text matches the regex it will not be stored. This can be used for
trivial secrets such as but not limited to GitHub tokens or secrets that follow
a rule, e.g. a prefix. You would typically set this in your ~/.bashrc or
similar but in some cases this might be a security flaw.
The safer alternative to this is using Systemd LoadCrediental. If Stash is
running as a Systemd service, you can provide a regex pattern using a crediental
file. For example, add to your stash.service:
LoadCredential=clipboard_filter:/etc/stash/clipboard_filter
The file /etc/stash/clipboard_filter should contain your regex pattern (no
quotes). This is done automatically in the
vendored Systemd service. Remember to set the
appropriate file permissions if using this option.
The service will check the credential file first, then the environment variable. If a clipboard entry matches the regex, it will be skipped and a warning will be logged.
[!TIP] Example regex to block common password patterns:
(password|secret|api[_-]?key|token)[=: ]+[^\s]+For security reasons, you are recommended to use the regex only for generic tokens that follow a specific rule, for example a generic prefix or suffix.
Stash allows blocking an entry from the persistent history if it has been copied
from certain applications. This depends on the use-toplevel feature flag and
uses the the wlr-foreign-toplevel-management-v1 protocol for precise focus
detection. While this feature flag is enabled (the default) you may use
--excluded-apps in, e.g., stash watch or set the STASH_EXCLUDED_APPS
environment variable to block entries from persisting in the database if they
are coming from your password manager for example. The entry is still copied to
the clipboard, but it will never be put inside the database.
This is a more robust alternative to using the regex method above, since you
likely do not want to catch your passwords with a regex. Simply pass your
password manager's window class to --excluded-apps and your passwords will
be only copied to the clipboard.
[!TIP] Example startup command for Stash daemon:
stash --excluded-apps Bitwarden watch
I've been a long-time user of Cliphist. You can probably tell by the number of times it has been mentioned in the README, if not for the attributions section, that Stash is clearly inspired and adapted from it. It's actually a great clipboard manager if your needs are simple, but mine aren't. I need an all-in-one solution, that I can freely hack on, with simple solutions to complex problems that I've had with managing my clipboard. I wanted it to be scriptable and interactive, I wanted it to be performant, I wanted it to be...
You get the point
$ claude mcp add stash \
-- python -m otcore.mcp_server <graph>