Skip to content
Guide

How to Track OpenCode Commands with Suvadu

By Madhubalan Appachi6 min read

OpenCode is the open-source coding agent from SST with over 120,000 GitHub stars. It reads your codebase, plans changes, and executes shell commands — all from a beautiful TUI. A single prompt can trigger multiple bash commands: reading files, running tests, installing packages, modifying configs. Suvadu captures every one of these commands automatically, including the prompt that triggered them.

The Challenge with OpenCode

Most AI coding tools that run in your terminal (Cursor, VS Code, Antigravity) execute commands through your shell's integrated terminal. Suvadu's shell hooks (eval "$(suv init zsh)") detect these automatically.

OpenCode is different. It spawns shell commands via Node.js child_process.spawn(), which bypasses your interactive shell entirely. Your .zshrc hooks never fire. This is the same challenge that required a dedicated integration for Claude Code.

The solution: OpenCode has a plugin system with a tool.execute.after hook that fires after every tool call. Suvadu installs a small plugin that uses this hook to record every bash command with the correct executor metadata.

Setup

One command installs the plugin:

$ suv init opencode
Suvadu — OpenCode Integration

✓ Plugin installed: ~/.opencode/plugins/suvadu.js

OpenCode will automatically load this plugin on next start.
Commands executed by OpenCode will be recorded with executor=opencode.

Verify with: suv search --executor opencode

This installs a JavaScript plugin at ~/.opencode/plugins/suvadu.js. OpenCode automatically loads all plugins from this directory — no config file editing needed. Restart OpenCode after setup.

What Gets Captured

Every bash command OpenCode executes is recorded with full metadata:

  • The command itself. Exactly what OpenCode ran.
  • Working directory. Where the command was executed.
  • Exit code. Whether it succeeded or failed.
  • Executor attribution. Tagged as executor=opencode so you can filter and search by agent.
  • Session ID. Each OpenCode session gets a unique ID for grouping commands.

Prompt Capture

Like Claude Code, Suvadu captures the user prompt that triggered each set of commands. When you type "add authentication to the API" in OpenCode, that prompt is cached and attached to every subsequent command OpenCode runs in response.

This means you don't just see what commands ran — you see why they ran. In the agent dashboard, you can trace any command back to the prompt that triggered it.

$ suv search --executor opencode

 # │ Command                               │ Dir         │ Exit
───┼───────────────────────────────────────┼─────────────┼──────
 1 │ ls -la                                │ ~/project   │  0
 2 │ cat package.json                      │ ~/project   │  0
 3 │ npm install express-rate-limit        │ ~/project   │  0
 4 │ npm test                              │ ~/project   │  0
 5 │ git diff --stat                       │ ~/project   │  0

Querying OpenCode History

Once commands are captured, you can use all of Suvadu's search and analytics features:

# Search OpenCode commands
suv search --executor opencode

# Agent dashboard with timeline and risk indicators
suv agent dashboard --executor opencode

# Per-agent analytics
suv agent stats

# Export agent activity report
suv agent report --format markdown > opencode-report.md

Risk Assessment

Every command OpenCode runs is automatically classified by risk level — the same system used for Claude Code and other agents:

  • Criticalrm -rf, git push --force origin main
  • Highnpm install, chmod 777
  • Mediumgit reset, docker run
  • Safegit status, ls, cat

Use the agent dashboard (suv agent dashboard) to filter by risk level and focus on the commands that matter.

Custom Agent Support

Don't see your AI tool listed? Suvadu v0.1.4 also introduced configurable agent detection. If your tool sets an environment variable in its child processes, you can add it via suv settings and navigate to the Agents tab. Define the tool's name, its environment variable, and the executor type — and Suvadu will detect it automatically.

For tools that bypass the shell entirely (like OpenCode), a plugin-based approach like suv init opencode is the way to go. If you'd like native integration for another tool, open an issue — we're happy to add it.

How It Works Under the Hood

The plugin uses two OpenCode hook points:

  1. event hook — listens for message.part.updated events to capture user prompts. When you type a prompt, it's cached to disk at ~/Library/Application Support/tech.appachi.suvadu/prompts/.
  2. tool.execute.after hook — fires after every tool call. For bash commands, it calls suv add with the command, working directory, exit code, and session ID. The cached prompt is automatically attached.

The plugin is designed for zero-overhead: it uses spawnSync with a 5-second timeout and silently catches errors so OpenCode is never affected even if Suvadu encounters an issue.

Getting Started

  1. Install Suvadu: brew tap AppachiTech/suvadu && brew install suvadu
  2. Set up shell hooks: eval "$(suv init zsh)" in your .zshrc
  3. Install the OpenCode plugin: suv init opencode
  4. Restart OpenCode
  5. Verify: suv search --executor opencode

That's it. Every command OpenCode runs from now on will be recorded, risk-assessed, and searchable — 100% locally, with no data leaving your machine.

Share this article

PostShare
👣Try Suvadu

Total recall for your terminal. Database-backed shell history with AI agent tracking, built in Rust.

Install now →
👣

Madhubalan Appachi

Building developer tools at Appachi Tech. Creator of Suvadu and Kaval.

Related Posts