AtomCode 源码编译与二次开发入门

AtomCode 源码编译与二次开发入门

引言

AtomCode 作为一款开源的 AI 编码助手,不仅提供了强大的功能,还开放了全部源代码,允许开发者进行二次开发和定制。本文将详细介绍如何从源码编译 AtomCode,如何理解其架构设计,以及如何进行二次开发,帮助你打造属于自己的 AI 编码工具。

一、环境准备

1.1 系统要求

项目 要求
操作系统 Windows 10+/macOS 12+/Linux
Node.js ≥ 18.0.0
npm ≥ 9.0.0
Git ≥ 2.0.0
Rust ≥ 1.70.0(可选,用于原生模块)

1.2 安装依赖

bash 复制代码
# 安装 Node.js 和 npm
# 访问 https://nodejs.org/ 下载

# 安装 Git
# 访问 https://git-scm.com/ 下载

# 安装 Rust(可选)
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

# 验证安装
node --version
npm --version
git --version

二、获取源码

2.1 克隆仓库

bash 复制代码
# 克隆主仓库
git clone https://atomgit.com/atomcode/atomcode.git

# 进入项目目录
cd atomcode

# 查看目录结构
ls -la

2.2 项目结构

复制代码
atomcode/
├── .github/           # GitHub 配置文件
├── apps/              # 应用程序目录
│   ├── desktop/       # 桌面端应用
│   ├── web/           # Web 端应用
│   └── mobile/        # 移动端应用(开发中)
├── packages/          # 核心包目录
│   ├── core/          # 核心功能
│   ├── ai/            # AI 模块
│   ├── editor/        # 编辑器模块
│   ├── plugins/       # 插件系统
│   └── utils/         # 工具函数
├── docs/              # 文档
├── scripts/           # 脚本文件
├── package.json       # 根 package.json
├── tsconfig.json      # TypeScript 配置
└── README.md          # 项目说明

2.3 安装依赖

bash 复制代码
# 安装项目依赖
npm install

# 如果使用 pnpm(推荐)
pnpm install

# 安装子包依赖
pnpm install --recursive

三、理解架构设计

3.1 核心架构

复制代码
┌─────────────────────────────────────────────────────────────┐
│                      应用层 (Apps)                          │
│  ┌───────────┐  ┌───────────┐  ┌───────────┐              │
│  │  Desktop  │  │    Web    │  │   Mobile  │              │
│  └─────┬─────┘  └─────┬─────┘  └─────┬─────┘              │
└────────┼──────────────┼──────────────┼────────────────────┘
         │              │              │
┌────────▼──────────────────────────────▼────────────────────┐
│                    核心层 (Packages)                        │
│  ┌───────────┐  ┌───────────┐  ┌───────────┐              │
│  │   Core    │  │    AI     │  │  Editor   │              │
│  │  核心功能  │  │  AI 模块   │  │ 编辑器模块 │              │
│  └───────────┘  └───────────┘  └───────────┘              │
│  ┌───────────┐  ┌───────────┐                              │
│  │  Plugins  │  │   Utils   │                              │
│  │  插件系统  │  │ 工具函数   │                              │
│  └───────────┘  └───────────┘                              │
└─────────────────────────────────────────────────────────────┘
         │              │              │
┌────────▼──────────────────────────────▼────────────────────┐
│                    基础设施层                                │
│  ┌───────────┐  ┌───────────┐  ┌───────────┐              │
│  │   Node.js │  │   Rust    │  │  Electron │              │
│  └───────────┘  └───────────┘  └───────────┘              │
└─────────────────────────────────────────────────────────────┘

3.2 核心模块详解

Core 模块

typescript 复制代码
// packages/core/src/index.ts
export interface CoreConfig {
  version: string;
  appName: string;
  defaultConfig: Config;
}

export class Core {
  private config: CoreConfig;
  private modules: Map<string, Module> = new Map();
  
  constructor(config: CoreConfig) {
    this.config = config;
  }
  
  registerModule(module: Module) {
    this.modules.set(module.id, module);
  }
  
  getModule<T extends Module>(id: string): T | undefined {
    return this.modules.get(id) as T;
  }
  
  async init() {
    for (const module of this.modules.values()) {
      await module.init();
    }
  }
}

AI 模块

typescript 复制代码
// packages/ai/src/index.ts
export interface AIModel {
  id: string;
  name: string;
  provider: string;
  apiKey: string;
  baseUrl: string;
  maxTokens: number;
  temperature: number;
}

