feat: 重构为 Monorepo 架构并实现 HTTP Server
架构变更: - 采用 pnpm workspaces 实现 Monorepo 结构 - 将现有代码迁移到 packages/core - 新增 packages/server HTTP 服务层 Server 功能: - REST API: 会话管理、工具管理、配置管理 - WebSocket: 实时双向通信支持 - SSE: 服务端事件推送 - Hono + Bun 作为运行时 API 端点: - GET/POST /api/sessions - 会话 CRUD - GET/POST /api/sessions/:id/messages - 消息管理 - GET /api/sessions/:id/events - SSE 事件流 - WS /api/ws/:sessionId - WebSocket 连接 - GET/POST /api/tools - 工具管理 - GET/PUT /api/config - 配置管理
This commit is contained in:
@@ -0,0 +1,272 @@
|
||||
import { describe, it, expect } from 'vitest';
|
||||
import {
|
||||
builtinSkills,
|
||||
codeReviewSkill,
|
||||
explainCodeSkill,
|
||||
generateDocsSkill,
|
||||
generateTestsSkill,
|
||||
refactorSuggestSkill,
|
||||
fixBugSkill,
|
||||
gitCommitSkill,
|
||||
apiDesignSkill,
|
||||
} from '../../../../src/skills/builtin/index.js';
|
||||
|
||||
describe('Builtin Skills - 内置技能', () => {
|
||||
describe('builtinSkills 数组', () => {
|
||||
it('包含所有内置 Skills', () => {
|
||||
expect(builtinSkills).toHaveLength(8);
|
||||
});
|
||||
|
||||
it('所有 Skills 都是启用状态', () => {
|
||||
builtinSkills.forEach((skill) => {
|
||||
expect(skill.enabled).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
it('所有 Skills 都有必要字段', () => {
|
||||
builtinSkills.forEach((skill) => {
|
||||
expect(skill.name).toBeDefined();
|
||||
expect(skill.displayName).toBeDefined();
|
||||
expect(skill.description).toBeDefined();
|
||||
expect(skill.promptTemplate).toBeDefined();
|
||||
expect(skill.parameters).toBeDefined();
|
||||
expect(skill.category).toBeDefined();
|
||||
expect(skill.source).toBe('builtin');
|
||||
});
|
||||
});
|
||||
|
||||
it('所有 Skills 都有关键词', () => {
|
||||
builtinSkills.forEach((skill) => {
|
||||
expect(skill.keywords).toBeDefined();
|
||||
expect(skill.keywords!.length).toBeGreaterThan(0);
|
||||
});
|
||||
});
|
||||
|
||||
it('Skills 名称唯一', () => {
|
||||
const names = builtinSkills.map((s) => s.name);
|
||||
const uniqueNames = new Set(names);
|
||||
expect(uniqueNames.size).toBe(names.length);
|
||||
});
|
||||
});
|
||||
|
||||
describe('codeReviewSkill - 代码审查', () => {
|
||||
it('有正确的名称', () => {
|
||||
expect(codeReviewSkill.name).toBe('code-review');
|
||||
expect(codeReviewSkill.displayName).toBe('代码审查');
|
||||
});
|
||||
|
||||
it('属于 development 分类', () => {
|
||||
expect(codeReviewSkill.category).toBe('development');
|
||||
});
|
||||
|
||||
it('code 参数是必需的', () => {
|
||||
expect(codeReviewSkill.parameters.code.required).toBe(true);
|
||||
});
|
||||
|
||||
it('focus 参数是可选的', () => {
|
||||
expect(codeReviewSkill.parameters.focus.required).toBe(false);
|
||||
});
|
||||
|
||||
it('模板包含审查相关内容', () => {
|
||||
expect(codeReviewSkill.promptTemplate).toContain('审查');
|
||||
expect(codeReviewSkill.promptTemplate).toContain('{{code}}');
|
||||
});
|
||||
|
||||
it('关键词包含相关词汇', () => {
|
||||
expect(codeReviewSkill.keywords).toContain('review');
|
||||
expect(codeReviewSkill.keywords).toContain('审查');
|
||||
});
|
||||
});
|
||||
|
||||
describe('explainCodeSkill - 代码解释', () => {
|
||||
it('有正确的名称', () => {
|
||||
expect(explainCodeSkill.name).toBe('explain-code');
|
||||
expect(explainCodeSkill.displayName).toBe('代码解释');
|
||||
});
|
||||
|
||||
it('属于 development 分类', () => {
|
||||
expect(explainCodeSkill.category).toBe('development');
|
||||
});
|
||||
|
||||
it('code 参数是必需的', () => {
|
||||
expect(explainCodeSkill.parameters.code.required).toBe(true);
|
||||
});
|
||||
|
||||
it('level 参数有枚举值', () => {
|
||||
expect(explainCodeSkill.parameters.level.enum).toContain('beginner');
|
||||
expect(explainCodeSkill.parameters.level.enum).toContain('intermediate');
|
||||
expect(explainCodeSkill.parameters.level.enum).toContain('advanced');
|
||||
});
|
||||
|
||||
it('level 参数有默认值', () => {
|
||||
expect(explainCodeSkill.parameters.level.default).toBe('intermediate');
|
||||
});
|
||||
});
|
||||
|
||||
describe('generateDocsSkill - 文档生成', () => {
|
||||
it('有正确的名称', () => {
|
||||
expect(generateDocsSkill.name).toBe('generate-docs');
|
||||
expect(generateDocsSkill.displayName).toBe('文档生成');
|
||||
});
|
||||
|
||||
it('属于 documentation 分类', () => {
|
||||
expect(generateDocsSkill.category).toBe('documentation');
|
||||
});
|
||||
|
||||
it('type 参数有多种文档类型', () => {
|
||||
expect(generateDocsSkill.parameters.type.enum).toContain('JSDoc');
|
||||
expect(generateDocsSkill.parameters.type.enum).toContain('TSDoc');
|
||||
expect(generateDocsSkill.parameters.type.enum).toContain('README');
|
||||
});
|
||||
|
||||
it('type 参数有默认值', () => {
|
||||
expect(generateDocsSkill.parameters.type.default).toBe('文档注释');
|
||||
});
|
||||
});
|
||||
|
||||
describe('generateTestsSkill - 测试生成', () => {
|
||||
it('有正确的名称', () => {
|
||||
expect(generateTestsSkill.name).toBe('generate-tests');
|
||||
expect(generateTestsSkill.displayName).toBe('测试生成');
|
||||
});
|
||||
|
||||
it('属于 testing 分类', () => {
|
||||
expect(generateTestsSkill.category).toBe('testing');
|
||||
});
|
||||
|
||||
it('framework 参数有多个框架选项', () => {
|
||||
expect(generateTestsSkill.parameters.framework.enum).toContain('vitest');
|
||||
expect(generateTestsSkill.parameters.framework.enum).toContain('jest');
|
||||
expect(generateTestsSkill.parameters.framework.enum).toContain('mocha');
|
||||
expect(generateTestsSkill.parameters.framework.enum).toContain('pytest');
|
||||
});
|
||||
|
||||
it('framework 默认为 vitest', () => {
|
||||
expect(generateTestsSkill.parameters.framework.default).toBe('vitest');
|
||||
});
|
||||
});
|
||||
|
||||
describe('refactorSuggestSkill - 重构建议', () => {
|
||||
it('有正确的名称', () => {
|
||||
expect(refactorSuggestSkill.name).toBe('refactor-suggest');
|
||||
expect(refactorSuggestSkill.displayName).toBe('重构建议');
|
||||
});
|
||||
|
||||
it('属于 development 分类', () => {
|
||||
expect(refactorSuggestSkill.category).toBe('development');
|
||||
});
|
||||
|
||||
it('goal 参数是可选的', () => {
|
||||
expect(refactorSuggestSkill.parameters.goal.required).toBe(false);
|
||||
});
|
||||
|
||||
it('模板包含重构相关内容', () => {
|
||||
expect(refactorSuggestSkill.promptTemplate).toContain('重构');
|
||||
expect(refactorSuggestSkill.promptTemplate).toContain('{{code}}');
|
||||
});
|
||||
});
|
||||
|
||||
describe('fixBugSkill - Bug 修复', () => {
|
||||
it('有正确的名称', () => {
|
||||
expect(fixBugSkill.name).toBe('fix-bug');
|
||||
expect(fixBugSkill.displayName).toBe('Bug 修复');
|
||||
});
|
||||
|
||||
it('属于 debugging 分类', () => {
|
||||
expect(fixBugSkill.category).toBe('debugging');
|
||||
});
|
||||
|
||||
it('有 error 和 context 可选参数', () => {
|
||||
expect(fixBugSkill.parameters.error.required).toBe(false);
|
||||
expect(fixBugSkill.parameters.context.required).toBe(false);
|
||||
});
|
||||
|
||||
it('模板支持错误信息和上下文', () => {
|
||||
expect(fixBugSkill.promptTemplate).toContain('{{#if error}}');
|
||||
expect(fixBugSkill.promptTemplate).toContain('{{#if context}}');
|
||||
});
|
||||
});
|
||||
|
||||
describe('gitCommitSkill - Git Commit', () => {
|
||||
it('有正确的名称', () => {
|
||||
expect(gitCommitSkill.name).toBe('git-commit');
|
||||
expect(gitCommitSkill.displayName).toBe('Git Commit');
|
||||
});
|
||||
|
||||
it('属于 git 分类', () => {
|
||||
expect(gitCommitSkill.category).toBe('git');
|
||||
});
|
||||
|
||||
it('diff 参数是必需的', () => {
|
||||
expect(gitCommitSkill.parameters.diff.required).toBe(true);
|
||||
});
|
||||
|
||||
it('type 参数有 conventional commit 类型', () => {
|
||||
expect(gitCommitSkill.parameters.type.enum).toContain('feat');
|
||||
expect(gitCommitSkill.parameters.type.enum).toContain('fix');
|
||||
expect(gitCommitSkill.parameters.type.enum).toContain('docs');
|
||||
expect(gitCommitSkill.parameters.type.enum).toContain('refactor');
|
||||
});
|
||||
|
||||
it('模板提到 Conventional Commits', () => {
|
||||
expect(gitCommitSkill.promptTemplate).toContain('Conventional Commits');
|
||||
});
|
||||
});
|
||||
|
||||
describe('apiDesignSkill - API 设计', () => {
|
||||
it('有正确的名称', () => {
|
||||
expect(apiDesignSkill.name).toBe('api-design');
|
||||
expect(apiDesignSkill.displayName).toBe('API 设计');
|
||||
});
|
||||
|
||||
it('属于 architecture 分类', () => {
|
||||
expect(apiDesignSkill.category).toBe('architecture');
|
||||
});
|
||||
|
||||
it('requirement 参数是必需的', () => {
|
||||
expect(apiDesignSkill.parameters.requirement.required).toBe(true);
|
||||
});
|
||||
|
||||
it('constraints 参数是可选的', () => {
|
||||
expect(apiDesignSkill.parameters.constraints.required).toBe(false);
|
||||
});
|
||||
|
||||
it('模板提到 RESTful API', () => {
|
||||
expect(apiDesignSkill.promptTemplate).toContain('RESTful API');
|
||||
});
|
||||
});
|
||||
|
||||
describe('参数类型验证', () => {
|
||||
it('所有必需参数都是 string 类型', () => {
|
||||
builtinSkills.forEach((skill) => {
|
||||
Object.entries(skill.parameters).forEach(([, param]) => {
|
||||
if (param.required) {
|
||||
expect(param.type).toBe('string');
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('所有参数都有描述', () => {
|
||||
builtinSkills.forEach((skill) => {
|
||||
Object.entries(skill.parameters).forEach(([, param]) => {
|
||||
expect(param.description).toBeDefined();
|
||||
expect(param.description.length).toBeGreaterThan(0);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('分类覆盖', () => {
|
||||
it('覆盖多个分类', () => {
|
||||
const categories = new Set(builtinSkills.map((s) => s.category));
|
||||
expect(categories.size).toBeGreaterThan(3);
|
||||
expect(categories).toContain('development');
|
||||
expect(categories).toContain('documentation');
|
||||
expect(categories).toContain('testing');
|
||||
expect(categories).toContain('debugging');
|
||||
expect(categories).toContain('git');
|
||||
expect(categories).toContain('architecture');
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user