clipsnip
v1.4.5
Published
Your local command library.
Readme
clipsnip

Your local command library.
Save shell commands you always forget. Find them instantly. Run them safely.
Built with Bun, SQLite, Ink, and zero cloud dependencies.
Requirements
- Bun v1.0+
Install
bun install -g clipsnipUsage
cs # home screen + snippet count
cs run # interactive picker (persistent session)CLI Commands
| Command | Description |
| ---------------------------------- | ------------------------------------- |
| cs add "desc" -- <cmd> | Save a new snippet |
| cs list | Show all snippets |
| cs search <query> | Fuzzy search by description |
| cs search <query> --tag <tag> | Search within a tag |
| cs run [desc] | Run a snippet (interactive if no arg) |
| cs run <desc> --with val1 val2 | Run with template values |
| cs run <desc> --dry-run | Preview resolved command |
| cs edit <desc> -- <new-cmd> | Update a snippet's command |
| cs edit <desc> --desc <new-desc> | Rename a snippet |
| cs edit <desc> --tag <tags> | Change tags (preserves tag otherwise) |
| cs copy <desc> | Copy command to clipboard |
| cs delete <desc> | Delete a snippet |
| cs history | Show recent adds and edits |
| cs history <desc> | Show history for one snippet |
| cs export > file.json | Export all snippets |
| cs import file.json | Import snippets (skips duplicates) |
| cs import --replace file.json | Import and replace everything |
| cs uninstall | Remove all data and config |
Interactive Picker
cs run opens a persistent interactive session. You never leave it just to run a command — info commands print their output and return you to the picker.
Keyboard shortcuts
| Key | Action |
| -------- | ------------------------------ |
| ↑ ↓ | Navigate snippets |
| ↵ | Run selected snippet |
| tab | Enter slot-fill for a template |
| / | Open command palette |
| esc | Quit / back |
| ctrl+c | Exit cleanly |
Command palette (/)
Type / from the search screen to open the palette. Type to filter, ↑↓ to navigate, ↵ to run.
| Command | Description | Args |
| ------------ | --------------------------------- | ------------------------- |
| /add | Add a new snippet inline | description, command |
| /search | Fuzzy search | query |
| /list | List all snippets | — |
| /history | View recent edits | — |
| /edit | Edit a snippet | pick snippet, new command |
| /delete | Delete a snippet | pick snippet |
| /copy | Copy to clipboard | pick snippet |
| /import | Import from a JSON file | file path |
| /export | Export to JSON (stdout) | — |
| /help | Show all commands | — |
| /uninstall | Remove all data (confirms inline) | type "yes" |
Commands that target an existing snippet (/edit, /delete, /copy) open a sub-picker — the full snippet list with fuzzy search. Pick with ↵, esc to go back.
Templates
Store commands with {{named}} placeholders and fill them at runtime:
cs add "git commit" -- git commit -m "{{message}}"
cs run "git commit" --with "fix navbar bug"
# runs: git commit -m 'fix navbar bug'
cs add "docker tag" -- docker tag {{source}} {{target}}
cs run "docker tag" --with myapp:latest registry/myapp:v1In the interactive picker, tab or ↵ on a template snippet opens slot-fill mode — step through each placeholder with a live preview of the resolved command.
Use --dry-run to preview before executing:
cs run "docker tag" --with myapp:latest registry/myapp:v1 --dry-run
# dry-run: docker tag 'myapp:latest' 'registry/myapp:v1'Values are shell-escaped automatically — injection attempts are treated as literal strings.
Tags
Tags are auto-detected from the first word (basename) of your command:
cs add "prune docker" -- docker system prune -af
# auto-tagged: #docker
cs add "deploy" --tag k8s -- kubectl apply -f .
# override tag: #k8sTags are preserved when you edit a command without specifying --tag:
cs edit "deploy" -- helm upgrade myapp ./chart
# tag remains: #k8s
cs edit "deploy" --tag helm -- helm upgrade myapp ./chart
# tag updated: #helmSearch within a tag:
cs search "prune" --tag dockerData
| Platform | Path |
| -------- | ---------------------------------------------------- |
| macOS | ~/Library/Application Support/clipsnip/snippets.db |
| Linux | ~/.local/share/clipsnip/snippets.db |
| Config | ~/.config/clipsnip/config.json |
XDG environment variables (XDG_DATA_HOME, XDG_CONFIG_HOME) are respected.
Upgrading from v1.0.x
Data directories are migrated from snip/ to clipsnip/ automatically on first launch. No manual steps required.
Configuration
~/.config/clipsnip/config.json:
{
"colors": true
}Set "colors": false or export NO_COLOR=1 to disable color output.
NO_COLOR takes precedence over the config file and applies to both the CLI output and the interactive UI.
Uninstall
cs uninstall # removes all data and config
bun remove -g clipsnip # removes the binaryOr from inside cs run, open the palette with / and select /uninstall.
Security
All --with values and inline slot-fill values are POSIX single-quote escaped before execution. Commands run via sh -c so pipes and redirects in stored commands work.
cs run "echo test" --with '$(rm -rf ~)'
# runs: echo '$(rm -rf ~)' ← literal string, not executedDevelopment
git clone https://github.com/grimmy-dev/clipsnip
cd clipsnip
bun install # also installs the pre-commit hook
bun test # run all tests
bun test --watch # watch mode
bun run typecheck # type-check without emittingProject structure
src/
index.ts entry point — wires Commander, nothing else
commands.ts CLI handlers + interactive palette dispatcher
snippets.ts service layer — business logic, throws CliError
db.ts SQLite connection, schema, prepared statements
shell.ts shell escaping, template resolution, tag helpers
format.ts terminal color helper, table printer
config.ts config loading, NO_COLOR flag
paths.ts data/config directory resolution, v1.0.x migration
__tests__/
shell.test.ts unit tests — pure functions, no DB
snippets.test.ts integration tests — in-memory SQLite
ui/
index.ts public exports — launchSelector, renderHome
selector.tsx interactive picker — all five modes
home.tsx home screen rendered by `cs` with no subcommand
theme.ts color tokens, NO_COLOR helper, layout constants
components/
Banner.tsx figlet banner with gradient
SnippetRow.tsx single row in the snippet list
KeyHints.tsx footer key-hint bar
scripts/
install-hooks.ts installs pre-commit git hook on bun installRunning from source
bun src/index.ts add "test" -- echo hello
bun src/index.ts runStack
License
MIT — see LICENSE
Source
Feedback & Issues
Found a bug or something not working as expected? Please open an issue on the repository — all reports and accessibility-related feedback are welcome.
