This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
# Install dependencies
bun install
# Start TUI development (runs in packages/opencode by default)
bun dev
# Run TUI against a specific directory
bun dev <directory>
bun dev . # Run in repo root
# Start headless API server (port 4096)
bun dev serve
bun dev serve --port 8080 # Custom port
# Start server + web interface
bun dev web
# Typecheck entire monorepo
bun turbo typecheck
# Run tests (from packages/opencode, not root)
cd packages/opencode && bun test
bun test test/tool/tool.test.ts # Single test file
# Build standalone executable
./packages/opencode/script/build.ts --single
# Output: ./packages/opencode/dist/opencode-<platform>/bin/opencode
# Regenerate SDK after server API changes
./script/generate.ts
# Web app dev server (requires API server running)
bun run --cwd packages/app dev
# Desktop app (requires Tauri/Rust)
bun run --cwd packages/desktop tauri devMonorepo Structure:
packages/opencode- Core engine: CLI, server, agent logic, TUI (SolidJS + opentui)packages/app- Web UI components (SolidJS + Vite)packages/desktop- Native Tauri v2 desktop apppackages/web- Documentation site (Astro + Starlight)packages/ui- Reusable UI component librarypackages/sdk/js- Auto-generated JavaScript SDK from OpenAPIpackages/plugin- Plugin system API (@opencode-ai/plugin)
Core Patterns:
- Runtime: Bun 1.3.5+ with TypeScript ESM
- AI SDK: Vercel AI SDK with multi-provider support (Anthropic, OpenAI, Google, Bedrock, etc.)
- Server: Hono on port 4096
- Validation: Zod schemas for all inputs
- Namespace organization:
Tool.define(),Session.create(),App.provide() - Logging:
Log.create({ service: "name" }) - Storage:
Storagenamespace for persistence
Two-Mode Agent System:
buildagent: Full access for developmentplanagent: Read-only for analysis/exploration
- Keep logic in single functions unless composable/reusable
- Avoid destructuring: use
obj.ainstead ofconst { a } = obj - Prefer
.catch()overtry/catch - Prefer
constoverlet; use ternaries instead of if/else assignment - Avoid
elsestatements; use early returns - Use single-word variable names when descriptive enough
- Use Bun APIs:
Bun.file(),Bun.spawn(), etc. - Avoid
anytype; use precise types - Result patterns for error handling in tools
- All PRs must reference an existing issue (
Fixes #123) - Conventional commit prefixes:
feat:,fix:,docs:,chore:,refactor:,test: - Optional scope:
feat(app):,fix(desktop): - Keep PRs small and focused
- UI changes require screenshots/videos
- Logic changes require verification steps