Skip to content

feat(acp): stage edits for native review in ACP clients - #31392

Closed
PacoDw wants to merge 9 commits into
anomalyco:devfrom
PacoDw:feat/acp-review-at-end
Closed

feat(acp): stage edits for native review in ACP clients#31392
PacoDw wants to merge 9 commits into
anomalyco:devfrom
PacoDw:feat/acp-review-at-end

Conversation

@PacoDw

@PacoDw PacoDw commented Jun 8, 2026

Copy link
Copy Markdown

Issue for this PR

Related to #4240
Related to #30913

Type of change

  • Bug fix
  • New feature
  • Refactor / code improvement
  • Documentation

What does this PR do?

This makes opencode work with the native file review in ACP clients like Zed and Devin.

Before, opencode wrote files directly to disk during the turn. Because of this, the client could not show its native review UI (the "Keep / Reject" diff).

Now, when the client supports fs.writeTextFile:

  • File creates and edits (add / update) are kept in memory during the turn. opencode sends them to the client with writeTextFile, so they appear in the native review UI.
  • Deletes and moves still go to disk, because ACP has no delete/rename method. They are shown as a diff in the tool call, and the tool output says they are not part of the staged review.
  • If the client does not support writeTextFile, opencode writes to disk like before (safe fallback).
  • The staged changes are cleared at the end of every turn (success, error, or cancel), so nothing leaks into the next turn.

How it works

agent turn
  │
  ├─ add / update ──► ReviewOverlay (memory) ──writeTextFile──► client review UI (Keep / Reject)
  │
  ├─ delete / move ──► disk  +  diff shown in tool_call
  │
  └─ no writeTextFile support ──► disk (fallback)

end of turn ──► overlay cleared

How did you verify your code works?

Added and updated unit tests: review-mode capability gating, staging via the tool registry, the apply_patch disk note, and clearing the overlay when a prompt fails. All tests pass and typecheck is clean.

Tested manually in Zed and Devin (see screenshots below).

How to try it

You need an ACP client that supports the fs.writeTextFile capability (Zed and Devin do).

  1. Clone this fork and check out the branch.
  2. Install dependencies: bun install.
  3. Add an ACP agent in your client that runs this repo (examples below). Replace /path/to/opencode with your local path, and make sure bun is on your PATH (or use the full path to the bun binary).
  4. Open the client, start a session with that agent, and ask it to create or edit a file.
  5. Expected: the change shows up in the native review UI ("Keep / Reject") instead of being written to disk right away. For apply_patch deletes and moves, you see a diff in the tool call.

Zed

Add this to your Zed settings.json:

{
  "agent_servers": {
    "OpenCode (Review UI)": {
      "type": "custom",
      "command": "bun",
      "args": [
        "run",
        "--conditions=browser",
        "/path/to/opencode/packages/opencode/src/index.ts",
        "acp"
      ]
    }
  }
}

Windsurf / Devin

Add this entry to your ACP registry.json:

{
  "id": "opencode-review-ui",
  "name": "OpenCode (Review UI)",
  "version": "1.0.0",
  "description": "OpenCode ACP review-at-end",
  "distribution": {
    "binary": {
      "darwin-aarch64": {
        "archive": "",
        "cmd": "bun",
        "args": [
          "run",
          "--conditions=browser",
          "/path/to/opencode/packages/opencode/src/index.ts",
          "acp"
        ]
      }
    }
  }
}

Use the platform key that matches your OS (for example darwin-aarch64 for Apple Silicon).

Screenshots / recordings

  • Zed:
zed_gif
  • Devin:
devin_gif

Checklist

  • I have tested my changes locally
  • I have not included unrelated changes in this PR

@github-actions github-actions Bot added needs:compliance This means the issue will auto-close after 2 hours. and removed needs:compliance This means the issue will auto-close after 2 hours. labels Jun 8, 2026
@github-actions

github-actions Bot commented Jun 8, 2026

Copy link
Copy Markdown
Contributor

Thanks for updating your PR! It now meets our contributing guidelines. 👍

@PacoDw
PacoDw force-pushed the feat/acp-review-at-end branch 3 times, most recently from 1a2ac59 to 2dab6a1 Compare June 8, 2026 23:04
@PacoDw
PacoDw force-pushed the feat/acp-review-at-end branch 5 times, most recently from 6517bab to 3ee004c Compare June 10, 2026 02:32
@PacoDw
PacoDw force-pushed the feat/acp-review-at-end branch 2 times, most recently from 278709b to 72426bf Compare June 10, 2026 03:30
@PacoDw
PacoDw force-pushed the feat/acp-review-at-end branch from 72426bf to 70f55c9 Compare June 10, 2026 11:22
@PacoDw
PacoDw force-pushed the feat/acp-review-at-end branch 6 times, most recently from 01855c7 to 2678171 Compare June 16, 2026 13:59
@PacoDw
PacoDw force-pushed the feat/acp-review-at-end branch 5 times, most recently from 63b0b5e to f323fce Compare June 23, 2026 15:04
@PacoDw
PacoDw force-pushed the feat/acp-review-at-end branch from f323fce to 0f207c3 Compare June 25, 2026 14:11
@PacoDw
PacoDw force-pushed the feat/acp-review-at-end branch 3 times, most recently from f753cca to 8680040 Compare July 1, 2026 16:38
PacoDw added 9 commits July 7, 2026 07:45
In-memory overlay that holds staged file content during an ACP turn so
add/update writes can be sent to the client for native review instead of
hitting disk immediately.
Gate review staging on the client writeTextFile capability, flush staged
edits through ACP, and wrap FSUtil so tool writes land in the overlay
instead of disk while review mode is active.
Wire review mode into ACP session lifecycle, tool registry, and edit/write/
apply_patch tools so add/update changes reach the client review UI via
writeTextFile. Delete/move still hit disk and show as tool_call diffs.
Upstream dropped @opencode-ai/core/util/log; migrate ACP review paths to
Effect.logInfo/logError so typecheck passes after the rebase.
ToolRegistry.defaultLayer already provides Agent; align the registry test
layer with skill.test and use an inline build agent to satisfy Effect types.
… migration

Re-add ReviewFs to ToolRegistry.node and createRoutes so tool writes stage
in memory again. Remove misplaced ReviewFs from AppRuntime, which ACP does
not use.
Verify ToolRegistry.node with ReviewFs stages edits through the same layer
wiring used by the HTTP server after the LayerNode migration.
Adapt ReviewFs.node and the HTTP review regression test to the new
LayerNode.make object form and compile() after upstream rebase.
Replace removed FSUtil.defaultLayer usage with compile-based ReviewFs nodes
and global FSUtil replacement in the HTTP app graph so ACP review staging
keeps working on the current dev stack.
@PacoDw
PacoDw force-pushed the feat/acp-review-at-end branch from 8680040 to a8d3d1a Compare July 7, 2026 13:52
@github-actions

github-actions Bot commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

Automated PR Cleanup

Thank you for contributing to opencode.

Due to the high volume of PRs from users and AI agents, we periodically close older PRs using automated criteria so maintainers can focus review time on the most active and community-supported contributions.

This PR was closed because it matched the following cleanup criteria:

  • The PR was created more than 1 month ago
  • The PR had fewer than 2 positive reactions
  • Positive reactions are counted as thumbs-up, heart, celebration, or rocket reactions on the PR

PRs created within the last month are not affected by this cleanup.

If you believe this PR was closed incorrectly, or if you are still actively working on it, please leave a comment explaining why it should be reopened. A maintainer can review and reopen it if appropriate.

Thanks again for taking the time to contribute.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant