Skip to content

feat!: migrations for opencode v2 - #20

Closed
valentimarco wants to merge 5 commits into
Mte90:masterfrom
valentimarco:feat/v2-port
Closed

valentimarco wants to merge 5 commits into
Mte90:masterfrom
valentimarco:feat/v2-port

Conversation

@valentimarco

Copy link
Copy Markdown

Why

Opencode2 while in early alpha doesnt give the option to continue the conv for any error occurred externally and i think is out of scope...

Changes

Ports from v1 hooks-object API to v2 promise-plugin API:

  • Event pump via AsyncIterable instead of event hook callback
  • Flattened SDK calls (session.prompt({sessionID, text}))
  • Assistant text accumulated from streaming events (no message history access)
  • New guards: permission-aware pausing, subagent-aware waiting, failure-recovery arming
  • All detection/recovery features preserved: stall watchdog, failure recovery, tool-call-as-text, ready-to-continue nudges, hallucination loop guard, etc.

Use of AI

The migration was done entirely by the AI with small steering in the architecture of the new SDK.
The code at the moment of writing was not reviewed bc of my little knowleadge of Typescript and Javascript so expect stupid error

Why make PR than?

I think is a great plugin and this migration can be used as start point

Tested against opencode2 v0.0.0-beta-18050, @opencode-ai/plugin 0.0.0-next-17403.

- Add src/v2/index.ts: full port using Plugin.define + ctx.event.subscribe()
- Add docs/v2/migration.md: migration notes and API mapping
- Update README.md: v2 callout banner and install instructions

Ports from v1 hooks-object API to v2 promise-plugin API:
- Event pump via AsyncIterable instead of event hook callback
- Flattened SDK calls (session.prompt({sessionID, text}))
- Assistant text accumulated from streaming events (no message history access)
- New guards: permission-aware pausing, subagent-aware waiting, failure-recovery arming
- All detection/recovery features preserved: stall watchdog, failure recovery,
  tool-call-as-text, ready-to-continue nudges, hallucination loop guard, etc.

Tested against opencode2 v0.0.0-beta-18050, @opencode-ai/plugin 0.0.0-next-17403.
@Mte90

Mte90 commented Aug 25, 2026

Copy link
Copy Markdown
Owner

It is not clear in the doc for migration to v2 how to install that version.
Ideally the plugin should identify the opencode version and use the right one but also we need tests.

@valentimarco

Copy link
Copy Markdown
Author

At the Moment the SDK doesnt provided a version but i Will monitor the situation.
The docs is for those who want to install It but i can be more precise

…ilure

Replace session.prompt() with session.synthetic() which injects a visible
message into the session timeline (shown in TUI) so the user knows the
plugin intervened. The synthetic message also resumes the session when
resume=true, replacing the separate prompt call.

Notification text per recovery path:
- "auto-resume: stalled — retrying" (watchdog stall)
- "auto-resume: recovering: <kind>" (tool-text, ready-to-continue, etc.)
- "auto-resume: abort+resume escalation" (loop guard / max retries)

Falls back to session.prompt() if synthetic is not available (beta compat).
12/12 typecheck + smoke tests pass.
- import from @opencode/plugin (stable package; @opencode-ai/plugin was beta-only)
- read authoritative assistant text from ctx.session.context() at idle time,
  keeping the delta accumulation for liveness
- pass an AbortSignal to ctx.event.subscribe() and abort it on cleanup
- honour session.execution.interrupted data.reason (only "user" disables recovery)
- drop the beta-era nested synthetic({ path, body }) fallback
- document session.reverted as v1 legacy (v2 emits session.revert.*)
- docs/v2/installing.md: step-by-step v2 install (drop-in + plugins entry),
  options reference, verification and troubleshooting
- docs/v2/migration.md: verified stable-vs-beta delta (package rename, event
  surface, new session methods, subscribe signal) and updated test notes
- README: point at the new install guide and stable API
A local .ts plugin is imported by opencode with normal ESM resolution and the
plugin dependency graph is resolved at server startup, so @opencode/plugin must
be installed in the config dir (~/.config/opencode) and opencode restarted.
Without it the log shows "failed to load plugin ... Cannot find package
'@opencode/plugin'".
@valentimarco

Copy link
Copy Markdown
Author

Update: upgrade to 2.0.5 api with imporved TUI msg when kicks in. Also add docs for installing, idk if its better to add the first step as git clone let me know

famewolf added a commit to famewolf/opencode-auto-resume that referenced this pull request Sep 28, 2026
- add row for 875d7e4: the v2 'Step interrupted' / synthetic-continue fix
- record that 875d7e4 is a strict superset of upstream PR Mte90#20 (b5fd8aa is a
  direct ancestor), so Mte90#37 already contains everything in Mte90#20
@famewolf

Copy link
Copy Markdown
Contributor

@valentimarco — the v2 port in this PR is yours and stays credited here.

Following up on the question in #33 about the two v2 PRs: my #37 now contains everything in this PR plus five additional commits. b5fd8aa (this PR's head) is a direct ancestor of 875d7e4 (#37's head), so #37 is a strict superset — nothing from this PR is dropped.

That means there is no cherry-picking to reconcile, and I am not asking you to port anything by hand. It also means one of the two is redundant:

  • If you are happy for Add OpenCode v2 port (src/v2) + OOC lock parity #37 to be the one that lands, I will close this PR as superseded and keep the port credited to you here.
  • If you would rather this PR stays canonical, say so and I will rebase my five commits onto it and open that instead.

The five commits are v2-only and touch src/v2/index.ts alone; v1 is unaffected either way. Attribution is the same in both directions.

@Mte90 Mte90 closed this Sep 29, 2026
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.

3 participants