Documentation Index
Fetch the complete documentation index at: https://agentstack.cc/llms.txt
Use this file to discover all available pages before exploring further.
OpenCode 架构文档
1. 项目概述
OpenCode是一个开源的AI编码代理工具,旨在提供强大的AI辅助开发体验。它采用模块化架构设计,支持多种交互界面(终端TUI、Web应用、桌面应用)和模型提供商。
核心特性
- 多界面支持:终端TUI、Web应用、桌面应用
- 客户端-服务器架构
- 多模型提供商兼容(Claude、OpenAI、Google等)
- 内置代理系统(build和plan)
- LSP支持
- 会话管理
- 主题定制
2. 目录结构
OpenCode采用monorepo结构,使用Bun作为包管理器:
opencode/
├── .github/ # GitHub配置和工作流
├── .opencode/ # 内置工具和主题配置
├── github/ # GitHub Action集成
├── infra/ # 基础设施配置
├── nix/ # Nix构建配置
├── packages/ # 核心包目录
│ ├── app/ # Web应用前端
│ ├── console/ # 控制台应用(前端+后端)
│ ├── desktop/ # 桌面应用
│ ├── docs/ # 文档
│ └── opencode/ # 主包(核心功能+CLI)
└── package.json # 根包配置
3. 核心模块
3.1 opencode 包
主包,包含核心功能和CLI,位于packages/opencode/:
主要组件
- CLI: 命令行界面,支持多种命令
- Agent: AI代理系统,包含build和plan两种内置代理
- LSP: 语言服务器协议支持
- File: 文件系统操作和观察器
- Auth: 认证系统
- Config: 配置管理
- Bus: 事件总线
- TUI: 终端用户界面(基于SolidJS)
核心入口
packages/opencode/src/index.ts是主入口文件,负责解析命令行参数并执行相应命令。
3.2 app 包
Web应用前端,位于packages/app/,采用SolidJS框架构建,实现了与OpenCode服务器的交互和用户界面:
主要组件
- Components: UI组件(文件树、终端、标题栏等)
- Context: 应用上下文管理(Sync上下文、会话管理等)
- Pages: 页面组件(首页、会话页、错误页等)
- Utils: 工具函数
核心架构
app包采用组件化架构,使用SolidJS的响应式系统和上下文管理:
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ UI组件层 │ │ 上下文层 │ │ SDK层 │
│ │ │ │ │ │
│ ┌─────────────┐ │ │ ┌─────────────┐ │ │ ┌─────────────┐ │
│ │ 会话界面 │ │ │ │ Sync上下文 │ │ │ │ OpenCode │ │
│ └─────────────┘ │ │ └─────────────┘ │ │ │ SDK │ │
│ ┌─────────────┐ │ │ ┌─────────────┐ │ │ └─────────────┘ │
│ │ 消息展示 │ │ │ │ 会话管理 │ │ │ │
│ └─────────────┘ │ │ └─────────────┘ │ └─────────────────┘
│ ┌─────────────┐ │ │ ┌─────────────┐ │
│ │ 输入框 │ │ │ │ 状态存储 │ │
│ └─────────────┘ │ │ └─────────────┘ │
└─────────────────┘ └─────────────────┘
状态管理
使用SolidJS的Store API和Context API实现状态管理:
- Sync上下文: 管理消息同步和存储
- 会话存储: 管理当前会话状态
- 主题存储: 管理UI主题设置
消息存储实现
前端存储
消息存储使用SolidJS的Store API实现,位于packages/app/src/context/sync.tsx:
// 核心存储结构
const store = createStore<{
message: Record<string, Message[]>
part: Record<string, Part[]>
}>({ message: {}, part: {} })
// 加载历史消息
async loadMessages(sessionID: string, limit: number) {
// 调用SDK获取历史消息
const result = await sdk.client.session.messages({
sessionID,
limit,
})
// 更新本地存储
batch(() => {
setStore("message", sessionID, reconcile(next, { key: "id" }))
// 更新消息部分
for (const message of items) {
setStore("part", message.info.id, reconcile(...))
}
})
}
后端存储
后端消息存储位于packages/opencode/src/storage/storage.ts,使用文件系统存储:
// 存储路径结构
const dir = path.join(Global.Path.data, "storage") // ~/.local/share/opencode/storage
// 存储操作
await Storage.write(["session", project.id, id], result)
await Storage.read(["message", sessionID, messageID])
历史消息拉取接口
服务端接口位于packages/opencode/src/server/routes/session.ts:
// 接口定义
.get("/:sessionID/message", describeRoute({
summary: "Get session messages",
description: "Retrieve all messages in a session, including user prompts and AI responses.",
operationId: "session.messages",
responses: {
200: {
description: "List of messages",
content: {
"application/json": {
schema: resolver(MessageV2.WithParts.array()),
},
},
},
...errors(400, 404),
},
}), async (c) => {
const query = c.req.valid("query")
const messages = await Session.messages({
sessionID: c.req.valid("param").sessionID,
limit: query.limit,
})
return c.json(messages)
})
模型流式回复上屏实现
核心组件
- Typewriter组件: 实现打字机效果,位于
packages/ui/src/components/typewriter.tsx
- SessionTurn组件: 渲染会话轮次,位于
packages/ui/src/components/session-turn.tsx
- Message组件: 处理消息显示,位于
packages/ui/src/components/message.tsx
实现流程
- 接收流式响应: 客户端通过SDK接收服务器的流式响应
- 分块处理: 逐块接收消息内容
- 打字机效果: 使用Typewriter组件实现渐进式渲染
- 自动滚动: 使用
createAutoScroll钩子实现自动滚动到底部
// Typewriter组件核心实现
const Typewriter = <T extends ValidComponent = "p">(props: { text?: string; class?: string; as?: T }) => {
const [store, setStore] = createStore({
typing: false,
displayed: "",
cursor: true,
})
createEffect(() => {
const text = props.text
if (!text) return
// 打字机效果实现
let i = 0
const timeouts: ReturnType<typeof setTimeout>[] = []
setStore("typing", true)
setStore("displayed", "")
setStore("cursor", true)
const getTypingDelay = () => {
// 随机延迟,模拟真实打字效果
const random = Math.random()
if (random < 0.05) return 150 + Math.random() * 100
if (random < 0.15) return 80 + Math.random() * 60
return 30 + Math.random() * 50
}
const type = () => {
if (i < text.length) {
setStore("displayed", text.slice(0, i + 1))
i++
timeouts.push(setTimeout(type, getTypingDelay()))
} else {
setStore("typing", false)
timeouts.push(setTimeout(() => setStore("cursor", false), 2000))
}
}
timeouts.push(setTimeout(type, 200))
onCleanup(() => {
for (const timeout of timeouts) clearTimeout(timeout)
})
})
return (
<Dynamic component={props.as || "p"} class={props.class}>
{store.displayed}
<Show when={store.cursor}>
<span classList={{ "blinking-cursor": !store.typing }}>│</span>
</Show>
</Dynamic>
)
}
自动滚动机制
使用createAutoScroll钩子实现消息区域的自动滚动:
// createAutoScroll钩子
const useAutoScroll = (ref: () => HTMLElement | undefined, enabled: Accessor<boolean>) => {
let timeoutId: number
createEffect(() => {
const element = ref()
if (!element || !enabled()) return
const checkScroll = () => {
const { scrollTop, scrollHeight, clientHeight } = element
const isAtBottom = scrollHeight - scrollTop - clientHeight < 100
if (isAtBottom) {
timeoutId = window.setTimeout(() => {
element.scrollTop = scrollHeight
}, 10)
}
}
const observer = new MutationObserver(checkScroll)
observer.observe(element, { childList: true, subtree: true })
checkScroll()
onCleanup(() => {
observer.disconnect()
clearTimeout(timeoutId)
})
})
}
3.3 console 包
控制台应用,位于packages/console/:
主要组件
- app: 控制台前端应用
- core: 控制台后端核心
- function: 云函数
- mail: 邮件服务
- resource: 资源管理
3.4 desktop 包
桌面应用,位于packages/desktop/:
主要组件
- src: 桌面应用源代码
- src-tauri: Tauri配置和Rust代码
4. 架构特点
4.1 客户端-服务器架构
OpenCode采用客户端-服务器架构,允许在不同设备上运行客户端,同时保持核心功能在服务器端:
┌─────────────┐ ┌─────────────┐
│ 终端TUI │ │ Web应用 │
└──────┬──────┘ └──────┬──────┘
│ │
└───────────┬───────┘
▼
┌─────────────┐
│ OpenCode │
│ 服务器 │
└──────┬──────┘
│
▼
┌─────────────┐
│ AI模型API │
└─────────────┘
4.2 代理系统
OpenCode内置两种代理:
- build代理: 默认代理,具有完整访问权限,用于开发工作
- plan代理: 只读代理,用于分析和代码探索
- 默认拒绝文件编辑
- 运行bash命令前需询问权限
- 适合探索不熟悉的代码库或规划更改
4.3 多模型支持
OpenCode支持多种AI模型提供商,包括Claude、OpenAI、Google等,用户可以根据需要进行配置。
5. 技术栈
前端技术
- SolidJS: UI框架(用于终端TUI和Web应用)
- Vite: 构建工具
- TailwindCSS: CSS框架
- Solid Router: 路由管理
后端技术
- TypeScript: 主要开发语言
- Bun: 运行时和包管理器
- Hono: Web框架
- Drizzle: ORM
桌面技术
- Tauri: 桌面应用框架
- Rust: 系统级开发
6. 关键功能模块
6.1 CLI命令系统
OpenCode提供丰富的CLI命令,包括:
run: 运行代理
generate: 生成代码
auth: 认证管理
agent: 代理管理
models: 模型管理
serve: 启动服务器
web: 启动Web应用
session: 会话管理
6.2 文件系统操作
文件系统模块提供:
6.3 会话管理
会话管理模块允许用户:
6.4 主题系统
OpenCode支持多种内置主题,并允许用户自定义主题。
7. 开发和部署
7.1 开发环境
- Bun: 用于开发和构建
- Turbo: 用于类型检查
- Husky: 用于Git钩子
7.2 部署选项
OpenCode支持多种部署方式:
8. 未来发展方向
- 增强多代理协作能力
- 扩展模型支持
- 改进性能和响应速度
- 增加更多开发工具集成
9. 总结
OpenCode采用模块化、客户端-服务器架构设计,提供多种交互界面和模型支持,旨在为开发者提供强大的AI辅助开发体验。其核心优势在于灵活性、可扩展性和多平台支持。