This repository is the opencode-xk maintenance fork. It is not the official OpenCode repository. Changes meant for this fork may include XK-* build behavior and workflow stability work. Changes meant for upstream OpenCode must be split onto a fresh branch from upstream/dev and must not include fork branding or XK-* versioning.
- Session, workflow, recovery, retry, task, and subagent stability
- CLI/TUI input responsiveness and prompt submission correctness
- MCP/tool boundary correctness
- Multi-window notification and sync reliability
- Low-risk performance fixes
- Documentation for fork-specific build and workflow behavior
When preparing a pull request for anomalyco/opencode:
- Keep the PR focused on one behavior fix.
- Base the branch on
upstream/dev, not this fork'sdevbranch. - Remove all
XK-*versioning and fork-specific branding. - Include targeted tests that run in the official repository.
- Do not include local
AGENTS.mdworkflow rules or fork README changes.
For this fork, the best contributions are narrow stability fixes with clear reproduction steps and focused verification. Common useful changes include:
- Bug fixes
- Improvements to agent workflow stability
- Task, subagent, retry, recovery, and sync fixes
- Fixes for environment-specific quirks
- Documentation improvements
Large UI or core product features should start as a design issue before implementation.
For official OpenCode contribution opportunities, use the upstream issue tracker:
Note
PRs that ignore these guardrails will likely be closed.
Want to take on an issue? Leave a comment and a maintainer may assign it to you unless it is something we are already working on.
New providers shouldn't require many if ANY code changes, but if you want to add support for a new provider first make a PR to: https://github.com/anomalyco/models.dev
-
Requirements: Bun 1.3+
-
Install dependencies and start the dev server from the repo root:
bun install bun dev
By default, bun dev runs OpenCode in the packages/opencode directory. To run it against a different directory or repository:
bun dev <directory>To run OpenCode in the root of the opencode repo itself:
bun dev .To compile a standalone executable:
./packages/opencode/script/build.ts --singleThen run it with:
./packages/opencode/dist/opencode-<platform>/bin/opencodeReplace <platform> with your platform (e.g., darwin-arm64, linux-x64).
- Core pieces:
packages/opencode: OpenCode core business logic & server.packages/opencode/src/cli/cmd/tui/: The TUI code, written in SolidJS with opentuipackages/app: The shared web UI components, written in SolidJSpackages/desktop: The native desktop app, built with Tauri (wrapspackages/app)packages/plugin: Source for@opencode-ai/plugin
During development, bun dev is the local equivalent of the built opencode command. Both run the same CLI interface:
# Development (from project root)
bun dev --help # Show all available commands
bun dev serve # Start headless API server
bun dev web # Start server + open web interface
bun dev <directory> # Start TUI in specific directory
# Production
opencode --help # Show all available commands
opencode serve # Start headless API server
opencode web # Start server + open web interface
opencode <directory> # Start TUI in specific directoryTo start the OpenCode headless API server:
bun dev serveThis starts the headless server on port 4096 by default. You can specify a different port:
bun dev serve --port 8080To test UI changes during development:
- First, start the OpenCode server (see Running the API Server section above)
- Then run the web app:
bun run --cwd packages/app devThis starts a local dev server at http://localhost:5173 (or similar port shown in output). Most UI changes can be tested here, but the server must be running for full functionality.
The desktop app is a native Tauri application that wraps the web UI.
To run the native desktop app:
bun run --cwd packages/desktop tauri devThis starts the web dev server on http://localhost:1420 and opens the native window.
If you only want the web dev server (no native shell):
bun run --cwd packages/desktop devTo create a production dist/ and build the native app bundle:
bun run --cwd packages/desktop tauri buildThis runs bun run --cwd packages/desktop build automatically via Tauri’s beforeBuildCommand.
Note
Running the desktop app requires additional Tauri dependencies (Rust toolchain, platform-specific libraries). See the Tauri prerequisites for setup instructions.
Note
If you make changes to the API or SDK (e.g. packages/opencode/src/server/server.ts), run ./script/generate.ts to regenerate the SDK and related files.
Please try to follow the style guide
Bun debugging is currently rough around the edges. We hope this guide helps you get set up and avoid some pain points.
The most reliable way to debug OpenCode is to run it manually in a terminal via bun run --inspect=<url> dev ... and attach
your debugger via that URL. Other methods can result in breakpoints being mapped incorrectly, at least in VSCode (YMMV).
Caveats:
- If you want to run the OpenCode TUI and have breakpoints triggered in the server code, you might need to run
bun dev spawninstead of the usualbun dev. This is becausebun devruns the server in a worker thread and breakpoints might not work there. - If
spawndoes not work for you, you can debug the server separately:- Debug server:
bun run --inspect=ws://localhost:6499/ --cwd packages/opencode ./src/index.ts serve --port 4096, then attach TUI withopencode attach http://localhost:4096 - Debug TUI:
bun run --inspect=ws://localhost:6499/ --cwd packages/opencode --conditions=browser ./src/index.ts
- Debug server:
Other tips and tricks:
- You might want to use
--inspect-waitor--inspect-brkinstead of--inspect, depending on your workflow - Specifying
--inspect=ws://localhost:6499/on every invocation can be tiresome, you may want toexport BUN_OPTIONS=--inspect=ws://localhost:6499/instead
If you use VSCode, you can use our example configurations .vscode/settings.example.json and .vscode/launch.example.json.
Some debug methods that can be problematic:
- Debug configurations with
"request": "launch"can have breakpoints incorrectly mapped and thus unusable - The same problem arises when running OpenCode in the VSCode
JavaScript Debug Terminal
With that said, you may want to try these methods, as they might work for you.
All PRs must reference an existing issue. Before opening a PR, open an issue describing the bug or feature. This helps maintainers triage and prevents duplicate work. PRs without a linked issue may be closed without review.
- Use
Fixes #123orCloses #123in your PR description to link the issue - For small fixes, a brief issue is fine - just enough context for maintainers to understand the problem
- Keep pull requests small and focused
- Explain the issue and why your change fixes it
- Before adding new functionality, ensure it doesn't already exist elsewhere in the codebase
If your PR includes UI changes, please include screenshots or videos showing the before and after. This helps maintainers review faster and gives you quicker feedback.
For non-UI changes (bug fixes, new features, refactors), explain how you verified it works:
- What did you test?
- How can a reviewer reproduce/confirm the fix?
Long, AI-generated PR descriptions and issues are not acceptable and may be ignored. Respect the maintainers' time:
- Write short, focused descriptions
- Explain what changed and why in your own words
- If you can't explain it briefly, your PR might be too large
PR titles should follow conventional commit standards:
feat:new feature or functionalityfix:bug fixdocs:documentation or README changeschore:maintenance tasks, dependency updates, etc.refactor:code refactoring without changing behaviortest:adding or updating tests
You can optionally include a scope to indicate which package is affected:
feat(app):feature in the app packagefix(desktop):bug fix in the desktop packagechore(opencode):maintenance in the opencode package
Examples:
docs: update contributing guidelinesfix: resolve crash on startupfeat: add dark mode supportfeat(app): add dark mode supportfix(desktop): resolve crash on startupchore: bump dependency versions
These are not strictly enforced, they are just general guidelines:
- Functions: Keep logic within a single function unless breaking it out adds clear reuse or composition benefits.
- Destructuring: Do not do unnecessary destructuring of variables.
- Control flow: Avoid
elsestatements. - Error handling: Prefer
.catch(...)instead oftry/catchwhen possible. - Types: Reach for precise types and avoid
any. - Variables: Stick to immutable patterns and avoid
let. - Naming: Choose concise single-word identifiers when they remain descriptive.
- Runtime APIs: Use Bun helpers such as
Bun.file()when they fit the use case.
For net-new functionality, start with a design conversation. Open an issue describing the problem, your proposed approach, and why it belongs in this stability-focused fork. Please wait for maintainer feedback before opening a large feature PR.
All issues must use one of our issue templates:
- Bug report — for reporting bugs (requires a description)
- Feature request — for suggesting enhancements (requires verification checkbox and description)
- Question — for asking questions (requires the question)
Blank issues are not allowed. There is no fork-owned bot that auto-closes issues, but maintainers may close issues that do not contain enough actionable information.
Issues may be flagged for:
- Not using a template
- Required fields left empty or filled with placeholder text
- AI-generated walls of text
- Missing meaningful content
If you believe your issue was incorrectly closed, add the missing context and ask a maintainer to reopen it.