Feature Request: Add Background Bash Execution (Like Claude Code’s Ctrl+b)
Feature Request: Support Long-Running Bash Processes in the Background (Async Execution)
Summary
Claude Code includes a feature that allows developers to run bash commands in the background without blocking the agent/chat interface. This enables long-running tasks (e.g., builds, servers, data processing) to continue running while the developer interacts with the AI for other tasks.
I propose adding similar functionality to OpenCode.
Motivation
Currently, when a bash command is run in OpenCode via the bash tool, the session is blocked until the command completes. This makes workflows involving:
- Development servers
- Continuous monitoring scripts
- Large builds or data processing jobs
…slow and cumbersome, since you can’t continue using the AI assistant while those commands are still running.
Background execution would:
- Keep the AI assistant responsive
- Allow parallel workstreams
- Reduce the need to switch out of OpenCode to manage long-running jobs in a separate shell
Reference: Claude Code’s Implementation
Claude Code provides Background Commands with a simple shortcut (Ctrl+b) to run bash processes asynchronously.
Reference: Claude Code FAQ – Background Commands
“Background commands allow you to run bash processes in the background using
Ctrl+b, enabling Claude to continue working on other tasks while long-running processes execute. Great for development servers and monitoring.”
Proposed Design Ideas
- Syntax Option: Add a
background: trueparameter to thebashtool. - Shortcut Key: Similar to Claude Code, provide a hotkey to run the currently typed bash command as a background job.
- Job Management: Include a simple job list/kill command to view or stop background processes.
- Output Handling: Stream or store background process logs for later inspection.
Workarounds Today
- Using
&ornohupinside the bash tool sometimes works, but behavior is inconsistent and often tied to the session lifecycle. - Running tasks outside of OpenCode in a multiplexer (
tmux,screen)—but this defeats the purpose of integrated AI-assisted workflows.
Impact
Implementing this feature would make OpenCode far more usable for developers with mixed workloads and align it with modern AI coding assistants’ capabilities.
Related links:
This issue might be a duplicate of existing issues. Please check:
- #1852: Commands that need sudo access break the UI and make the agent hang (addresses UI hanging with certain bash commands)
- #1955: bash tool missing tree-sitter-bash.wasm and it will cause the process to become stuck (addresses bash tool getting stuck)
- #1868: Request to make Bash line output configurable (related to bash tool behavior and output handling)
While these issues address different aspects of bash tool problems (hanging, getting stuck, output handling), none specifically address background/async execution like your feature request. Your proposal for background bash execution appears to be a new and distinct feature request.
idk if it helps but this is what i had created a while ago to handle running dev servers without the agent trying to start multiple, getting stuck by not realizing its an infinite process, and being able to look at logs as needed while we work.
this is just for "dev" mode but conceptually it could be used for other processes besides a dev server.
#!/bin/bash
# Generic development process manager
# Usage: ./dev.sh start "your dev command here"
PID_FILE=".dev.pid"
LOG_FILE=".dev.log"
run() {
case "$1" in
start) shift; start "$@" ;;
stop) stop ;;
restart) shift; restart "$@" ;;
logs) shift; logs "$@" ;;
status) status ;;
*) echo "Usage: $0 {start|stop|restart|logs|status} [command]" ;;
esac
}
start() {
if [ $# -eq 0 ]; then
echo "Usage: $0 start \"command to run\""
return 1
fi
if [ -f "$PID_FILE" ]; then
if kill -0 $(cat "$PID_FILE") 2>/dev/null; then
echo "Process already running (PID: $(cat $PID_FILE))"
return 1
else
echo "Removing stale PID file"
rm "$PID_FILE"
fi
fi
echo "Starting: $*"
echo "=== Started at $(date) ===" > "$LOG_FILE"
"$@" >> "$LOG_FILE" 2>&1 &
PID=$!
echo $PID > "$PID_FILE"
echo "Process started (PID: $PID)"
# Give it a moment to start
sleep 2
# Verify it's still running
if kill -0 "$PID" 2>/dev/null; then
echo "Process is running. Logs: ./dev.sh logs"
else
echo "Process failed to start. Check logs: ./dev.sh logs"
rm "$PID_FILE"
fi
}
stop() {
if [ -f "$PID_FILE" ]; then
PID=$(cat "$PID_FILE")
if kill -0 "$PID" 2>/dev/null; then
echo "Stopping process (PID: $PID)"
kill "$PID"
rm "$PID_FILE"
else
echo "Process not running"
rm "$PID_FILE"
fi
else
echo "No PID file found"
fi
}
restart() {
if [ $# -eq 0 ]; then
echo "Usage: $0 restart \"command to run\""
return 1
fi
stop
sleep 1
start "$@"
}
logs() {
if [ ! -f "$LOG_FILE" ]; then
echo "No log file found"
return 1
fi
case "${1:-tail}" in
tail|follow)
echo "Following logs (Ctrl+C to exit)..."
tail -f "$LOG_FILE"
;;
recent)
lines="${2:-50}"
echo "Last $lines lines:"
tail -"$lines" "$LOG_FILE"
;;
clear)
> "$LOG_FILE"
echo "Log file cleared"
;;
all)
cat "$LOG_FILE"
;;
search)
if [ -z "$2" ]; then
echo "Usage: $0 logs search <pattern>"
echo "Example: $0 logs search ERROR"
return 1
fi
echo "Searching for: $2"
grep -n --color=auto "$2" "$LOG_FILE"
;;
*)
echo "Usage: $0 logs [tail|recent|clear|all|search] [args]"
echo " tail/follow - Follow logs in real-time (default)"
echo " recent [N] - Show last N lines (default: 50)"
echo " clear - Clear log file"
echo " all - Show entire log"
echo " search <pattern> - Search logs with grep"
echo ""
echo "Examples:"
echo " $0 logs recent 100 # Last 100 lines"
echo " $0 logs search ERROR # Find error messages"
echo " $0 logs search 'POST.*ws' # Find WebSocket POST requests"
;;
esac
}
status() {
if [ -f "$PID_FILE" ]; then
PID=$(cat "$PID_FILE")
if kill -0 "$PID" 2>/dev/null; then
echo "Process running (PID: $PID)"
echo "Log file: $LOG_FILE"
else
echo "Process not running (stale PID file)"
fi
else
echo "Process not running"
fi
}
run
Agreed that tmux is a workaround but would be nice to have this built in to be on part with claude code
yeah makes sense
I built an MCP server for this, which is a solid alternative for now:
https://github.com/waylaidwanderer/background-process-mcp
tmux works really well for running commands in background
it can
- start bash commands (sessions) in background with a name
- list sessions
- kill sessions
- get last N logs for a session
that's all you need, with the added advantage that you can attach to these sessions yourself to send interactive commands yourself! something that Claude Code does not have
you can give this document to your agent to let it know the commands to use https://github.com/remorses/AGENTS.md/blob/main/tmux.md
yeah makes sense
hi @thdxr & @rekram1-node Could you share the estimated completion time for this feature?
no official timeline I guess we would prolly roll out experimental version first and see how it does
no official timeline I guess we would prolly roll out experimental version first and see how it does
@rekram1-node So when will the experimental version be released?
you can also use opencode-pty plugin, it does exactly that and more: https://github.com/shekohex/opencode-pty