export class AIService {
  private models: Map<string, AIModel> = new Map();
  private currentModel: AIModel | null = null;
  
  registerModel(model: AIModel) {
    this.models.set(model.id, model);
  }
  
  setCurrentModel(modelId: string): boolean {
    const model = this.models.get(modelId);
    if (model) {
      this.currentModel = model;
      return true;
    }
    return false;
  }
  
  async generate(prompt: string): Promise<string> {
    if (!this.currentModel) {
      throw new Error('No model selected');
    }
    
    return this.callAPI(this.currentModel, prompt);
  }
}

Editor 模块

typescript 复制代码
// packages/editor/src/index.ts
export interface EditorConfig {
  theme: string;
  fontSize: number;
  tabSize: number;
  lineNumbers: boolean;
}

export class Editor {
  private config: EditorConfig;
  private view: EditorView;
  
  constructor(config: EditorConfig) {
    this.config = config;
    this.view = new EditorView(config);
  }
  
  setContent(content: string) {
    this.view.setContent(content);
  }
  
  getContent(): string {
    return this.view.getContent();
  }
  
  highlightSyntax(language: string) {
    this.view.highlight(language);
  }
}

3.3 插件系统架构

typescript 复制代码
// packages/plugins/src/index.ts
export interface PluginManifest {
  id: string;
  name: string;
  version: string;
  description: string;
  author: string;
  dependencies?: string[];
  entry: string;
}

export interface PluginAPI {
  core: Core;
  ai: AIService;
  editor: Editor;
  registerCommand(command: Command): void;
  registerHook(hook: Hook): void;
}

export class PluginLoader {
  private plugins: Map<string, Plugin> = new Map();
  private api: PluginAPI;
  
  constructor(api: PluginAPI) {
    this.api = api;
  }
  
  async loadPlugin(manifest: PluginManifest): Promise<void> {
    const module = await import(manifest.entry);
    const plugin = new module.default(this.api);
    this.plugins.set(manifest.id, plugin);
    await plugin.init();
  }
  
  async unloadPlugin(pluginId: string): Promise<void> {
    const plugin = this.plugins.get(pluginId);
    if (plugin) {
      await plugin.destroy();
      this.plugins.delete(pluginId);
    }
  }
}

四、编译与运行

4.1 编译项目

bash 复制代码
# 编译所有包
pnpm build

# 编译特定包
pnpm build --filter @atomcode/core
pnpm build --filter @atomcode/ai
pnpm build --filter @atomcode/editor

# 编译桌面应用
pnpm build --filter atomcode-desktop

# 编译 Web 应用
pnpm build --filter atomcode-web

4.2 运行开发服务器

bash 复制代码
# 运行桌面应用开发模式
pnpm dev --filter atomcode-desktop

# 运行 Web 应用开发模式
pnpm dev --filter atomcode-web

4.3 构建生产版本

bash 复制代码
# 构建桌面应用
pnpm build:prod --filter atomcode-desktop

# 构建 Web 应用
pnpm build:prod --filter atomcode-web

# 构建安装包(桌面应用)
pnpm package --filter atomcode-desktop

五、二次开发实战

5.1 创建自定义插件

步骤 1:创建插件目录

bash 复制代码
mkdir -p packages/plugins/my-plugin
cd packages/plugins/my-plugin

步骤 2:创建 package.json

json 复制代码
{
  "name": "@atomcode/my-plugin",
  "version": "1.0.0",
  "description": "My custom AtomCode plugin",
  "main": "dist/index.js",
  "types": "dist/index.d.ts",
  "scripts": {
    "build": "tsc",
    "dev": "tsc --watch"
  },
  "dependencies": {
    "@atomcode/core": "^1.0.0",
    "@atomcode/ai": "^1.0.0",
    "@atomcode/editor": "^1.0.0"
  },
  "devDependencies": {
    "typescript": "^5.0.0"
  }
}

步骤 3:创建插件代码

typescript 复制代码
// src/index.ts
import { PluginAPI, Command, Hook } from '@atomcode/core';

export default class MyPlugin {
  private api: PluginAPI;
  
  constructor(api: PluginAPI) {
    this.api = api;
  }
  
  async init() {
    console.log('MyPlugin initialized');
    
    // 注册命令
    this.registerCommands();
    
    // 注册钩子
    this.registerHooks();
  }
  
