feat: 优化鲁班角色并完善ToolSandbox工具开发体系
## 鲁班角色优化 - 新增tool-best-practices知识模块:工具设计最佳实践、性能优化、安全防护 - 新增dpml-tool-tagging知识模块:DPML工具标签四组件架构精通 - 增强craftsmanship思维模式:现代工具特征完善 - 资源迁移到包级别:支持跨项目共享 ## ToolSandbox架构完善 - 实现ToolSandbox类:支持@tool://协议的三阶段执行流程 - 优化依赖管理:getDependencies()接口标准化 - 完善UserProtocol:支持@user://沙箱目录访问 - 增强工具发现:FilePatternDiscovery支持多种文件模式 ## 工具生态建设 - 添加tool.tag.md:DPML工具标签框架完整定义 - 重构ToolInterface:统一getDependencies()接口规范 - 优化ToolExecutor:集成ToolSandbox执行流程 - 更新注册表:29个资源完整注册发现 ## 技术架构改进 - pnpm依赖集成:自动化沙箱环境管理 - 协议系统完善:@tool://和@user://协议标准化 - 资源结构统一:包级别和项目级别一致性 - 开发流程标准化:从需求分析到质量保证的完整工作流 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
264
resource/role/luban/knowledge/dpml-tool-tagging.knowledge.md
Normal file
264
resource/role/luban/knowledge/dpml-tool-tagging.knowledge.md
Normal file
@ -0,0 +1,264 @@
|
||||
# DPML工具标签体系精通
|
||||
|
||||
<knowledge>
|
||||
|
||||
## 🏷️ DPML工具标签框架深度理解
|
||||
|
||||
### 四组件架构精通
|
||||
DPML#工具提示单元 基于四组件架构构建完整的AI工具定义:
|
||||
|
||||
```xml
|
||||
<tool>
|
||||
<purpose>用途说明 - 明确工具解决什么问题</purpose>
|
||||
<usage>使用方法 - 详细说明如何正确使用</usage>
|
||||
<parameter>参数定义 - 明确工具需要什么输入</parameter>
|
||||
<outcome>预期结果 - 描述工具执行后的预期输出</outcome>
|
||||
</tool>
|
||||
```
|
||||
|
||||
### 指导与执行分离哲学
|
||||
- **工具定义专注于使用指导**:不包含具体代码实现
|
||||
- **代码执行通过MCP工具系统**:`promptx_tool`负责具体执行
|
||||
- **实现完整闭环**:指导-执行-验证的完整流程
|
||||
|
||||
## 📝 标准工具标签编写模板
|
||||
|
||||
### Purpose组件编写精要
|
||||
```xml
|
||||
<purpose>
|
||||
## 核心问题定义
|
||||
明确描述工具要解决的具体问题和适用场景
|
||||
|
||||
## 价值主张
|
||||
- 🎯 **解决什么痛点**:具体描述用户痛点
|
||||
- 🚀 **带来什么价值**:明确量化收益
|
||||
- 🌟 **独特优势**:相比其他解决方案的优势
|
||||
|
||||
## 应用边界
|
||||
- ✅ **适用场景**:详细列出适用情况
|
||||
- ❌ **不适用场景**:明确使用边界
|
||||
</purpose>
|
||||
```
|
||||
|
||||
### Usage组件编写精要
|
||||
```xml
|
||||
<usage>
|
||||
## 使用时机
|
||||
- 在什么情况下应该使用这个工具
|
||||
- 如何判断是否需要使用
|
||||
|
||||
## 操作步骤
|
||||
1. **准备阶段**:需要提前准备什么
|
||||
2. **执行阶段**:具体操作流程
|
||||
3. **验证阶段**:如何验证结果
|
||||
|
||||
## 最佳实践
|
||||
- 🎯 **效率提升技巧**
|
||||
- ⚠️ **常见陷阱避免**
|
||||
- 🔧 **故障排除指南**
|
||||
|
||||
## 注意事项
|
||||
- 安全性考虑
|
||||
- 性能优化建议
|
||||
- 兼容性要求
|
||||
</usage>
|
||||
```
|
||||
|
||||
### Parameter组件编写精要
|
||||
```xml
|
||||
<parameter>
|
||||
## 必需参数
|
||||
| 参数名 | 类型 | 描述 | 示例 |
|
||||
|--------|------|------|------|
|
||||
| input | string | 输入文本 | "Hello World" |
|
||||
|
||||
## 可选参数
|
||||
| 参数名 | 类型 | 默认值 | 描述 |
|
||||
|--------|------|--------|------|
|
||||
| format | string | "json" | 输出格式 |
|
||||
|
||||
## 参数约束
|
||||
- **长度限制**:input 不超过 10000 字符
|
||||
- **格式要求**:必须是有效的 UTF-8 编码
|
||||
- **安全限制**:不允许包含可执行代码
|
||||
|
||||
## 参数示例
|
||||
```json
|
||||
{
|
||||
"input": "需要处理的文本内容",
|
||||
"options": {
|
||||
"format": "json",
|
||||
"encoding": "utf-8"
|
||||
}
|
||||
}
|
||||
```
|
||||
</parameter>
|
||||
```
|
||||
|
||||
### Outcome组件编写精要
|
||||
```xml
|
||||
<outcome>
|
||||
## 成功返回格式
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"data": {
|
||||
"result": "处理结果",
|
||||
"metadata": {
|
||||
"processingTime": 150,
|
||||
"timestamp": "2024-01-01T12:00:00Z"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 错误处理格式
|
||||
```json
|
||||
{
|
||||
"success": false,
|
||||
"error": {
|
||||
"code": "VALIDATION_ERROR",
|
||||
"message": "输入参数验证失败",
|
||||
"details": "具体错误详情"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 结果解读指南
|
||||
- **如何判断执行成功**:检查 success 字段
|
||||
- **如何获取核心数据**:data.result 包含主要结果
|
||||
- **如何处理错误**:根据 error.code 分类处理
|
||||
- **如何优化下次使用**:根据 metadata 调优参数
|
||||
|
||||
## 后续动作建议
|
||||
- 成功时的下一步操作
|
||||
- 失败时的重试策略
|
||||
- 结果的进一步处理方式
|
||||
</outcome>
|
||||
```
|
||||
|
||||
## 🎯 工具标签质量标准
|
||||
|
||||
### Purpose质量检查
|
||||
- ✅ 问题定义清晰具体
|
||||
- ✅ 价值主张明确量化
|
||||
- ✅ 应用边界明确划分
|
||||
- ✅ 用户痛点精准描述
|
||||
|
||||
### Usage质量检查
|
||||
- ✅ 使用时机判断明确
|
||||
- ✅ 操作步骤完整可执行
|
||||
- ✅ 最佳实践实用有效
|
||||
- ✅ 注意事项全面详细
|
||||
|
||||
### Parameter质量检查
|
||||
- ✅ 参数分类准确(必需/可选)
|
||||
- ✅ 类型定义精确
|
||||
- ✅ 约束条件明确
|
||||
- ✅ 示例完整有效
|
||||
|
||||
### Outcome质量检查
|
||||
- ✅ 返回格式标准化
|
||||
- ✅ 错误处理完整
|
||||
- ✅ 解读指南清晰
|
||||
- ✅ 后续动作明确
|
||||
|
||||
## 🛠️ 工具标签与代码实现的映射关系
|
||||
|
||||
### 从Purpose到getMetadata()
|
||||
```javascript
|
||||
// Purpose中的核心问题 → getMetadata()中的description
|
||||
getMetadata() {
|
||||
return {
|
||||
name: 'text-processor',
|
||||
description: 'Purpose中定义的核心问题和价值主张',
|
||||
category: 'Purpose中的应用领域'
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
### 从Parameter到getSchema()
|
||||
```javascript
|
||||
// Parameter中的参数定义 → getSchema()中的JSON Schema
|
||||
getSchema() {
|
||||
return {
|
||||
type: 'object',
|
||||
properties: {
|
||||
// Parameter表格中的每个参数
|
||||
input: {
|
||||
type: 'string',
|
||||
description: 'Parameter中的参数描述'
|
||||
}
|
||||
},
|
||||
required: ['input'] // Parameter中的必需参数
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
### 从Usage到validate()和execute()
|
||||
```javascript
|
||||
// Usage中的最佳实践 → validate()中的验证逻辑
|
||||
validate(params) {
|
||||
// Usage中提到的参数约束检查
|
||||
// Usage中的安全性考虑
|
||||
}
|
||||
|
||||
// Usage中的操作步骤 → execute()中的执行流程
|
||||
async execute(params) {
|
||||
// 1. 准备阶段的代码实现
|
||||
// 2. 执行阶段的核心逻辑
|
||||
// 3. 验证阶段的结果检查
|
||||
}
|
||||
```
|
||||
|
||||
### 从Outcome到返回值格式
|
||||
```javascript
|
||||
// Outcome中的返回格式 → execute()的返回值结构
|
||||
return {
|
||||
success: true, // Outcome中定义的成功标识
|
||||
data: result, // Outcome中定义的数据格式
|
||||
metadata: { // Outcome中定义的元数据
|
||||
executionTime: Date.now() - startTime
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
## 📊 标签驱动的开发流程
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A[用户需求] --> B[编写Purpose]
|
||||
B --> C[设计Usage]
|
||||
C --> D[定义Parameter]
|
||||
D --> E[规划Outcome]
|
||||
E --> F[生成工具标签]
|
||||
F --> G[映射到代码接口]
|
||||
G --> H[实现具体逻辑]
|
||||
H --> I[测试验证]
|
||||
I --> J[完整工具交付]
|
||||
```
|
||||
|
||||
### 开发质量保证
|
||||
1. **标签先行**:先完成工具标签定义,再编写代码
|
||||
2. **映射验证**:确保代码实现与标签定义一致
|
||||
3. **用户测试**:基于标签进行用户验收测试
|
||||
4. **文档同步**:保持标签和代码的同步更新
|
||||
|
||||
## 🌟 卓越工具标签特征
|
||||
|
||||
### 用户友好性
|
||||
- 语言通俗易懂,避免技术术语
|
||||
- 结构清晰,信息层次分明
|
||||
- 示例丰富,便于理解和使用
|
||||
|
||||
### 技术准确性
|
||||
- 参数定义精确,类型明确
|
||||
- 约束条件完整,边界清晰
|
||||
- 返回格式标准,错误处理完善
|
||||
|
||||
### 实用可操作性
|
||||
- 步骤详细具体,可直接执行
|
||||
- 最佳实践实用,经过验证
|
||||
- 故障排除全面,覆盖常见问题
|
||||
|
||||
</knowledge>
|
||||
549
resource/role/luban/knowledge/javascript-ecosystem.knowledge.md
Normal file
549
resource/role/luban/knowledge/javascript-ecosystem.knowledge.md
Normal file
@ -0,0 +1,549 @@
|
||||
# JavaScript生态系统精通
|
||||
|
||||
<knowledge>
|
||||
|
||||
## 🚀 现代JavaScript精通
|
||||
|
||||
### ES6+核心特性
|
||||
```javascript
|
||||
// 解构赋值与默认参数
|
||||
function createTool({ name, version = '1.0.0', dependencies = [] }) {
|
||||
return { name, version, dependencies };
|
||||
}
|
||||
|
||||
// 箭头函数与Promise
|
||||
const processAsync = async (data) => {
|
||||
const results = await Promise.all(
|
||||
data.map(item => processItem(item))
|
||||
);
|
||||
return results.filter(Boolean);
|
||||
};
|
||||
|
||||
// 模板字符串与标签函数
|
||||
function sqlQuery(strings, ...values) {
|
||||
return strings.reduce((query, string, i) => {
|
||||
const value = values[i] ? sanitize(values[i]) : '';
|
||||
return query + string + value;
|
||||
}, '');
|
||||
}
|
||||
|
||||
// 类与继承
|
||||
class ToolBase {
|
||||
constructor(name) {
|
||||
this.name = name;
|
||||
this.startTime = Date.now();
|
||||
}
|
||||
|
||||
async execute(params) {
|
||||
throw new Error('子类必须实现execute方法');
|
||||
}
|
||||
|
||||
getExecutionTime() {
|
||||
return Date.now() - this.startTime;
|
||||
}
|
||||
}
|
||||
|
||||
// Symbol与迭代器
|
||||
const PRIVATE_KEY = Symbol('private');
|
||||
class Tool {
|
||||
constructor() {
|
||||
this[PRIVATE_KEY] = { cache: new Map() };
|
||||
}
|
||||
|
||||
*[Symbol.iterator]() {
|
||||
yield* this.getResults();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 异步编程精通
|
||||
```javascript
|
||||
// Promise链式处理
|
||||
function processChain(data) {
|
||||
return Promise.resolve(data)
|
||||
.then(validate)
|
||||
.then(transform)
|
||||
.then(save)
|
||||
.catch(handleError)
|
||||
.finally(cleanup);
|
||||
}
|
||||
|
||||
// async/await错误处理
|
||||
async function safeExecute(fn, ...args) {
|
||||
try {
|
||||
const result = await fn(...args);
|
||||
return { success: true, data: result };
|
||||
} catch (error) {
|
||||
return { success: false, error: error.message };
|
||||
}
|
||||
}
|
||||
|
||||
// 并发控制
|
||||
class ConcurrencyManager {
|
||||
constructor(limit = 3) {
|
||||
this.limit = limit;
|
||||
this.running = 0;
|
||||
this.queue = [];
|
||||
}
|
||||
|
||||
async execute(fn) {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.queue.push({ fn, resolve, reject });
|
||||
this.process();
|
||||
});
|
||||
}
|
||||
|
||||
async process() {
|
||||
if (this.running >= this.limit || this.queue.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.running++;
|
||||
const { fn, resolve, reject } = this.queue.shift();
|
||||
|
||||
try {
|
||||
const result = await fn();
|
||||
resolve(result);
|
||||
} catch (error) {
|
||||
reject(error);
|
||||
} finally {
|
||||
this.running--;
|
||||
this.process();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 超时控制
|
||||
function withTimeout(promise, ms) {
|
||||
const timeout = new Promise((_, reject) =>
|
||||
setTimeout(() => reject(new Error('操作超时')), ms)
|
||||
);
|
||||
return Promise.race([promise, timeout]);
|
||||
}
|
||||
```
|
||||
|
||||
## 📦 npm生态系统精通
|
||||
|
||||
### package.json深度配置
|
||||
```json
|
||||
{
|
||||
"name": "my-awesome-tool",
|
||||
"version": "1.0.0",
|
||||
"description": "一个很棒的工具",
|
||||
"main": "index.js",
|
||||
"engines": {
|
||||
"node": ">=14.0.0",
|
||||
"npm": ">=6.0.0"
|
||||
},
|
||||
"scripts": {
|
||||
"start": "node index.js",
|
||||
"test": "jest",
|
||||
"lint": "eslint .",
|
||||
"format": "prettier --write .",
|
||||
"preinstall": "node scripts/check-env.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"lodash": "^4.17.21",
|
||||
"axios": "^1.6.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"jest": "^29.0.0",
|
||||
"eslint": "^8.0.0",
|
||||
"prettier": "^2.8.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": ">=16.8.0"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"fsevents": "^2.3.0"
|
||||
},
|
||||
"keywords": ["tool", "automation", "utility"],
|
||||
"author": "鲁班 <luban@promptx.ai>",
|
||||
"license": "MIT",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/promptx/awesome-tool.git"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/promptx/awesome-tool/issues"
|
||||
},
|
||||
"homepage": "https://github.com/promptx/awesome-tool#readme"
|
||||
}
|
||||
```
|
||||
|
||||
### 版本管理策略
|
||||
```javascript
|
||||
// 语义化版本控制
|
||||
const semver = require('semver');
|
||||
|
||||
function updateVersion(currentVersion, changeType) {
|
||||
switch (changeType) {
|
||||
case 'patch': // 1.0.0 -> 1.0.1 (bug fixes)
|
||||
return semver.inc(currentVersion, 'patch');
|
||||
case 'minor': // 1.0.0 -> 1.1.0 (new features)
|
||||
return semver.inc(currentVersion, 'minor');
|
||||
case 'major': // 1.0.0 -> 2.0.0 (breaking changes)
|
||||
return semver.inc(currentVersion, 'major');
|
||||
default:
|
||||
throw new Error('无效的版本类型');
|
||||
}
|
||||
}
|
||||
|
||||
// 版本兼容性检查
|
||||
function checkCompatibility(required, current) {
|
||||
return semver.satisfies(current, required);
|
||||
}
|
||||
```
|
||||
|
||||
### 依赖管理最佳实践
|
||||
```javascript
|
||||
// 依赖安全检查
|
||||
const auditDependencies = async () => {
|
||||
const { exec } = require('child_process');
|
||||
const { promisify } = require('util');
|
||||
const execAsync = promisify(exec);
|
||||
|
||||
try {
|
||||
const { stdout } = await execAsync('npm audit --json');
|
||||
const auditResult = JSON.parse(stdout);
|
||||
|
||||
if (auditResult.vulnerabilities) {
|
||||
console.warn('发现安全漏洞:', auditResult.vulnerabilities);
|
||||
}
|
||||
|
||||
return auditResult;
|
||||
} catch (error) {
|
||||
console.error('安全审计失败:', error.message);
|
||||
}
|
||||
};
|
||||
|
||||
// 依赖大小分析
|
||||
const analyzeBundleSize = (packageName) => {
|
||||
const bundlePhobia = require('bundle-phobia');
|
||||
return bundlePhobia.getPackageStats(packageName);
|
||||
};
|
||||
|
||||
// 依赖树分析
|
||||
const analyzeDependencyTree = () => {
|
||||
const fs = require('fs');
|
||||
const packageLock = JSON.parse(fs.readFileSync('package-lock.json'));
|
||||
|
||||
function walkDependencies(deps, level = 0) {
|
||||
for (const [name, info] of Object.entries(deps)) {
|
||||
console.log(' '.repeat(level) + `${name}@${info.version}`);
|
||||
if (info.dependencies) {
|
||||
walkDependencies(info.dependencies, level + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
walkDependencies(packageLock.dependencies);
|
||||
};
|
||||
```
|
||||
|
||||
## 🔧 模块系统精通
|
||||
|
||||
### CommonJS深度应用
|
||||
```javascript
|
||||
// 模块导出模式
|
||||
// 1. 单一导出
|
||||
module.exports = class Tool {
|
||||
execute() { /* ... */ }
|
||||
};
|
||||
|
||||
// 2. 多重导出
|
||||
module.exports = {
|
||||
Tool,
|
||||
ToolManager,
|
||||
createTool: (config) => new Tool(config)
|
||||
};
|
||||
|
||||
// 3. 动态导出
|
||||
const tools = {};
|
||||
const toolFiles = fs.readdirSync('./tools');
|
||||
toolFiles.forEach(file => {
|
||||
const name = path.basename(file, '.js');
|
||||
tools[name] = require(`./tools/${file}`);
|
||||
});
|
||||
module.exports = tools;
|
||||
|
||||
// 4. 条件导出
|
||||
if (process.env.NODE_ENV === 'development') {
|
||||
module.exports.debug = require('./debug');
|
||||
}
|
||||
```
|
||||
|
||||
### require缓存机制
|
||||
```javascript
|
||||
// 缓存清理
|
||||
function clearRequireCache(modulePath) {
|
||||
const resolved = require.resolve(modulePath);
|
||||
delete require.cache[resolved];
|
||||
}
|
||||
|
||||
// 热重载实现
|
||||
class HotReloader {
|
||||
constructor() {
|
||||
this.watchers = new Map();
|
||||
}
|
||||
|
||||
watch(modulePath, callback) {
|
||||
const watcher = fs.watch(modulePath, () => {
|
||||
clearRequireCache(modulePath);
|
||||
const newModule = require(modulePath);
|
||||
callback(newModule);
|
||||
});
|
||||
|
||||
this.watchers.set(modulePath, watcher);
|
||||
}
|
||||
|
||||
unwatch(modulePath) {
|
||||
const watcher = this.watchers.get(modulePath);
|
||||
if (watcher) {
|
||||
watcher.close();
|
||||
this.watchers.delete(modulePath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 模块路径解析
|
||||
function resolveModule(moduleName, fromPath) {
|
||||
const Module = require('module');
|
||||
const originalResolveFilename = Module._resolveFilename;
|
||||
|
||||
return originalResolveFilename.call(Module, moduleName, {
|
||||
id: fromPath,
|
||||
filename: fromPath,
|
||||
paths: Module._nodeModulePaths(path.dirname(fromPath))
|
||||
});
|
||||
}
|
||||
```
|
||||
|
||||
## 🛠️ 开发工具精通
|
||||
|
||||
### ESLint配置优化
|
||||
```javascript
|
||||
// .eslintrc.js
|
||||
module.exports = {
|
||||
env: {
|
||||
node: true,
|
||||
es2021: true,
|
||||
jest: true
|
||||
},
|
||||
extends: [
|
||||
'eslint:recommended',
|
||||
'plugin:security/recommended'
|
||||
],
|
||||
parserOptions: {
|
||||
ecmaVersion: 'latest',
|
||||
sourceType: 'module'
|
||||
},
|
||||
plugins: ['security'],
|
||||
rules: {
|
||||
'no-console': 'warn',
|
||||
'no-unused-vars': 'error',
|
||||
'prefer-const': 'error',
|
||||
'no-var': 'error',
|
||||
'security/detect-eval-with-expression': 'error',
|
||||
'security/detect-non-literal-fs-filename': 'warn'
|
||||
},
|
||||
overrides: [
|
||||
{
|
||||
files: ['*.test.js', '*.spec.js'],
|
||||
rules: {
|
||||
'no-console': 'off'
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
```
|
||||
|
||||
### Prettier格式化配置
|
||||
```json
|
||||
{
|
||||
"semi": true,
|
||||
"trailingComma": "es5",
|
||||
"singleQuote": true,
|
||||
"printWidth": 80,
|
||||
"tabWidth": 2,
|
||||
"useTabs": false,
|
||||
"bracketSpacing": true,
|
||||
"arrowParens": "avoid",
|
||||
"endOfLine": "lf"
|
||||
}
|
||||
```
|
||||
|
||||
### Jest测试框架
|
||||
```javascript
|
||||
// jest.config.js
|
||||
module.exports = {
|
||||
testEnvironment: 'node',
|
||||
roots: ['<rootDir>/src', '<rootDir>/tests'],
|
||||
testMatch: [
|
||||
'**/__tests__/**/*.js',
|
||||
'**/?(*.)+(spec|test).js'
|
||||
],
|
||||
collectCoverageFrom: [
|
||||
'src/**/*.js',
|
||||
'!src/**/*.test.js'
|
||||
],
|
||||
coverageDirectory: 'coverage',
|
||||
coverageReporters: ['text', 'lcov', 'html'],
|
||||
setupFilesAfterEnv: ['<rootDir>/tests/setup.js']
|
||||
};
|
||||
|
||||
// 测试示例
|
||||
describe('Tool', () => {
|
||||
let tool;
|
||||
|
||||
beforeEach(() => {
|
||||
tool = new Tool();
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
||||
await tool.cleanup();
|
||||
});
|
||||
|
||||
test('should execute successfully', async () => {
|
||||
const result = await tool.execute({ input: 'test' });
|
||||
expect(result).toHaveProperty('success', true);
|
||||
});
|
||||
|
||||
test('should handle errors gracefully', async () => {
|
||||
await expect(tool.execute({})).rejects.toThrow('Missing input');
|
||||
});
|
||||
|
||||
test('should validate parameters', () => {
|
||||
const validation = tool.validate({ input: 'valid' });
|
||||
expect(validation.valid).toBe(true);
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
## 🔒 安全编程实践
|
||||
|
||||
### 输入验证与清理
|
||||
```javascript
|
||||
const validator = require('validator');
|
||||
|
||||
class InputValidator {
|
||||
static sanitizeString(input, maxLength = 1000) {
|
||||
if (typeof input !== 'string') {
|
||||
throw new Error('输入必须是字符串');
|
||||
}
|
||||
|
||||
// 长度限制
|
||||
if (input.length > maxLength) {
|
||||
throw new Error(`输入长度超过限制: ${maxLength}`);
|
||||
}
|
||||
|
||||
// XSS防护
|
||||
return validator.escape(input);
|
||||
}
|
||||
|
||||
static validateEmail(email) {
|
||||
if (!validator.isEmail(email)) {
|
||||
throw new Error('无效的邮箱地址');
|
||||
}
|
||||
return validator.normalizeEmail(email);
|
||||
}
|
||||
|
||||
static validateURL(url) {
|
||||
if (!validator.isURL(url)) {
|
||||
throw new Error('无效的URL');
|
||||
}
|
||||
return url;
|
||||
}
|
||||
|
||||
static sanitizeFilename(filename) {
|
||||
// 移除危险字符
|
||||
return filename.replace(/[^a-zA-Z0-9._-]/g, '');
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 错误处理与日志
|
||||
```javascript
|
||||
class ToolLogger {
|
||||
constructor(toolName) {
|
||||
this.toolName = toolName;
|
||||
this.startTime = Date.now();
|
||||
}
|
||||
|
||||
info(message, data = {}) {
|
||||
console.log(JSON.stringify({
|
||||
level: 'info',
|
||||
tool: this.toolName,
|
||||
message,
|
||||
data,
|
||||
timestamp: new Date().toISOString()
|
||||
}));
|
||||
}
|
||||
|
||||
error(message, error = {}) {
|
||||
console.error(JSON.stringify({
|
||||
level: 'error',
|
||||
tool: this.toolName,
|
||||
message,
|
||||
error: {
|
||||
message: error.message,
|
||||
stack: error.stack
|
||||
},
|
||||
timestamp: new Date().toISOString()
|
||||
}));
|
||||
}
|
||||
|
||||
performance(operation, duration) {
|
||||
this.info(`Performance: ${operation}`, { duration });
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 资源管理与限制
|
||||
```javascript
|
||||
class ResourceManager {
|
||||
constructor(options = {}) {
|
||||
this.maxMemory = options.maxMemory || 100 * 1024 * 1024; // 100MB
|
||||
this.maxExecutionTime = options.maxExecutionTime || 30000; // 30s
|
||||
this.activeOperations = new Set();
|
||||
}
|
||||
|
||||
async executeWithLimits(operation, context) {
|
||||
const operationId = Math.random().toString(36);
|
||||
this.activeOperations.add(operationId);
|
||||
|
||||
const timeoutPromise = new Promise((_, reject) => {
|
||||
setTimeout(() => {
|
||||
reject(new Error('操作超时'));
|
||||
}, this.maxExecutionTime);
|
||||
});
|
||||
|
||||
try {
|
||||
// 内存监控
|
||||
const initialMemory = process.memoryUsage().heapUsed;
|
||||
|
||||
const result = await Promise.race([
|
||||
operation(),
|
||||
timeoutPromise
|
||||
]);
|
||||
|
||||
const finalMemory = process.memoryUsage().heapUsed;
|
||||
const memoryUsed = finalMemory - initialMemory;
|
||||
|
||||
if (memoryUsed > this.maxMemory) {
|
||||
console.warn(`内存使用超限: ${memoryUsed / 1024 / 1024}MB`);
|
||||
}
|
||||
|
||||
return result;
|
||||
} finally {
|
||||
this.activeOperations.delete(operationId);
|
||||
}
|
||||
}
|
||||
|
||||
getActiveOperations() {
|
||||
return this.activeOperations.size;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
</knowledge>
|
||||
@ -0,0 +1,416 @@
|
||||
# PromptX工具架构知识体系
|
||||
|
||||
<knowledge>
|
||||
|
||||
## 🏗️ 核心架构组件
|
||||
|
||||
### ToolSandbox系统架构
|
||||
```mermaid
|
||||
graph TD
|
||||
A[Tool Request] --> B[ResourceManager]
|
||||
B --> C[Protocol Resolution]
|
||||
C --> D[ToolSandbox Creation]
|
||||
D --> E[Dependency Management]
|
||||
E --> F[VM Execution]
|
||||
F --> G[Result Return]
|
||||
|
||||
subgraph "沙箱环境"
|
||||
H[@user://.promptx/toolbox]
|
||||
I[pnpm dependencies]
|
||||
J[isolated execution]
|
||||
end
|
||||
|
||||
D --> H
|
||||
E --> I
|
||||
F --> J
|
||||
```
|
||||
|
||||
### 工具接口标准
|
||||
```javascript
|
||||
// PromptX ToolInterface v2.0
|
||||
module.exports = {
|
||||
// 🆕 新接口:依赖管理
|
||||
getDependencies() {
|
||||
return ['lodash@^4.17.21', 'axios@^1.6.0'];
|
||||
},
|
||||
|
||||
// 核心接口:元信息
|
||||
getMetadata() {
|
||||
return {
|
||||
name: 'tool-name',
|
||||
description: '工具描述',
|
||||
version: '1.0.0',
|
||||
category: 'utility',
|
||||
author: '作者',
|
||||
tags: ['tag1', 'tag2']
|
||||
};
|
||||
},
|
||||
|
||||
// 核心接口:参数Schema
|
||||
getSchema() {
|
||||
return {
|
||||
type: 'object',
|
||||
properties: {
|
||||
input: { type: 'string', description: '输入参数' }
|
||||
},
|
||||
required: ['input']
|
||||
};
|
||||
},
|
||||
|
||||
// 可选接口:参数验证
|
||||
validate(params) {
|
||||
return { valid: true, errors: [] };
|
||||
},
|
||||
|
||||
// 核心接口:执行逻辑
|
||||
async execute(params) {
|
||||
// 工具核心逻辑
|
||||
return result;
|
||||
},
|
||||
|
||||
// 可选接口:初始化
|
||||
async init() {
|
||||
// 初始化逻辑
|
||||
},
|
||||
|
||||
// 可选接口:清理
|
||||
async cleanup() {
|
||||
// 清理逻辑
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
## 🔧 技术栈知识
|
||||
|
||||
### Node.js生态精通
|
||||
```javascript
|
||||
// ES6+特性应用
|
||||
const { promisify } = require('util');
|
||||
const fs = require('fs').promises;
|
||||
|
||||
// 异步编程模式
|
||||
async function processData(data) {
|
||||
try {
|
||||
const result = await Promise.all(
|
||||
data.map(item => processItem(item))
|
||||
);
|
||||
return result;
|
||||
} catch (error) {
|
||||
throw new Error(`Processing failed: ${error.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
// 错误处理最佳实践
|
||||
class ToolError extends Error {
|
||||
constructor(message, code, details) {
|
||||
super(message);
|
||||
this.name = 'ToolError';
|
||||
this.code = code;
|
||||
this.details = details;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 依赖管理精通
|
||||
```json
|
||||
// package.json最佳实践
|
||||
{
|
||||
"name": "toolbox-text-analyzer",
|
||||
"version": "1.0.0",
|
||||
"description": "Sandbox for tool: text-analyzer",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"lodash": "^4.17.21",
|
||||
"axios": "^1.6.0",
|
||||
"validator": "^13.11.0"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**依赖选择原则**:
|
||||
- **成熟度**:选择下载量大、维护活跃的包
|
||||
- **轻量化**:避免过重的依赖,注意bundle size
|
||||
- **兼容性**:确保Node.js版本兼容
|
||||
- **安全性**:定期检查安全漏洞
|
||||
|
||||
### VM沙箱技术
|
||||
```javascript
|
||||
// 基础沙箱环境
|
||||
const basicSandbox = {
|
||||
require: require,
|
||||
module: { exports: {} },
|
||||
exports: {},
|
||||
console: console,
|
||||
Buffer: Buffer,
|
||||
process: {
|
||||
env: process.env,
|
||||
hrtime: process.hrtime
|
||||
},
|
||||
// JavaScript内置对象
|
||||
Object, Array, String, Number, Boolean,
|
||||
Date, JSON, Math, RegExp, Error, URL
|
||||
};
|
||||
|
||||
// 智能沙箱环境(支持依赖)
|
||||
const smartSandbox = {
|
||||
require: (moduleName) => {
|
||||
try {
|
||||
// 优先从沙箱目录查找
|
||||
return require(require.resolve(moduleName, {
|
||||
paths: [
|
||||
path.join(sandboxPath, 'node_modules'),
|
||||
sandboxPath,
|
||||
process.cwd() + '/node_modules'
|
||||
]
|
||||
}));
|
||||
} catch (error) {
|
||||
return require(moduleName);
|
||||
}
|
||||
},
|
||||
// ... 其他环境对象
|
||||
};
|
||||
```
|
||||
|
||||
## 📚 工具库生态
|
||||
|
||||
### 常用工具库分类
|
||||
|
||||
**🔧 工具函数库**
|
||||
- **lodash** `^4.17.21` - 全功能工具函数库
|
||||
- **ramda** `^0.29.0` - 函数式编程工具
|
||||
- **validator** `^13.11.0` - 数据验证工具
|
||||
|
||||
**🌐 网络请求库**
|
||||
- **axios** `^1.6.0` - HTTP客户端库
|
||||
- **node-fetch** `^3.3.0` - Fetch API实现
|
||||
- **got** `^13.0.0` - 轻量HTTP请求库
|
||||
|
||||
**📄 文件处理库**
|
||||
- **fs-extra** `^11.1.0` - 增强文件系统操作
|
||||
- **glob** `^10.3.0` - 文件模式匹配
|
||||
- **chokidar** `^3.5.0` - 文件监控
|
||||
|
||||
**📊 数据处理库**
|
||||
- **moment** `^2.29.0` - 日期时间处理
|
||||
- **mathjs** `^11.11.0` - 数学计算库
|
||||
- **csv-parser** `^3.0.0` - CSV文件解析
|
||||
|
||||
**📧 服务集成库**
|
||||
- **nodemailer** `^6.9.0` - 邮件发送
|
||||
- **node-cron** `^3.0.0` - 定时任务
|
||||
- **sharp** `^0.32.0` - 图像处理
|
||||
|
||||
### 库选择决策树
|
||||
```mermaid
|
||||
graph TD
|
||||
A[需要功能] --> B{功能类型}
|
||||
B -->|数据处理| C[lodash/ramda]
|
||||
B -->|网络请求| D[axios/node-fetch]
|
||||
B -->|文件操作| E[fs-extra/glob]
|
||||
B -->|数据验证| F[validator/joi]
|
||||
B -->|日期时间| G[moment/dayjs]
|
||||
B -->|数学计算| H[mathjs]
|
||||
B -->|邮件服务| I[nodemailer]
|
||||
B -->|图像处理| J[sharp/jimp]
|
||||
```
|
||||
|
||||
## 🛡️ 安全与最佳实践
|
||||
|
||||
### 安全编程原则
|
||||
```javascript
|
||||
// 输入验证
|
||||
function validateInput(input) {
|
||||
if (typeof input !== 'string') {
|
||||
throw new Error('输入必须是字符串');
|
||||
}
|
||||
|
||||
if (input.length > 10000) {
|
||||
throw new Error('输入内容过长');
|
||||
}
|
||||
|
||||
// 防止代码注入
|
||||
if (/[<>'"&]/.test(input)) {
|
||||
throw new Error('输入包含危险字符');
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// 错误信息安全
|
||||
function safeErrorMessage(error) {
|
||||
// 不暴露敏感信息
|
||||
const safeMessage = error.message.replace(
|
||||
/\/Users\/[^\/]+/g, '~/***'
|
||||
);
|
||||
return safeMessage;
|
||||
}
|
||||
|
||||
// 资源限制
|
||||
function executeWithTimeout(fn, timeout = 30000) {
|
||||
return Promise.race([
|
||||
fn(),
|
||||
new Promise((_, reject) =>
|
||||
setTimeout(() => reject(new Error('执行超时')), timeout)
|
||||
)
|
||||
]);
|
||||
}
|
||||
```
|
||||
|
||||
### 性能优化模式
|
||||
```javascript
|
||||
// 缓存机制
|
||||
const cache = new Map();
|
||||
function memoize(fn) {
|
||||
return function(...args) {
|
||||
const key = JSON.stringify(args);
|
||||
if (cache.has(key)) {
|
||||
return cache.get(key);
|
||||
}
|
||||
const result = fn.apply(this, args);
|
||||
cache.set(key, result);
|
||||
return result;
|
||||
};
|
||||
}
|
||||
|
||||
// 批处理优化
|
||||
function batchProcess(items, batchSize = 10) {
|
||||
const batches = [];
|
||||
for (let i = 0; i < items.length; i += batchSize) {
|
||||
batches.push(items.slice(i, i + batchSize));
|
||||
}
|
||||
return batches;
|
||||
}
|
||||
|
||||
// 资源池管理
|
||||
class ResourcePool {
|
||||
constructor(createFn, maxSize = 10) {
|
||||
this.createFn = createFn;
|
||||
this.maxSize = maxSize;
|
||||
this.pool = [];
|
||||
this.active = new Set();
|
||||
}
|
||||
|
||||
async acquire() {
|
||||
if (this.pool.length > 0) {
|
||||
const resource = this.pool.pop();
|
||||
this.active.add(resource);
|
||||
return resource;
|
||||
}
|
||||
|
||||
if (this.active.size < this.maxSize) {
|
||||
const resource = await this.createFn();
|
||||
this.active.add(resource);
|
||||
return resource;
|
||||
}
|
||||
|
||||
throw new Error('资源池已满');
|
||||
}
|
||||
|
||||
release(resource) {
|
||||
this.active.delete(resource);
|
||||
this.pool.push(resource);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 🔄 协议系统深度理解
|
||||
|
||||
### ResourceManager工作流程
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant User
|
||||
participant RM as ResourceManager
|
||||
participant TP as ToolProtocol
|
||||
participant TS as ToolSandbox
|
||||
|
||||
User->>RM: loadResource('@tool://text-analyzer')
|
||||
RM->>RM: parseProtocol('tool', 'text-analyzer')
|
||||
RM->>TP: resolve('text-analyzer')
|
||||
TP->>TP: findResourceById('text-analyzer', 'tool')
|
||||
TP->>RM: return tool content
|
||||
RM->>User: return {success: true, content: '...'}
|
||||
User->>TS: new ToolSandbox('@tool://text-analyzer')
|
||||
TS->>RM: loadResource('@tool://text-analyzer')
|
||||
TS->>TS: analyze() → prepareDependencies() → execute()
|
||||
```
|
||||
|
||||
### 协议引用系统
|
||||
```javascript
|
||||
// 协议解析示例
|
||||
const parsed = protocolParser.parse('@tool://text-analyzer');
|
||||
// 结果: { protocol: 'tool', path: 'text-analyzer', queryParams: {} }
|
||||
|
||||
// 用户协议解析
|
||||
const userPath = protocolParser.parse('@user://.promptx/toolbox/text-analyzer');
|
||||
// 结果: { protocol: 'user', path: '.promptx/toolbox/text-analyzer' }
|
||||
|
||||
// 资源查找逻辑
|
||||
const resourceData = registryData.findResourceById('text-analyzer', 'tool');
|
||||
// 查找ID为'text-analyzer'且protocol为'tool'的资源
|
||||
```
|
||||
|
||||
## 📈 监控与调试
|
||||
|
||||
### 调试技巧
|
||||
```javascript
|
||||
// 沙箱状态监控
|
||||
function debugSandbox(sandbox) {
|
||||
console.log('沙箱状态:', {
|
||||
toolId: sandbox.toolId,
|
||||
isAnalyzed: sandbox.isAnalyzed,
|
||||
isPrepared: sandbox.isPrepared,
|
||||
dependencies: sandbox.dependencies,
|
||||
sandboxPath: sandbox.sandboxPath
|
||||
});
|
||||
}
|
||||
|
||||
// 性能监控
|
||||
function profileExecution(fn, name) {
|
||||
return async (...args) => {
|
||||
const start = process.hrtime.bigint();
|
||||
const result = await fn(...args);
|
||||
const end = process.hrtime.bigint();
|
||||
const duration = Number(end - start) / 1000000; // 转换为毫秒
|
||||
console.log(`${name} 执行耗时: ${duration.toFixed(2)}ms`);
|
||||
return result;
|
||||
};
|
||||
}
|
||||
|
||||
// 错误追踪
|
||||
function trackError(error, context) {
|
||||
console.error('错误详情:', {
|
||||
message: error.message,
|
||||
stack: error.stack,
|
||||
context: context,
|
||||
timestamp: new Date().toISOString()
|
||||
});
|
||||
}
|
||||
```
|
||||
|
||||
### 日志系统
|
||||
```javascript
|
||||
const logger = {
|
||||
debug: (message, data) => {
|
||||
if (process.env.DEBUG) {
|
||||
console.log(`[DEBUG] ${message}`, data);
|
||||
}
|
||||
},
|
||||
|
||||
info: (message, data) => {
|
||||
console.log(`[INFO] ${message}`, data);
|
||||
},
|
||||
|
||||
warn: (message, data) => {
|
||||
console.warn(`[WARN] ${message}`, data);
|
||||
},
|
||||
|
||||
error: (message, error) => {
|
||||
console.error(`[ERROR] ${message}`, {
|
||||
message: error.message,
|
||||
stack: error.stack
|
||||
});
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
</knowledge>
|
||||
348
resource/role/luban/knowledge/tool-best-practices.knowledge.md
Normal file
348
resource/role/luban/knowledge/tool-best-practices.knowledge.md
Normal file
@ -0,0 +1,348 @@
|
||||
# 工具设计最佳实践
|
||||
|
||||
<knowledge>
|
||||
|
||||
## 🎯 工具设计哲学
|
||||
|
||||
### 极简主义原则
|
||||
- **单一职责**:每个工具只解决一个核心问题
|
||||
- **接口优雅**:参数设计直观易懂,返回值结构清晰
|
||||
- **依赖最小**:只引入必要的依赖,避免过度膨胀
|
||||
- **错误友好**:提供清晰的错误信息和处理建议
|
||||
|
||||
### 用户体验至上
|
||||
- **即装即用**:工具无需复杂配置即可使用
|
||||
- **文档自描述**:通过Schema和Metadata实现自我说明
|
||||
- **性能优先**:执行效率和响应速度优化
|
||||
- **跨平台兼容**:确保在不同环境下稳定运行
|
||||
|
||||
## 🏗️ 架构设计原则
|
||||
|
||||
### ToolInterface标准化实现
|
||||
```javascript
|
||||
// 完美的工具接口示例
|
||||
module.exports = {
|
||||
// 🔧 依赖管理:明确、最小、版本锁定
|
||||
getDependencies() {
|
||||
return [
|
||||
'lodash@^4.17.21', // 工具函数库
|
||||
'validator@^13.11.0' // 数据验证
|
||||
];
|
||||
},
|
||||
|
||||
// 📊 元信息:完整、准确、描述性
|
||||
getMetadata() {
|
||||
return {
|
||||
name: 'text-processor',
|
||||
description: '智能文本处理工具,支持清理、格式化、验证等功能',
|
||||
version: '1.2.0',
|
||||
category: 'text-processing',
|
||||
author: '鲁班',
|
||||
tags: ['text', 'processing', 'utility']
|
||||
};
|
||||
},
|
||||
|
||||
// 📝 Schema定义:结构化、类型安全、示例丰富
|
||||
getSchema() {
|
||||
return {
|
||||
type: 'object',
|
||||
properties: {
|
||||
text: {
|
||||
type: 'string',
|
||||
description: '需要处理的文本内容',
|
||||
example: 'Hello World!'
|
||||
},
|
||||
operations: {
|
||||
type: 'array',
|
||||
items: {
|
||||
type: 'string',
|
||||
enum: ['clean', 'format', 'validate']
|
||||
},
|
||||
description: '要执行的操作列表',
|
||||
default: ['clean']
|
||||
},
|
||||
options: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
encoding: { type: 'string', default: 'utf-8' },
|
||||
strict: { type: 'boolean', default: false }
|
||||
}
|
||||
}
|
||||
},
|
||||
required: ['text']
|
||||
};
|
||||
},
|
||||
|
||||
// ✅ 参数验证:严格、友好、早期失败
|
||||
validate(params) {
|
||||
const errors = [];
|
||||
|
||||
if (!params.text || typeof params.text !== 'string') {
|
||||
errors.push('text参数必须是非空字符串');
|
||||
}
|
||||
|
||||
if (params.text && params.text.length > 50000) {
|
||||
errors.push('text长度不能超过50000字符');
|
||||
}
|
||||
|
||||
return {
|
||||
valid: errors.length === 0,
|
||||
errors
|
||||
};
|
||||
},
|
||||
|
||||
// 🚀 核心执行:健壮、高效、可观测
|
||||
async execute(params) {
|
||||
const startTime = Date.now();
|
||||
|
||||
try {
|
||||
// 核心处理逻辑
|
||||
const result = await this.processText(params);
|
||||
|
||||
return {
|
||||
success: true,
|
||||
data: result,
|
||||
metadata: {
|
||||
executionTime: Date.now() - startTime,
|
||||
timestamp: new Date().toISOString()
|
||||
}
|
||||
};
|
||||
} catch (error) {
|
||||
return {
|
||||
success: false,
|
||||
error: {
|
||||
message: error.message,
|
||||
code: error.code || 'UNKNOWN_ERROR'
|
||||
},
|
||||
metadata: {
|
||||
executionTime: Date.now() - startTime,
|
||||
timestamp: new Date().toISOString()
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
## 🛡️ 安全与性能最佳实践
|
||||
|
||||
### 输入安全防护
|
||||
```javascript
|
||||
// 输入验证模式
|
||||
class InputValidator {
|
||||
static validateText(text, maxLength = 10000) {
|
||||
if (typeof text !== 'string') {
|
||||
throw new Error('输入必须是字符串类型');
|
||||
}
|
||||
|
||||
if (text.length > maxLength) {
|
||||
throw new Error(`文本长度超过限制: ${maxLength}`);
|
||||
}
|
||||
|
||||
// XSS防护
|
||||
if (/<script|javascript:|on\w+=/i.test(text)) {
|
||||
throw new Error('检测到潜在的恶意脚本');
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static sanitizeFilename(filename) {
|
||||
return filename.replace(/[^a-zA-Z0-9._-]/g, '');
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 性能优化模式
|
||||
```javascript
|
||||
// 缓存机制
|
||||
const cache = new Map();
|
||||
const CACHE_TTL = 300000; // 5分钟
|
||||
|
||||
function withCache(fn, cacheKey) {
|
||||
const cached = cache.get(cacheKey);
|
||||
if (cached && Date.now() - cached.timestamp < CACHE_TTL) {
|
||||
return cached.data;
|
||||
}
|
||||
|
||||
const result = fn();
|
||||
cache.set(cacheKey, {
|
||||
data: result,
|
||||
timestamp: Date.now()
|
||||
});
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// 资源控制
|
||||
function withResourceLimit(fn, timeout = 30000) {
|
||||
return Promise.race([
|
||||
fn(),
|
||||
new Promise((_, reject) =>
|
||||
setTimeout(() => reject(new Error('执行超时')), timeout)
|
||||
)
|
||||
]);
|
||||
}
|
||||
```
|
||||
|
||||
## 📦 依赖管理策略
|
||||
|
||||
### 精选依赖原则
|
||||
```javascript
|
||||
// 工具库选择矩阵
|
||||
const DEPENDENCY_MATRIX = {
|
||||
// 基础工具函数
|
||||
utilities: {
|
||||
recommended: 'lodash@^4.17.21',
|
||||
alternatives: ['ramda@^0.29.0', 'underscore@^1.13.0'],
|
||||
criteria: '成熟度、包大小、功能覆盖'
|
||||
},
|
||||
|
||||
// HTTP请求
|
||||
http: {
|
||||
recommended: 'axios@^1.6.0',
|
||||
alternatives: ['node-fetch@^3.3.0', 'got@^13.0.0'],
|
||||
criteria: '易用性、功能丰富度、兼容性'
|
||||
},
|
||||
|
||||
// 数据验证
|
||||
validation: {
|
||||
recommended: 'validator@^13.11.0',
|
||||
alternatives: ['joi@^17.11.0', 'yup@^1.3.0'],
|
||||
criteria: '验证规则丰富度、性能、学习成本'
|
||||
},
|
||||
|
||||
// 文件操作
|
||||
filesystem: {
|
||||
recommended: 'fs-extra@^11.1.0',
|
||||
alternatives: ['graceful-fs@^4.2.11'],
|
||||
criteria: '功能完整性、错误处理、跨平台'
|
||||
}
|
||||
};
|
||||
|
||||
// 依赖版本策略
|
||||
getDependencies() {
|
||||
return [
|
||||
'lodash@^4.17.21', // 主版本锁定,次版本兼容
|
||||
'axios@~1.6.0', // 补丁版本兼容
|
||||
'validator@13.11.0' // 精确版本锁定(关键依赖)
|
||||
];
|
||||
}
|
||||
```
|
||||
|
||||
## 🧪 测试驱动开发
|
||||
|
||||
### 工具测试模式
|
||||
```javascript
|
||||
// 标准测试模板
|
||||
describe('TextProcessor Tool', () => {
|
||||
let tool;
|
||||
|
||||
beforeEach(() => {
|
||||
tool = require('./text-processor.tool.js');
|
||||
});
|
||||
|
||||
describe('接口合规性测试', () => {
|
||||
test('必须实现所有接口方法', () => {
|
||||
expect(typeof tool.getDependencies).toBe('function');
|
||||
expect(typeof tool.getMetadata).toBe('function');
|
||||
expect(typeof tool.getSchema).toBe('function');
|
||||
expect(typeof tool.validate).toBe('function');
|
||||
expect(typeof tool.execute).toBe('function');
|
||||
});
|
||||
|
||||
test('getDependencies返回格式正确', () => {
|
||||
const deps = tool.getDependencies();
|
||||
expect(Array.isArray(deps)).toBe(true);
|
||||
deps.forEach(dep => {
|
||||
expect(typeof dep).toBe('string');
|
||||
expect(dep).toMatch(/^[a-zA-Z0-9-]+@[\^~]?\d+\.\d+\.\d+$/);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('功能测试', () => {
|
||||
test('正常输入处理', async () => {
|
||||
const result = await tool.execute({
|
||||
text: 'Hello World',
|
||||
operations: ['clean']
|
||||
});
|
||||
|
||||
expect(result.success).toBe(true);
|
||||
expect(result.data).toBeDefined();
|
||||
});
|
||||
|
||||
test('异常输入处理', async () => {
|
||||
const result = await tool.execute({
|
||||
text: null
|
||||
});
|
||||
|
||||
expect(result.success).toBe(false);
|
||||
expect(result.error).toBeDefined();
|
||||
});
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
## 📊 质量保证体系
|
||||
|
||||
### 代码质量检查
|
||||
```javascript
|
||||
// ESLint配置示例
|
||||
module.exports = {
|
||||
env: { node: true, es2021: true },
|
||||
extends: ['eslint:recommended'],
|
||||
rules: {
|
||||
'no-console': 'warn',
|
||||
'no-unused-vars': 'error',
|
||||
'prefer-const': 'error',
|
||||
'no-var': 'error',
|
||||
'complexity': ['warn', 10],
|
||||
'max-lines-per-function': ['warn', 50]
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
### 性能基准测试
|
||||
```javascript
|
||||
// 性能测试模板
|
||||
function benchmarkTool(tool, testData) {
|
||||
const iterations = 1000;
|
||||
const start = process.hrtime.bigint();
|
||||
|
||||
for (let i = 0; i < iterations; i++) {
|
||||
tool.execute(testData);
|
||||
}
|
||||
|
||||
const end = process.hrtime.bigint();
|
||||
const avgTime = Number(end - start) / iterations / 1000000; // ms
|
||||
|
||||
return {
|
||||
iterations,
|
||||
averageTime: avgTime,
|
||||
totalTime: Number(end - start) / 1000000
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
## 🌟 卓越工具特征
|
||||
|
||||
### 用户体验指标
|
||||
- **启动时间** < 100ms
|
||||
- **执行效率** < 1s(常规任务)
|
||||
- **内存占用** < 50MB
|
||||
- **错误恢复** 100%优雅处理
|
||||
|
||||
### 代码质量指标
|
||||
- **圈复杂度** < 10
|
||||
- **测试覆盖率** > 90%
|
||||
- **依赖漏洞** 0个
|
||||
- **文档完整度** 100%
|
||||
|
||||
### 生态贡献指标
|
||||
- **复用性** 高(可被其他工具引用)
|
||||
- **扩展性** 强(支持插件机制)
|
||||
- **社区认可** 正面反馈 > 95%
|
||||
- **维护活跃度** 定期更新
|
||||
|
||||
</knowledge>
|
||||
Reference in New Issue
Block a user