Skip to content
Open
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
1 change: 1 addition & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ jobs:
shell: bash
run: |
set -euo pipefail
# Version bumps are reviewed separately; this workflow publishes package.json verbatim.
version="$(node -p "require('./package.json').version")"
if [[ ! "$version" =~ ^[0-9]+\.[0-9]+\.[0-9]+-beta\.[0-9]+$ ]]; then
echo "Expected package version X.Y.Z-beta.N, got: $version" >&2
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ dist/

# Local agent notes / environment-specific
AGENTS.md
.opencode/

# Graphify knowledge graph output
graphify-out/
6 changes: 0 additions & 6 deletions .opencode/opencode.json

This file was deleted.

110 changes: 32 additions & 78 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,80 +1,34 @@
# Changelog

All notable changes to this project are documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [3.0.0-beta.2] - 2026-08-24

### Added

- OpenCode V2 `Plugin.define` entrypoint with native integration, catalog, and
`LanguageModelV3` registrations
- Native Cursor AgentService transport for images, cancellation, parallel tool
calls, bounded H2 pooling, and live tool-result continuation
- V2 loader, package, lifecycle, catalog, integration, and language-adapter tests
- Preserved OpenCode V1 adapter at the `./v1` package export; npm `latest`
remains on the `2.x` release line while V2 publishes under npm `beta`

### Changed

- OpenCode V2 now owns transcript reconstruction, credential persistence,
permissions, tool execution, and compaction; the V2 path no longer uses the
localhost OpenAI-compatible proxy
- Adapted from CasualDeveloper's V2 implementation in commit
`3af03f605243b58b33c2a9e1f9fa638280bca693`

## [2.2.0] - 2026-08-05

### Changed

- Phase-aware stall budget for post-tool resumes: silent tool continuations recover in **90s** instead of 180s
- H2 bridge workers pre-connect TLS/HTTP-2 at startup (faster first message after restart)
- Tool-call debounce reduced from 500ms → 250ms
- Title-gen model probe result persisted to disk (skip ~2.5s Zen probe after restart)

### Added

- `OPENCODE_CURSOR_POST_TOOL_PRE_OUTPUT_STALL_TIMEOUT_MS` (default 90s)
- Regression coverage for silent post-tool stall recovery

### Performance

- First message (`gpt-5.4-nano`): **8.5s → 4.8s** (−44%)
- First message (`cursor/default`): **6.1s → 3.7s** (−39%)

## [2.1.0] - 2026-08-05

### Changed

- Phase-aware stall budgets: cold thinking gets **180s** so reasoning models are not discarded mid-thought
- Recovery limits honor `MAX_STALL_RECOVERIES`
- `proxyTelemetry` exported for observability and tests

### Added

- `OPENCODE_CURSOR_PRE_OUTPUT_STALL_TIMEOUT_MS` (default 180s)

## [2.0.0] - 2026-08-04

### Fixed

- Root-cause restate loop: tool-result follow-ups no longer look like user interrupts that discard parked bridges
- Frozen sessions: visible-text stalls surface an error in ~90s instead of holding a step for up to 12 minutes
- Infinite recovery restarts capped by forward progress
- Model discovery retries 3× on transient bridge failures

### Removed

- Accumulated loop detectors, loop-break notes, compaction re-framing, and auto-continue nudges (~1,450 lines)

## [1.4.0] - 2026-08-03

