Shell Integration
Shell integration connects Suvadu to your terminal so that every command you run is automatically recorded with full metadata: working directory, duration, exit code, executor, and, inside a git repository, the branch it started on.
Zsh Setup
Add the Suvadu hook to your ~/.zshrc and reload:
echo 'eval "$(suv init zsh)"' >> ~/.zshrc && source ~/.zshrc This appends a single line to your Zsh configuration. The suv init zsh command outputs the shell functions that Suvadu needs; eval loads them into your current session.
The hook runs under Zsh's default options whatever your own are, so since 0.5.1 OCTAL_ZEROES, SH_WORD_SPLIT, NO_UNSET, or a suv path containing a space no longer break recording, and managed aliases load when the data directory's path contains quotes, $ or backticks.
Bash Setup
Add the Suvadu hook to your ~/.bashrc and reload:
echo 'eval "$(suv init bash)"' >> ~/.bashrc && source ~/.bashrc For login shells that only source ~/.bash_profile, add the same line to ~/.bash_profile instead, or make sure your ~/.bash_profile sources ~/.bashrc.
Since 0.5.1 the Bash hook records the whole line you typed: cd /tmp && ls is stored as typed, and a pipeline as the whole pipeline with its whole duration. Earlier releases stored only the last simple command (ls). An empty Enter no longer re-records a prompt command, lines typed with a leading space are skipped under HISTCONTROL=ignorespace or ignoreboth, and loading the hook keeps an existing multi-line DEBUG trap working.
What the Hooks Do
The shell hooks set up two functions that run transparently around every command you execute:
- Pre-exec hook: Fires just before a command starts. It captures the command text, working directory, timestamp, and which executor is running the command (you, or an AI agent like Claude Code or Cursor).
- Post-exec hook: Fires after the command finishes. It records the exit code and how long the command took (duration in milliseconds), by running
suv addbefore the next prompt.
They do not modify your command, its output, or its exit code, and they never see the output: capturing it would mean standing between the program and the terminal. What a prompt pays is one suv add process. On an Apple M4 Max (BENCHMARKS.md), a whole suv add took 13.4 ms p50 and 14.3 ms p95 from inside a repository, nearly all of it starting the process and opening the database; writing the command itself took 207 µs p95 on the 100,000-entry benchmark corpus. Treat these as one machine's order of magnitude, not a guarantee.
Git Branch Capture
Since 0.5.1, every command recorded live inside a git repository — by the Zsh or Bash hook, or by an agent integration — keeps the branch checked out in the directory it started in, or the 7-character commit hash of a detached HEAD. Linked worktrees and submodules are followed. Recall's detail pane shows it as a Branch row, and detailed MCP command rows add branch <name>.
- No
gitruns at your prompt. The branch is read from the repository's own files: 11–21 µs per lookup on an Apple M4 Max (BENCHMARKS.md), inside the run-to-run noise of a wholesuv add. - A command that changes directory, like
cd ../other, is filed under the branch it was typed on; one that switches branches, under the branch it switched to. - The branch is redacted like command text and never stored for an excluded command.
Turn it off with Record Git Branch in suv settings, or in config.toml; a project's .suvadu.toml can turn it off but not back on:
[shell]
capture_git_branch = false Up-arrow recall
In Zsh, Up and Down recall from Suvadu as soon as the hook is loaded; there is nothing else to set up. Up brings back the newest command that starts with what you have typed, then older ones, newest first — the current directory only breaks ties between commands recorded at the same millisecond — and Down walks back towards what you typed. Only commands you typed are recalled: Alt+A shows AI-agent commands too, for that shell.
- Turn it off with Enable Arrow Key Navigation on the Shell tab of
suv settings, or inconfig.toml. It takes effect in new shells (or afterexec zsh), which keep Zsh's own Up/Down and leave Alt+A alone:[shell] enable_arrow_navigation = false - Bash is not covered yet. The Bash hook binds only Ctrl+R; Up and Down keep Bash's own history.
- Check it in the shell you are using:
bindkey '^[[A' # expect "^[[A" suvadu-up-arrow bindkey '^[OA' # expect "^[OA" suvadu-up-arrow (the sequence many terminals send) - If something else answers Up, a plugin loaded after
eval "$(suv init zsh)"rebound it: oh-my-zsh's key bindings, zsh-history-substring-search, zsh-vi-mode, fzf's key bindings, atuin and mcfly all bind Up. Put theeval "$(suv init zsh)"line last in~/.zshrc, after your plugin manager and plugins, then runexec zsh. A plain setting such asZSH_AUTOSUGGEST_STRATEGYcan still follow it. zsh-vi-mode binds its keys at the first prompt instead, so also setZVM_INIT_MODE=sourcingbefore it loads. suv doctorreports it (since 0.5.1). Once per Zsh, at its first prompt — when all of~/.zshrchas run — the hook checks whether Up is still Suvadu's and notes what took it over; doctor's Up-arrow line names that widget and the fix, and the note is removed when a later Zsh finds Up is Suvadu's again. The check prints nothing, costs about 0.8 ms per shell start on an Apple M4 Max (BENCHMARKS.md), and is skipped when arrow navigation is off.
Still not working? See Up-arrow shows Zsh's own history.
zsh-autosuggestions
Since 0.5.1 the Zsh hook ships a strategy for zsh-autosuggestions that suggests what Up would recall: the newest command starting with what you typed, with AI-agent commands hidden unless Alt+A revealed them. Add this line to ~/.zshrc, after the eval line; history after it falls back to Zsh's own history when Suvadu has nothing:
ZSH_AUTOSUGGEST_STRATEGY=(suvadu history) The hook does not change your strategy setting on its own; suv init --help and the hook's header show the line. Each suggestion is one suv get --prefix lookup, the same one Up makes: 5–8 ms p95 on a 100,000-command history on an Apple M4 Max, about 1–4 ms of it beyond starting the process (BENCHMARKS.md). zsh-autosuggestions 0.7 fetches suggestions asynchronously by default, so this delays the suggestion, not your typing.
Verify Shell Integration
After setting up the hooks, run:
suv status You should see output similar to:
Suvadu Status:
Recording: enabled in config
Capture: most recent record received 4s ago, from this shell session Key things to check:
- Recording — what the configuration says. It is configuration, not evidence that anything was stored.
- Capture — the evidence: whether a command from this shell session has actually reached the database. Until one has, it says not yet verified and lists the steps to check end to end.
Try running a few commands, then verify they were recorded:
suv search Your recent commands should appear in the search TUI.
Terminal Multiplexers
Suvadu works with tmux, screen, Zellij, and any other terminal multiplexer. Each pane or window gets its own unique session ID, so commands are tracked separately per pane. No extra configuration is needed.
Pausing and Disabling Recording
Sometimes you want to stop recording temporarily — for example, when entering sensitive commands.
Pause (Current Session Only)
Pause recording for just the current shell session. Other terminal windows and panes continue recording normally:
suv pause Recording resumes automatically when you open a new terminal session, or you can re-source your shell config:
source ~/.zshrc # Zsh
source ~/.bashrc # Bash Disable / Enable (Global)
Globally disable recording across all sessions:
suv disable To re-enable recording globally:
suv enable When disabled, suv status will show "Recording: disabled". No commands are captured in any terminal until you run suv enable.
suv pause only affects the current shell session and is not persistent — a new terminal will record normally. suv disable is a global, persistent setting that stops all recording until you explicitly run suv enable.
Fish Shell
Fish shell is not yet supported: suv init generates hooks for Zsh and Bash only. It is on the Suvadu roadmap. If you use Fish, you can track progress on GitHub Issues.
Troubleshooting
- "command not found: suv" — The
suvbinary is not in yourPATH. Check your installation and make sure the directory holdingsuv—/usr/local/bin,~/.local/bin(install.sh --user), or~/.cargo/bin— is in yourPATH. - "no such file or directory" pointing at an old path (e.g.
suv:8: no such file or directory: /opt/homebrew/bin/suv) — The shell hook records the absolute path of thesuvbinary when your session starts. If you later move the binary — switching package managers (for example Homebrew → Cargo), runningbrew unlink suvadu, or uninstalling and reinstalling elsewhere — already-open shells keep pointing at the old, now-deleted path and print this error on every prompt. Reload the shell to pick up the new location:exec zsh(orexec bash), or just open a new terminal. - Recording shows "disabled" after setup — You may have previously run
suv disable. Runsuv enableto re-enable recording globally. - Commands not appearing in search — Make sure you sourced your shell config after adding the
evalline. Open a new terminal tab and try again. Runsuv statusto confirm hooks are active. - Duplicate eval lines — If you ran the setup command more than once, you may have multiple
eval "$(suv init zsh)"lines in your config. This is harmless but you can remove duplicates. Only one line is needed.