Skip to content

[FEATURE]: Agent should use integrated terminal (PTY) instead of spawning new shell processes #23449

@herjarsa

Description

@herjarsa

Pre-flight Checks

  • I have verified this feature hasn't been suggested before
  • I understand this issue needs status:approved before a PR can be opened

Problem Description

OpenCode has a built-in terminal panel powered by ghostty-web with full PTY support. The terminal panel is accessible via `Ctrl+`` and supports:

  • Multiple tabs
  • 10,000 lines of scrollback
  • Themes (light/dark)
  • WebSocket bridge to /pty/{id}/connect

However, when the agent executes shell commands, it uses the bash tool which spawns a completely new shell process each time. This creates several problems:

  1. No interactive command support - Commands like htop, vim, ssh, mysql that require a TTY can't run
  2. State not shared - Environment variables, working directory changes, and shell state don't persist between commands
  3. Timeout issues - Interactive commands often get killed after the timeout
  4. Waste of resources - New process spawned for every command instead of reusing the PTY

Proposed Solution

Expose the integrated terminal (PTY) to the agent as a tool, so instead of:

Agent -> bash tool -> spawns new process -> returns output

It would be:

Agent -> terminal tool -> connects to existing PTY via WebSocket -> streams I/O

This would enable:

  • Truly interactive commands - ssh, vim, htop, interactive CLIs
  • Persistent shell state - Same session, same environment
  • Better UX - User can see what commands the agent is running in real-time
  • Shared PTY - Agent and user share the same terminal session

Affected Area

  • Core (agent shell execution)
  • ACP protocol (terminal stub mentioned in docs)

References

  • ACP README states: "Terminal support (stub for future)"
  • Commit 21c52fd5c: "fix bash tool getting stuck on interactive commands" shows ongoing work on this area
  • The terminal panel component already exists at packages/app/src/components/terminal.tsx

Related Code

The terminal WebSocket endpoint already exists:

URL: /pty/{id}/connect
Protocol: WebSocket
Backend: ghostty-web + PTY bridge

The bash tool currently spawns via ChildProcessSpawner in packages/opencode/src/tool/bash.ts

Metadata

Metadata

Assignees

Labels

acpcoreAnything pertaining to core functionality of the application (opencode server stuff)

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions