AI-IDE 项目架构详解
基于 Eclipse Theia 1.66.0 的企业级 AI 集成开发环境
📊 项目概览
基本信息
- 项目类型: Lerna 管理的 monorepo
- 版本: 1.66.0
- 包总数: 76 个包 (22 个 AI 相关 + 54 个 Theia 核心)
- 技术栈: TypeScript 5.4.5 + React 18.2.0 + Monaco Editor
- 部署方式: 浏览器版 (Web) + Electron 桌面版
- 基础框架: Eclipse Theia (云端和桌面 IDE 框架)
核心特性
- ✅ 多 AI 提供商抽象 (OpenAI, Claude, Ollama, Gemini 等 8+ 提供商)
- ✅ Agent 驱动的智能编程助手
- ✅ 上下文感知的 Prompt 系统
- ✅ 代码补全、编辑器增强、终端集成
- ✅ MCP (Model Context Protocol) 支持
- ✅ VS Code 扩展兼容
🏗️ 项目目录结构
根目录结构
/home/kinbos/Desktop/AI-IDE/├── packages/ # 75 个运行时包│ ├── ai-* # 22 个 AI 相关包│ ├── core/ # Theia 核心框架│ ├── terminal/ # 终端模拟│ ├── editor/ # 代码编辑│ ├── debug/ # 调试支持│ ├── git/ # Git 集成│ ├── filesystem/ # 文件系统│ ├── task/ # 任务管理│ └── [50+ 其他包] # 其他 IDE 功能│├── dev-packages/ # 14 个开发工具包│ ├── application-manager/ # 应用管理│ ├── application-package/ # 应用打包│ ├── cli/ # CLI 工具│ └── ...│├── examples/ # 示例应用│ ├── browser/ # 浏览器版 IDE│ ├── electron/ # Electron 桌面版│ ├── playwright/ # UI 自动化测试│ └── api-tests/ # API 测试│├── configs/ # 构建配置├── scripts/ # 构建脚本├── .notes/ # 开发笔记└── lerna.json # Monorepo 配置
AI 包生态系统 (22 个包)
核心基础设施 (4 个)
packages/├── ai-core/ # AI 核心抽象层│ ├── LanguageModel # 语言模型接口│ ├── Agent # Agent 系统│ ├── PromptService # Prompt 构建│ └── VariableService # 上下文变量│├── ai-chat/ # 聊天服务│ ├── ChatService # 聊天管理│ ├── AgentService # Agent 协调│ └── SessionStore # 会话存储│├── ai-chat-ui/ # 聊天界面 (React)│ ├── ChatWidget # 聊天组件│ ├── MessageRenderer # 消息渲染│ └── InputArea # 输入区域│└── ai-terminal/ # AI 增强终端├── TerminalAgent # 终端 Agent└── CommandHelper # 命令助手
AI 提供商集成 (8 个)
packages/├── ai-openai/ # OpenAI GPT 模型├── ai-anthropic/ # Anthropic Claude├── ai-ollama/ # 本地 Ollama 模型├── ai-google/ # Google Gemini├── ai-hugging-face/ # Hugging Face 模型├── ai-llamafile/ # Llamafile 本地模型├── ai-codex/ # OpenAI Codex└── ai-vercel-ai/ # Vercel AI SDK 集成
专业功能 (10 个)
packages/├── ai-code-completion/ # 内联代码补全├── ai-editor/ # 编辑器 AI 助手├── ai-ide/ # IDE 编排 Agent├── ai-claude-code/ # Claude Code 集成 (Alpha)├── ai-mcp/ # Model Context Protocol├── ai-mcp-server/ # MCP 服务器实现├── ai-mcp-ui/ # MCP 配置界面├── ai-scanoss/ # 许可证/安全扫描├── ai-history/ # 对话历史管理└── ai-core-ui/ # AI 配置界面
🎯 前后端分离架构
架构层级说明
Theia 采用严格的按运行环境分层的架构模式:
packages/{package-name}/src/├── browser/ # 🌐 前端层 - 浏览器环境├── node/ # 🖥️ 后端层 - Node.js 环境├── common/ # 🔗 共享层 - 前后端通用├── electron-browser/ # ⚡ Electron 渲染进程 (可选)├── electron-main/ # ⚡ Electron 主进程 (可选)├── electron-common/ # ⚡ Electron 共享代码 (可选)├── electron-node/ # ⚡ Electron Node 层 (可选)└── browser-only/ # 🌐 纯浏览器环境 (可选)
实际统计数据
从 76 个包中的分层分布:
| 层级 | 包数量 | 占比 |
|---|---|---|
browser/ |
66 | 87% |
common/ |
54 | 71% |
node/ |
47 | 62% |
electron-browser/ |
10 | 13% |
electron-main/ |
3 | 4% |
📁 各层级详解
1️⃣ browser/ - 前端层
运行环境: 浏览器/Electron 渲染进程 可用 API: DOM, Window, React, Monaco Editor, xterm.js
典型文件示例
// packages/terminal/src/browser/terminal-widget-impl.tsimport { Terminal } from 'xterm';@injectable()export class TerminalWidgetImpl extends BaseWidget {protected readonly xterm: Terminal;@inject(TerminalServer) // RPC 代理,实际在后端protected readonly terminalServer: TerminalServer;constructor() {super();// 可以使用浏览器 APIthis.xterm = new Terminal({cursorBlink: true,theme: this.getTheme()});// 监听用户输入this.xterm.onData(data => {// 通过 RPC 发送到后端this.terminalServer.write(this.terminalId, data);});}protected render(): React.ReactNode {return <div ref={this.attachXterm} />;}}
包含内容
- ✅ React 组件 (
.tsx文件) - ✅ UI Widgets 和视图
- ✅ 前端服务
- ✅ 前端 DI 模块 (
*-frontend-module.ts) - ✅ 前端贡献点 (
*-frontend-contribution.ts) - ✅ CSS 样式文件
Terminal 包示例
packages/terminal/src/browser/├── terminal-widget-impl.ts # 终端 UI Widget├── terminal-frontend-contribution.ts # 命令、菜单贡献├── terminal-frontend-module.ts # DI 容器配置├── terminal-theme-service.ts # 主题服务├── terminal-profile-service.ts # 配置管理├── search/│ ├── terminal-search-widget.tsx # React 搜索组件│ └── terminal-search-container.ts # 搜索容器└── style/├── terminal.css # 终端样式└── terminal-search.css # 搜索样式
2️⃣ node/ - 后端层
运行环境: Node.js 进程 可用 API: Node.js API, fs, child_process, path, os 等
典型文件示例
// packages/terminal/src/node/shell-terminal-server.tsimport * as pty from 'node-pty';import * as fs from 'fs-extra';@injectable()export class ShellTerminalServer implements IShellTerminalServer {protected readonly processes = new Map<number, TerminalProcess>();async create(options: IShellTerminalServerOptions): Promise<number> {// 使用 Node.js API 创建伪终端const ptyProcess = pty.spawn(options.shell, options.args, {name: 'xterm-256color',cols: 80,rows: 30,cwd: options.cwd || process.cwd(),env: { ...process.env, ...options.env }});const id = ptyProcess.pid;this.processes.set(id, ptyProcess);// 监听输出并通过 RPC 发送到前端ptyProcess.onData(data => {this.emitOutput(id, data);});return id;}async write(id: number, data: string): Promise<void> {const process = this.processes.get(id);if (process) {process.write(data);}}protected async readShellConfig(): Promise<string[]> {// 可以访问文件系统const content = await fs.readFile('/etc/shells', 'utf-8');return content.split('\n').filter(line => !line.startsWith('#'));}}
包含内容
- ✅ 后端服务实现
- ✅ 文件系统操作
- ✅ 进程管理
- ✅ 后端 DI 模块 (
*-backend-module.ts) - ✅ 后端贡献点 (
*-backend-contribution.ts) - ✅ CLI 工具实现
Terminal 包示例
packages/terminal/src/node/├── shell-terminal-server.ts # RPC 服务实现├── shell-process.ts # Shell 进程管理├── terminal-server.ts # 基础终端服务├── terminal-backend-contribution.ts # 后端启动逻辑├── terminal-backend-module.ts # DI 容器配置├── buffering-stream.ts # 流缓冲└── test/└── terminal-test-container.ts # 测试容器
3️⃣ common/ - 共享层
运行环境: 前端和后端都可以使用 可用 API: ⚠️ 仅 JavaScript 基础 API (不能用 DOM 或 Node.js 特定 API)
典型文件示例
// packages/terminal/src/common/terminal-protocol.ts// 1. 定义 RPC 服务接口export interface IShellTerminalServer {create(options: IShellTerminalServerOptions): Promise<number>;write(id: number, data: string): Promise<void>;resize(id: number, cols: number, rows: number): Promise<void>;destroy(id: number): Promise<void>;}// 2. 定义数据传输对象 (DTO)export interface IShellTerminalServerOptions {shell: string;args: string[];cwd?: string;env?: { [key: string]: string | null };}// 3. 定义 DI 符号export const IShellTerminalServer = Symbol('IShellTerminalServer');// 4. 定义 RPC 路径export const shellTerminalPath = '/services/shell-terminal';// 5. 定义事件类型export interface TerminalOutputEvent {id: number;data: string;}export interface TerminalExitEvent {id: number;code: number;}
包含内容
- ✅ TypeScript 接口定义
- ✅ 数据传输对象 (DTOs)
- ✅ RPC 协议定义
- ✅ 共享工具函数 (纯 JS)
- ✅ 偏好设置定义
- ✅ 常量和枚举
Terminal 包示例
packages/terminal/src/common/├── terminal-protocol.ts # 基础终端协议├── shell-terminal-protocol.ts # Shell 终端协议├── terminal-preferences.ts # 偏好设置├── terminal-watcher.ts # 监听器接口├── shell-type.ts # Shell 类型定义└── base-terminal-protocol.ts # 基础协议
4️⃣ electron-browser/ - Electron 渲染进程
运行环境: Electron 渲染进程 (浏览器 + 部分 Node API) 可用 API: DOM + Electron Renderer API + require()
典型示例
// packages/core/src/electron-browser/menu/electron-menu-renderer.tsimport { remote } from 'electron';@injectable()export class ElectronContextMenuRenderer {show(items: MenuItem[], x: number, y: number): void {const menu = remote.Menu.buildFromTemplate(items.map(item => ({label: item.label,click: () => item.execute()})));menu.popup({ x, y });}}
5️⃣ electron-main/ - Electron 主进程
运行环境: Electron 主进程 (完整 Node.js + Electron Main API) 可用 API: Node.js + Electron Main API
典型示例
// packages/core/src/electron-main/electron-main-application.tsimport { app, BrowserWindow } from 'electron';@injectable()export class ElectronMainApplication {async start(): Promise<void> {await app.whenReady();const mainWindow = new BrowserWindow({width: 1200,height: 800,webPreferences: {nodeIntegration: true,contextIsolation: false}});await mainWindow.loadFile('index.html');}}
6️⃣ electron-common/ - Electron 共享代码
运行环境: Electron 主进程和渲染进程共享
packages/core/src/electron-common/├── electron-api.ts # Electron API 定义├── electron-token.ts # 安全令牌└── electron-window-preferences.ts # 窗口偏好
🔗 前后端通信机制
RPC (Remote Procedure Call) 架构
前端和后端通过 WebSocket 进行双向通信,使用代理模式调用远程方法。
完整示例:Terminal 通信流程
// ========================================// 第 1 步:在 common/ 定义接口// ========================================// packages/terminal/src/common/terminal-protocol.tsexport const IShellTerminalServer = Symbol('IShellTerminalServer');export interface IShellTerminalServer {$createTerminal(options: TerminalOptions): Promise<number>;$write(id: number, data: string): void;$resize(id: number, cols: number, rows: number): void;onOutput: Event<TerminalOutputEvent>;}export interface TerminalOptions {shell: string;args: string[];cwd?: string;}export interface TerminalOutputEvent {id: number;data: string;}// ========================================// 第 2 步:在 node/ 实现后端服务// ========================================// packages/terminal/src/node/shell-terminal-server.tsimport * as pty from 'node-pty';@injectable()export class ShellTerminalServer implements IShellTerminalServer {protected readonly processes = new Map<number, pty.IPty>();protected readonly onOutputEmitter = new Emitter<TerminalOutputEvent>();readonly onOutput = this.onOutputEmitter.event;async $createTerminal(options: TerminalOptions): Promise<number> {// 在后端创建真实的终端进程const ptyProcess = pty.spawn(options.shell, options.args, {cwd: options.cwd || process.cwd(),env: process.env});const id = ptyProcess.pid;this.processes.set(id, ptyProcess);// 监听终端输出ptyProcess.onData(data => {this.onOutputEmitter.fire({ id, data });});return id;}$write(id: number, data: string): void {const process = this.processes.get(id);if (process) {process.write(data);}}$resize(id: number, cols: number, rows: number): void {const process = this.processes.get(id);if (process) {process.resize(cols, rows);}}}// ========================================// 第 3 步:在 browser/ 通过代理调用// ========================================// packages/terminal/src/browser/terminal-widget-impl.tsimport { Terminal } from 'xterm';@injectable()export class TerminalWidgetImpl extends BaseWidget {protected xterm: Terminal;protected terminalId: number;@inject(IShellTerminalServer)protected readonly server: IShellTerminalServer; // 自动注入 RPC 代理async initialize(): Promise<void> {// 创建 xterm.js 实例this.xterm = new Terminal();// 这个调用会通过 WebSocket 发送到后端this.terminalId = await this.server.$createTerminal({shell: '/bin/bash',args: [],cwd: '/home/user/project'});// 监听用户输入this.xterm.onData(data => {// 通过 RPC 发送到后端this.server.$write(this.terminalId, data);});// 监听后端输出this.server.onOutput(event => {if (event.id === this.terminalId) {this.xterm.write(event.data);}});// 窗口大小变化时通知后端this.xterm.onResize(({ cols, rows }) => {this.server.$resize(this.terminalId, cols, rows);});}}
消息流程图
┌─────────────────────────────────────────────────────────────────┐│ 用户输入流程 │└─────────────────────────────────────────────────────────────────┘用户按键 "ls -la"↓xterm.js onData 事件↓TerminalWidgetImpl.xterm.onData(data => ...)↓server.$write(terminalId, "ls -la") ← 调用 RPC 代理↓━━━━━━━━━━━━━━ WebSocket 消息 ━━━━━━━━━━━━━━{method: "$write",args: [12345, "ls -la"]}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━↓ShellTerminalServer.$write(12345, "ls -la")↓ptyProcess.write("ls -la") ← node-pty↓OS Shell (/bin/bash) 执行命令┌─────────────────────────────────────────────────────────────────┐│ 输出返回流程 │└─────────────────────────────────────────────────────────────────┘OS Shell 输出: "total 128\ndrwxr-xr-x ..."↓node-pty: ptyProcess.onData(data => ...)↓ShellTerminalServer: onOutputEmitter.fire({ id: 12345, data })↓━━━━━━━━━━━━━━ WebSocket 事件 ━━━━━━━━━━━━━━{event: "onOutput",data: { id: 12345, data: "total 128\n..." }}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━↓TerminalWidgetImpl: server.onOutput(event => ...)↓if (event.id === this.terminalId)↓this.xterm.write(event.data)↓xterm.js 渲染输出到屏幕
🤖 AI 包架构深度解析
AI-Core 包结构
packages/ai-core/src/│├── browser/ # 前端 AI 服务│ ├── frontend-language-model-registry.ts # 模型注册表│ ├── frontend-language-model-service.ts # 模型服务代理│ ├── frontend-variable-service.ts # 变量解析服务│ ├── frontend-prompt-customization-service.ts # Prompt 定制│ ├── ai-core-frontend-module.ts # DI 容器│ ├── file-variable-contribution.ts # 文件上下文变量│ ├── open-editors-variable-contribution.ts # 打开编辑器变量│ └── theia-variable-contribution.ts # Theia 环境变量│├── node/ # 后端 AI 服务│ ├── backend-language-model-registry.ts # 后端模型注册│ ├── language-model-frontend-delegate.ts # 前端委托│ ├── token-usage-service-impl.ts # Token 使用统计│ └── ai-core-backend-module.ts # DI 容器│└── common/ # 共享 AI 协议├── language-model.ts # 核心模型接口├── agent.ts # Agent 接口定义├── prompt-service.ts # Prompt 服务接口├── variable-service.ts # 变量服务接口├── language-model-service.ts # 模型服务接口├── prompt-text.ts # Prompt 文本类型├── protocol.ts # RPC 协议└── tool-invocation-registry.ts # 工具调用注册表
AI-Chat 包结构
packages/ai-chat/src/│├── browser/ # 聊天前端│ ├── frontend-chat-service.ts # 聊天服务实现│ ├── chat-session-store-impl.ts # 会话存储│ ├── custom-agent-factory.ts # 自定义 Agent 工厂│ ├── file-chat-variable-contribution.ts # 文件变量贡献│ ├── image-context-variable-contribution.ts # 图片上下文│ ├── task-context-service.ts # 任务上下文服务│ ├── chat-tool-request-service.ts # 工具请求服务│ └── ai-chat-frontend-module.ts # DI 容器│├── common/ # 聊天协议│ ├── chat-model.ts # 聊天数据模型│ ├── chat-service.ts # 聊天服务接口│ ├── chat-agent-service.ts # Agent 服务接口│ ├── chat-agents.ts # Agent 定义│ ├── chat-request-parser.ts # 请求解析器│ ├── chat-model-serialization.ts # 序列化/反序列化│ ├── chat-session-store.ts # 会话存储接口│ ├── parsed-chat-request.ts # 解析后的请求│ └── context-variables.ts # 上下文变量定义│└── node/ # 聊天后端└── ai-chat-backend-module.ts # DI 容器
AI-Chat-UI 包结构
packages/ai-chat-ui/src/browser/│├── chat-view-widget.tsx # 主聊天视图├── chat-input-widget.tsx # 输入组件├── chat-tree-view-widget.tsx # 会话树视图│├── chat-response-renderer/ # 消息渲染器│ ├── chat-response-renderer.tsx # 主渲染器│ ├── markdown-chat-response-renderer.tsx # Markdown 渲染│ ├── code-chat-response-renderer.tsx # 代码块渲染│ └── error-chat-response-renderer.tsx # 错误渲染│├── chat-response-content/ # 内容组件│ ├── command-chat-response-content.tsx # 命令响应│ ├── tool-call-chat-response-content.tsx # 工具调用│ └── delegation-response-content.tsx # 委托响应│└── style/ # 样式└── chat.css
AI 消息流程
┌──────────────────────────────────────────────────────────────┐│ 用户发送消息流程 │└──────────────────────────────────────────────────────────────┘用户输入: "帮我重构这个函数"↓ChatInputWidget (browser)↓ChatService.sendMessage(message)↓ChatRequestParser.parse(message)├─> 提取 @文件引用├─> 提取 /命令└─> 提取 #上下文↓AgentService.selectAgent(request)↓PromptService.buildPrompt(agent, request)├─> 解析变量: ${file}, ${selection}, ${workspace}├─> VariableService.resolve(variables)│ ├─> FileVariableContribution → 读取文件内容│ ├─> EditorVariableContribution → 获取选中内容│ └─> WorkspaceVariableContribution → 获取项目信息└─> 构建最终 Prompt↓LanguageModelService.request(prompt, options)├─> 路由到对应的提供商 (OpenAI/Claude/...)└─> 流式返回响应↓ChatResponseRenderer 渲染消息├─> Markdown 内容├─> 代码块├─> 工具调用结果└─> 错误信息
📐 依赖规则和最佳实践
✅ 允许的依赖方向
browser/ ──┐├──> common/ (前端和后端都可以依赖 common)node/ ──┘electron-browser/ ──> browser/ ──> common/electron-main/ ──> node/ ──> common/electron-node/ ──> node/ ──> common/
❌ 禁止的依赖方向
common/ ──✗──> browser/ # common 不能依赖前端common/ ──✗──> node/ # common 不能依赖后端browser/ ──✗──> node/ # 前端不能直接依赖后端node/ ──✗──> browser/ # 后端不能直接依赖前端
📝 架构最佳实践
1. 接口优先原则
// ✅ 正确:在 common/ 定义接口// packages/my-package/src/common/my-service.tsexport const MyService = Symbol('MyService');export interface MyService {doSomething(param: string): Promise<Result>;}// 在 node/ 实现// packages/my-package/src/node/my-service-impl.ts@injectable()export class MyServiceImpl implements MyService {async doSomething(param: string): Promise<Result> {// 后端实现}}// 在 browser/ 通过代理调用// packages/my-package/src/browser/my-widget.ts@injectable()export class MyWidget {@inject(MyService)protected readonly service: MyService; // RPC 代理}
2. DTO (Data Transfer Object) 模式
// ✅ 正确:跨层传输的数据对象必须可序列化// packages/my-package/src/common/my-protocol.tsexport interface MyDataDTO {id: string;name: string;timestamp: number;metadata: Record<string, unknown>;}// ❌ 错误:不能包含函数或类实例export interface BadDTO {id: string;process: ChildProcess; // ✗ Node.js 特定对象onClick: () => void; // ✗ 函数不能序列化date: Date; // ✗ 使用 number (timestamp) 代替}
3. RPC 服务命名规范
// packages/my-package/src/common/my-protocol.ts// 1. 定义 Symbolexport const MyRpcService = Symbol('MyRpcService');// 2. 定义接口,RPC 方法使用 $ 前缀export interface MyRpcService {$create(options: CreateOptions): Promise<number>;$update(id: number, data: UpdateData): Promise<void>;$delete(id: number): Promise<void>;onDataChange: Event<DataChangeEvent>;}// 3. 定义服务路径export const myRpcServicePath = '/services/my-rpc';
4. 模块化 DI 配置
// packages/my-package/src/browser/my-frontend-module.tsexport default new ContainerModule(bind => {// 绑定前端服务bind(MyWidgetFactory).toSelf().inSingletonScope();bind(MyFrontendService).toSelf().inSingletonScope();// 绑定 Widgetbind(MyWidget).toSelf();bind(WidgetFactory).toDynamicValue(ctx => ({id: MY_WIDGET_ID,createWidget: () => ctx.container.get(MyWidget)})).inSingletonScope();// 绑定贡献点bind(FrontendApplicationContribution).to(MyFrontendContribution);bind(CommandContribution).to(MyCommandContribution);});// packages/my-package/src/node/my-backend-module.tsexport default new ContainerModule(bind => {// 绑定后端服务bind(MyRpcService).to(MyRpcServiceImpl).inSingletonScope();// 绑定后端贡献点bind(BackendApplicationContribution).to(MyBackendContribution);});
5. 测试分离
packages/my-package/src/├── browser/│ ├── my-service.ts│ └── my-service.spec.ts # 前端单元测试├── node/│ ├── my-backend-service.ts│ ├── my-backend-service.spec.ts # 后端单元测试│ └── my-backend-service.slow-spec.ts # 集成测试 (慢)└── common/├── my-protocol.ts└── my-protocol.spec.ts # 协议测试
🚀 开发命令速查
基础命令
# 安装依赖npm install# 编译所有 TypeScript 包npm run compile# 构建浏览器应用npm run build:browser# 启动浏览器开发服务器 (http://localhost:3000)npm run start:browser# 启动 Electron 桌面应用npm run start:electron# 监听模式 (自动重新编译)npm run watch
测试命令
# 运行所有测试npm run test# 运行特定包的测试npx lerna run test --scope @theia/terminal# 运行测试并监听变化npx lerna run test:watch --scope @theia/ai-chat
包管理命令
# 编译特定包npx lerna run compile --scope @theia/ai-core# 监听特定包及其依赖npx lerna run watch --scope @theia/ai-chat --include-filtered-dependencies --parallel# 清理所有构建产物npx lerna run clean
代码质量
# 运行 ESLintnpm run lint# 自动修复 lint 问题npm run lint:fix# 生成 API 文档npm run docs
📚 关键技术栈
| 技术 | 版本 | 用途 |
|---|---|---|
| Eclipse Theia | 1.66.0 | IDE 基础框架 |
| TypeScript | ~5.4.5 | 开发语言 |
| React | 18.2.0 | UI 框架 |
| Monaco Editor | 1.96.302 | 代码编辑器 |
| InversifyJS | 6.1.3 | 依赖注入容器 |
| Express.js | 4.21.0 | 后端 HTTP 服务器 |
| Socket.io | 4.5.3 | WebSocket 实时通信 |
| xterm.js | - | 终端模拟器 |
| node-pty | - | 伪终端 (PTY) |
| Lerna | 7.1.1 | Monorepo 管理 |
| Webpack | 5.x | 应用打包 |
🎯 当前开发重点
根据最近的 Git 提交记录和 .notes/ 目录:
最近提交 (倒序)
聊天窗口需求分析 (2025-11-21)
- 规划聊天界面与终端的集成
终端时序图 (2025-11-21)
- 文档化终端数据流和架构
终端模块分析 (2025-11-21)
- 深入分析终端前后端通信机制
开发目标:Chat-Terminal 桥接
需求描述: 创建一个聊天界面,在后台隐藏终端中运行基于 CLI 的 AI 工具 (如 Claude Code 或 OpenAI Codex),将终端输出解析为聊天消息并展示给用户。
技术方案:
┌─────────────────────────────────────────────────────────────┐│ Chat-Terminal 桥接架构 │└─────────────────────────────────────────────────────────────┘用户输入 (ChatInputWidget)↓ChatTerminalService.sendMessage(message)↓创建隐藏终端 (TerminalService)↓发送命令到终端: `claude-code "${message}"`↓监听终端输出 (onOutput 事件)↓解析 JSON 输出{"type": "message","content": "AI 回复内容","thinking": "思考过程"}↓转换为 ChatMessage 对象↓ChatResponseRenderer 渲染
关键组件 (待实现):
// packages/ai-terminal/src/browser/chat-terminal-widget.tsx@injectable()export class ChatTerminalWidget extends ReactWidget {@inject(ChatTerminalService)protected readonly chatTerminalService: ChatTerminalService;protected render(): React.ReactNode {return (<div className="chat-terminal-container"><MessageList messages={this.messages} /><ChatInput onSend={this.handleSend} /></div>);}protected handleSend = async (message: string) => {await this.chatTerminalService.sendMessage(message);};}// packages/ai-terminal/src/browser/chat-terminal-service.ts@injectable()export class ChatTerminalService {@inject(TerminalService)protected readonly terminalService: TerminalService;protected hiddenTerminal?: TerminalWidget;async sendMessage(message: string): Promise<void> {if (!this.hiddenTerminal) {this.hiddenTerminal = await this.createHiddenTerminal();}// 发送命令到隐藏终端await this.hiddenTerminal.sendText(`claude-code "${this.escapeMessage(message)}"\n`);}protected async createHiddenTerminal(): Promise<TerminalWidget> {const terminal = await this.terminalService.newTerminal({shell: '/bin/bash',cwd: this.workspaceRoot});// 监听输出并解析terminal.onOutput(data => {this.parseAndDispatch(data);});return terminal;}protected parseAndDispatch(data: string): void {try {const json = JSON.parse(data);if (json.type === 'message') {this.onMessageReceived.fire(json.content);}} catch (e) {// 非 JSON 输出,作为普通文本处理}}}
📖 学习路径建议
初级 - 理解基础架构
- ✅ 阅读本文档,理解整体架构
- ✅ 阅读
CLAUDE.md和doc/coding-guidelines.md - ✅ 探索
packages/core/src/目录结构 - ✅ 运行浏览器应用:
npm run start:browser - ✅ 在浏览器调试工具中探索 DI 容器
中级 - 深入特定模块
- 选择一个模块深入学习 (推荐从 Terminal 开始)
- 阅读该模块的
common/接口定义 - 调试
browser/前端代码 - 调试
node/后端代码 - 跟踪 RPC 调用流程
高级 - 开发新功能
- 设计新功能的架构
- 定义
common/接口和 DTO - 实现
node/后端服务 - 实现
browser/前端 UI - 编写测试 (
*.spec.ts) - 集成到应用 (贡献点、命令、菜单等)
🔗 相关资源
官方文档
项目文档
/CLAUDE.md- Claude Code 使用指南/doc/coding-guidelines.md- 编码规范/doc/Testing.md- 测试指南/doc/Plugin-API.md- 插件 API 文档
社区
🏁 总结
AI-IDE 是一个基于 Eclipse Theia 的企业级 AI 集成开发环境,采用严格的前后端分离架构:
- browser/ - 前端 UI 层 (React + Monaco + xterm.js)
- node/ - 后端服务层 (Node.js + 文件系统 + 进程管理)
- common/ - 共享协议层 (接口 + DTO + 常量)
- electron-* - Electron 平台特定代码
通过 RPC over WebSocket 实现前后端通信,使用 InversifyJS 进行依赖注入,支持 VS Code 扩展,集成 8+ AI 提供商。
当前开发重点是 Chat-Terminal 桥接功能,将 CLI 工具集成到聊天界面中。