  private registerCommands() {
    const helloCommand: Command = {
      id: 'my-plugin.hello',
      name: 'Hello World',
      description: 'Say hello to the world',
      shortcut: 'Ctrl+Shift+H',
      execute: () => {
        this.api.editor.setContent('Hello from MyPlugin!');
      }
    };
    
    this.api.registerCommand(helloCommand);
  }
  
  private registerHooks() {
    const fileOpenHook: Hook = {
      id: 'my-plugin.file-open',
      type: 'file-open',
      callback: (file) => {
        console.log(`File opened: ${file.name}`);
      }
    };
    
    this.api.registerHook(fileOpenHook);
  }
  
  async destroy() {
    console.log('MyPlugin destroyed');
  }
}

步骤 4:编译插件

bash 复制代码
pnpm install
pnpm build

步骤 5:注册插件

packages/plugins/src/plugins.ts 中注册你的插件:

typescript 复制代码
import MyPlugin from '@atomcode/my-plugin';

export const plugins = [
  // 其他插件...
  {
    id: 'my-plugin',
    name: 'My Plugin',
    version: '1.0.0',
    description: 'My custom AtomCode plugin',
    entry: '@atomcode/my-plugin',
    Plugin: MyPlugin
  }
];

5.2 扩展 AI 模块

添加自定义模型

typescript 复制代码
// packages/ai/src/models/custom.ts
import { AIModel } from '../types';
import { BaseModel } from './base';

export class CustomModel extends BaseModel {
  constructor(config: AIModel) {
    super(config);
  }
  
  async generate(prompt: string): Promise<string> {
    // 实现自定义模型的调用逻辑
    const response = await fetch(this.config.baseUrl, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'Authorization': `Bearer ${this.config.apiKey}`
      },
      body: JSON.stringify({
        prompt,
        max_tokens: this.config.maxTokens,
        temperature: this.config.temperature
      })
    });
    
    const data = await response.json();
    return data.choices[0].text;
  }
}

注册自定义模型

typescript 复制代码
// packages/ai/src/index.ts
import { CustomModel } from './models/custom';

const aiService = new AIService();

aiService.registerModel({
  id: 'custom-model',
  name: 'Custom Model',
  provider: 'custom',
  apiKey: process.env.CUSTOM_API_KEY || '',
  baseUrl: 'https://api.custom-model.com/v1/completions',
  maxTokens: 4096,
  temperature: 0.7
});

aiService.setCurrentModel('custom-model');

5.3 自定义编辑器主题

创建主题文件

typescript 复制代码
// packages/editor/src/themes/my-theme.ts
import { Theme } from '../types';

export const myTheme: Theme = {
  id: 'my-theme',
  name: 'My Theme',
  type: 'dark',
  colors: {
    background: '#1a1a2e',
    foreground: '#e4e4e7',
    primary: '#818cf8',
    secondary: '#c084fc',
    success: '#4ade80',
    warning: '#fbbf24',
    error: '#f87171',
    comment: '#6b7280',
    string: '#a78bfa',
    number: '#fbbf24',
    keyword: '#f472b6',
    function: '#60a5fa',
    variable: '#e4e4e7',
    class: '#34d399',
    interface: '#2dd4bf',
    type: '#a5b4fc'
  },
  font: {
    family: 'JetBrains Mono, Consolas, monospace',
    size: 14
  }
};

注册主题

typescript 复制代码
// packages/editor/src/index.ts
import { myTheme } from './themes/my-theme';

const editor = new Editor({
  theme: 'my-theme',
  fontSize: 14,
  tabSize: 2,
  lineNumbers: true
});

editor.registerTheme(myTheme);

六、调试与测试

6.1 调试技巧

bash 复制代码
# 使用 Chrome DevTools 调试桌面应用
pnpm dev --filter atomcode-desktop --inspect

# 使用 VS Code 调试
# 配置 .vscode/launch.json

# 查看日志
pnpm dev --filter atomcode-desktop --verbose

VS Code 调试配置

json 复制代码
{
  "version": "0.2.0",
  "configurations": [
    {
      "name": "AtomCode Desktop",
      "type": "node",
      "request": "launch",
      "cwd": "${workspaceFolder}/apps/desktop",
      "program": "${workspaceFolder}/apps/desktop/src/main.ts",
      "runtimeArgs": ["--inspect"],
      "preLaunchTask": "npm: build"
    },
    {
      "name": "AtomCode Web",
      "type": "chrome",
      "request": "launch",
      "url": "http://localhost:3000",
      "webRoot": "${workspaceFolder}/apps/web"
    }
  ]
}

6.2 测试框架

bash 复制代码
# 运行所有测试
pnpm test

# 运行特定包的测试
pnpm test --filter @atomcode/core
pnpm test --filter @atomcode/ai

# 运行测试并生成覆盖率报告
pnpm test --coverage

测试示例

typescript 复制代码
// packages/ai/src/tests/ai-service.test.ts
import { AIService, AIModel } from '../index';

describe('AIService', () => {
  let aiService: AIService;
  
  beforeEach(() => {
    aiService = new AIService();
  });
  
  describe('registerModel', () => {
    it('should register a model', () => {
      const model: AIModel = {
        id: 'test-model',
        name: 'Test Model',
        provider: 'test',
        apiKey: 'test-key',
        baseUrl: 'http://localhost:3000',
        maxTokens: 1024,
        temperature: 0.7
      };
      
      aiService.registerModel(model);
      
      expect(aiService.getModel('test-model')).toEqual(model);
    });
  });
  
  describe('setCurrentModel', () => {
    it('should set the current model', () => {
      const model: AIModel = {
        id: 'test-model',
        name: 'Test Model',
        provider: 'test',
        apiKey: 'test-key',
        baseUrl: 'http://localhost:3000',
        maxTokens: 1024,
        temperature: 0.7
      };
      
      aiService.registerModel(model);
      const result = aiService.setCurrentModel('test-model');
      
      expect(result).toBe(true);
    });
  });
});

七、贡献代码

7.1 贡献流程

复制代码
┌─────────────────────────────────────────────────────────────┐
│                    贡献流程                                  │
├─────────────────────────────────────────────────────────────┤
│  1. Fork 仓库                                               │
│     └── 在 AtomGit 上 Fork atomcode/atomcode                │
├─────────────────────────────────────────────────────────────┤
│  2. 克隆仓库                                               │
│     └── git clone https://atomgit.com/your-username/atomcode│
├─────────────────────────────────────────────────────────────┤
│  3. 创建分支                                               │
│     └── git checkout -b feature/my-feature                 │
├─────────────────────────────────────────────────────────────┤
│  4. 编写代码                                               │
│     └── 实现功能,添加测试                                   │
├─────────────────────────────────────────────────────────────┤
│  5. 提交代码                                               │
│     └── git commit -m "feat: add my feature"                │
├─────────────────────────────────────────────────────────────┤
│  6. 推送到远程                                             │
│     └── git push origin feature/my-feature                  │
├─────────────────────────────────────────────────────────────┤
│  7. 创建 Pull Request                                      │
│     └── 在 AtomGit 上创建 PR                                │
└─────────────────────────────────────────────────────────────┘

7.2 代码规范

TypeScript 代码规范

typescript 复制代码
// ✅ 好的代码风格
export class AIService {
  private models: Map<string, AIModel> = new Map();
  
  registerModel(model: AIModel): void {
    this.models.set(model.id, model);
  }
  
  getModel(id: string): AIModel | undefined {
    return this.models.get(id);
  }
}

// ❌ 不好的代码风格
export class AIService {
  private models: Map<string, AIModel> = new Map();
  
  registerModel(model: AIModel) {
    this.models.set(model.id, model);
  }
  
  getModel(id: string) {
    return this.models.get(id);
  }
}

提交信息规范

bash 复制代码
# 格式:<type>(<scope>): <description>
# 示例:
git commit -m "feat(ai): add custom model support"
git commit -m "fix(editor): resolve syntax highlighting issue"
git commit -m "docs(core): update API documentation"
git commit -m "refactor(plugins): simplify plugin loader"
git commit -m "test(ai): add unit tests for AI service"

7.3 常见贡献类型

类型 说明 示例
Bug Fix 修复 Bug 修复编辑器崩溃问题
Feature 添加新功能 添加代码解释功能
Enhancement 改进现有功能 优化代码补全速度
Documentation 更新文档 添加 API 参考文档
Refactor 重构代码 简化核心模块结构
Test 添加测试 添加单元测试用例
Plugin 创建插件 创建代码质量插件

八、部署与发布

8.1 打包应用

bash 复制代码
# 打包桌面应用
pnpm package --filter atomcode-desktop

# 打包 Web 应用
pnpm build:prod --filter atomcode-web

打包产物

复制代码
apps/desktop/dist/
├── win-unpacked/       # Windows 解压版
├── linux-unpacked/     # Linux 解压版
├── mac-unpacked/       # macOS 解压版
├── atomcode-setup.exe  # Windows 安装包
├── atomcode.deb        # Debian/Ubuntu 安装包
└── atomcode.dmg        # macOS 安装包

8.2 发布新版本

更新版本号

bash 复制代码
# 更新根 package.json 版本号
pnpm version minor

# 更新所有子包版本号
pnpm version --recursive minor

发布到 npm

bash 复制代码
# 登录 npm
npm login

# 发布所有包
pnpm publish --recursive

发布到 GitHub Releases

bash 复制代码
# 创建发布标签
git tag v1.0.0
git push origin v1.0.0

# 上传发布包
# 在 GitHub Releases 页面手动上传

九、常见问题与解决方案

Q1:编译失败

原因:依赖版本不兼容或缺少依赖

解决方案

bash 复制代码
# 删除 node_modules 并重新安装
rm -rf node_modules
pnpm install

# 清理构建缓存
pnpm clean
pnpm build

# 检查 Node.js 版本
node --version

Q2:运行时错误

原因:模块未正确编译或配置错误

解决方案

bash 复制代码
# 检查日志
pnpm dev --verbose

# 重新编译项目
pnpm build

# 检查配置文件
cat ~/.atomcode/config.json

Q3:插件加载失败

原因:插件依赖缺失或代码错误

解决方案

bash 复制代码
# 检查插件依赖
cd packages/plugins/my-plugin
pnpm install

# 编译插件
pnpm build

# 检查插件日志
cat ~/.atomcode/logs/plugin.log

Q4:AI 模型调用失败

原因:API Key 无效或网络问题

解决方案

bash 复制代码
# 检查 API Key
echo $OPENAI_API_KEY

# 测试网络连接
curl https://api.openai.com/v1/models

# 检查模型配置
cat ~/.atomcode/models.json

十、未来发展方向

10.1 技术路线图

  • 短期目标:完善核心功能,优化性能
  • 中期目标:支持更多 AI 模型,扩展插件生态
  • 长期目标:构建完整的 AI 编码平台

10.2 社区发展

  • 建立官方文档网站
  • 组织社区活动和 Hackathon
  • 建立贡献者激励机制
  • 支持多语言社区

10.3 商业化方向

  • 提供企业版定制服务
  • 开发付费插件市场
  • 提供云端 AI 服务
  • 建立技术支持体系

结语

AtomCode 的开源特性为开发者提供了无限的定制空间。通过源码编译和二次开发,你可以打造一个完全符合自己需求的 AI 编码工具。无论是创建插件、扩展 AI 模块,还是自定义编辑器主题,AtomCode 的架构设计都提供了良好的扩展性。

二次开发建议

  1. 📚 先理解项目架构,再进行修改
  2. 🔧 从创建插件开始,逐步深入核心模块
  3. ✅ 编写测试用例,确保代码质量
  4. 🤝 积极参与社区,分享你的成果

现在就开始探索 AtomCode 的源码,打造属于你的 AI 编码工具吧!


本文为原创内容,基于作者实际编译和二次开发经验整理。如需转载,请注明出处。

相关推荐
hanbr1 小时前
我做了个工具:把 Typora 笔记一键变成 CSDN 博客,截图自动生成描述,还能 AI 润色
开源·开源软件
小小测试开发1 小时前
Goose AI Agent 完全指南:Linux 基金会加持的开源 AI 编程助手
linux·人工智能·开源
分布式存储与RustFS11 小时前
RustFS S3 Table 开源后,我重新梳理了一下 Iceberg 数据湖的选型思路
人工智能·开源·minio·dpu·rustfs·ai存储·s3 table
梦梦代码精12 小时前
2026年PHP开源商城系统实测对比:架构、多商户、商用授权,谁才是真·省心?
vue.js·docker·架构·开源·代码规范
冬奇Lab14 小时前
每日一个开源项目(第127篇):PM Skills Marketplace - 把顶级产品方法论塞进 AI Agent
人工智能·开源·资讯
文创工作室1 天前
蓝奏云批量下载工具
开源
狗凯之家源码网1 天前
PHP 原版公众号无限回调系统修复版效果实测
开源·php
南知意-1 天前
MonkeyCode:长亭开源的企业级AI开发平台,GitHub 3.2k Star!
人工智能·ai·开源·github·ai编程·开源项目