ai-worktool 1.0.12 → 1.0.13

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 CHANGED
@@ -1,4 +1,4 @@
1
- ## 1.0.12 (2025-08-03)
1
+ ## 1.0.13 (2025-08-04)
2
2
 
3
3
 
4
4
  ### Bug Fixes
@@ -152,6 +152,7 @@
152
152
  * **toolbox:** 重构并增强项目配置检测功能 ([6cc4e33](https://codeup.aliyun.com/666cf9ed29ecbe23053513a3/JianGuoKe/ai-worktools/commits/6cc4e33a58c7ebb622d27bc643c1e65d1e8af577))
153
153
  * **tools:** 为简咕客插件生成 zod 工具 ([42dfcd9](https://codeup.aliyun.com/666cf9ed29ecbe23053513a3/JianGuoKe/ai-worktools/commits/42dfcd9eb337603ecb0c5fa381ad89784345c9dc))
154
154
  * **tools:** 优化工具插件支持连续多行操作并添加新功能 ([734ca52](https://codeup.aliyun.com/666cf9ed29ecbe23053513a3/JianGuoKe/ai-worktools/commits/734ca5287785d84be0f8fc98b074476a3cc643f2))
155
+ * **user:** 实现登录、登出功能并优化 token 存储 ([1514408](https://codeup.aliyun.com/666cf9ed29ecbe23053513a3/JianGuoKe/ai-worktools/commits/151440887e90d90d0522303009f6940f0507258e))
155
156
  * **user:** 实现登录取消功能并优化登录流程 ([50d124e](https://codeup.aliyun.com/666cf9ed29ecbe23053513a3/JianGuoKe/ai-worktools/commits/50d124e720c778e537488ca436855af21dcbcdeb))
156
157
  * **user:** 为认证回调页面添加立即关闭按钮 ([4328b48](https://codeup.aliyun.com/666cf9ed29ecbe23053513a3/JianGuoKe/ai-worktools/commits/4328b48e06002fa9d70427b21992f1022ffa73a0))
157
158
  * **views:** 优化代码覆盖率显示 ([ef98b11](https://codeup.aliyun.com/666cf9ed29ecbe23053513a3/JianGuoKe/ai-worktools/commits/ef98b115e57650483fae65ddec5ded085839ddd0))
package/dist/program.js CHANGED
@@ -6,15 +6,54 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
6
6
  Object.defineProperty(exports, "__esModule", { value: true });
7
7
  const commander_1 = require("commander");
8
8
  const path_1 = __importDefault(require("path"));
9
+ const promises_1 = __importDefault(require("fs/promises"));
10
+ const os_1 = __importDefault(require("os"));
9
11
  const testAgent_1 = require("./testAgent");
10
12
  const tools_1 = require("./tools");
11
13
  const view_1 = require("./view");
14
+ const user_1 = require("./user");
12
15
  // import { showCoverageView } from './view';
13
16
  const program = new commander_1.Command();
14
17
  program.name('testAgent').description('吃豆豆:单测智能体').version('1.0.1');
15
18
  // 屏蔽调试日志
16
19
  const logHandler = console.log;
17
20
  console.log = () => { };
21
+ const tokenFile = path_1.default.join(os_1.default.homedir(), '.aiworktools');
22
+ // token存储在系统用户文件夹的.ai-worktools
23
+ (0, user_1.setTokenStorage)({
24
+ get: async () => {
25
+ let exists = false;
26
+ try {
27
+ await promises_1.default.access(tokenFile);
28
+ exists = true;
29
+ }
30
+ catch (err) {
31
+ return false;
32
+ }
33
+ if (exists) {
34
+ return JSON.parse(await promises_1.default.readFile(tokenFile, 'utf-8')).token;
35
+ }
36
+ return null;
37
+ },
38
+ set: async (token) => {
39
+ await promises_1.default.writeFile(tokenFile, JSON.stringify({ token }), 'utf-8');
40
+ },
41
+ clear: async () => {
42
+ await promises_1.default.unlink(tokenFile);
43
+ }
44
+ });
45
+ program
46
+ .command('login')
47
+ .description('登录')
48
+ .action(async () => {
49
+ await (0, user_1.login)('ai-worktools-cli');
50
+ });
51
+ program
52
+ .command('logout')
53
+ .description('登出')
54
+ .action(async () => {
55
+ await (0, user_1.logout)();
56
+ });
18
57
  program
19
58
  .command('start [projectRoot]')
20
59
  .description('启动单测智能体,根据源代码文件开始补全单测代码,直到覆盖率100%')
@@ -27,7 +66,7 @@ program
27
66
  .option('--fullCoverageEnd <boolean>', '是否在达到100%覆盖率后结束', (txt) => txt === 'true', true)
28
67
  .action(async (projectRoot, options) => {
29
68
  let projectConfig;
30
- (0, testAgent_1.startTestAgent)({
69
+ await (0, testAgent_1.startTestAgent)({
31
70
  ...options,
32
71
  projectRoot: projectRoot || options.projectRoot,
33
72
  onReady: async (project) => {
package/dist/tools/git.js CHANGED
@@ -73,7 +73,7 @@ async function commit(repoPath, message, files) {
73
73
  const git = createGitInstance(repoPath);
74
74
  try {
75
75
  const result = files ? await git.commit(message, files) : await git.commit(message);
76
- console.log(`提交成功: ${result.summary}`);
76
+ console.log(`提交成功: ${result?.summary}`);
77
77
  }
78
78
  catch (error) {
79
79
  console.error(`提交失败: ${error}`);
@@ -91,7 +91,7 @@ async function pull(repoPath, remote = 'origin', branch) {
91
91
  try {
92
92
  const currentBranch = branch || (await git.branchLocal()).current;
93
93
  const result = await git.pull(remote, currentBranch);
94
- console.log(`拉取成功: ${result.summary}`);
94
+ console.log(`拉取成功: ${result?.summary}`);
95
95
  }
96
96
  catch (error) {
97
97
  console.error(`拉取失败: ${error}`);
@@ -54,7 +54,7 @@ async function wait(timerout = 1000) {
54
54
  }, timerout);
55
55
  });
56
56
  }
57
- function runTests(projectRoot, testFramework, coverageDir, configPath) {
57
+ async function runTests(projectRoot, testFramework, coverageDir, configPath) {
58
58
  if (testFramework === 'jest') {
59
59
  return (0, jest_1.runJestTests)(projectRoot, coverageDir, configPath);
60
60
  }
@@ -4,6 +4,15 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.detectProjectConfig = detectProjectConfig;
7
+ exports.checkProjectInstalled = checkProjectInstalled;
8
+ exports.detectPackageManager = detectPackageManager;
9
+ exports.detectLanguages = detectLanguages;
10
+ exports.detectSrcDir = detectSrcDir;
11
+ exports.detectTestConfig = detectTestConfig;
12
+ exports.detectExistingTestPatterns = detectExistingTestPatterns;
13
+ exports.getDependencies = getDependencies;
14
+ exports.detectProjectType = detectProjectType;
15
+ exports.detectFramework = detectFramework;
7
16
  const promises_1 = __importDefault(require("fs/promises"));
8
17
  const path_1 = __importDefault(require("path"));
9
18
  /**
@@ -207,13 +216,13 @@ async function detectTestConfig(projectRoot, config) {
207
216
  ];
208
217
  // 根据项目语言生成对应扩展名的模式
209
218
  const extensions = new Set();
210
- if (config.languages.includes('javascript')) {
219
+ if (config.languages?.includes('javascript')) {
211
220
  extensions.add('js');
212
221
  }
213
- if (config.languages.includes('typescript')) {
222
+ if (config.languages?.includes('typescript')) {
214
223
  extensions.add('ts');
215
224
  }
216
- if (config.languages.includes('coffeescript')) {
225
+ if (config.languages?.includes('coffeescript')) {
217
226
  extensions.add('coffee');
218
227
  }
219
228
  // 默认为js(如果没有检测到语言)
@@ -404,11 +413,11 @@ async function calculateScore(projectRoot, type) {
404
413
  }
405
414
  });
406
415
  // 检查配置文件匹配(并行处理)
407
- const configFileChecks = features.configFiles.map((file) => fileExists(path_1.default.join(process.cwd(), file)));
416
+ const configFileChecks = features.configFiles.map((file) => fileExists(path_1.default.join(projectRoot, file)));
408
417
  const configFileResults = await Promise.all(configFileChecks);
409
418
  score += configFileResults.filter(Boolean).length * 2; // 配置文件权重中等
410
419
  // 检查目录结构匹配(并行处理)
411
- const directoryChecks = features.directories.map((dir) => directoryExists(path_1.default.join(process.cwd(), dir)));
420
+ const directoryChecks = features.directories.map((dir) => directoryExists(path_1.default.join(projectRoot, dir)));
412
421
  const directoryResults = await Promise.all(directoryChecks);
413
422
  score += directoryResults.filter(Boolean).length * 1; // 目录权重较低
414
423
  return score;
@@ -430,11 +439,6 @@ async function detectProjectType(projectRoot, config) {
430
439
  backend: backendScore,
431
440
  cli: cliScore
432
441
  };
433
- // 判断是否为全栈项目
434
- const isFullstack = frontendScore > 0 && backendScore > 0 && Math.abs(frontendScore - backendScore) < frontendScore * 0.5;
435
- if (isFullstack) {
436
- config.projectType = 'fullstack';
437
- }
438
442
  // 确定最高分数的项目类型
439
443
  const maxScore = Math.max(frontendScore, backendScore, cliScore);
440
444
  if (maxScore === 0) {
@@ -449,6 +453,11 @@ async function detectProjectType(projectRoot, config) {
449
453
  else {
450
454
  config.projectType = 'cli';
451
455
  }
456
+ // 判断是否为全栈项目
457
+ const isFullstack = frontendScore > 0 && backendScore > 0 && Math.abs(frontendScore - backendScore) < frontendScore * 0.5;
458
+ if (isFullstack) {
459
+ config.projectType = 'fullstack';
460
+ }
452
461
  }
453
462
  /**
454
463
  * 检测框架信息
package/dist/user.js CHANGED
@@ -56,8 +56,25 @@ const util_1 = __importDefault(require("util"));
56
56
  const child_process_1 = require("child_process");
57
57
  // 转换exec为Promise形式,便于async/await使用
58
58
  const execAsync = util_1.default.promisify(child_process_1.exec);
59
- let tokenStorage;
60
- let environment;
59
+ let tokenStorage = {
60
+ get: async () => {
61
+ return localStorage.getItem('token');
62
+ },
63
+ set: async (token) => {
64
+ localStorage.setItem('token', token);
65
+ },
66
+ clear: async () => {
67
+ localStorage.removeItem('token');
68
+ }
69
+ };
70
+ let environment = {
71
+ showInfoMessage: async (message) => {
72
+ console.log(message);
73
+ },
74
+ showErrorMessage: async (message) => {
75
+ console.error(message);
76
+ }
77
+ };
61
78
  function setEnvironment(env) {
62
79
  environment = env;
63
80
  }
@@ -335,6 +352,7 @@ async function openExternalUrl(url) {
335
352
  return false;
336
353
  }
337
354
  }
355
+ const AUTH_SERVER_URL = 'https://login.jianguoke.cn/login';
338
356
  /**
339
357
  * 执行登录流程
340
358
  * @param env 环境接口
@@ -343,7 +361,8 @@ async function openExternalUrl(url) {
343
361
  * @param clientId 客户端ID
344
362
  * @returns 登录成功后的token
345
363
  */
346
- async function login(authServerUrl, clientId) {
364
+ async function login(clientId) {
365
+ const authServerUrl = AUTH_SERVER_URL;
347
366
  const env = getEnvironment();
348
367
  const tokenStorage = getTokenStorage();
349
368
  const state = generateState();
@@ -407,8 +426,8 @@ function isLoggedIn() {
407
426
  }
408
427
  return true;
409
428
  }
410
- function getUserData() {
411
- const token = getTokenStorage().get();
429
+ async function getUserData() {
430
+ const token = await getTokenStorage().get();
412
431
  if (!token) {
413
432
  return null;
414
433
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "ai-worktool",
3
3
  "displayName": "吃豆豆:单测智能体",
4
- "version": "1.0.12",
4
+ "version": "1.0.13",
5
5
  "description": "单元测试智能体,帮你开发单元测试用例代码直到100%单测覆盖通过。",
6
6
  "author": "jianguoke.cn",
7
7
  "license": "MIT",
@@ -13,6 +13,7 @@
13
13
  "watch": "tsc -w",
14
14
  "build": "tsc",
15
15
  "test": "jest test/tools",
16
+ "coverage": "jest --coverage test/tools",
16
17
  "plugin": "ts-node ./tools.ts && dify plugin package plugins/dify-plugin",
17
18
  "package": "cross-env PKG_CACHE_PATH=./binaries pkg . --targets node20-win-x64 --out-path aicoder ",
18
19
  "changelog": "conventional-changelog -p angular -i CHANGELOG.md -s -r 0",