架构概览
Dline 目前以一个 VS Code 扩展发布,内嵌 React Webview。本页按运行时的层次说明主要模块及其源码位置,便于修改前找到真正的入口。
| 目录 | 内容 |
|---|---|
src/ | 扩展主体:入口、核心逻辑、宿主适配、共享代码和测试 |
webview-ui/ | 独立的 React + Vite Webview 项目 |
proto/ | Protobuf 合同,见 Protobuf 与 ProtoBus |
scripts/ | 代码生成、打包、测试与构建辅助脚本 |
docs/ | 本文档站(独立的 Astro Starlight 项目)和英文更新日志 |
standalone/、src/standalone/、src/hosts/external/ | 为未来的独立可执行程序保留的代码,当前发布只包含 VS Code 扩展 |
testing-platform/、tests/ | 独立集成测试客户端和 Storybook 等附加测试 |
src/core 是源码分组,不是单独部署的产品。
package.json 的入口是 dist/extension.js,源码为 src/extension.ts 中的 activate()。启动顺序如下:
setupHostProvider()通过HostProvider.initialize()注册 VS Code 版本的 Webview、diff、review、终端和宿主桥接实现;- 立即创建并注册侧边栏 Webview 提供者,它的 Controller 稍后才创建;
- 清理旧的 VS Code 存储;Dline 不会导入 Cline 数据(手动步骤见从 Cline 迁移);
createStorageContext()解析存储根目录,exportVSCodeStorageToSharedFiles()把旧的ExtensionContext状态导出到文件存储;initialize()(src/common.ts)初始化StateManager和ModelRegistry,创建 Controller 并挂到 Webview 提供者上,同时注册为编排器的主 Controller;- 注册编辑器面板的序列化器、测试模式和钩子,最后注册 VS Code 命令。
src/hosts/host-provider.ts 中的 HostProvider 让任务和服务模块不直接依赖编辑器 API。VS Code 实现在 src/hosts/vscode/:
- 宿主桥接的每个服务方法实现在
src/hosts/vscode/hostbridge/<service>/下,例如window/showMessage.ts; - 请求分发在
src/hosts/vscode/hostbridge-grpc-handler.ts,它使用生成的服务配置; - 终端、diff 和 review 的 VS Code 实现也在这个目录下。
VS Code API 调用应当留在宿主和集成边界内。
Webview 与 Controller
Section titled “Webview 与 Controller”| 组件 | 源码 | 职责 |
|---|---|---|
VscodeWebviewProvider | src/hosts/vscode/VscodeWebviewProvider.ts | 绑定 VS Code 侧边栏 |
WebviewProvider | src/core/webview/WebviewProvider.ts | 侧边栏和编辑器面板共用的生命周期 |
WebviewProviderRegistry | src/core/webview/WebviewProviderRegistry.ts | 跟踪侧边栏和额外面板 |
Controller | src/core/controller/index.ts | 协调任务、状态投影、RPC 处理和 Webview 更新 |
OrchestratorController | src/core/orchestrator/OrchestratorController.ts | 管理主 Controller、面板 Controller、Profile 广播和父子任务关系 |
每个 Webview 提供者拥有一个 Controller。React 端从 webview-ui/src/main.tsx 启动并渲染 App.tsx;共享的扩展状态通过 webview-ui/src/context/ExtensionStateContext.tsx 提供。
扩展与 Webview 之间的 RPC 是经 VS Code postMessage 传递的 ProtoBus 请求/响应信封,不是网络 gRPC 连接。
Task 运行时
Section titled “Task 运行时”任务运行在基于日志(journal)的内核之上。Controller 为每个打开的任务持有一个 session/ActiveTaskSession.ts,所有生命周期变化都经过以下组件:
| 源码 | 职责 |
|---|---|
shell/Task.ts、shell/TaskShell.ts | 任务的对外接口:打开、启动、提交输入、响应、取消和终止 |
kernel/transition.ts | 纯转换函数,按任务状态校验每个事件 |
kernel/hydrate.ts、kernel/recovery.ts | 任务重新打开时从 state.json 与日志重建状态,并恢复被中断的工作 |
runtime/TaskRuntime.ts | 串行处理事件,经提交管线持久化,并从持久化的 outbox 分发命令 |
stores/ | 每次提交背后的日志、载荷与状态存储 |
composition/ | 组装会话的运行时、存储与执行器,包括导入旧版本对话的升级流程 |
session/ActiveTaskSession.ts | 管理一个打开任务的资源,以及本窗口是否可以写入它 |
session/TaskInteractionOwner.ts | 管理审批、重试、恢复、问答、计划和完成等用户交互 |
MessageChannel.ts、message-state.ts | 串行投递消息并投影聊天行 |
activity/TaskActivityStore.ts | 管理聊天和 Activities 视图中的任务活动 |
以上路径都相对于 src/core/task/。新的生命周期转换应当表达为事件,经内核转换函数校验,再投影到界面;不要在 TaskRuntime 旁边另建布尔状态机。只有持有任务锁的窗口可以写入任务:在 TaskShell.open() 授予写入所有权之前,运行时以 read_only 拒绝所有事件,Controller 以只读方式显示该任务。
| 位置 | 内容 |
|---|---|
src/shared/tools.ts | 内置工具身份,枚举 DlineDefaultTool |
src/core/prompts/tools/tool-specs.ts | 规范工具描述 STANDARD_TOOL_SPECS |
src/core/prompts/tools/tool-ids.ts | 按顺序列出 Standard 与 Lite 注册的工具 ID |
src/core/prompts/tools/provider-projector.ts | 投影为服务商原生工具 Schema |
src/core/prompts/tools/xml-tool-projector.ts | 投影为 XML 工具说明 |
src/core/task/tools/handlers/ | 各工具的运行时处理器 |
src/core/task/ToolExecutor.ts、src/core/task/tools/ToolExecutorCoordinator.ts | 工具执行协调 |
原生工具和 XML 工具是同一套规范描述的两种投影。提示词与工具的关系见提示词架构,工具块的执行方式见工具执行域。
服务商与模型
Section titled “服务商与模型”src/core/api/index.ts的buildApiHandler()取当前模式的 Profile,经buildApiHandlerFromProfile()调用createHandlerForProvider(),按profile.provider选择src/core/api/providers/下的处理器;未知的服务商 ID 会抛出错误。src/core/model-registry/ModelRegistry.ts是运行时模型目录。- API 格式
ApiFormat定义在proto/dline/models/metadata.proto。服务商元数据和 API 格式决定原生工具、托管工具、图片、推理和传输能力。
扩展侧代码必须通过 src/shared/net.ts 访问网络,不要使用全局 fetch 或默认的 Axios 实例:
| 导出 | 用途 |
|---|---|
fetch | 普通网络请求 |
providerFetch | 服务商 API 请求,会计入服务商请求观测 |
getAxiosSettings() | 为 Axios 请求提供共享的传输设置 |
createOpenAIClient() | 使用 providerFetch 的 OpenAI 兼容 SDK 客户端 |
mockFetchForTesting() | 测试时在限定范围内替换共享传输 |
按 Profile 创建 OpenAI 客户端的 createOpenAIClientForProfile() 位于 src/core/api/providers/openai-client-factory.ts。Webview 运行在浏览器环境中,可以使用浏览器自带的 fetch。
src/services/mcp/McpHub.ts 是多个 Controller 共享、按引用计数管理的实例,支持 stdio、sse 和 streamableHttp 三种传输;OAuth 只用于后两种远程传输。MCP 配置本身不会授予任务审批。