Skip to content

OpenCode sessions can finish before Daytona returns the Git changes #46

Description

@geoff-ux

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

  1. Start OpenCode 1.18.16 in a normal Git worktree with @daytona/opencode@0.191.0.
  2. Let the plugin create a sandbox and have OpenCode change a tracked file through the Daytona tools.
  3. Observe the session.idle event from the host and treat it as the end of the coding turn.
  4. Exit or close the supervised run immediately after that event.
  5. 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:

  1. 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.
  2. 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:

  1. Does not report success until the sandbox commit has reached the intended local worktree.
  2. Returns a Git failure to the host in a structured way.
  3. Uses the active OpenCode worktree.
  4. 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions