Feature Request: Add Background Bash Execution (Like Claude Code’s Ctrl+b) #1320

Open
opened 2026-02-16 17:30:25 -05:00 by yindo · 13 comments
Owner

Originally created by @elloydfetch on GitHub (Aug 15, 2025).

Originally assigned to: @thdxr on GitHub.

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: true parameter to the bash tool.
  • 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 & or nohup inside 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:

Originally created by @elloydfetch on GitHub (Aug 15, 2025). Originally assigned to: @thdxr on GitHub. # 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](https://claudelog.com/faq?utm_source=chatgpt.com) > “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: true` parameter to the `bash` tool. - **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 `&` or `nohup` inside 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:** - [Claude Code FAQ – Background Commands](https://claudelog.com/faq?utm_source=chatgpt.com)
Author
Owner

@github-actions[bot] commented on GitHub (Aug 15, 2025):

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.

@github-actions[bot] commented on GitHub (Aug 15, 2025): 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.
Author
Owner

@the-vampiire commented on GitHub (Aug 15, 2025):

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
@the-vampiire commented on GitHub (Aug 15, 2025): 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. ```sh #!/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 ```
Author
Owner

@ironbelly commented on GitHub (Oct 9, 2025):

Agreed that tmux is a workaround but would be nice to have this built in to be on part with claude code

@ironbelly commented on GitHub (Oct 9, 2025): Agreed that tmux is a workaround but would be nice to have this built in to be on part with claude code
Author
Owner

@rekram1-node commented on GitHub (Oct 9, 2025):

yeah makes sense

@rekram1-node commented on GitHub (Oct 9, 2025): yeah makes sense
Author
Owner

@waylaidwanderer commented on GitHub (Nov 28, 2025):

I built an MCP server for this, which is a solid alternative for now:

https://github.com/waylaidwanderer/background-process-mcp

@waylaidwanderer commented on GitHub (Nov 28, 2025): I built an MCP server for this, which is a solid alternative for now: https://github.com/waylaidwanderer/background-process-mcp
Author
Owner

@remorses commented on GitHub (Dec 6, 2025):

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

@remorses commented on GitHub (Dec 6, 2025): 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
Author
Owner

@junmediatek commented on GitHub (Dec 18, 2025):

yeah makes sense

hi @thdxr & @rekram1-node
Could you share the estimated completion time for this feature?

@junmediatek commented on GitHub (Dec 18, 2025): > yeah makes sense hi @thdxr & @rekram1-node Could you share the estimated completion time for this feature?
Author
Owner

@rekram1-node commented on GitHub (Dec 18, 2025):

no official timeline I guess we would prolly roll out experimental version first and see how it does

@rekram1-node commented on GitHub (Dec 18, 2025): no official timeline I guess we would prolly roll out experimental version first and see how it does
Author
Owner

@junmediatek commented on GitHub (Dec 18, 2025):

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?

@junmediatek commented on GitHub (Dec 18, 2025): > 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?
Author
Owner

@shekohex commented on GitHub (Dec 18, 2025):

you can also use opencode-pty plugin, it does exactly that and more: https://github.com/shekohex/opencode-pty

@shekohex commented on GitHub (Dec 18, 2025): you can also use `opencode-pty` plugin, it does exactly that and more: https://github.com/shekohex/opencode-pty
Author
Owner

@PlaneInABottle commented on GitHub (Feb 12, 2026):

opencde-pty has a major limitation, you have to configure the permissions beforehand, it can't trigger ask permission tool of the opencode.

@PlaneInABottle commented on GitHub (Feb 12, 2026): `opencde-pty` has a major limitation, you have to configure the permissions beforehand, it can't trigger `ask permission` tool of the opencode.
Author
Owner

@shekohex commented on GitHub (Feb 12, 2026):

opencde-pty has a major limitation, you have to configure the permissions beforehand, it can't trigger ask permission tool of the opencode.

That's a limitation of opencode plugins API rather than the plugin itself.

@shekohex commented on GitHub (Feb 12, 2026): > `opencde-pty` has a major limitation, you have to configure the permissions beforehand, it can't trigger `ask permission` tool of the opencode. That's a limitation of opencode plugins API rather than the plugin itself.
Author
Owner

@PlaneInABottle commented on GitHub (Feb 12, 2026):

opencde-pty has a major limitation, you have to configure the permissions beforehand, it can't trigger ask permission tool of the opencode.

That's a limitation of opencode plugins API rather than the plugin itself.

Oh yes, sorry for that, I have described wrongly.

We should either have support in the plugins API or native background bash execution.

@PlaneInABottle commented on GitHub (Feb 12, 2026): > > `opencde-pty` has a major limitation, you have to configure the permissions beforehand, it can't trigger `ask permission` tool of the opencode. > > That's a limitation of opencode plugins API rather than the plugin itself. Oh yes, sorry for that, I have described wrongly. We should either have support in the plugins API or native background bash execution.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: anomalyco/opencode#1320