↑ ↓ to move · Enter to open · Esc to close Something not working? Troubleshooting
    On this page

    Fix Missing History and Agent Capture

    Find your symptom below. Each fix follows the same steps: check what is happening, repair only the part that is broken, and verify the fix with a result you can see. None of these fixes deletes history or replaces your shell startup files. This page describes Suvadu 0.5.0, and says where earlier releases behave differently.

    Before you start

    suv --version    # the version you are running
    suv status       # Recording (config) and Capture (last record received, and from which shell)
    suv doctor       # shell version, hooks line, config, database integrity, Up-arrow binding, MCP registration, agent hook scripts

    These checks have limits. Since 0.4.2 suv status reports Recording (enabled in the config and not paused in this shell) and Capture (whether a record from a shell hook has arrived, how long ago, and whether from this shell) as separate facts; imported history never counts as capture. suv doctor confirms that your shell startup file contains suv init and reports one row per agent — whether it is running, installed, capturing commands and, for Claude Code and Cursor, registered for MCP; it does not read the Codex or OpenCode MCP configuration. See what doctor checks. The visible test at the end of each fix below is what confirms it worked.

    Ctrl+R opens the wrong tool or native search

    Check. Ask your shell which command Ctrl+R runs:

    bindkey '^R'                   # Zsh: expect  "^R" suvadu-search
    bind -X | grep -F '\C-r'       # Bash 4.3+: expect __suvadu_search_widget

    If the result names another tool, or a built-in search such as history-incremental-search-backward, then either something bound Ctrl+R after Suvadu, or Suvadu's hook never loaded. The last binding set during shell startup wins. Search your startup file for other history tools:

    grep -n 'suv init\|bindkey\|bind -x\|fzf\|atuin\|mcfly\|hstr' ~/.zshrc    # or ~/.bashrc

    Suvadu's widget also falls back to the shell's own reverse search in three cases: no terminal device is readable, the suv binary cannot be found (see stale binary path), or recording is disabled (suv disable) or paused in this shell. In Bash, the widget does nothing in those cases.

    Repair. Pick one history tool to own Ctrl+R. To make it Suvadu, move eval "$(suv init zsh)" (or bash) below the other tool's line, or comment out the other tool's key binding. Change only that line. If recording is disabled, run suv enable; if this shell is paused, run unset SUVADU_PAUSED. To undo, move the line back.

    Verify. Open a new terminal, run bindkey '^R' (Zsh) or bind -X | grep -F '\C-r' (Bash) again, then press Ctrl+R. The Suvadu search screen should open.

    Up-arrow shows Zsh's own history, not Suvadu's

    Check. Ask Zsh which widget Up runs, and ask doctor what the hook saw when this shell started:

    bindkey '^[[A'    # expect  "^[[A" suvadu-up-arrow
    bindkey '^[OA'    # expect  "^[OA" suvadu-up-arrow (the sequence many terminals send)
    suv doctor        # since 0.5.1: the Up-arrow line names the widget that took it over

    The cause is one of three:

    • A plugin loaded after the hook rebound the key. bindkey names another widget, such as up-line-or-beginning-search (oh-my-zsh) or history-substring-search-up, and doctor warns bound to … by something loaded after Suvadu (see doctor's Up-arrow check). zsh-vi-mode, fzf's key bindings, atuin and mcfly bind Up too. The last binding set during shell startup wins.
    • Arrow navigation is off. Enable Arrow Key Navigation in suv settings ([shell] enable_arrow_navigation) is off, so the hook leaves Up to Zsh; doctor says off.
    • The shell is Bash. Bash's Up keeps Bash's own history; Suvadu's recall there is Ctrl+R.

    Repair. Move eval "$(suv init zsh)" to the end of ~/.zshrc, after your plugin manager and plugins, then run exec zsh. For zsh-vi-mode, which binds its keys at the first prompt, also set ZVM_INIT_MODE=sourcing before it loads. If the setting is off, turn it back on and open a new shell. To undo, move the line back.

    Verify. In the new shell, both bindkey lines print suvadu-up-arrow, and suv doctor's Up-arrow line shows ✓. Type the start of a command you ran before and press Up: the newest command starting with it appears. See Up-arrow recall.

    History is enabled but a new command does not appear

    Check. Run each of these in the shell that should be recording:

    suv status                        # "Recording: enabled in config" and a "Capture:" line from this shell?
    echo "$SUVADU_PAUSED"             # empty means not paused
    echo "$SUVADU_SESSION_ID"         # must not be empty
    type _suvadu_precmd               # Zsh: the recording hook exists in this shell
    type __suvadu_precmd              # Bash: the recording hook exists in this shell
    echo $ZSH_VERSION $BASH_VERSION   # hooks require Zsh 5.1+ or Bash 4.0+

    Common causes, each confirmed in the source (reviewed at 0.4.1, and again for 0.5.1):

    • The hook is not loaded in this shell. The startup file is missing eval "$(suv init zsh)" or eval "$(suv init bash)", or it was added after this terminal opened. Hooks load in interactive shells that read your startup file.
    • The shell is too old. The hook turns itself off and prints a warning on Zsh older than 5.1 or Bash older than 4.0. The Bash that ships with macOS is 3.2.
    • No session ID. The Zsh hook uses uuidgen to create SUVADU_SESSION_ID. If uuidgen is not installed, the ID is empty and every command is dropped.
    • Recording is paused or disabled. eval $(suv pause) pauses only the current shell. suv disable stops recording everywhere.
    • The command was skipped on purpose. Commands that start with a space are never recorded. Commands that match your exclusion patterns are skipped. A .suvadu.toml in the command's directory or any parent directory can turn recording off and add exclusion patterns; since 0.5.1 it can no longer turn recording back on or replace your global exclusions.
    • An older release dropped it. Before 0.5.1, a command over 64 KB (a long heredoc, a generated command line) was silently not recorded, a command starting with - was lost, several shells starting together right after an upgrade could fail with database is locked, and a config.toml or .suvadu.toml that did not parse stopped recording. 0.5.1 records the long command cut to 64 KB (ending in …[truncated N bytes], redacted in full first), records the dash command, upgrades the database one process at a time, and falls back to your global config or the defaults with redaction on; suv doctor then shows a Capture config warning naming the broken file.
    • Bash recorded only part of the line. Before 0.5.1 the Bash hook stored only the last simple command, so cd /tmp && ls appeared as ls. 0.5.1 records the whole line; open a new terminal after upgrading so the new hook loads.
    • The command is recorded but hidden. Agent, bot, CI, and script commands are hidden from search by default. See agent commands are hidden.

    Repair. Fix only the cause you found:

    • Hook missing from the startup file: add the eval line once, as described in Shell Integration. If the file already has it, open a new terminal instead.
    • Paused shell: unset SUVADU_PAUSED. Disabled: suv enable. Both are safe to reverse.
    • Old shell: install a newer Zsh or Bash and make it your login shell. Keep the old one until the new one works.
    • Missing uuidgen: install your distribution's package that provides it (often util-linux), then open a new terminal.
    • Skipped on purpose: edit the matching exclusion pattern or .suvadu.toml setting, or leave it if the skip was intended.

    Verify. In a new terminal, run a harmless, unique command, then look for it:

    echo suvadu-check-1
    suv history -n 3        # the echo line appears at the top

    Shell still references a moved or uninstalled binary

    Check. You see an error like suv binary not found (recorded path: …) or no such file or directory: /opt/homebrew/bin/suv. You may also see agent hooks fail with suvadu: binary not found; reinstall Suvadu and run suv init <agent>.

    whence -p suv           # Zsh: where the binary is now (empty = not on PATH)
    type -P suv             # Bash: the same check
    echo "$_SUVADU_BIN"     # the path this shell recorded at startup
    suv doctor              # an agent's row fails if its hook's saved binary is missing and suv is not on PATH

    The Zsh and Bash hooks save the binary's absolute path when the shell starts. The saved path goes stale after you switch package managers, unlink with Homebrew, or reinstall somewhere else. The hooks try to recover by looking up suv on your PATH. Agent hook scripts in ~/.config/suvadu/hooks/ do the same.

    Repair.

    • Make sure the new location, such as ~/.cargo/bin, is on your PATH. Then reload the shell with exec zsh or exec bash, or open a new terminal.
    • For agent hooks, run suv init <agent> again, then relaunch the agent. This rewrites Suvadu's hook scripts with the current binary path. The Codex setup saves a backup of hooks.json before it changes the file. For Claude Code, back up your settings first if you want an easy undo: cp ~/.claude/settings.json ~/.claude/settings.json.bak.
    • The pi.dev extension runs suv from your PATH, so it only needs the binary to be on the PATH that pi.dev sees.
    • If an MCP client cannot start the server, see stale MCP configuration.

    Verify. Run echo suvadu-check-2, then suv history -n 3; the line should appear. suv doctor should no longer show that agent's row as installed but broken.

    Existing history has not been imported

    Check. Suvadu records new commands after its hook loads. It does not import your old shell history automatically. Since 0.4.2, suv import reads four formats: Zsh history files, Bash history files, an Atuin database, and JSONL files that Suvadu exported. On 0.4.1 only the first and last are available.

    Repair. Preview the import first, then run it:

    suv import --from zsh-history --dry-run ~/.zsh_history   # shows the count; writes nothing
    suv import --from zsh-history ~/.zsh_history             # imports; skips entries already present

    The import leaves the source file alone. Imported entries go into a new session named import-zsh-…. If the result is not what you wanted, restore the database from a backup. Run suv backup before a large import so you have one. See Import & Export and Backup.

    Verify. Use the -q flag to search the full database for an old command you remember:

    suv search -q "some old command"

    Agent commands are hidden by recall filters

    Check. By default, search, Ctrl+R, and Zsh Up-arrow recall hide commands whose executor type is agent, bot, ci, or programmatic. Commands with no known executor type are shown. Confirm the agent's commands were recorded:

    suv history --executor agent -n 10     # suv history never hides agent commands
    suv history --executor claude-code -n 10

    Repair. Pick the narrowest option:

    • In the search screen, press Ctrl+A to show or hide agent commands.
    • For one search: suv search --include-agents, or suv search --executor <name>. Filtering by executor includes agent commands.
    • For Zsh Up/Down recall in the current shell, press Alt+A.
    • To show agent commands by default everywhere, set recall_show_agents = true in the [search] section of config.toml. Delete the line to undo.

    Verify. Open suv search and press Ctrl+A. The status line reads Agent commands shown, and the agent's commands appear in the list.

    If suv history --executor … finds nothing either, the commands were not recorded. See the next section.

    An integration records commands but not prompts or sessions

    Check. First confirm the integration can capture what you expect. Claude Code, Codex, and OpenCode import native sessions with prompts, responses, models, and tokens. Since 0.5.1 Cursor sessions carry prompts, final responses and models, but never tokens: Cursor's hooks do not report usage. pi.dev attaches prompts to commands. Antigravity (through suv init antigravity) and other agents detected through the shell record commands only. See the capability matrix. Then check what has arrived:

    suv agent sessions                          # native sessions (Claude Code, Codex, OpenCode, Cursor)
    suv agent prompts --executor claude-code    # commands that have a linked prompt
    suv doctor                                  # the agent's row: integration, commands, MCP
    • The turn is still running. Native session content is imported when a turn finishes: at Stop or SessionEnd for Claude Code and Codex, and when an OpenCode session goes idle. Finish one turn, then check again.
    • Hooks are from an older Suvadu. Setups from before 0.4.1 lack the Stop and SessionEnd hooks. Interactive suv commands print "your Codex hooks need refreshing" or "your Claude Code hooks need refreshing" when this applies. A Cursor setup from before 0.5.1 lacks the afterAgentResponse and stop hooks, so it records commands and prompts but no sessions; an OpenCode plugin from before 0.5.1 stops capturing a session once its history passes 16 MB. Rerun suv init cursor or suv init opencode.
    • A transcript line was torn. Before 0.5.1, one Codex or Claude Code transcript line that was not valid JSON stopped every later import of that session, and forked or subagent Codex sessions were never captured. 0.5.1 skips the torn line once a complete one follows (the session's capture.known_missing counts it) and captures forked sessions as their own.
    • Codex hooks are not trusted. Codex does not run the new hooks until you review and trust them in /hooks in the Codex terminal CLI.
    • Claude Code settings were not updated. If ~/.claude/settings.json did not exist, suv init claude-code printed a settings snippet for you to add instead of reporting Settings auto-configured.
    • OpenCode config could not be edited. If ~/.config/opencode/opencode.jsonc contains comments, suv init opencode does not edit it. It prints the exact lines to add instead.
    • Only shell-tool commands are recorded. For Claude Code, only Bash tool calls are recorded. Other tools do not create command rows.
    • Capture was paused or excluded. Records skipped while paused, or in a disabled or excluded directory, are not added later.

    Repair. Run the setup command for your agent again with the current binary. Relaunch the agent; for its VS Code extension, fully quit and reopen VS Code.

    suv init claude-code    # then relaunch Claude Code
    suv init codex          # then open /hooks in the Codex terminal CLI, trust Suvadu's hooks, relaunch Codex
    suv init opencode       # then fully quit and relaunch OpenCode
    suv init cursor         # then restart Cursor

    Re-running setup preserves unrelated hooks. Codex keeps a timestamped hooks.json.suvadu-backup-… copy of the previous file. For a Claude Code or Codex session that already ended, you can import its transcript file directly. Running this again only imports new records:

    suv agent import-session /path/to/transcript.jsonl

    Verify. Start a fresh agent turn that runs one harmless command, such as echo suvadu-agent-check. Let the turn finish, then run suv sessions, find the session, and open it. The timeline should show the prompt, the command, and the response. For pi.dev, run suv agent prompts and look for the prompt with its command. A Cursor session shows Tokens unavailable; that is expected.

    A failed command shows no output or "fixed it with" line

    Check. Failure output is opt-in and comes only from agent hooks and suv wrap. The MCP failure tools say why it is missing in their response. Then check:

    • Keep Failure Output is off. It is off by default. Turn it on in the Shell tab of suv settings, or set failure_output = true under [capture]. A project's .suvadu.toml can turn it off for that project. Only commands that fail after you turn it on keep output.
    • You typed the command in your shell. The Zsh and Bash hooks never see output, by design. Run it as suv wrap -- <command> to keep its stderr, or let it come from an agent integration.
    • The agent did not send output. Claude Code sends the error text of a failed Bash call, Cursor its afterShellExecution output, and Codex output only when the response also carries an exit code. OpenCode needs the plugin from suv init opencode run with 0.5.1. pi.dev is not one of the paths that keep output.
    • The command was excluded, or it exited with 130 (Ctrl+C), which is not treated as a failure.

    The Last time this failed, you fixed it with … line needs no setting. It appears only when your history shows a failure of exactly that command followed, in the same session and directory within 15 minutes, by a successful similar command or a setup step and a rerun. See how it is worked out.

    Verify. With Keep Failure Output on, run suv wrap -- ls /no-such-dir, then open recall with Ctrl+A (agent commands shown), select it, and press Tab: the detail pane shows an Output row.

    Summary saving is disabled or MCP has stale configuration

    Check. Look for these symptoms:

    • The agent says save_session_summary is not available, or reports "Tool 'save_session_summary' is disabled; enable mcp.allow_session_summaries…".
    • The agent cannot connect to the Suvadu MCP server at all.
    • MCP connects but uses old settings.

    Saving summaries is off by default. Since 0.4.2 the MCP tab of suv settings can turn it on; on 0.4.1 you edit the file. The MCP server reads config.toml once when it starts. Project .suvadu.toml files do not change MCP settings.

    grep -n -A8 '^\[mcp\]' "$HOME/Library/Application Support/tech.appachi.suvadu/config.toml"   # macOS
    grep -n -A8 '^\[mcp\]' ~/.config/suvadu/config.toml                                         # Linux
    suv doctor                                                                                   # MCP: in the Claude Code and Cursor rows

    Repair.

    • To enable summaries, add allow_session_summaries = true to the [mcp] section. Create the section if it does not exist. Remove save_session_summary from disabled_tools if it is listed there. Then restart the agent so it starts a new MCP server. To undo, set the value back to false. See Save a summary.
    • If the MCP entry points to a binary that no longer exists, fix it for your agent. suv init codex updates the command in Codex's config.toml every time it runs. suv init claude-code and suv init cursor add an entry only if none exists, so they do not repair a stale path. For those, back up ~/.claude.json or ~/.cursor/mcp.json, then change mcpServers.suvadu.command to the binary's current path. Get it with whence -p suv in Zsh or type -P suv in Bash. Plain command -v suv returns the shell wrapper function when Suvadu's hook is loaded. suv init opencode also leaves an existing mcp.suvadu entry in opencode.jsonc unchanged; edit its command the same way.
    • If the MCP server reports a database schema error, a different Suvadu build has updated the database. The agent may be running an older suv path. Point the entry at the current binary.

    Verify. Restart the agent and ask it to list its Suvadu tools. save_session_summary should appear. Then ask it to "summarize and save the current session". Open the session in suv sessions and press s; the new summary is labeled CURRENT.

    An older command exists but typed search misses it

    Fixed in 0.4.2. Affected: Suvadu 0.4.1 and earlier, which have a similar candidate limit according to the source history. Upgrade with suv update, brew upgrade suvadu, or cargo install suvadu. Nothing was ever deleted; the command is still in your database either way.

    Check. Search the whole database for the command:

    suv search -q "exact text"               # the first results come from a database query over all history

    If the command appears here but not when you type the same text in the open search screen, you are on a release with this limitation: before 0.4.2, typing or editing a query loaded only the newest 5,000 entries that passed your filters and matched against those, and unique mode (--unique) used the same limit. From 0.4.2 on, matching and counting happen in the database over your whole eligible history, so this cannot happen — the 5,000 limit now caps only how many matches are ranked by relevance, and every page of the reported count opens.

    On an older release, work around it. Each of these searches beyond the newest 5,000 entries:

    • Start with the query. Run suv search -q "text", or type the text at your prompt before pressing Ctrl+R. The first result list comes from the database. It matches the text as one continuous phrase. Editing the query switches back to the limited search.
    • Narrow the filters. Filters are applied in the database before the 5,000-entry limit. They include date (--after/--before or the Ctrl+F panel), directory (--here), tag, exit code, executor, failed-only, and bookmarks. For example: suv search --before 2026-01-01, then type your text.
    • Use a text pipeline. suv history --before 2026-01-01 -n 100000 | grep "text".
    • Ask a connected agent. The MCP search_commands tool searches the full database.

    Verify. The workaround works when the older command appears in the results. See Search for more detail.

    Still stuck? Report a reproducible problem

    If your question is about what Suvadu does rather than a fault, the FAQ covers shell support, privacy, performance, and AI-agent capture.

    Open an issue at github.com/AppachiTech/suvadu/issues. Include:

    • The output of suv --version and suv doctor
    • Your operating system and CPU architecture, shell and version, and terminal (plus tmux or screen, if you use one)
    • The agent name and version, if the problem involves an agent
    • The smallest sequence of steps that reproduces the problem

    Do not include history, prompts, or configuration that contain secrets or private paths.

    Related: Compatibility, Agent Sessions, Doctor, Shell Integration, and Agent Setup.