Skip to content

fix(acp): emit terminal_info/_output/_exit meta for IDE terminal display#1016

Merged
bug-ops merged 1 commit intomainfrom
fix/acp-terminal-meta-extension
Feb 27, 2026
Merged

fix(acp): emit terminal_info/_output/_exit meta for IDE terminal display#1016
bug-ops merged 1 commit intomainfrom
fix/acp-terminal-meta-extension

Conversation

@bug-ops
Copy link
Owner

@bug-ops bug-ops commented Feb 27, 2026

Summary

  • Follow the Zed _meta extension pattern used by Claude Code for terminal output display in the ACP thread panel
  • Use tool_call_id as the display terminal ID instead of the UUID from terminal/create
  • Emit terminal_info in _meta on the initial ToolCall notification (registers display terminal in Zed)
  • Emit terminal_output in _meta on an intermediate ToolCallUpdate (streams output to display)
  • Emit terminal_exit in _meta on the final ToolCallUpdate (completes terminal widget)

Root Cause

Previously Zeph sent ToolCallContent::Terminal referencing the UUID from terminal/create. Zed looked up this terminal in its terminals HashMap, but _output_task (which sets terminal.output = Some(...)) had a race condition: when entry_view_state.sync() ran after processing tool_call_update, terminal.output() was still None, triggering TerminalMovedToBackground and collapsing the block before output could be shown.

The _meta extension pattern avoids this entirely. Zed creates a display-only terminal via terminal_info, populates it synchronously via terminal_output/terminal_exit as the updates arrive, and terminal.output() is Some(...) by the time sync() runs.

Test plan

  • All existing tests pass (2963 tests)
  • New tests added: loopback_tool_start_execute_sets_terminal_info, updated loopback_tool_output_with_terminal_id to verify 2-update pattern with correct meta fields
  • Manual verification: Run zeph acp --stdio in Zed and execute a bash command — terminal output should appear in the Run Command block

Follow the Zed _meta extension pattern used by Claude Code to render
terminal output in the ACP thread panel.

Previously, Zeph sent ToolCallContent::Terminal referencing a UUID
from terminal/create. Zed's _output_task race condition caused
terminal.output() to still be None when entry_view_state.sync()
ran, triggering TerminalMovedToBackground and collapsing the block.

Now Zeph uses tool_call_id as the display terminal ID and emits:
- terminal_info in _meta on the initial ToolCall notification
- terminal_output in _meta on an intermediate ToolCallUpdate
- terminal_exit in _meta on the final ToolCallUpdate

ToolCallContent::Terminal also references tool_call_id, which Zed
looks up in its terminals map populated by terminal_info — bypassing
the _output_task race entirely. The actual ACP terminal lifecycle
(terminal/create, terminal/release) is unchanged.
@github-actions github-actions bot added rust bug Something isn't working size/M labels Feb 27, 2026
@bug-ops bug-ops enabled auto-merge (squash) February 27, 2026 03:31
@bug-ops bug-ops merged commit c19da0c into main Feb 27, 2026
25 checks passed
@bug-ops bug-ops deleted the fix/acp-terminal-meta-extension branch February 27, 2026 03:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working rust size/M

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant