架构概览

wescode 的整体技术架构——三进程模型、Window-Process-Cell 映射、包结构与数据布局。


三进程模型

wescode 运行时由三个进程协作:

wescode 三进程架构

通信协议

路径协议
Electron ↔ ExtensionExtension Host IPC
Extension ↔ WebviewpostMessage
Extension ↔ Gostdio JSON-RPC

Window-Process-Cell 架构

核心映射

1 workspace = 1 Go 进程 = 1 Cell (ws-{hash})

CellID 确定性派生

cellID := "ws-" + sha256(canonicalize(root))[:4]
// 示例:/Users/dev/project → ws-a1b2c3d4

CellID 在 Go 进程生命周期内不可变(INV-WS-05)。

多窗口场景

窗口 1 (workspace=/project-a) → Go 进程 A → Cell ws-a1b2
窗口 2 (workspace=/project-a) → Go 进程 A → Cell ws-a1b2 (共享)
窗口 3 (workspace=/project-b) → Go 进程 B → Cell ws-c3d4

Config Mode

无工作区 = 无 Cell = 无 Go 进程:

打开 VS Code(无文件夹)
  → Config Mode
  → 只支持 auth/provider/settings RPC
  → GateGuard 引导用户打开文件夹

Multi-root Workspace

所有文件夹属于同一 Cell:

Multi-root workspace:
  /project-a
  /project-b
  → CellID = hash(primary folder = /project-a)
  → 两个文件夹共享同一 Cell

Go 后端包结构

backend/internal/
├── codeintel/       # CKG 代码知识图谱(tree-sitter 解析 + FTS5 索引)
├── editengine/      # 编辑引擎(三级匹配 + diff 预览)
├── verification/    # QualityGate(验证命令路由)
├── engine/          # Service 主入口(Hypervisor + Cell map)
├── deviceagent/     # IDE Device Agent(buffer overlay + terminal 路由)
├── notify/          # ★ Go→TS 通知契约单点(method.go + tsgen.go)
├── failure/         # 具名失败条件(renderer 据此选句子)
├── store/           # 应用层存储(会话 + 消息持久化)
├── runtime/         # 运行时装配
├── platform/        # 平台差异(macOS/Linux/Windows)
├── treesitter/      # tree-sitter 绑定
├── rpc/             # JSON-RPC 协议
├── bench/           # wescode bench 评测
└── e2e/             # 端到端测试

核心初始化流程

// backend/internal/engine/engine.go
func (s *Service) Initialize(ctx context.Context) error {
    // 1. StartEngine(只挂身份骨架)
    eng, err := engine.StartEngine(ctx, engine.Config{
        DataDir: dataDir,
        Logger:  logger,
    })

    // 2. 绑 ProviderLiveKeyFn(GetOrCreate 之前)
    spec.ProviderLiveKeyFn = tokenSource.Key

    // 3. GetOrCreate Cell(per-workspace)
    cell, err := eng.Hypervisor.Cells().GetOrCreate(ctx, spec)

    // 4. 装配 Device Agent + Skills + Tools
    registerTools(cell)
    seedBuiltinSkills(cell)
}

前端技术栈

层技术
编辑器基座VSCode Open Source Fork
AI 集成src/vs/workbench/contrib/wescode/
Web 控制台React 19 + Vite
通信stdio JSON-RPC

前端入口

src/vs/workbench/contrib/wescode/
├── browser/           # Chat / Inline / Terminal / StatusBar
│   ├── codeintel/     # CKG HoverProvider + CodeLensProvider
│   └── statusbar/     # AI 状态栏 + 索引进度栏
├── common/            # 共享类型 + Mock
└── node/              # Go 后端进程管理

web/src/
├── pages/ProjectOverviewPage.tsx  # 项目概览大面板
└── components/codeintel/          # D3 交互式调用图

数据目录结构

$XDG_DATA_HOME/wescode/           # macOS: ~/Library/Application Support/wescode/
├── hypervisor.db                  # Cell 注册表(wesgine Hypervisor)
├── cells/ws-{hash}/               # per-workspace Cell 数据
│   ├── meta.db                    # Cell 元数据
│   ├── sessions.db                # 会话 + 记忆
│   ├── state.db                   # 运行时状态 + 观测
│   ├── index/                     # CKG 代码知识图谱索引
│   │   └── code.db                # FTS5 + 符号表
│   ├── knowledge/                 # 知识库文件
│   ├── skills/                    # Tier C 技能包
│   ├── .scratch/                  # 临时计算域(Run 结束后 GC)
│   └── .plans/                    # Plan artifact
├── db/wescode_auth.db             # 登录 session(跨 workspace 共享)
├── crashes/                       # 崩溃日志
└── logs/wescode.log               # Go 后端日志

配置目录

$XDG_CONFIG_HOME/wescode/          # macOS: ~/Library/Application Support/wescode/
└── config.yaml                    # 用户配置(按需创建)

事件路由

INV-WS-06:不跨窗口广播

Go 后端通知绝不跨窗口/跨工作区广播:

事件类型路由方式
chat/stream按 JSON-RPC request id 路由到发起窗口
terminal/*扇出到绑定该后端的窗口
codeintel/*扇出到绑定该后端的窗口
engine/*扇出到绑定该后端的窗口

INV-WS-07:方法名映射

Renderer 方法名(camelCase)与 Go RPC 名通过 METHOD_MAP 解耦:

// WescodeBackendMainService.METHOD_MAP
'listConversations' → 'sidebar/listConversations'
'chatSend'          → 'chat/send'
'providerCatalog'   → 'providerCatalog' // 同名

INV-WS-12:Go→TS 通知闭合

Go 能发的通知方法名是封闭集合:

method.go(Go 源码,权威)
  → tsgen.go(AST 生成 TS 联合类型)
  → _dispatchNotification(switch + assertNever)
  → 新增 Method 忘了接线 = tsc 编译报错

生命周期回收(INV-WS-08)

窗口打开 → 绑定到 workspace 对应的 Go 后端 → 引用计数 +1
窗口关闭 → 引用计数 -1
  → 无任何窗口引用 → shutdown Go 进程

最佳实践

  1. 一个 workspace 一个项目:利用 Cell 隔离获得最佳体验
  2. 关注数据目录:了解数据存储位置有助于故障排查
  3. 避免删除 hypervisor.db:它是 Cell 注册表
  4. 使用 Config Mode:无工作区时仍可配置 Provider