Skip to content

chore: extract ACP stdio transport pre-patch#3310

Open
ssfdust wants to merge 1 commit intotailcallhq:mainfrom
ssfdust:feat/acp-pre
Open

chore: extract ACP stdio transport pre-patch#3310
ssfdust wants to merge 1 commit intotailcallhq:mainfrom
ssfdust:feat/acp-pre

Conversation

@ssfdust
Copy link
Copy Markdown

@ssfdust ssfdust commented May 11, 2026

ACP stdio transport pre-patch

Extracts independently-mergable fixes from the ongoing ACP work in #2858.

Background

When spawning forge machine stdio as an ACP subprocess, stdin is a pipe
that remains open for bidirectional JSON-RPC communication. This patch
resolves three classes of bug discovered during ACP integration testing.

Changes

  1. stdin pre-read encapsulation (cli.rs, main.rs)
    Added Cli::uses_stdin() method that centralizes the decision of
    which subcommands own stdin. Subcommands opt in via uses_stdin()
    rather than having the startup pipeline guess from a hardcoded
    exclusion list. This makes it easy to add new stdin-consuming
    subcommands (e.g. an ACP stdio server) without touching the
    startup logic.

  2. tool output leaking to stdout (context.rs, tool_executor.rs)
    Shell tool execution always streamed raw output to io::stdout(),
    corrupting the ACP JSON-RPC stream. Added a silent: bool field
    on ToolCallContext (the correct home for per-invocation runtime
    flags). Default false, ACP sets .silent(true) — output then
    goes to io::sink() instead.

  3. stderr vs stdout discipline (main.rs, sandbox.rs)
    Panic hook and worktree status messages used println!, which
    writes to stdout and contaminates structured transport. Changed
    to eprintln! (stderr).

@CLAassistant
Copy link
Copy Markdown

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

@github-actions github-actions Bot added type: chore Routine tasks like conversions, reorganization, and maintenance work. type: fix Iterations on existing features or infrastructure. labels May 11, 2026
Extracts independently-mergable fixes from the ongoing ACP work
(tailcallhq#2858) that can land on main immediately.

Three classes of fix:

1. stdin pre-read encapsulation (cli.rs, main.rs)
   Add Cli::uses_stdin() method that centralizes the decision of which
   subcommands own stdin. Subcommands opt in via uses_stdin() rather
   than having the startup pipeline guess from a hardcoded exclusion
   list. This makes it easy to add new stdin-consuming subcommands
   (e.g. an ACP stdio server) without touching the startup logic.

2. Tool output leaking to stdout (context.rs, tool_executor.rs)
   Shell tool execution streamed raw output to io::stdout(), corrupting
   the ACP JSON-RPC stream. Add silent: bool field on ToolCallContext
   (the correct home for per-invocation runtime flags). Default false;
   ACP sets .silent(true) to route output to io::sink() instead.

3. Stderr vs stdout discipline (main.rs, sandbox.rs)
   Panic hook and worktree status messages used println! which writes
   to stdout. Changed to eprintln! (stderr) to avoid contaminating
   structured transport channels.

Signed-off-by: ssfdust <ssfdust@gmail.com>
Co-authored-by: ForgeCode <noreply@forgecode.dev>
Co-authored-by: DeepSeek <deepseek-ai@deepseek.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

type: chore Routine tasks like conversions, reorganization, and maintenance work. type: fix Iterations on existing features or infrastructure.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants