Describe the bug
We are building an internal coding agent on top of OpenCode. OpenCode stays on our trusted host, and Daytona provides the isolated computer where the repository tools run.
The remote file and shell tools work well, and we were able to resume the same sandbox after restarting OpenCode. The blocker is the Git return path.
When an OpenCode session becomes idle, the Daytona plugin starts autoCommitAndPull(). The Daytona handler awaits that work internally, but OpenCode dispatches generic plugin events without awaiting the returned promise. The plugin also catches sync failures and only writes them to its own log. As a result, a host can receive the terminal session.idle event and close the run before the Daytona changes have reached the local Git repository.
In our live test, the coding turn finished successfully while the Git handoff was still running. That makes it impossible for a supervisor to distinguish “the agent finished and the change is safely back” from “the model finished but Git is still pending or failed.”
Current source:
Which package or app?
packages/opencode-plugin, published as @daytona/opencode@0.191.0.
To Reproduce
- Start OpenCode 1.18.16 in a normal Git worktree with
@daytona/opencode@0.191.0.
- Let the plugin create a sandbox and have OpenCode change a tracked file through the Daytona tools.
- Observe the
session.idle event from the host and treat it as the end of the coding turn.
- Exit or close the supervised run immediately after that event.
- The local
opencode/N branch may not contain the sandbox change yet. If the Git handoff fails, the failure is logged by the plugin but is not returned to the caller that observed the completed turn.
We also hit two related problems on this path:
- The first noninteractive Git sync stopped at SSH host verification for
ssh.app.daytona.io. The integration did not provide a trusted host-key path that our supervisor could verify without trust on first use.
- The plugin binds tools and session events to
ctx.project.worktree, even though OpenCode provides the active ctx.worktree. In a linked-worktree setup, this can select a previously persisted checkout instead of the active one. See session events, custom tools, and OpenCode's plugin context.
Expected behavior
The native integration should provide one completion boundary that a host can await and that:
- Does not report success until the sandbox commit has reached the intended local worktree.
- Returns a Git failure to the host in a structured way.
- Uses the active OpenCode worktree.
- Supports noninteractive, independently verifiable SSH host trust.
This does not need to be tied to session.idle if OpenCode's event contract cannot provide that guarantee. An explicit native sync operation or another official lifecycle hook would also work, as long as the result is observable and failure-bearing.
Screenshots
Not applicable. The public source links and steps above reproduce the lifecycle gap.
Environment
- Package/app + version:
@daytona/opencode@0.191.0
- Daytona SDK version:
@daytona/sdk@0.163.0
- OpenCode version:
1.18.16
- Runtime: Node.js
24.15.0
- Host OS: macOS
26.5.2
Additional context
A clean install of @daytona/opencode@0.191.0 currently reports 5 high vulnerabilities through @daytona/sdk@0.163.0 when run with npm audit --audit-level=high, with fixAvailable: false. We did not include security-sensitive Git credential details here because this repository's security policy asks for those to be reported privately.
Happy to help test a candidate release against the full create, edit, return, resume, and cleanup lifecycle.
Describe the bug
We are building an internal coding agent on top of OpenCode. OpenCode stays on our trusted host, and Daytona provides the isolated computer where the repository tools run.
The remote file and shell tools work well, and we were able to resume the same sandbox after restarting OpenCode. The blocker is the Git return path.
When an OpenCode session becomes idle, the Daytona plugin starts
autoCommitAndPull(). The Daytona handler awaits that work internally, but OpenCode dispatches generic plugin events without awaiting the returned promise. The plugin also catches sync failures and only writes them to its own log. As a result, a host can receive the terminalsession.idleevent and close the run before the Daytona changes have reached the local Git repository.In our live test, the coding turn finished successfully while the Git handoff was still running. That makes it impossible for a supervisor to distinguish “the agent finished and the change is safely back” from “the model finished but Git is still pending or failed.”
Current source:
Which package or app?
packages/opencode-plugin, published as@daytona/opencode@0.191.0.To Reproduce
@daytona/opencode@0.191.0.session.idleevent from the host and treat it as the end of the coding turn.opencode/Nbranch may not contain the sandbox change yet. If the Git handoff fails, the failure is logged by the plugin but is not returned to the caller that observed the completed turn.We also hit two related problems on this path:
ssh.app.daytona.io. The integration did not provide a trusted host-key path that our supervisor could verify without trust on first use.ctx.project.worktree, even though OpenCode provides the activectx.worktree. In a linked-worktree setup, this can select a previously persisted checkout instead of the active one. See session events, custom tools, and OpenCode's plugin context.Expected behavior
The native integration should provide one completion boundary that a host can await and that:
This does not need to be tied to
session.idleif OpenCode's event contract cannot provide that guarantee. An explicit native sync operation or another official lifecycle hook would also work, as long as the result is observable and failure-bearing.Screenshots
Not applicable. The public source links and steps above reproduce the lifecycle gap.
Environment
@daytona/opencode@0.191.0@daytona/sdk@0.163.01.18.1624.15.026.5.2Additional context
A clean install of
@daytona/opencode@0.191.0currently reports 5 high vulnerabilities through@daytona/sdk@0.163.0when run withnpm audit --audit-level=high, withfixAvailable: false. We did not include security-sensitive Git credential details here because this repository's security policy asks for those to be reported privately.Happy to help test a candidate release against the full create, edit, return, resume, and cleanup lifecycle.