Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 14 additions & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,9 @@ The **1.18 v2** API and **OpenCode 2.0** are source-incompatible:
actions, final error codes, `isRetryable: false` and bare `permission_denied`
end the turn. Final and auth failures reach both hosts as `APICallError` with
`x-should-retry: false`, a status below 500 and a message without OpenCode 1.x
retry triggers (`src/errors.ts`); the Connect code stays on `cause`.
retry triggers (`src/errors.ts`); the Connect code stays on `cause`. A
`hostRetryable` failure is the exception: an `APICallError` with
`isRetryable: true`, `x-should-retry: true` and no status, so both hosts retry.

## Context, identity and persistence

Expand Down Expand Up @@ -200,6 +202,17 @@ The **1.18 v2** API and **OpenCode 2.0** are source-incompatible:
- Drain a held Run before a fresh user turn. Rebuild late tool results from
host history; checkpoint resume would request the tool again. Never replay
side effects after the replay barrier or treat EOF as successful `stop`.
- Retry like Cursor CLI's Run loop: an attempt without its own checkpoint
resumes the turn's latest eligible one. Delivered tool results and follow-up
user messages revoke earlier checkpoints; queued frames use receipt order.
Stateful barriers survive host tool steps. Two resumed attempts that stream
without a new checkpoint end the turn. With
no checkpoint in the turn, a transient failure after only text or reasoning
is `hostRetryable` (the CLI resends the action). A silent drop immediately
after delivered host results may rebase from history only when every observed
exec has a completed result and no opaque activity occurred. Include all
completed tool steps; never resume their earlier checkpoint. Other barriers
stay final.
Missing-blob recovery is limited to the initial control-only checkpoint path
(`isSoleControlFrame`); unknown/mixed frames keep the normal replay barrier.
- Carry an uncheckpointed request only on its unchanged checkpoint; persist it
Expand Down
9 changes: 7 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,16 @@
- A turn stopped mid-step keeps its Cursor conversation and prompt cache at the next message, also after a restart ([#58](https://github.com/oakimov/cursor-opencode-provider/pull/58) by [@nkoynov](https://github.com/nkoynov), [#74](https://github.com/oakimov/cursor-opencode-provider/issues/74))
- On OpenCode 2, plain-text steers without files or skills can reach Cursor during a background-shell wait; queued messages are preserved after Stop and mixed tool continuations, and answered copies are deduplicated across restarts and retries while preserving later identical requests and neighboring attachments ([#57](https://github.com/oakimov/cursor-opencode-provider/pull/57) by [@nkoynov](https://github.com/nkoynov))
- On OpenCode 2, a steer that Cursor took after tool results is no longer sent twice when its Run drops and cannot be recovered; the retried step rebuilds from host history ([#92](https://github.com/oakimov/cursor-opencode-provider/pull/92) by [@nkoynov](https://github.com/nkoynov))
- Large file writes no longer fail after 120 s while the model is still composing them; a Run now fails only when Cursor sends nothing at all for that long ([#66](https://github.com/oakimov/cursor-opencode-provider/issues/66))
- Large file writes stay alive while Cursor is composing them and sending frames; like Cursor CLI, an active Run with no pending host work now retries after 30 seconds of complete silence ([#66](https://github.com/oakimov/cursor-opencode-provider/issues/66))
- Long-running tools keep their Cursor Run alive with the same exec heartbeats Cursor CLI sends
- Errors show Cursor's own explanation (for example "Request blocked by Anthropic …"), and a request Cursor marks as not retryable is no longer retried by OpenCode (OpenCode 2 sent it 11 times in testing; OpenCode 1.x resent a used-up usage limit five more times because of its message wording)
- Like Cursor CLI, errors that need your action (usage or rate limits, sign-in, pricing, API key, outdated client), a bare `permission_denied`, and authentication failures, including those before a Run opens, end the turn instead of being retried; on OpenCode 1.x this also covers final `internal`/`unknown` errors. Final Cursor details take precedence over token renewal ([#97](https://github.com/oakimov/cursor-opencode-provider/pull/97))
- Once the provider spends its retry budget or cannot safely replay a Run, OpenCode no longer starts another retry loop ([#97](https://github.com/oakimov/cursor-opencode-provider/pull/97))
- Once the provider spends its retry budget, or cannot replay a Run without repeating a tool call or other side effect, OpenCode no longer starts another retry loop ([#97](https://github.com/oakimov/cursor-opencode-provider/pull/97))
- Like Cursor CLI, a Run that drops or stalls after showing only text or reasoning, before Cursor saved a checkpoint, is retried by OpenCode instead of ending the turn, and the request reaches Cursor in that retry instead of with your next message. A retry after a checkpoint resumes the turn's latest checkpoint, and two resumes that save nothing end the turn ([#100](https://github.com/oakimov/cursor-opencode-provider/issues/100), reported by [@nkoynov](https://github.com/nkoynov))
- Retry counts now follow Cursor CLI: up to 10 transport retries (including streams that end without `turn_ended`) and 3 server retries per user turn, shared across checkpoints and OpenCode retries, including OpenCode 2's interruption notices with appended host reminders. `CURSOR_ENDLESS_RETRIES=1` or `true` bypasses count limits while preserving replay guards and the no-progress and stall cutoffs ([#103](https://github.com/oakimov/cursor-opencode-provider/pull/103))
- A dropped or stalled Run with an unfinished tool display row can be retried when no exec or started tool lifecycle arrived; the row closes without executing a tool ([#103](https://github.com/oakimov/cursor-opencode-provider/pull/103))
- Tool recovery accepts checkpoints received while a completed result drains, and retains completed results across resumed Runs even when exec IDs restart ([#103](https://github.com/oakimov/cursor-opencode-provider/pull/103))
- Interrupted Runs retain their checkpoint across credential renewal, including a rejected login on an untouched resumed attempt. A drop immediately after completed tools can recover from complete host history before new output, without resuming a checkpoint predating their results. Other stateful activity remains a replay barrier. Follow-ups accept checkpoints received while opening the new Run. An ambiguous replacement upload ends the turn instead of retrying through an older checkpoint, including in endless mode ([#103](https://github.com/oakimov/cursor-opencode-provider/pull/103))
- On macOS, a shell command that printed nothing before being moved to the background no longer reports `head: illegal byte count -- 0`
- A tool that is still running no longer lets its Cursor Run expire at the inactivity limit. The Run stays open until the tool finishes, for up to four hours from when that tool started
- An edit Cursor starts announcing shows its tool row while the arguments are still streaming. If that call never runs, the row closes instead of being left for the host to execute ([#73](https://github.com/oakimov/cursor-opencode-provider/issues/73))
Expand Down
Loading
Loading