Skip to content

fix(opencode): preserve turn outcomes and avoid auto permission attention - #24612

Merged
nwparker merged 5 commits into
mainfrom
nwparker/OpenCode-Agent-Status
Oct 2, 2026
Merged

nwparker merged 5 commits into
mainfrom
nwparker/OpenCode-Agent-Status

Conversation

@nwparker

@nwparker nwparker commented Oct 2, 2026 •

Copy link
Copy Markdown
Contributor
Files Added Deleted Net
Test 3 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​185 $\color{#cf222e}{\Huge{\mathbf{−}}}$​128 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​57
Prod 4 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​243 $\color{#cf222e}{\Huge{\mathbf{−}}}$​18 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​225

ELI5

An OpenCode turn that failed looked Done, and Auto mode could briefly look like it needed your input even while it continued by itself. Orca now distinguishes failed and stopped turns and lets immediately answered permissions settle before asking for attention.

What Changed

The OpenCode 2 terminal plugin reads the current root outcome and binds a captured failure or user interruption to that completed turn's timestamp. A later turn completed while the plugin was unloaded replaces the old verdict when the reporter returns. It includes that verdict in its existing hook posts. The execution host translates those optional fields into the existing agent outcome contract, which the tab already renders as Failed or Interrupted. A child still working keeps the aggregate Working; a child's failure does not become the root's failure.

Permission requests remain Working for up to 500 ms. A request still present after that interval becomes Needs input; a reply received during that interval never publishes waiting. Questions remain immediate. Permission posts now carry the existing approval-card envelope so native Chat can display the actual command awaiting approval. The reporter uses its existing session data and tick, with no extra timers or status store.

Why

OpenCode v2.0.16 exposes failed/interrupted lifecycle events, but its session status alone says only whether the turn is running. Reading the current session outcome and matching ending event timestamps preserves the root verdict without guessing from terminal text or process state. The optional hook fields keep older clients and plugins compatible and leave status authority on the execution host.

In a real Auto run, permission replies followed requests by 6–18 ms. Waiting briefly for an unanswered request avoids false attention while preserving real permission prompts, including when Auto is toggled inside the terminal. Upstream issue anomalyco/opencode#47545 documents the same ordering; warpdotdev/opencode-warp#26 uses a 500 ms notification grace.

Linked Issue

Fixes #18950. Adapts and credits brennanb2025's root outcome proposal in #23105 to the current terminal-owned lifecycle. This does not replace that PR's broader older-server and reader work.

Visual Proof

Real OpenCode v2.0.16 in an isolated, hidden Orca folder workspace on macOS. These are CDP screenshots; no window was shown or focused.

Before: the exact previous reporter displays Done beside a genuine rate-limit failure.

Before

After: the same failure displays Failed.

After

A user-stopped real turn displays Interrupted.

Stopped

A genuine unanswered permission still displays Needs input.

Manual permission

Testing

  • I manually tested these changes locally
  • Automated tests added/updated, or explained why not below

Real CLI --standalone with isolated HOME and all four XDG directories: a Muse free model returned a rate-limit error; a Fledge turn was interrupted with two Escape presses; Auto ran three harmless printf tool calls without intervention; a manual permission waited, was approved, and finished. Baseline Auto status observations included waiting; candidate observations contained only working/done. Raw provider events confirmed requests and automatic replies rather than a run that bypassed permissions. Private PTY captures were scanned for secrets.

The four lifecycle/store-publication suites passed 93 tests before the permission change; the final combined terminal ownership, permission, and host normalizer suites passed all 117 tests. pnpm tc:node, changed-code quality checks, formatting, whitespace checks, and the Electron/relay/CLI build phases passed. The full build stopped at mobile web because this worktree lacks react-native-web/expo-router dependencies. Windows/WSL and live SSH validation are pending; those platforms are not claimed tested.

Review

The invariant is that a completed root outcome belongs to its current turn, and only an unanswered provider permission needs input. Failure modes covered include stale session data inside the ending-event callback, a whole turn missed during plugin unload, child work continuing after root failure, and automatic permission replies. The execution host normalizer owns the result for native and relay consumers; optional payload fields preserve mixed-version compatibility. Existing 100 ms polling and bounded memory remain unchanged; permission settling adds no subprocess or timer. Windows/WSL and SSH remain pending real validation.

Agent skill upstream boundary

  • Not applicable, or this change follows docs/reference/agent-skill-sharing-upstream-boundary.md and copies or mechanically translates no upstream skill-installer source, tests, fixtures, registry entries, path tables, comments, or documentation.

Notes

No renderer styling, remote stream opcode, platform-specific command, or reader-side status precedence changed. Older plugin payloads continue to normalize without an invented outcome. Auto replies taking longer than 500 ms can still require attention until answered; this is a bounded downstream workaround for the upstream event ordering.

Checklist

  • This PR is small and focused
  • I explained what changed and why (ELI5, the user-facing before/after, the mechanism, and why over the alternatives)
  • Before/after screenshots or videos attached for UI changes, or N/A with reason
  • Self-reviewed for correctness, security, and performance
  • Cross-platform, SSH/remote, and path/shortcut impact considered (or N/A)
  • pnpm lint, pnpm typecheck, pnpm test, and pnpm build pass (or CI will cover; local preferred)

@nwparker
nwparker force-pushed the nwparker/OpenCode-Agent-Status branch from 8796515 to 5fc4101 Compare October 2, 2026 09:57
@nwparker
nwparker marked this pull request as ready for review October 2, 2026 12:01
@coderabbitai

coderabbitai Bot commented Oct 2, 2026

Copy link
Copy Markdown
Contributor

Warning

Review limit reached

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Next included review available in 29 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used all 10 included reviews currently available.

Learn how review limits work.

Review configuration:

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Advanced

Run ID: 1c6678d0-83e7-455f-a1cd-c99d665520fc

📥 Commits

Reviewing files that changed from the base of the PR and between efbf651 and 5fc4101.

📒 Files selected for processing (7)
  • src/main/agent-hooks/server-opencode-normalization.test.ts
  • src/main/opencode/hook-plugin-opencode2-tui-ownership.test.ts
  • src/main/opencode/opencode-tui-session-fixture.ts
  • src/main/opencode2/status-plugin-tui-source.ts
  • src/shared/agent-hook-listener/providers/opencode-family-events.ts
  • src/shared/agent-hook-listener/providers/opencode-family-tool-fields.ts
  • src/shared/opencode-permission-status.test.ts
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Autopilot is currently an internal CodeRabbit preview.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@nwparker
nwparker merged commit 8765f8c into main Oct 2, 2026
35 of 36 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: OpenCode Auto mode sends repeated false permission notifications

1 participant