0xPeerHold

You already solved this command once.

cmdvault is an offline command-line snippet manager. It keeps that command findable, fills in the variable parts when you copy, and keeps everything you knew about it attached. One binary for Linux, macOS or Windows, no install, no account. It runs on your machine and makes no outbound requests, and the whole vault is a JSON file you own.

cmdvault icon

cmdvault

Run it Try it below Free to download and use. Nothing to sign up for.

Try it here

Twenty-one sample entries running inside this page. Try dockr, k8s, or --force-with-lease, then pick one and fill in the blanks. Nothing you type is stored or sent anywhere — open the network tab and watch.

cmdvault sample data · no network calls
cmdvault

    © 2026 0xPeerHold LLC dba 0xPeerHold About Safety notes Privacy License Licenses Imprint

    The search here is a stand-in, and the usage numbers are invented. The real engine is a four-stage pipeline and reproducing it in a page script would misrepresent it. Everything else behaves the way the app does: the same placeholder grammar, the same seven types, secrets dropped after the copy, and a destructive marker that tells you what somebody wrote and then gets out of the way.

    Who this is for

    Phone and small-screen terminals

    Typing a long command on a phone keyboard is where the typos come from: no tab completion, half the screen taken by the keyboard, one wrong character and you start again. Switch sharing on, open the address on your phone, fill the blanks in a form, and copy the finished command in one go.

    Penetration testers

    Your engagement toolkit on a machine that originates no traffic. Values you type into a field marked secret are never written to the vault file. Export per client and hand the file over — or delete it — when the job ends.

    System administrators

    One entry for a command instead of one per server. What you actually use rises to the top, because ranking decays with a fourteen-day half-life rather than counting forever.

    Teachers and students

    Build a command set for a course, export it as one file, hand it to a class. No accounts and no license keys. Students keep it, add their own, and it is still theirs after the term ends.

    Anyone who lives in a terminal

    If your reference is a text file you can't search, a browser tab you're afraid to close, or your own memory, this replaces all three. If the problem is getting output off a second machine rather than remembering a command, pastebridge is the other half of that.

    What it does Seven things, with what each one looks like in practice.

    One entry covers every server, cluster, and client

    kubectl logs -f {pod} -n {namespace} --tail={lines:number=200}

    Write the variable parts as blanks and cmdvault asks for them when you copy. Seven types: text, number, choice, path, url, boolean, and secret. A choice becomes a menu, a number gets a number pad on a phone. Use the same name twice in one command and you fill it once — docker run -p {port}:{port} {image} is a two-field form.

    The parser is deliberately narrow about what counts as a blank. ${PORT} is a shell variable, {{.Names}} is a Go template, and {{port}} is an escaped literal. None of them are fields, and the fill form leaves all three alone.

    Secret values are never written to the vault file

    PGPASSWORD={dbpass:secret} pg_restore -h {host} -d {database}

    Mark a blank secret and its value builds the command and is then dropped. It is not saved to the vault, not kept in the remembered-values list, not recorded in a usage event, and never appears in an export.

    Two honest limits on that. Copying still puts the finished command on your system clipboard, where other applications can read it and where some operating systems sync it between devices. And a placeholder's default value is part of the command text, so it is stored and does appear in exports whatever the placeholder is marked.

    The command, and everything you knew about it

    What it does  Load a .dump into an existing database
    Prerequisites  Target database must exist and be empty
    Example usage  the real invocation, not a synopsis
    Notes  anything that bit you the first time

    Every entry carries a description, prerequisites, a real example, notes, a shell, and a platform — all searchable alongside the command text. Description and example are weighted differently by the search, which is why they are separate fields rather than one long box.

    A destructive marker that admits what it is

    Marked destructive  Deletes named volumes too. Any database
     running in Docker loses its data.

    You tick a box in the editor and write a note in your own words. From then on the note sits above the command every time you open it. There is no detector, no pattern list, and no rescan on save, so there is exactly one source for that flag: you.

    Which cuts both ways, and the app says so where the marker appears. An unmarked command has not been checked and found harmless. It has not been checked at all. Nothing in cmdvault reads command text and forms an opinion about it.

    Find it however you happen to remember it

    k8s  →  finds everything tagged kubernetes
    docekr  →  finds docker, through the fuzzy fallback
    --force-with-lease  →  matched whole, not split at the dashes
    Clients / Northwind  →  nested projects, still in global search

    Four stages: recall by weighted token match unioned with trigram substring match, a structural filter, a fuzzy rescore, then a blended score. Recall is OR rather than AND, so "see running containers" doesn't require the word "see" to appear anywhere. When recall comes up empty the search falls back to a bounded scan and lets the fuzzy cutoff do the filtering, which is how a typo like docekr still lands.

    The tokenizer keeps - _ . : / @ inside tokens, so docker-compose and node_modules survive whole. Ranking decays on a fourteen-day half-life, and it decays when read as well as when written — a score that only decays when you touch it leaves stale entries sitting at the top.

    Your vault is a file, and import can't damage it

    ~/.cmdvault/vault.json
    Import: 14 added, 5 skipped — nothing modified, nothing replaced

    Import only ever adds. It cannot modify, replace, or delete a command already in your vault, and there is no flag that makes it. An incoming entry is skipped if its UUID is already present, or if its command text hashes to something already in the same project. Re-import last week's export and you get nothing new; if you edited one of those commands since, your edit stands.

    Import runs in two steps. The file is summarized first — projects, tags, counts, with nothing written — and that summary becomes the filter list, so you can take a colleague's whole vault and pull in only their Kubernetes commands. Export mirrors it: project and tag checkboxes, a live "N of M commands" count, and toggles for sub-projects, ALL-versus-ANY tag matching, favorites only, and whether usage statistics travel with it.

    The same vault on your phone, without a server

    Share on this network  →  https://192.168.1.24:7718
    Then enter this PIN  →  418 302

    Flip the switch in the header and a second listener starts on your local network over TLS, using a certificate the machine generates for itself. Your phone opens the address, accepts the certificate warning once, enters the six-digit PIN, and is looking at the same vault. Ten wrong guesses locks pairing until you reset it.

    Off means no listener exists, not a listener refusing connections. Turning sharing off stops it and ends every paired session, so switching it back on doesn't silently re-admit a device you disconnected. The certificate is self-signed, which defeats passive listening on the network and does not defeat someone already positioned to intercept traffic between your two devices.

    What it doesn't do Listed as features, because that's what they are.

    • No account, no sign-in, no email address
    • No outbound requests, ever — no update check either
    • No sync server, because there is no server
    • No telemetry, crash reporting, or analytics
    • No Electron, no runtime, no bundled browser
    • No database engine to install or keep patched
    • No subscription, no paid tier, no upsell
    • No lock-in — your vault is JSON you can read

    How to check any of this cmdvault is proprietary. You can't read the source, so here is what you can do instead.

    We would rather say this plainly than let a page full of privacy claims imply an audit route that doesn't exist. The license is on the next section. What it doesn't grant is the right to read, modify, or reverse engineer the binary. So the claims above are worth exactly as much as your ability to test them from outside, and most of them are testable from outside.

    Watch the network the big claim

    sudo tcpdump -i any host not 127.0.0.1 and port not 22

    Run it, use the app normally, and watch nothing happen. With sharing off there is no listener on the network at all; check with ss -ltn.

    Cut it off entirely stronger version

    unshare -rn ./cmdvault -no-browser

    No network namespace, no route anywhere. The app works exactly the same, because it never needed one.

    Read your own vault the storage claims

    grep -i 'hunter2' ~/.cmdvault/vault.json

    Fill a field marked secret with a string you'll recognize, copy the command, then go looking for it in the file. It isn't there, and it isn't in an export either.

    Check the download before you run it

    sha256sum -c cmdvault-linux-v1_1.tar.gz.sha256

    Every archive publishes its own .sha256 file alongside it, listed in full with curl commands further down. They tell you the file arrived intact; they don't tell you what's inside it.

    Run it One file. No installer, no package manager, no dependencies.

    cmdvault is a single static binary of about 7.5 MB, built from the Go standard library with nothing else linked in. Run it and it opens your browser at a loopback address; the interface is served by the binary itself. Your vault lands at ~/.cmdvault/vault.json.

    Linux x86-64

    tar -xzf cmdvault-linux-v1_1.tar.gz && chmod +x cmdvault-linux-v1_1 && ./cmdvault-linux-v1_1

    No runtime, no libraries, no package to install. Drop it anywhere on your path.

    macOS Apple silicon

    tar -xzf cmdvault-mac-v1_1.tar.gz && chmod +x cmdvault-mac-v1_1 && ./cmdvault-mac-v1_1

    Unsigned, so Gatekeeper will ask the first time. Right-click and choose Open, or clear the quarantine attribute yourself. Intel Macs aren't published; it builds for them, ask if you need one.

    Windows x86-64

    cmdvault-v1_1.exe

    Built with the GUI flag, so there's no console window sitting behind your browser.

    Phone and tablet no app to install

    Share on this network → open the address → enter the PIN

    There is no separate mobile build, because there doesn't need to be one. Your phone talks to the machine already running the vault, over your own network. Nothing is installed on the phone.

    Useful flags all optional

    ./cmdvault -seed tour.json -exit-on-idle 10m -no-browser

    -seed imports a starter file if the vault is empty. -port and -vault move things. -exit-on-idle quits after a stretch with no browser attached. Stop it from the Quit button, with Ctrl-C, or by letting it time out — all three flush the pending save first.

    Downloads and checksums

    A tour file ships alongside: twelve commands covering all seven placeholder types, the parser guards, the destructive marker, nested projects, tag aliases, and four shells.

    Downloads One archive per platform, each with its own SHA-256 file. Check it before you unpack it.

    Each platform ships as one compressed archive with the binary inside it. Check it before you unpack it.

    cmdvault-linux-v1_1.tar.gz 6.2 MB Linux · x86-64 Archivebc2e88a074e419e8b0c961413c90d930e2ae121df7e0abcafc075cf3efc385de Sums filecmdvault-linux-v1_1.tar.gz.sha256 Binary insidecmdvault-linux-v1_18014b0f63807cf27e90a326635bf6936e742ea1e12205135a629d2881be9b24f
    cmdvault-mac-v1_1.tar.gz 5.9 MB macOS · Apple silicon Archived8ce52abbe6a77487fd5b85b9e4b2fd6a7913fb509bacd2e98c358c3850f5760 Sums filecmdvault-mac-v1_1.tar.gz.sha256 Binary insidecmdvault-mac-v1_177b220fe988e977e67ae135b86ce9bc9c673cf86736e5968201561c456ac1316
    cmdvault-v1_1.zip 6.2 MB Windows · x86-64 Archivebc69276b932c2ccc675f3950a21eceb42d684ae980f7cf69b66b0b4da97b0d6a Sums filecmdvault-v1_1.zip.sha256 Binary insidecmdvault-v1_1.exe1349132710ecccb3deb1371883910a090de9a4ca8a2809cace8932a2c2470e98

    Linux curl, check, unpack

    # download the archive and its sums file curl -LO https://0xpeerhold.com/builds/cmdvault/cmdvault-linux-v1_1.tar.gz curl -LO https://0xpeerhold.com/builds/cmdvault/cmdvault-linux-v1_1.tar.gz.sha256 # check it, then unpack and run sha256sum -c cmdvault-linux-v1_1.tar.gz.sha256 tar -xzf cmdvault-linux-v1_1.tar.gz chmod +x cmdvault-linux-v1_1 && ./cmdvault-linux-v1_1

    sha256sum -c reads the sums file, hashes the archive next to it and prints OK or FAILED. One line, because there is one file in it. If it fails, delete the download and fetch it again rather than unpacking it.

    macOS curl, check, unpack

    # download the archive and its sums file curl -LO https://0xpeerhold.com/builds/cmdvault/cmdvault-mac-v1_1.tar.gz curl -LO https://0xpeerhold.com/builds/cmdvault/cmdvault-mac-v1_1.tar.gz.sha256 # check it, then unpack and run shasum -a 256 -c cmdvault-mac-v1_1.tar.gz.sha256 tar -xzf cmdvault-mac-v1_1.tar.gz chmod +x cmdvault-mac-v1_1 && ./cmdvault-mac-v1_1

    macOS ships shasum rather than sha256sum; -a 256 picks the same algorithm and -c checks the file the same way. The binary is unsigned, so Gatekeeper will ask the first time — right-click and choose Open, or run xattr -d com.apple.quarantine cmdvault-mac-v1_1.

    Windows curl, check, unpack

    # PowerShell — download the archive and its sums file curl.exe -LO https://0xpeerhold.com/builds/cmdvault/cmdvault-v1_1.zip curl.exe -LO https://0xpeerhold.com/builds/cmdvault/cmdvault-v1_1.zip.sha256 # check it, then unpack $want = (Get-Content cmdvault-v1_1.zip.sha256).Split(' ')[0] $got = (Get-FileHash cmdvault-v1_1.zip -Algorithm SHA256).Hash.ToLower() if ($got -eq $want) { 'OK' } else { 'FAILED' } Expand-Archive cmdvault-v1_1.zip -DestinationPath .

    curl.exe is built into Windows 10 and later, as is Get-FileHash, so there is nothing to install. The comparison prints OK or FAILED the same way sha256sum -c does. certutil -hashfile cmdvault-v1_1.zip SHA256 works too if you would rather read the hash yourself and compare it against the row above.

    Check what you unpacked the binary itself

    sha256sum cmdvault-linux-v1_1 # macOS: shasum -a 256 cmdvault-mac-v1_1 # Windows: certutil -hashfile cmdvault-v1_1.exe SHA256

    The archive hash covers the download. This one covers the file you will actually run, which is the one that matters if the archive was unpacked somewhere else or passed to you on a stick. Compare it with the Binary inside line in the table above; it should match character for character.

    What a matching hash tells you is that the file arrived intact and is the same file we hashed. It does not tell you what the file does, and it cannot: a hash published on the same site as the download is only worth as much as the site. It catches a corrupted transfer or a tampered mirror. It is not an audit, and cmdvault is proprietary, so there is no source to audit against. The checks in the section above are the ones that test behavior.

    The license Free to use. Not open source. The full text is in the app under License.

    cmdvault is proprietary software published by 0xPeerHold LLC under an end user license agreement, not under an open source license. In practice:

    • You may install and use it on any number of devices you own or control, for personal or internal business use, free of charge
    • You may pass the binary on, provided it is unmodified, complete with its notices, and free of charge
    • You may not modify it, make derivative works, or reverse engineer it — except where your local law says otherwise and doesn't allow that to be contracted away
    • Your vault file is yours. It stays yours if the license ends, and it is readable JSON with or without us

    The License, Privacy, Safety notes, About, Licenses and Imprint panels are all inside the app, offline, with the version and effective date on each so a support conversation can establish which text you actually saw.

    Questions we'd ask too

    The name says "Vault" — is my data encrypted?
    No, and the app says so in its own About panel rather than leaving you to find out. The vault file is plaintext JSON and so is every export. Anyone who can read your disk or your backups can read your entries, including any password or connection string you have stored in one. Use full-disk encryption or keep the file on an encrypted volume if that matters. The one thing the name does earn is the secret field: values typed there are never written at all.
    Does it detect dangerous commands?
    No. Nothing inspects, parses, or analyzes command text at any point. You tick a box and write a note in your own words, and that note is what you see afterwards. The important half of that is the half people skip: an unmarked command has not been checked and found harmless, it has not been checked at all. Treat the absence of a marker as no information whatsoever.
    Does it run the commands?
    Never. cmdvault stores text and puts text on your clipboard. Nothing you save, import, or copy is executed by the application at any point. You are the execution step, in your own terminal, with your own privileges.
    How do I sync between machines?
    With infrastructure you already run. Export to JSON and keep it in a Git repo alongside your dotfiles, or drop it in a Syncthing folder. Because import only ever adds and never overwrites, merging is safe in the boring direction: you cannot lose a local edit to an incoming file. The failure mode is the opposite one — edit a command, then import a file containing the original under a different UUID, and you get a near-duplicate rather than a conflict. We don't offer sync because sync means running a server, and not running a server is the point.
    Is sharing safe to leave on?
    It is a debugging and phone convenience, not a hardened channel. Anyone with the address and the PIN can read and write your vault. The PIN is six digits, locked out after ten wrong guesses, and sessions last twelve hours; the certificate is self-signed, so it stops passive listening and does not stop someone already able to intercept traffic between your devices. Use it on a network you have reason to trust, and switch it off when you're done — that stops the listener and ends every paired session.
    What actually gets stored, and for how long?
    One JSON file, at the path shown in the About panel: your commands, projects, tags, placeholder metadata, and usage history. Usage events are kept for 365 days or the most recent 100 per command, whichever is smaller. Remembered placeholder values are capped at 10 per placeholder, oldest dropped first. Secret values are never written. Deleting a command moves it to the trash, where it stays inside the file until you empty it.
    Why isn't it open source?
    Because it isn't, and we would rather say that than imply otherwise on a page that makes a lot of privacy claims. It is free to download and use, free to pass on unmodified, and it will not grow a subscription. What you don't get is the source, so the claims here are worth what you can test from outside — which is most of them. The section above lists the checks we'd run in your position.
    Why not just fzf and a text file?
    If that already works for you, keep it. What got tedious for us was filling in the variable parts by hand every time, keeping credentials out of a file that gets backed up, remembering what a command needed six months later, and doing any of it on a phone. If none of those bother you, you don't need this.
    What happens if you stop maintaining it?
    Your vault is a JSON file on your own disk and the binary keeps working, because nothing about it depends on us being here. There is no license server to expire, no account to deactivate, and no update check to fail. You lose future versions, and nothing else. We're under no obligation to keep shipping them, and the license says so rather than implying a promise we haven't made.

    Support the work

    cmdvault is free to download and use, with no paid tier planned. Donations cover build machines, signing, and maintenance hours.

    If something here saved you an afternoon, buy us a coffee. Bitcoin goes straight to a wallet we hold, with no processor in the middle taking a cut or a name. Or a clear bug report to [email protected] is worth more than most donations and costs you less.