-
Notifications
You must be signed in to change notification settings - Fork 2
Development Guide
thend edited this page Nov 30, 2025
·
2 revisions
欢迎为 CCMage 贡献代码!本指南将帮助你快速了解项目结构和开发流程。
ccmage/
├── backend/ # 后端服务
│ ├── server.js # Express 主服务器
│ ├── routes.js # 进程/AI 路由模块
│ ├── managementRoutes.js # 项目管理 API 路由
│ ├── database.js # SQLite 数据库服务层
│ ├── database-schema.sql # 数据库模式定义
│ ├── processManager.js # 进程管理(EventEmitter)
│ ├── startupDetector.js # 启动命令自动检测
│ └── claudeCodeManager.js # AI 对话管理
├── frontend/ # 前端应用
│ └── src/
│ ├── components/ # React 组件
│ │ ├── TodoManager.tsx # Todo 任务管理
│ │ ├── ProjectCard.tsx # 项目卡片
│ │ ├── AiDialog.tsx # AI 对话框
│ │ └── LogViewer.tsx # 日志查看器
│ ├── App.tsx # 主应用
│ ├── api.ts # API 封装
│ └── types.ts # TypeScript 类型
├── .claude/ # 项目配置
│ └── projects.json # 项目列表配置
└── docs/ # 文档
├── ARCHITECTURE.md # 架构文档
└── API.md # API 文档
# Fork 仓库到你的 GitHub 账号
# 然后克隆
git clone https://github.com/YOUR_USERNAME/ccmage.git
cd ccmagenpm run install:allcp .env.example .env
# 编辑 .env 添加必要的配置# 同时启动前后端
npm run dev
# 或分别启动
npm run dev:frontend # http://localhost:5173
npm run dev:backend # http://localhost:9999- KISS 原则 - 保持简单直观
- YAGNI 原则 - 只实现当前所需
- DRY 原则 - 消除重复
- SOLID 原则 - 单一职责等
- TypeScript/JavaScript: ≤ 200 行
- Python: ≤ 200 行
- 超出限制时主动拆分文件
文件命名:
- React 组件:
PascalCase.tsx(例如:ProjectCard.tsx) - 工具函数:
camelCase.ts(例如:apiClient.ts) - 常量文件:
UPPER_CASE.ts(例如:CONSTANTS.ts)
变量命名:
// 组件
const ProjectCard = () => { ... }
// 函数
const fetchProjects = async () => { ... }
// 常量
const MAX_PROJECTS = 100
// 类型
interface Project { ... }
type ProjectStatus = 'active' | 'archived'严格模式:
// tsconfig.json
{
"compilerOptions": {
"strict": true,
"noImplicitAny": true,
"strictNullChecks": true
}
}避免 any:
// ❌ 不好
function process(data: any) { ... }
// ✅ 好
function process(data: Project) { ... }定义类型:
// frontend/src/types.ts
export interface Project {
name: string
path: string
tech: string[]
status: ProjectStatus
port?: number
}
export type ProjectStatus = 'active' | 'production' | 'archived'import React, { useState, useEffect } from 'react'
import type { Project } from './types'
interface ProjectCardProps {
project: Project
onUpdate?: (project: Project) => void
}
export const ProjectCard: React.FC<ProjectCardProps> = ({
project,
onUpdate
}) => {
const [status, setStatus] = useState<string>('loading')
useEffect(() => {
loadStatus()
}, [project.name])
const loadStatus = async () => {
// 实现
}
return (
<div className="project-card">
{/* UI */}
</div>
)
}// frontend/src/api.ts
export const api = {
async getProjects(): Promise<ProjectsResponse> {
const response = await fetch('/api/projects')
if (!response.ok) {
throw new Error('Failed to fetch projects')
}
return response.json()
},
async startProject(name: string, command?: string): Promise<void> {
const response = await fetch(`/api/projects/${name}/start`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ command })
})
if (!response.ok) {
throw new Error('Failed to start project')
}
}
}使用 React Hooks:
// 本地状态
const [projects, setProjects] = useState<Project[]>([])
// 副作用
useEffect(() => {
loadProjects()
}, [])
// 引用
const logViewerRef = useRef<HTMLDivElement>(null)// backend/server.js
app.get('/api/projects', async (req, res) => {
try {
const projects = await loadProjects()
res.json({ success: true, data: projects })
} catch (error) {
res.status(500).json({
success: false,
error: error.message
})
}
})// 统一错误处理
app.use((err, req, res, next) => {
console.error('Error:', err)
res.status(500).json({
success: false,
error: err.name,
message: err.message
})
})// backend/database.js
class Database {
getTodos(projectName, filters = {}) {
const { status, priority, type } = filters
let query = 'SELECT * FROM todos WHERE project_name = ?'
const params = [projectName]
if (status) {
query += ' AND status = ?'
params.push(status)
}
return this.db.prepare(query).all(...params)
}
}// backend/claudeCodeManager.js
async execute(projectName, projectPath, prompt, sessionId) {
const sdk = await this.loadSDK()
const queryInstance = sdk.query({
prompt,
options: {
cwd: projectPath,
systemPrompt: { type: 'preset', preset: 'claude_code' },
maxTurns: 50
}
})
for await (const message of queryInstance) {
const logEntry = this.messageToLogEntry(message, sessionId)
this.emit(`ai-output:${sessionId}`, logEntry)
}
}// __tests__/database.test.js
import { Database } from '../backend/database'
describe('Database', () => {
let db
beforeEach(() => {
db = new Database(':memory:')
})
test('should create todo', () => {
const todo = db.createTodo('test-project', {
title: 'Test Todo',
priority: 'high'
})
expect(todo.title).toBe('Test Todo')
expect(todo.priority).toBe('high')
})
})// e2e/project-management.spec.js
test('should create and manage project', async ({ page }) => {
await page.goto('http://localhost:5173')
// 创建项目
await page.click('button:has-text("新建项目")')
await page.fill('input[name="name"]', 'test-project')
await page.click('button:has-text("创建")')
// 验证项目显示
await expect(page.locator('.project-card')).toBeVisible()
})React DevTools:
# 安装浏览器扩展
# Chrome: React Developer Tools
# Firefox: React Developer ToolsConsole 调试:
console.log('[ProjectCard] Loading status for:', project.name)
console.error('[API] Failed to fetch:', error)Nodemon 配置:
{
"watch": ["backend/**/*.js"],
"ext": "js,json",
"ignore": ["backend/node_modules/**"],
"exec": "node backend/server.js"
}日志输出:
console.log(`[Server] Starting on port ${PORT}`)
console.error('[Database] Failed to connect:', error)npm run build
# 输出到 frontend/dist# 设置环境变量
NODE_ENV=production
# 启动服务器
npm startFROM node:16
WORKDIR /app
COPY package*.json ./
RUN npm install --production
COPY . .
RUN npm run build
EXPOSE 9999
CMD ["npm", "start"]git checkout -b feature/amazing-feature# 开发功能
# ...
# 提交更改
git add .
git commit -m "feat: add amazing feature"# 推送到你的 fork
git push origin feature/amazing-feature
# 在 GitHub 上创建 Pull Request使用语义化提交信息:
feat: 新功能
fix: Bug 修复
docs: 文档更新
style: 代码格式(不影响功能)
refactor: 重构
test: 测试相关
chore: 构建/工具相关
示例:
git commit -m "feat: add project filtering by status"
git commit -m "fix: resolve AI dialog streaming issue"
git commit -m "docs: update API reference"- 在 GitHub Issues 中创建功能需求
- Fork 仓库并创建特性分支
- 实现功能(遵循代码规范)
- 编写测试(如果有测试框架)
- 更新文档
- 提交 Pull Request
- 等待 Code Review
- 在 Issues 中报告 Bug
- 重现问题
- 定位问题代码
- 修复并测试
- 提交 PR 关联 Issue
- 代码编辑器:VS Code
- Git 客户端:GitKraken / SourceTree
- API 测试:Postman / Insomnia
- 数据库查看:DB Browser for SQLite
- 保持简洁 - 每个函数只做一件事
- 注释清晰 - 复杂逻辑必须注释
- 错误处理 - 所有异步操作都要处理错误
- 类型安全 - 充分利用 TypeScript
- 避免不必要的渲染 - 使用 React.memo
- 懒加载 - 大组件使用 lazy loading
- 缓存数据 - 避免重复请求
- 批量操作 - 使用 Promise.all
- 输入验证 - 验证所有用户输入
- 路径检查 - 防止路径遍历攻击
- 敏感信息 - 不要提交密钥到 Git
- CORS 配置 - 生产环境使用白名单
- 📖 阅读 架构文档
- 💬 在 Discussions 讨论
- 🐛 提交 Issue
- 📧 联系维护者
感谢你的贡献! 🎉
CCMage - AI 辅助开发系统
GitHub 仓库 • 问题反馈 • 社区讨论 • MIT License
Made with ❤️ by CCMage Contributors
© 2025 CCMage Project