ai-worktool 1.0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +169 -0
- package/LICENSE.txt +1 -0
- package/README.md +67 -0
- package/dist/agents/chanjet.js +377 -0
- package/dist/agents/index.js +73 -0
- package/dist/agents/jianguoke.js +182 -0
- package/dist/agents/prompt.js +41 -0
- package/dist/agents/toolCall.js +135 -0
- package/dist/cli.js +9 -0
- package/dist/loging.js +110 -0
- package/dist/program.js +35 -0
- package/dist/testAgent.js +142 -0
- package/dist/tools/file.js +543 -0
- package/dist/tools/git.js +204 -0
- package/dist/tools/index.js +71 -0
- package/dist/tools/interface.js +3 -0
- package/dist/tools/javascript.js +180 -0
- package/dist/tools/jest.js +482 -0
- package/dist/tools/mocha.js +107 -0
- package/dist/tools/package.js +376 -0
- package/dist/tools/project.js +541 -0
- package/dist/tools/typescript.js +242 -0
- package/dist/tools/vitest.js +115 -0
- package/dist/user.js +472 -0
- package/dist/view.js +216 -0
- package/package.json +289 -0
@@ -0,0 +1,242 @@
|
|
1
|
+
"use strict";
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
3
|
+
if (k2 === undefined) k2 = k;
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
7
|
+
}
|
8
|
+
Object.defineProperty(o, k2, desc);
|
9
|
+
}) : (function(o, m, k, k2) {
|
10
|
+
if (k2 === undefined) k2 = k;
|
11
|
+
o[k2] = m[k];
|
12
|
+
}));
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
15
|
+
}) : function(o, v) {
|
16
|
+
o["default"] = v;
|
17
|
+
});
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
19
|
+
var ownKeys = function(o) {
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
21
|
+
var ar = [];
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
23
|
+
return ar;
|
24
|
+
};
|
25
|
+
return ownKeys(o);
|
26
|
+
};
|
27
|
+
return function (mod) {
|
28
|
+
if (mod && mod.__esModule) return mod;
|
29
|
+
var result = {};
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
31
|
+
__setModuleDefault(result, mod);
|
32
|
+
return result;
|
33
|
+
};
|
34
|
+
})();
|
35
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
36
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
37
|
+
};
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
39
|
+
exports.parseTsFile = parseTsFile;
|
40
|
+
exports.createTsConfigFile = createTsConfigFile;
|
41
|
+
const typescript_1 = __importDefault(require("typescript"));
|
42
|
+
const fs = __importStar(require("fs/promises")); // 使用promises版本的fs
|
43
|
+
/**
|
44
|
+
* 创建TypeScript源文件
|
45
|
+
* @param filePath 要创建源文件的文件路径
|
46
|
+
* @returns 解析为ts.SourceFile的Promise对象
|
47
|
+
*/
|
48
|
+
async function createSourceFile(filePath) {
|
49
|
+
const fileContent = await fs.readFile(filePath, 'utf8');
|
50
|
+
return typescript_1.default.createSourceFile(filePath, fileContent, typescript_1.default.ScriptTarget.Latest, true);
|
51
|
+
}
|
52
|
+
/**
|
53
|
+
* 获取节点在源文件中的行号
|
54
|
+
* @param sourceFile TypeScript源文件对象
|
55
|
+
* @param position 节点在源文件中的位置索引
|
56
|
+
* @returns 对应的行号(从1开始计数)
|
57
|
+
*/
|
58
|
+
function getLineNumber(sourceFile, position) {
|
59
|
+
return sourceFile.getLineAndCharacterOfPosition(position).line + 1;
|
60
|
+
}
|
61
|
+
/**
|
62
|
+
* 获取参数的JSDoc注释描述
|
63
|
+
* @param paramName 参数名称
|
64
|
+
* @param jsDoc JSDoc注释对象
|
65
|
+
* @param sourceFile TypeScript源文件对象
|
66
|
+
* @returns 参数的描述信息,若不存在则返回undefined
|
67
|
+
*/
|
68
|
+
function getParameterDescription(paramName, jsDoc, sourceFile) {
|
69
|
+
if (!jsDoc || !jsDoc.tags) {
|
70
|
+
return undefined;
|
71
|
+
}
|
72
|
+
const paramTag = jsDoc.tags.find((tag) => tag.tagName.getText(sourceFile) === 'param' &&
|
73
|
+
tag.name?.getText(sourceFile) === paramName);
|
74
|
+
return paramTag?.comment?.toString();
|
75
|
+
}
|
76
|
+
/**
|
77
|
+
* 解析参数信息
|
78
|
+
* @param param 参数声明节点
|
79
|
+
* @param sourceFile TypeScript源文件对象
|
80
|
+
* @param jsDoc JSDoc注释对象
|
81
|
+
* @returns 包含参数详细信息的ParameterInfo对象
|
82
|
+
*/
|
83
|
+
function parseParameter(param, sourceFile, jsDoc) {
|
84
|
+
const paramName = param.name.getText(sourceFile);
|
85
|
+
const paramType = param.type ? param.type.getText(sourceFile) : 'any';
|
86
|
+
const isOptional = !!param.questionToken || !!param.initializer;
|
87
|
+
const description = getParameterDescription(paramName, jsDoc, sourceFile);
|
88
|
+
return {
|
89
|
+
name: paramName,
|
90
|
+
type: paramType,
|
91
|
+
isOptional,
|
92
|
+
description
|
93
|
+
};
|
94
|
+
}
|
95
|
+
/**
|
96
|
+
* 获取节点的源代码
|
97
|
+
* @param node TypeScript AST节点
|
98
|
+
* @param sourceFile TypeScript源文件对象
|
99
|
+
* @returns 节点对应的源代码字符串
|
100
|
+
*/
|
101
|
+
function getNodeSourceCode(node, sourceFile) {
|
102
|
+
return sourceFile.getFullText().substring(node.getFullStart(), node.getEnd());
|
103
|
+
}
|
104
|
+
/**
|
105
|
+
* 获取节点的JSDoc注释
|
106
|
+
* @param node TypeScript AST节点
|
107
|
+
* @returns 节点的JSDoc注释数组,若不存在则返回undefined
|
108
|
+
*/
|
109
|
+
function getJsDocComment(node) {
|
110
|
+
return node.jsDoc;
|
111
|
+
}
|
112
|
+
/**
|
113
|
+
* 检查节点是否在导出的模块中
|
114
|
+
* @param node TypeScript AST节点
|
115
|
+
* @returns 若节点在导出的模块中则返回true,否则返回false
|
116
|
+
*/
|
117
|
+
function isInExportedModule(node) {
|
118
|
+
let current = node.parent;
|
119
|
+
while (current) {
|
120
|
+
if (typescript_1.default.isModuleDeclaration(current) && current.modifiers?.some((m) => m.kind === typescript_1.default.SyntaxKind.ExportKeyword)) {
|
121
|
+
return true;
|
122
|
+
}
|
123
|
+
current = current.parent;
|
124
|
+
}
|
125
|
+
return false;
|
126
|
+
}
|
127
|
+
/**
|
128
|
+
* 解析TypeScript文件,提取导入信息和导出函数信息
|
129
|
+
* @param filePath 要解析的TypeScript文件路径
|
130
|
+
* @returns 解析结果的Promise对象,包含文件路径、导入信息和导出函数信息
|
131
|
+
*/
|
132
|
+
async function parseTsFile(filePath) {
|
133
|
+
const sourceFile = await createSourceFile(filePath);
|
134
|
+
const result = {
|
135
|
+
filePath,
|
136
|
+
imports: [],
|
137
|
+
exportedFunctions: []
|
138
|
+
};
|
139
|
+
/**
|
140
|
+
* 访问AST节点并提取信息
|
141
|
+
* @param node 当前访问的AST节点
|
142
|
+
*/
|
143
|
+
function visitNode(node) {
|
144
|
+
// 处理导入语句
|
145
|
+
if (typescript_1.default.isImportDeclaration(node)) {
|
146
|
+
const moduleSpecifier = node.moduleSpecifier.text;
|
147
|
+
const importInfo = {
|
148
|
+
moduleSpecifier,
|
149
|
+
namedImports: []
|
150
|
+
};
|
151
|
+
// 处理命名导入
|
152
|
+
if (node.importClause?.namedBindings && typescript_1.default.isNamedImports(node.importClause.namedBindings)) {
|
153
|
+
importInfo.namedImports = node.importClause.namedBindings.elements.map((element) => element.name.text);
|
154
|
+
}
|
155
|
+
// 处理默认导入
|
156
|
+
if (node.importClause?.name) {
|
157
|
+
importInfo.defaultImport = node.importClause.name.text;
|
158
|
+
}
|
159
|
+
// 处理命名空间导入
|
160
|
+
if (node.importClause?.namedBindings && typescript_1.default.isNamespaceImport(node.importClause.namedBindings)) {
|
161
|
+
importInfo.namespaceImport = node.importClause.namedBindings.name.text;
|
162
|
+
}
|
163
|
+
result.imports.push(importInfo);
|
164
|
+
}
|
165
|
+
// 处理导出函数
|
166
|
+
if (typescript_1.default.isFunctionDeclaration(node) &&
|
167
|
+
(node.modifiers?.some((m) => m.kind === typescript_1.default.SyntaxKind.ExportKeyword) || isInExportedModule(node))) {
|
168
|
+
if (node.name) {
|
169
|
+
const jsDocs = getJsDocComment(node);
|
170
|
+
const mainJsDoc = jsDocs?.[0];
|
171
|
+
const functionInfo = {
|
172
|
+
name: node.name.text,
|
173
|
+
parameters: node.parameters.map((param) => parseParameter(param, sourceFile, mainJsDoc)),
|
174
|
+
returnType: node.type ? node.type.getText(sourceFile) : 'void',
|
175
|
+
isAsync: !!node.modifiers?.some((m) => m.kind === typescript_1.default.SyntaxKind.AsyncKeyword),
|
176
|
+
isGenerator: !!node.asteriskToken,
|
177
|
+
sourceCode: getNodeSourceCode(node, sourceFile),
|
178
|
+
startLine: getLineNumber(sourceFile, node.getStart()),
|
179
|
+
endLine: getLineNumber(sourceFile, node.getEnd()),
|
180
|
+
description: mainJsDoc?.comment?.toString(),
|
181
|
+
example: mainJsDoc?.tags?.find((tag) => tag.tagName.text === 'example')?.comment?.toString()
|
182
|
+
};
|
183
|
+
result.exportedFunctions.push(functionInfo);
|
184
|
+
}
|
185
|
+
}
|
186
|
+
// 处理导出的箭头函数
|
187
|
+
if (typescript_1.default.isVariableDeclaration(node) &&
|
188
|
+
node.initializer &&
|
189
|
+
typescript_1.default.isArrowFunction(node.initializer) &&
|
190
|
+
node.parent &&
|
191
|
+
typescript_1.default.isVariableDeclarationList(node.parent) &&
|
192
|
+
node.parent.parent &&
|
193
|
+
typescript_1.default.isVariableStatement(node.parent.parent) &&
|
194
|
+
node.parent.parent.modifiers?.some((m) => m.kind === typescript_1.default.SyntaxKind.ExportKeyword)) {
|
195
|
+
if (node.name && typescript_1.default.isIdentifier(node.name)) {
|
196
|
+
const arrowFunction = node.initializer;
|
197
|
+
const jsDocs = getJsDocComment(node.parent.parent);
|
198
|
+
const mainJsDoc = jsDocs?.[0];
|
199
|
+
const functionInfo = {
|
200
|
+
name: node.name.text,
|
201
|
+
parameters: arrowFunction.parameters.map((param) => parseParameter(param, sourceFile, mainJsDoc)),
|
202
|
+
returnType: arrowFunction.type ? arrowFunction.type.getText(sourceFile) : 'void',
|
203
|
+
isAsync: !!arrowFunction.modifiers?.some((m) => m.kind === typescript_1.default.SyntaxKind.AsyncKeyword),
|
204
|
+
isGenerator: false, // 箭头函数不能是生成器
|
205
|
+
sourceCode: getNodeSourceCode(arrowFunction, sourceFile),
|
206
|
+
startLine: getLineNumber(sourceFile, arrowFunction.getStart()),
|
207
|
+
endLine: getLineNumber(sourceFile, arrowFunction.getEnd()),
|
208
|
+
description: mainJsDoc?.comment?.toString()
|
209
|
+
};
|
210
|
+
result.exportedFunctions.push(functionInfo);
|
211
|
+
}
|
212
|
+
}
|
213
|
+
// 递归访问子节点
|
214
|
+
typescript_1.default.forEachChild(node, (child) => visitNode(child));
|
215
|
+
}
|
216
|
+
// 开始访问节点
|
217
|
+
visitNode(sourceFile);
|
218
|
+
return result;
|
219
|
+
}
|
220
|
+
/**
|
221
|
+
* 创建tsconfig.json文件
|
222
|
+
* @param outputPath tsconfig.json文件的输出路径(包含文件名)
|
223
|
+
* @param compilerOptions TypeScript编译器选项
|
224
|
+
* @param include 需要包含的文件路径数组,默认为空数组,多个路径逗号分隔,例如 src/**\/*.ts,tests/**\/*.spec.ts
|
225
|
+
* @param exclude 需要排除的文件路径数组,默认为空数组,多个路径逗号分隔,例如 src/**\/*.js,tests/**\/*.spec.js
|
226
|
+
* @returns 当文件创建成功时解析的Promise
|
227
|
+
* @throws {Error} 如果文件写入过程中发生错误则抛出异常
|
228
|
+
*/
|
229
|
+
async function createTsConfigFile(outputPath, compilerOptions, include = [], exclude = []) {
|
230
|
+
const tsconfigContent = {
|
231
|
+
compilerOptions: typeof compilerOptions === 'string' ? JSON.parse(compilerOptions) : compilerOptions,
|
232
|
+
include: Array.isArray(include) ? include : include?.split(','),
|
233
|
+
exclude: Array.isArray(exclude) ? exclude : exclude?.split(',')
|
234
|
+
};
|
235
|
+
try {
|
236
|
+
await fs.writeFile(outputPath, JSON.stringify(tsconfigContent, null, 2), 'utf8');
|
237
|
+
}
|
238
|
+
catch (error) {
|
239
|
+
throw new Error(`创建tsconfig.json失败: ${error.message}`);
|
240
|
+
}
|
241
|
+
}
|
242
|
+
//# sourceMappingURL=typescript.js.map
|
@@ -0,0 +1,115 @@
|
|
1
|
+
"use strict";
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
3
|
+
if (k2 === undefined) k2 = k;
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
7
|
+
}
|
8
|
+
Object.defineProperty(o, k2, desc);
|
9
|
+
}) : (function(o, m, k, k2) {
|
10
|
+
if (k2 === undefined) k2 = k;
|
11
|
+
o[k2] = m[k];
|
12
|
+
}));
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
15
|
+
}) : function(o, v) {
|
16
|
+
o["default"] = v;
|
17
|
+
});
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
19
|
+
var ownKeys = function(o) {
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
21
|
+
var ar = [];
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
23
|
+
return ar;
|
24
|
+
};
|
25
|
+
return ownKeys(o);
|
26
|
+
};
|
27
|
+
return function (mod) {
|
28
|
+
if (mod && mod.__esModule) return mod;
|
29
|
+
var result = {};
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
31
|
+
__setModuleDefault(result, mod);
|
32
|
+
return result;
|
33
|
+
};
|
34
|
+
})();
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
36
|
+
exports.createVitestConfigFile = createVitestConfigFile;
|
37
|
+
exports.runVitestTests = runVitestTests;
|
38
|
+
const child_process_1 = require("child_process");
|
39
|
+
const fs = __importStar(require("fs/promises"));
|
40
|
+
const path = __importStar(require("path"));
|
41
|
+
/**
|
42
|
+
* 创建 Vitest 配置文件
|
43
|
+
*/
|
44
|
+
async function createVitestConfigFile(configPath, options = {}) {
|
45
|
+
try {
|
46
|
+
await fs.access(configPath);
|
47
|
+
return null;
|
48
|
+
}
|
49
|
+
catch {
|
50
|
+
// 继续创建文件
|
51
|
+
}
|
52
|
+
options = typeof options === 'string' ? JSON.parse(options) : options;
|
53
|
+
const defaultConfig = {
|
54
|
+
include: ['**/*.{test,spec}.{js,ts,jsx,tsx}'],
|
55
|
+
exclude: ['node_modules/**', 'dist/**'],
|
56
|
+
extensions: ['js', 'ts', 'jsx', 'tsx'],
|
57
|
+
coverage: {
|
58
|
+
enabled: true,
|
59
|
+
reporter: ['text', 'lcov', 'json-summary'],
|
60
|
+
reportsDirectory: 'coverage',
|
61
|
+
include: ['src/**/*.{js,ts,jsx,tsx}'],
|
62
|
+
exclude: ['**/*.d.ts', 'src/mocks/**', 'node_modules/**']
|
63
|
+
}
|
64
|
+
};
|
65
|
+
const mergedConfig = { ...defaultConfig, ...options };
|
66
|
+
const configContent = `export default ${JSON.stringify(mergedConfig, null, 2)};\n`;
|
67
|
+
const dirPath = path.dirname(configPath);
|
68
|
+
await fs.mkdir(dirPath, { recursive: true });
|
69
|
+
await fs.writeFile(configPath, configContent, 'utf-8');
|
70
|
+
return configPath;
|
71
|
+
}
|
72
|
+
/**
|
73
|
+
* 执行 Vitest 测试
|
74
|
+
*/
|
75
|
+
async function runVitestTests(projectRoot, coverageDir = 'coverage', configPath) {
|
76
|
+
coverageDir = coverageDir || 'coverage';
|
77
|
+
return new Promise((resolve, reject) => {
|
78
|
+
const now = Date.now();
|
79
|
+
const testResultsFile = path.join(projectRoot, coverageDir, 'test-results.json');
|
80
|
+
const vitestCommand = configPath
|
81
|
+
? `npx vitest run --coverage --reporter=json --outputFile="${testResultsFile}" --config ${configPath}`
|
82
|
+
: `npx vitest run --coverage --reporter=json --outputFile="${testResultsFile}"`;
|
83
|
+
const childProcess = (0, child_process_1.exec)(vitestCommand, { cwd: projectRoot, encoding: 'utf-8' });
|
84
|
+
let stdout = '';
|
85
|
+
let stderr = '';
|
86
|
+
childProcess.stdout?.on('data', (data) => (stdout += data));
|
87
|
+
childProcess.stderr?.on('data', (data) => (stderr += data));
|
88
|
+
childProcess.on('close', async (code) => {
|
89
|
+
const state = await getTestResultsState(projectRoot, coverageDir);
|
90
|
+
resolve({
|
91
|
+
testResultsFile,
|
92
|
+
success: code === 0,
|
93
|
+
noTestsFound: stderr.includes('No tests found'),
|
94
|
+
exitCode: code,
|
95
|
+
stdout,
|
96
|
+
stderr
|
97
|
+
});
|
98
|
+
});
|
99
|
+
childProcess.on('error', (err) => reject(err));
|
100
|
+
});
|
101
|
+
}
|
102
|
+
async function getTestResultsState(projectRoot, coverageDir) {
|
103
|
+
const testResultsPath = path.join(projectRoot, coverageDir, 'test-results.json');
|
104
|
+
return (await fileExists(testResultsPath)) ? fs.stat(testResultsPath) : null;
|
105
|
+
}
|
106
|
+
async function fileExists(path) {
|
107
|
+
try {
|
108
|
+
await fs.access(path);
|
109
|
+
return true;
|
110
|
+
}
|
111
|
+
catch {
|
112
|
+
return false;
|
113
|
+
}
|
114
|
+
}
|
115
|
+
//# sourceMappingURL=vitest.js.map
|