1. OpenClaw Skill 开发环境准备
1.1 安装 OpenClaw CLI 工具链
OpenClaw 提供了完整的命令行工具链,这是开发 Skill 的基础。首先需要安装 OpenClaw CLI:
bash复制curl -sSL https://get.openclaw.io | bash
安装完成后,验证版本:
bash复制claw --version
# 预期输出:claw version 2026.3.1
注意:如果遇到权限问题,可以添加
--insecure参数跳过证书验证,但在生产环境不建议这样做。
1.2 初始化 Code Review Skill 项目
使用 CLI 创建新 Skill 项目:
bash复制claw skill init code-review-skill --template=typescript
目录结构说明:
code复制/code-review-skill
├── .claw/ # OpenClaw 配置文件
├── src/
│ ├── actions/ # 技能动作实现
│ ├── triggers/ # 事件触发器
│ ├── types/ # 类型定义
│ └── index.ts # 入口文件
├── tests/ # 测试用例
├── package.json
└── README.md
1.3 开发环境配置建议
推荐使用 VS Code 配合以下插件:
- OpenClaw Toolkit(官方插件)
- TypeScript Vue Plugin
- ESLint
在 .vscode/settings.json 中添加:
json复制{
"typescript.tsdk": "node_modules/typescript/lib",
"openclaw.skillRoot": "${workspaceFolder}/src"
}
2. Code Review Skill 核心架构设计
2.1 技能工作流设计
一个完整的 Code Review 技能应包含以下阶段:
- 代码获取:从 GitHub/GitLab 等平台拉取代码
- 静态分析:使用 ESLint/TypeScript 编译器分析
- AI 审查:调用 OpenClaw 的代码理解引擎
- 结果生成:输出结构化审查报告
- 交互反馈:支持开发者对话式交互
2.2 关键技术组件
| 组件 | 技术选型 | 说明 |
|---|---|---|
| 代码解析 | TypeScript Compiler API | 提供精准的语法树分析 |
| 规则引擎 | ESLint + 自定义规则 | 基础代码规范检查 |
| AI 分析 | OpenClaw Codex API | 代码语义理解 |
| 报告生成 | Markdown + Code2Prompt | 可读性优化 |
2.3 状态管理设计
使用有限状态机(FSM)管理审查流程:
typescript复制enum ReviewState {
IDLE = 'idle',
FETCHING = 'fetching',
ANALYZING = 'analyzing',
REPORTING = 'reporting',
FEEDBACK = 'feedback'
}
class CodeReviewSkill {
private state: ReviewState = ReviewState.IDLE;
async startReview(payload: ReviewRequest) {
this.transition(ReviewState.FETCHING);
// ...各状态处理逻辑
}
}
3. 实现代码审查核心功能
3.1 代码获取模块实现
使用 Octokit 从 GitHub 获取代码:
typescript复制import { Octokit } from '@octokit/rest';
async function fetchCode(repo: string, prNumber: number) {
const octokit = new Octokit({
auth: process.env.GITHUB_TOKEN
});
const { data: diff } = await octokit.pulls.get({
owner: repo.split('/')[0],
repo: repo.split('/')[1],
pull_number: prNumber,
mediaType: { format: 'diff' }
});
return parseDiff(diff);
}
安全提示:永远不要将 Token 硬编码在代码中,应该使用 OpenClaw 的 Secret 管理功能。
3.2 静态分析增强实现
结合 TypeScript 编译器进行深度分析:
typescript复制import ts from 'typescript';
function analyzeWithTS(source: string) {
const sourceFile = ts.createSourceFile(
'temp.ts',
source,
ts.ScriptTarget.Latest
);
const diagnostics: ts.Diagnostic[] = [];
ts.forEachChild(sourceFile, node => {
// 检测未处理的 promise
if (ts.isCallExpression(node) &&
ts.isIdentifier(node.expression) &&
node.expression.text === 'fetch') {
if (!isPromiseHandled(node)) {
diagnostics.push(createDiagnostic(node, 'Unhandled fetch promise'));
}
}
});
return diagnostics;
}
3.3 AI 审查集成
调用 OpenClaw 的代码理解 API:
typescript复制async function aiReview(code: string) {
const response = await fetch('https://api.openclaw.io/v1/code/analyze', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${context.skillToken}`
},
body: JSON.stringify({
code,
lang: 'typescript',
checks: ['security', 'performance', 'maintainability']
})
});
return response.json();
}
4. 审查报告生成与交互
4.1 结构化报告生成
生成 Markdown 格式的审查报告:
typescript复制function generateReport(results: AnalysisResult[]) {
let markdown = `# Code Review Report\n\n`;
results.forEach(result => {
markdown += `## File: ${result.filePath}\n`;
markdown += `### Criticality: ${result.criticality}/10\n`;
result.issues.forEach(issue => {
markdown += `- [${issue.type}] ${issue.message}\n`;
markdown += ` \`\`\`typescript\n${issue.codeSnippet}\n \`\`\`\n`;
markdown += ` Suggested fix: ${issue.suggestion || 'None'}\n`;
});
});
return markdown;
}
4.2 交互式对话实现
处理开发者追问:
typescript复制claw.dialogHandler('ask_about_issue', async (session) => {
const { issueId } = session.params;
const issue = await findIssueInContext(issueId);
if (!issue) {
return 'Could not find the specified issue.';
}
return {
type: 'detailed_response',
issue,
related: await findRelatedIssues(issue),
examples: await getFixExamples(issue)
};
});
5. 测试与部署
5.1 单元测试策略
使用 Jest 进行分层测试:
typescript复制describe('Code Analysis', () => {
test('should detect unhandled promises', () => {
const code = `fetch('/api');`;
const diagnostics = analyzeWithTS(code);
expect(diagnostics).toHaveLength(1);
expect(diagnostics[0].message).toContain('Unhandled');
});
test('AI review for SQL injection', async () => {
const code = `const query = "SELECT * FROM users WHERE id = " + input;`;
const result = await aiReview(code);
expect(result.issues.some(i => i.type === 'security')).toBeTruthy();
});
});
5.2 生产环境部署
使用 OpenClaw CLI 部署:
bash复制claw skill deploy --env=production \
--secret GITHUB_TOKEN=$GITHUB_TOKEN \
--scale medium
部署后检查状态:
bash复制claw skill status code-review-skill
# 预期输出:
# Service: code-review-skill
# Status: Running
# Endpoint: https://api.openclaw.io/skill/code-review
# Version: 1.0.0
6. 性能优化技巧
6.1 缓存策略实现
typescript复制const cache = new Map<string, AnalysisResult>();
async function cachedReview(code: string) {
const hash = createHash('sha256').update(code).digest('hex');
if (cache.has(hash)) {
return cache.get(hash)!;
}
const result = await aiReview(code);
cache.set(hash, result);
return result;
}
6.2 增量分析优化
对于大型 PR,实现增量分析:
typescript复制function analyzeIncrementally(diff: Diff) {
return diff.chunks.map(chunk => {
return {
file: chunk.filePath,
issues: analyzeWithTS(chunk.newCode)
};
});
}
7. 实战经验分享
在开发过程中遇到的典型问题及解决方案:
-
长方法检测误报:
- 问题:AI 经常将合理的工厂方法误判为过长
- 解决:添加白名单模式
@review-ignore length
-
第三方库理解不足:
- 问题:对框架特定模式(如 React Hooks)理解不准确
- 解决:上传项目类型定义到分析上下文
-
敏感信息泄露:
- 问题:测试代码中的 mock 数据被标记为敏感
- 解决:在
.clawignore中添加**/__mocks__/**
typescript复制// 最佳实践示例:防御性代码审查
function safeReview(code: string) {
try {
return aiReview(code);
} catch (error) {
logError(error);
return {
error: 'Analysis failed',
fallback: basicStaticAnalysis(code)
};
}
}
