Process Tools for Interactive CLI commands
Summary
This PR introduces background process handling capabilities to the bash tool, allowing OpenCode to manage interactive and long-running processes without blocking the conversation flow. Processes that produce no output within a configurable timeout are automatically backgrounded and can be interacted with using a new suite of process management tools.
Problem Solved
Previously, running interactive commands (like python, node REPLs) or long-running processes (like npm run dev, development servers) would block the bash tool until a timeout occurs. This made it impossible for the AI to effectively work with development workflows that involve servers, watchers, or interactive tools.
Implementation Details
Enhanced Bash Tool
- Added
outputTimeoutparameter (default: 3 seconds) to detect non-responsive processes - Processes with no output are automatically backgrounded and tracked
- Returns a unique process ID for future interaction
- Includes buffer memory warnings in all bash command responses
New Process Management Tools
process_list- View all background processes with runtime and memory statsprocess_stream- Read output with stream-like semantics (read/peek/tail/reset)process_interact- Send input or signals to background processesprocess_trim- Manage memory by trimming output buffers
Memory Management
- Soft limit: 100MB (warning issued)
- Hard limit: 200MB (auto-trim to 1MB)
- Buffer warnings appear in bash command metadata to prompt proactive management
Technical Approach
- Uses
Promise.race()for non-blocking timeout detection - Global
Maptracks all running processes - Stream-like API with read cursors prevents duplicate output
- Automatic cleanup on process termination
Use Cases
- Development servers:
npm run dev,python -m http.server - Interactive REPLs:
python,node,psql - Build watchers:
webpack --watch,tsc --watch - Long-running processes: database clients, log tails
Testing
Includes a test file demonstrating process lifecycle management and output capture.
Breaking Changes
None. The feature is fully backward compatible - existing bash commands work exactly as before, with the added benefit of automatic backgrounding when appropriate.
Considerations:
- Make sure the bash command returns the PID and information about it going to a background process in the output
- Need to be able to exit processes when opencode exits
- Add config for automatic timeout
- Add a UI to manually send process to background (more user control)
Just sharing my own experience with interacting with TUI/ interactive clis Prior art here is: https://github.com/mitsuhiko/pexpect-mcp/tree/main
I built a similar tool for my own use. The observation was that it seems productive if it can chain multiple functions. LLMs already know how to use libraries widespread. Disadvantage is that this can get harder to review / follow. I added a little CLI tool that can stream out logs.
What does mean for this PR? Executing Python or similar might be indeed to powerful but having an API that is close to the original expect or similar to pexpect while also providing a Pty abstraction to emulate a Terminal might be desirable.
@Mic92 I don't understand your question. This PR changes the bash tool call failure timeout to a timeout that leaves the process in the background and allows the agent to continue to use and interact with that process.
Can you describe how your tool is relevant/different to this PR? I see it looks to try to emulate a PTY for the agent, which is great! I think giving the agent the ability to use the terminal in an interactive way would be way more useful overtime for users even if users don't use it. Overtime, I think as users shift towards more agentic development (less HIL), this will be increasingly more useful.
Some problems noticed with this PRs approach:
- The agent cannot use commands that require an PTY (like vim)
- When an agent tries to use vim, it can cause display bugs in the TUI
I think making OC better at multiplexing could really elevate the issues observed.
My comment was regarding the process_interact tool. It currently sends text to a process unconditionally. Usually this requires some timing, i. E. one has to wait for a certain output before sending input. This what expect was developed for: https://linux.die.net/man/1/expect
Of course this might be out of scope for this PR but maybe a future direction to enable opencode with debugger and other tuis
Right now the bash tool returns output after the timeout. Then the agent can send more input and then call another tool to read output. But having it send back out put on the process_interact would make sense (with a timeout).
Just switched from the Gemini CLI to OpenCode and had hoped this would already be supported, but alas, both CLIs are missing it. Inspired by Claude Code, I built an MCP server for this, which is a solid alternative until something native is added:
https://github.com/waylaidwanderer/background-process-mcp