Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
239 changes: 239 additions & 0 deletions analysis-and-understanding/01-high-level-architecture.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
262 changes: 262 additions & 0 deletions analysis-and-understanding/02-session-message-flow.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
183 changes: 183 additions & 0 deletions analysis-and-understanding/03-package-dependency-graph.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
373 changes: 373 additions & 0 deletions analysis-and-understanding/04-core-modules.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
151 changes: 151 additions & 0 deletions analysis-and-understanding/05-event-bus-instance-state.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
280 changes: 280 additions & 0 deletions analysis-and-understanding/06-data-model-erd.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
166 changes: 166 additions & 0 deletions analysis-and-understanding/07-startup-bootstrap.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
315 changes: 315 additions & 0 deletions analysis-and-understanding/08-tool-invocation-permission.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
281 changes: 281 additions & 0 deletions analysis-and-understanding/09-skills-plugins-injection.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
283 changes: 283 additions & 0 deletions analysis-and-understanding/10-skills-plugins-runtime-sequence.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
255 changes: 255 additions & 0 deletions analysis-and-understanding/12-desktop-bootstrap-sequence.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
85 changes: 85 additions & 0 deletions analysis-and-understanding/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
# OpenCode - System Diagrams

Generated by reading `opencode/` (the open-source AI coding agent by anomalyco).
Rendered as Mermaid SVGs using the `tokyo-night` theme.

## What OpenCode is

A terminal-first, provider-agnostic AI coding agent with a **client/server
architecture**. The headless server (Hono on Bun) runs the agent loop, talks to
LLMs, executes tools, and streams events; multiple clients (TUI, desktop
Tauri app, web, SDK) drive it via HTTP/WebSocket.

Core is written in TypeScript with heavy use of [Effect](https://effect.website)
for composable services, `Layer`s and per-directory `InstanceState` scoped
caches. Persistence is SQLite via Drizzle ORM.

## Diagrams

| # | File | What it shows |
|---|------|---------------|
| 01 | [`01-high-level-architecture.svg`](./01-high-level-architecture.svg) | 10,000-ft view: clients → SDK → server → core → services → persistence/external |
| 02 | [`02-session-message-flow.svg`](./02-session-message-flow.svg) | Sequence: user prompt → LLM stream → tool calls → permission → events → render |
| 03 | [`03-package-dependency-graph.svg`](./03-package-dependency-graph.svg) | How the monorepo's ~20 packages depend on each other (runtime / SDK / UI / platform) |
| 04 | [`04-core-modules.svg`](./04-core-modules.svg) | Inside `packages/opencode/src`: entry, server, session, agent, tools, providers, storage |
| 05 | [`05-event-bus-instance-state.svg`](./05-event-bus-instance-state.svg) | Bus `PubSub` wiring, `InstanceState` per-directory scoping, GlobalBus fan-out |
| 06 | [`06-data-model-erd.svg`](./06-data-model-erd.svg) | SQLite schema: workspace, project, session, part (message-v2), todo, permission, snapshot |
| 07 | [`07-startup-bootstrap.svg`](./07-startup-bootstrap.svg) | `index.ts` → yargs → log/heap → first-run migration → command dispatch → Effect layers |
| 08 | [`08-tool-invocation-permission.svg`](./08-tool-invocation-permission.svg) | State machine for a single tool call: permission gate, exec dispatch, feedback to LLM |
| 09 | [`09-skills-plugins-injection.svg`](./09-skills-plugins-injection.svg) | How skills are discovered/loaded and how plugins register hooks into a session |
| 10 | [`10-skills-plugins-runtime-sequence.svg`](./10-skills-plugins-runtime-sequence.svg) | Per-turn sequence: system prompt injection, `tool.definition`, `permission.ask`, `skill` tool execution, compaction hooks |
| 11 | [`11-desktop-architecture-tauri-vs-electron.svg`](./11-desktop-architecture-tauri-vs-electron.svg) | Side-by-side: Tauri (Rust shell + bundled sidecar + `tauri-specta` IPC) vs Electron (Node main + embedded `virtual:opencode-server` + `window.api` contextBridge), both over the same SolidJS `@opencode-ai/app` |
| 12 | [`12-desktop-bootstrap-sequence.svg`](./12-desktop-bootstrap-sequence.svg) | Shared startup state machine: port/password pick → sidecar spawn / `Server.listen` → `ServerReadyData` → parallel health poll + sqlite migration → optional loading window → MainWindow + `awaitInitialization` stream |

## Key findings

### Client/server split
`packages/opencode/src/cli/cmd/serve.ts` starts a Hono server
(`server/server.ts`). The TUI (`cli/cmd/tui/`) is an Ink/React React app that
talks to the same server over HTTP/WebSocket — as do the desktop (Tauri) and
web clients via the generated `sdk/js` client. This is why OpenCode can run
headlessly and be driven remotely.

### Effect-based service graph
Every subsystem (`Bus`, `Config`, `Provider`, `Agent`, `Skill`, `Plugin`,
`Storage`, `Session`) is an `Effect.Service` with a `Layer`. `makeRuntime`
(`src/effect/run-service.ts`) deduplicates layers via a shared `memoMap`;
`InstanceState` (`src/effect/instance-state.ts`) uses `ScopedCache` keyed by
directory so each open project gets its own state with automatic cleanup.

### Streaming session processor
`session/processor.ts` is the engine: it wraps `Provider.streamText`, routes
`text` / `tool-call` / `reasoning` deltas into message parts, persists them via
Drizzle, and republishes over the `Bus`. It handles compaction, retries,
tool-call deduplication, and a "doom-loop" threshold.

### Tool registry + permission
`tool/registry.ts` exposes all built-in tools plus MCP-proxied ones. Each
invocation passes through `permission/` which can match `allow`/`ask`/`deny`
rules. An `ask` decision publishes a `question` event on the bus; a TUI/desktop
client renders a prompt and posts the answer back.

### Persistence
All state lives in SQLite (`storage/db.bun.ts`) with Drizzle schemas in
`**/*.sql.ts`. A one-time `JsonMigration` on first boot moves legacy JSON data
into SQLite (shown in diagram 07). Shares/sync stream deltas to a remote
service.

### Pluggability
- **Providers** — AI SDK v3 bundled providers (Anthropic, OpenAI, Google,
Bedrock, Azure, Vertex, etc.) plus dynamically-loaded NPM providers.
- **Plugins** — `plugin/` package with a TUI runtime (`cli/cmd/tui/plugin/`)
that registers sidebar widgets, keybinds, and slots.
- **MCP** — External tools via the Model Context Protocol client in `mcp/`.
- **LSP** — Language server launcher/client in `lsp/` feeding the `lsp` tool.
- **Skills** — Markdown-based prompt packs under `skill/`.

## Source references

- Entry: `opencode/packages/opencode/src/index.ts`
- Server: `opencode/packages/opencode/src/server/server.ts`
- Session processor: `opencode/packages/opencode/src/session/processor.ts`
- Bus: `opencode/packages/opencode/src/bus/index.ts`
- Agent: `opencode/packages/opencode/src/agent/agent.ts`
- Tool registry: `opencode/packages/opencode/src/tool/registry.ts`
- Provider: `opencode/packages/opencode/src/provider/provider.ts`
Loading
Loading