libs/opencode-plugin/README.md
This is an OpenCode plugin that automatically runs OpenCode sessions in Daytona sandboxes. Each session has its own remote sandbox which is automatically synced to a local git branch.
To add the plugin to a project, edit opencode.json in the project directory:
{
"$schema": "https://opencode.ai/config.json",
"plugin": ["@daytona/opencode"]
}
Now that the Daytona plugin is in the plugins list, it will automatically be downloaded when OpenCode starts.
To install the plugin globally, edit ~/.config/opencode/opencode.json.
This plugin requires a Daytona account and Daytona API key to create sandboxes.
Set your Daytona API key and URL as environment variables:
export DAYTONA_API_KEY="your-api-key"
Or create a .env file in your project root:
DAYTONA_API_KEY=your-api-key
Before starting OpenCode, ensure that your project is a git repository:
git init
Now start OpenCode in your project using the OpenCode command:
opencode
To check that the plugin is working, type pwd in the chat. You should see a response like /home/daytona/project, and a toast notification that a new sandbox was created.
OpenCode will create new branches using the format opencode/1, opencode/2, etc. To work with these changes, use normal git commands in a separate terminal window. List branches:
git branch
Check out OpenCode's latest changes on your local system:
git checkout [branch]
To view live logs from the plugin for debugging, run this command in a separate terminal:
tail -f ~/.local/share/opencode/log/daytona.log
The plugin uses git to synchronize files between the sandbox and your local system. This happens automatically and in the background, keeping your copy of the code up-to-date without exposing your system to the agent.
When a new Daytona sandbox is created:
opencode branch, mirroring the checked out local branch.sandbox remote is added to the local repository using an SSH connection to the sandbox.HEAD of the local repository is pushed to opencode, and the sandbox repository is reset to match this initial state.Each time the agent makes changes:
opencode branch.opencode/1, opencode/2, etc. This keeps both environments in sync while isolating changes from different sandboxes in separate local branches.The plugin only synchronizes changes from the sandbox to your system. To pass local changes to the agent, commit them to a local branch, and start a new OpenCode session with that branch checked out.
[!CAUTION] When changes are synchronized to local
opencodebranches, any locally made changes will be overwritten.
The plugin keeps track of which sandbox belongs to each OpenCode project using local state files. This data is stored in a separate JSON file for each project:
~/.local/share/opencode/storage/daytona/[projectid].json.%LOCALAPPDATA%\opencode\storage\daytona\[projectid].json.Each JSON file contains the sandbox metadata for each session in the project, including when the sandbox was created, and when it was last used.
The plugin uses XDG Base Directory specifically to resolve the path to this directory, using the convention set by OpenCode.
This plugin is part of the Daytona monorepo.
First, clone the Daytona monorepo:
git clone https://github.com/daytonaio/daytona
cd daytona
Install dependencies:
yarn install
To modify the plugin, edit the source code files in libs/opencode-plugin/.opencode.
To test the OpenCode plugin, create a test project to run OpenCode in:
mkdir ~/myproject
cd myproject
Add a symlink from the project directory to the plugin source code:
ln -s [ABSOLUTE_PATH_TO_DAYTONA]/libs/opencode-plugin/.opencode .opencode
Initialize git to enable file syncing:
git init
Start OpenCode in the test project:
opencode
Use the instructions from Running OpenCode above to check that the plugin is running and view live logs for debugging.
[!NOTE] When developing locally with a symlink, OpenCode loads the TypeScript source directly, so no build step is required.
Build the plugin:
npx nx run opencode-plugin:build
This compiles the TypeScript source files in .opencode/ to JavaScript in dist/.opencode/.
After building, create a test project and add a plugin file to load the built plugin (replace [ABSOLUTE_PATH_TO_DAYTONA] with your clone path, e.g. /Users/you/daytona):
mkdir -p ~/myproject && cd ~/myproject
mkdir -p .opencode/plugins
cat > .opencode/plugins/daytona-local.js << 'EOF'
module.exports = require('[ABSOLUTE_PATH_TO_DAYTONA]/dist/libs/opencode-plugin/.opencode/plugin')
EOF
Initialize git to enable file syncing, and start OpenCode:
git init
opencode
Log into npm:
npm login
Publish the compiled JavaScript package to npm:
npx nx run opencode-plugin:publish
This will publish to npm with public access and use the version number from package.json.
libs/opencode-plugin/
├── .opencode/ # Source TypeScript files
│ ├── plugin/
│ │ ├── daytona/ # Main Daytona integration
│ │ │ └── ...
│ │ └── index.ts # Plugin entry point
├── dist/ # Build output
│ └── .opencode/ # Compiled JavaScript files
├── .gitignore
├── .npmignore
├── package.json # Package metadata (includes main/types)
├── project.json # Nx build configuration
├── tsconfig.json # TypeScript config
├── tsconfig.lib.json # TypeScript config for library build
└── README.md
Apache-2.0