See [GitHub Releases](https://github.com/otto-assistant/opencode-cursor/releases) for earlier notes.

[2.2.0]: https://github.com/otto-assistant/opencode-cursor/compare/v2.1.0...v2.2.0
[3.0.0-beta.2]: https://github.com/otto-assistant/opencode-cursor/compare/v2.2.0...v3.0.0-beta.2
[2.1.0]: https://github.com/otto-assistant/opencode-cursor/compare/v2.0.0...v2.1.0
[2.0.0]: https://github.com/otto-assistant/opencode-cursor/compare/v1.4.0...v2.0.0
[1.4.0]: https://github.com/otto-assistant/opencode-cursor/releases/tag/v1.4.0
This channel targets OpenCode V2 exclusively.

## Unreleased

Live release validation remains pending for instruction precedence, opaque-reasoning
replay, and continued work after automatic compaction, as recorded in
the [acceptance report](docs/opencode-v2-release-acceptance.md).

- Reconstruct authoritative host history through structured Cursor root blobs.
- Observe host tool, permission, question, and session events while forwarding
results only from the next authoritative model invocation.
- Use bounded, per-Run Node HTTP/2 workers with validated Connect completion.
- Preserve late reasoning signatures in durable host metadata for fresh replay.
- Report terminal input, output, cache, and reasoning counters with explicit
usage scope and separate checkpoint occupancy.
- Keep multi-invocation Run totals in durable provider metadata rather than
misreporting them as usage for the final host invocation. Verify the correction
against the pinned host's automatic compaction behavior.
- Preserve checkpoint-referenced opaque reasoning in durable host metadata and
restore its exact placement during replay. Reject ambiguous or changed new
roots rather than guessing their relationship to emitted output.
- Add deterministic pinned-host acceptance and opt-in synthetic live probes.
- Project host system instructions into ordered Cursor rules as well as history
roots. Add an explicit host contract for precedence and genuine tool outcomes.
Instruction delivery remains best effort; live acceptance is pending.
- Restrict this package to the native V2 plugin API and its runtime dependencies.

## 3.0.0-beta.2

- Native OpenCode V2 plugin, integration, catalog, and language-model APIs.
- Account-discovered Cursor models with exact model/variant routing.
- OpenCode-owned OAuth credentials, permissions, sessions, tools, and compaction.
75 changes: 60 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,20 @@ Use the models available to your Cursor account from OpenCode 2, including
Cursor private models, live model variants, image input, streaming, and tool
continuation.

This is the V2 beta line. OpenCode 1 users remain supported by the `2.x`
release on npm's `latest` tag; the beta package also exposes the preserved
legacy adapter as `@otto-assistant/opencode-cursor-oauth/v1` for migration
testing.
This package and the `beta` branch target OpenCode V2 exclusively. The channel
name identifies the OpenCode compatibility line; users of this channel require
a complete, release-ready plugin.

## Status

**Live release validation pending.** The local adapter includes the corrected
usage projection and opaque-reasoning replay. Host instructions use global rules
with an explicit host contract; their precedence remains best effort. Live
validation of these changes and sustained automatic compaction is still pending.
See the [acceptance report](docs/opencode-v2-release-acceptance.md) for evidence
and the remaining release requirements. The `beta` channel requires production
readiness for OpenCode V2 users.

- Plugin version: `3.0.0-beta.2`
- OpenCode channel: V2 beta
- Plugin API: pinned to the matching OpenCode beta build
Expand Down Expand Up @@ -79,16 +86,24 @@ The Cursor desktop application and `cursor-agent` CLI are not required.
OpenCode 2
└─ V2 integration and catalog APIs
└─ native LanguageModelV3 adapter
└─ Node HTTP/2 bridge pool
└─ request-scoped Node HTTP/2 worker
└─ Cursor AgentService
```

OpenCode owns provider selection, credentials, permissions, persistence, and
tool execution. Each user turn starts a Cursor AgentService Run from OpenCode's
active transcript. If Cursor requests a tool, that Run remains alive only until
OpenCode returns the matching result; terminal responses discard it. Cursor
checkpoints are not retained, while private Composer models and native Cursor
rate limits remain available.
tool execution. The adapter reconstructs structured history from OpenCode's
active transcript and can retain a bounded live Run across tool steps. Late
calls remain queued for delivery. Host events keep the stream open while tools
run; results come only from the next OpenCode checkpoint. History or account
changes discard the continuation. Access and billing remain subject to the
connected Cursor account.

Host system messages also become ordered, always-apply Cursor rules. This
delivers instructions through Cursor's context mechanism, but does not establish
the same precedence as an independently controlled system prompt.

See the [adapter decision and acceptance status](docs/opencode-v2-host-owned-adapter.md)
for the implementation lifecycle, evidence, and remaining live release gates.

### Model routing

Expand All @@ -102,13 +117,14 @@ the plugin refreshes discovery and asks OpenCode to reload the catalog.

### Lifecycle

The plugin starts a bounded HTTP/2 worker pool during V2 `setup()`. Disabling,
reloading, or shutting down the plugin stops:
V2 starts a Node worker lazily for each admitted Run. Disabling, reloading, or
shutting down a plugin instance stops its:

- active AgentService Runs
- HTTP/2 bridge workers
- pending OAuth polling
- catalog event subscriptions
- tool-observation subscriptions

## Development

Expand All @@ -117,6 +133,7 @@ npm test
npm run test:v2
npm run typecheck
npm run build
npm run test:v2-host
npm run test:package
npm run test:v2-loader
```
Expand All @@ -131,6 +148,21 @@ npm run verify
dependencies with lifecycle scripts disabled, imports it independently, and
loads that extracted package through the pinned `opencode2` beta.

The [Cursor capability probe](docs/opencode-v2-cursor-capability-probe.md)
compares tool restrictions and structured history on synthetic conversations.
Its offline tests run in `verify`; live Runs require a separate invocation.

### Beta release

Before dispatching the **Release V2 Beta** workflow, land a reviewed commit that
updates `package.json` to the next unused `X.Y.Z-beta.N` version and updates any
lockfiles changed by the package manager. Run the workflow from `beta` with
`dry_run` enabled first, then rerun the same commit with `dry_run` disabled to
publish.

The workflow does not bump versions or create release commits. It validates,
packs, and publishes the exact reviewed version to npm's `beta` dist-tag.

## Debugging

Enable plugin logs:
Expand All @@ -142,16 +174,14 @@ OPENCODE_CURSOR_DEBUG=1 opencode2
Optional AgentService controls:

- `OPENCODE_CURSOR_NATIVE_TOOL_SETTLE_MS`
- `OPENCODE_CURSOR_NATIVE_TOOL_WAIT_MS`
- `OPENCODE_CURSOR_PRE_OUTPUT_STALL_TIMEOUT_MS`
- `OPENCODE_CURSOR_POST_TOOL_PRE_OUTPUT_STALL_TIMEOUT_MS`
- `OPENCODE_CURSOR_STALL_TIMEOUT_MS`
- `OPENCODE_CURSOR_MAX_ACTIVE_RUNS`
- `OPENCODE_CURSOR_NATIVE_PARK_TTL_MS`
- `OPENCODE_CURSOR_DEFAULT_CONTEXT_WINDOW`
- `OPENCODE_CURSOR_DEFAULT_MAX_TOKENS`
- `OPENCODE_CURSOR_BRIDGE_POOL_MIN`
- `OPENCODE_CURSOR_BRIDGE_POOL_MAX`
- `OPENCODE_CURSOR_BRIDGE_POOL_DISABLED`

## Known beta constraints

Expand All @@ -162,6 +192,21 @@ Optional AgentService controls:
- Models without explicit Cursor context metadata use the configurable default
context and output limits listed above.
- The plugin relies on Cursor's private API, which can change without notice.
- The replacement has offline host acceptance and live Composer/Auto/Opus,
signed-reasoning restart, 452k mixed-history, and billing-comparison evidence.
Retained Runs reported cache reads; fresh long Runs did not show a warm-replay
saving. See the [release acceptance report](docs/opencode-v2-release-acceptance.md).
- Terminal inference and cache counters are retained in `cursor.turnUsage`
provider metadata. A Run spanning multiple host invocations has unknown
per-invocation usage, so OpenCode's built-in token and cost totals are incomplete
for those turns. Checkpoint occupancy and progress deltas remain separate.
- Signed and opaque reasoning have offline-verified persistence and restart
replay. Opaque blocks retain their exact data and placement, anchored to one
unchanged assistant message. Unmatched or ambiguous new blocks fail explicitly.
Signed reasoning also has live replay evidence; opaque reasoning does not yet.
- Host instructions are sent as ordered global rules and genuine system-history
roots, with an explicit rule for instruction priority and real host-tool use.
This is best-effort delivery, not verified replacement of Cursor's system prompt.

## License

Expand Down
Loading
Loading