ai-worktool 1.0.65 → 1.0.66

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.65 (2025-08-15)
1
+ ## 1.0.66 (2025-08-17)
2
2
 
3
3
 
4
4
  ### Bug Fixes
@@ -106,8 +106,10 @@
106
106
  * **dify-plugin:** 新增重命名文件或目录的功能 ([9bb6961](https://codeup.aliyun.com/666cf9ed29ecbe23053513a3/JianGuoKe/ai-worktools/commits/9bb69613a28aba6859f72b14b2aa1a586ac9ca70))
107
107
  * **extension:** 重构 Webview 并添加覆盖率报告功能 ([fd8a62b](https://codeup.aliyun.com/666cf9ed29ecbe23053513a3/JianGuoKe/ai-worktools/commits/fd8a62b79aff4c03af8b56779d607f01d65c175a))
108
108
  * **jianguoke:** 优化工具调用信息格式化及消息 ID 生成 ([1b240e7](https://codeup.aliyun.com/666cf9ed29ecbe23053513a3/JianGuoKe/ai-worktools/commits/1b240e7fbcabb2112789c116b7f483308c184fce))
109
+ * **logger:** 实现日志记录功能并优化工具调用处理 ([84bbd9b](https://codeup.aliyun.com/666cf9ed29ecbe23053513a3/JianGuoKe/ai-worktools/commits/84bbd9be8338e80779eb9159ba62ffb9c59cdbd7))
109
110
  * **log:** 增加日志容器拖动调整功能 ([cfdaf9d](https://codeup.aliyun.com/666cf9ed29ecbe23053513a3/JianGuoKe/ai-worktools/commits/cfdaf9d7bec56687a2d49ca92785463dc6713a77))
110
111
  * **package:** 添加阿里云 OSS 发布脚本并更新版本号 ([572ef25](https://codeup.aliyun.com/666cf9ed29ecbe23053513a3/JianGuoKe/ai-worktools/commits/572ef25f36c949672c4d1c062015f970c9862e69))
112
+ * **package:** 添加项目关键词 ([d4707a1](https://codeup.aliyun.com/666cf9ed29ecbe23053513a3/JianGuoKe/ai-worktools/commits/d4707a12adbd510088d3fa7fdae78e8b6d858eb6))
111
113
  * **plugin:** 更新插件版本和功能描述 ([f3773d6](https://codeup.aliyun.com/666cf9ed29ecbe23053513a3/JianGuoKe/ai-worktools/commits/f3773d675fcb274080339cd0274a1a7aff8415a9))
112
114
  * **program:** 增加代码覆盖率报告展示功能 ([60da9b5](https://codeup.aliyun.com/666cf9ed29ecbe23053513a3/JianGuoKe/ai-worktools/commits/60da9b59e4b913695daa8697dd9aeec16cf78a5f))
113
115
  * **program:** 增加代码覆盖率报告展示功能 ([f693e27](https://codeup.aliyun.com/666cf9ed29ecbe23053513a3/JianGuoKe/ai-worktools/commits/f693e272ef0fe7e58083d2589339af17e45cff95))
@@ -122,13 +122,8 @@ async function startAgent(name, question, vars, withConversation, ctrl, mode, on
122
122
  lastMsgNo = data.no;
123
123
  msg = '';
124
124
  }
125
- if (mode === 'full') {
126
- msg += data.content;
127
- }
128
- else {
129
- msg = data.content;
130
- }
131
- await onMessage?.(msg, 'msg-' + data.id + data.no);
125
+ msg += data.content;
126
+ await onMessage?.(mode === 'full' ? msg : data.content, 'msg-' + data.id + data.no);
132
127
  }
133
128
  if (ev?.event === 'TOOL' && lastToolId !== 'tool-' + data.id + data.no) {
134
129
  lastToolId = 'tool-' + data.id + data.no;
@@ -119,7 +119,7 @@ async function callWithObject(name, argsObj, cwd) {
119
119
  return argsObj[name];
120
120
  });
121
121
  // 调用函数
122
- let data = (await fn(...args));
122
+ let data = await fn(...args);
123
123
  if (name === 'readFile') {
124
124
  data = `\n\`\`\`${inferCodeTypeFromExtension(argsObj.filePath)}\n${data}\n\`\`\``;
125
125
  }
package/dist/program.js CHANGED
@@ -15,10 +15,23 @@ const user_1 = require("./user");
15
15
  const program = new commander_1.Command();
16
16
  program.name('testAgent').description('吃豆豆:单测智能体').version('1.0.1');
17
17
  // 屏蔽调试日志
18
- const logHandler = console.log;
18
+ let lastLineNo;
19
+ const outputLine = (message, id) => {
20
+ if (id && lastLineNo !== id) {
21
+ process.stdout.write('\n');
22
+ }
23
+ process.stdout.write(message);
24
+ if (!id) {
25
+ process.stdout.write('\n');
26
+ }
27
+ lastLineNo = id;
28
+ };
19
29
  if (process.env.NODE_ENV !== 'test') {
20
30
  console.log = () => { };
21
31
  }
32
+ else {
33
+ console.log = (...txt) => outputLine(txt.join(' '));
34
+ }
22
35
  const tokenFile = path_1.default.join(os_1.default.homedir(), '.aiworktools');
23
36
  // token存储在系统用户文件夹的.ai-worktools
24
37
  (0, user_1.setTokenStorage)({
@@ -48,12 +61,12 @@ program
48
61
  .description('登录')
49
62
  .action(async () => {
50
63
  try {
51
- logHandler(`正在打开浏览器进行登录...`);
64
+ outputLine(`正在打开浏览器进行登录...`);
52
65
  await (0, user_1.login)('ai-worktools-cli');
53
- logHandler('登录成功!');
66
+ outputLine('登录成功!');
54
67
  }
55
68
  catch (err) {
56
- logHandler('登录失败', err.message);
69
+ outputLine('登录失败', err.message);
57
70
  }
58
71
  });
59
72
  program
@@ -61,7 +74,7 @@ program
61
74
  .description('登出')
62
75
  .action(async () => {
63
76
  await (0, user_1.logout)();
64
- logHandler('已成功退出');
77
+ outputLine('已成功退出');
65
78
  });
66
79
  program
67
80
  .command('start [projectRoot]')
@@ -87,26 +100,13 @@ program
87
100
  onReady: async (project) => {
88
101
  projectConfig = project;
89
102
  },
90
- onMessage: (message) => {
91
- logHandler(message);
92
- if (message.includes('当前代码总覆盖率')) {
93
- const task = (0, view_1.loadAndDisplayCoverage)(path_1.default.join(projectConfig.projectRoot, projectConfig.coverageDir, view_1.COVERAGE_FILE_PATH), 0);
94
- tasks.push(task);
95
- task
96
- .then(() => {
97
- tasks.splice(tasks.indexOf(task), 1);
98
- })
99
- .catch(() => {
100
- tasks.splice(tasks.indexOf(task), 1);
101
- });
102
- }
103
- }
103
+ onMessage: outputLine
104
104
  });
105
105
  await Promise.all(tasks);
106
106
  if (result?.name === '') {
107
107
  if (result?.name === 'ExpiredException') {
108
- logHandler('您的Tokens已用完,请充值。执行下面命令打开使用面板:');
109
- logHandler('testAgent usage');
108
+ outputLine('您的Tokens已用完,请充值。执行下面命令打开使用面板:');
109
+ outputLine('testAgent usage');
110
110
  }
111
111
  }
112
112
  });
package/dist/testAgent.js CHANGED
@@ -9,9 +9,12 @@ const agents_1 = require("./agents");
9
9
  const tools_1 = require("./tools");
10
10
  async function startTestAgent(options) {
11
11
  const ctrl = options.controller;
12
- const log = options.onMessage || console.log;
12
+ let no = 0;
13
+ const output = (txt, id) => {
14
+ options.onMessage?.(txt, id || '#' + ++no);
15
+ };
13
16
  let isErrorEnd;
14
- log(`开始干活... 😎`);
17
+ output(`开始干活... 😎`);
15
18
  console.log(options.projectRoot);
16
19
  try {
17
20
  isErrorEnd = false;
@@ -19,7 +22,7 @@ async function startTestAgent(options) {
19
22
  // 1、检查当前项目单元测试工具是否安装好,否则安装测试工具搭建测试环境
20
23
  const projectConfig = await (0, tools_1.detectProjectConfig)(options.projectRoot, options);
21
24
  if (!projectConfig.isInstalled) {
22
- log('项目初始化...');
25
+ output('项目初始化...');
23
26
  await (0, tools_1.initProject)(options.projectRoot, projectConfig.packageManager);
24
27
  }
25
28
  if (options.setupEnv !== false) {
@@ -34,7 +37,7 @@ async function startTestAgent(options) {
34
37
  toolCalls = [];
35
38
  }
36
39
  // 2、先执行单测并生成单测覆盖报告
37
- log('开始检查测试覆盖率...');
40
+ output('开始检查测试覆盖率...');
38
41
  const result = await (0, tools_1.runTests)(projectConfig.projectRoot, projectConfig.testFramework, projectConfig.coverageDir, projectConfig.testConfigFile);
39
42
  if (ctrl?.signal.aborted) {
40
43
  break;
@@ -43,13 +46,13 @@ async function startTestAgent(options) {
43
46
  // 上一次执行必须有写入类操作,否则不会有新的单测覆盖率变化
44
47
  if (lastTestResult?.stderr === result.stderr &&
45
48
  toolCalls.every((toolCall) => !tools_1.modifyTools.includes(toolCall.functionName))) {
46
- log('没有新的代码修改,等待中...');
49
+ output('没有新的代码修改,等待中...');
47
50
  await (0, tools_1.wait)(options.idleTimeout || 5000);
48
51
  continue;
49
52
  }
50
53
  lastTestResult = result;
51
54
  // 单测执行失败,比如代码编译不通过
52
- log('单测执行失败,开始修复...');
55
+ output('单测执行失败,开始修复...');
53
56
  await (0, agents_1.startAgent)(options.platform, 'fixconfig', (0, agents_1.fixErrorPrompt)(result.stderr), projectConfig, options.withConversation, ctrl, options.mode, options.onMessage, async (tool) => {
54
57
  toolCalls.push(tool);
55
58
  });
@@ -69,13 +72,13 @@ async function startTestAgent(options) {
69
72
  lastFailedTest.testFilePath === failedTest.testFilePath &&
70
73
  lastFailedTest.testName === failedTest.testName &&
71
74
  toolCalls.every((toolCall) => !tools_1.modifyTools.includes(toolCall.functionName))) {
72
- log('没有新的单测失败,等待中...');
75
+ output('没有新的单测失败,等待中...');
73
76
  await (0, tools_1.wait)(options.idleTimeout || 5000);
74
77
  continue;
75
78
  }
76
79
  lastFailedTest = failedTest;
77
80
  // 不能并行修复,改完行号都会变,所以每次修复完需要重新执行单测
78
- log(`发现有失败的单测${path_1.default.basename(failedTest.testFilePath)},开始修复...`);
81
+ output(`发现有失败的单测${path_1.default.basename(failedTest.testFilePath)},开始修复...`);
79
82
  await (0, agents_1.startAgent)(options.platform,
80
83
  // 没有testName说明是修复单测代码本身问题
81
84
  failedTest.testName ? 'fixbug' : 'fixconfig', await (0, agents_1.fixCodePrompt)(failedTest), projectConfig, options.withConversation, ctrl, options.mode, options.onMessage, async (tool) => {
@@ -94,12 +97,12 @@ async function startTestAgent(options) {
94
97
  if (ctrl?.signal.aborted) {
95
98
  break;
96
99
  }
97
- log(`当前代码总覆盖率为${parseFloat(total[options.measureType || 'branches'].pct.toString()) || 0}%`);
100
+ output(`当前代码总覆盖率为${parseFloat(total[options.measureType || 'branches'].pct.toString()) || 0}%`);
98
101
  const finished = total[options.measureType || 'branches'].pct >= 100;
99
102
  if (!finished) {
100
103
  if (files.length) {
101
104
  for (const uncoveredLineFile of files.sort((a, b) => a.lines.coverage.branches.pct - b.lines.coverage.branches.pct)) {
102
- log(`发现有未覆盖行,开始补充...`, uncoveredLineFile.filePath);
105
+ output(`发现有未覆盖行,开始补充...`, uncoveredLineFile.filePath);
103
106
  await (0, agents_1.startAgent)(options.platform, 'addtest', await (0, agents_1.addUncoveredLinePrompt)(uncoveredLineFile.filePath, uncoveredLineFile.lines), projectConfig, options.withConversation, ctrl, options.mode, options.onMessage, async (tool) => {
104
107
  toolCalls.push(tool);
105
108
  });
@@ -110,7 +113,7 @@ async function startTestAgent(options) {
110
113
  }
111
114
  else {
112
115
  // 如果没有测试文件,则尝试修复代码
113
- log(`发现有未覆盖文件,开始补充...`);
116
+ output(`发现有未覆盖文件,开始补充...`);
114
117
  await (0, agents_1.startAgent)(options.platform, 'addtest', await (0, agents_1.addUncoveredFilePrompt)(total, files), projectConfig, options.withConversation, ctrl, options.mode, options.onMessage, async (tool) => {
115
118
  toolCalls.push(tool);
116
119
  });
@@ -134,10 +137,10 @@ async function startTestAgent(options) {
134
137
  else {
135
138
  isErrorEnd = err;
136
139
  console.error(err);
137
- log('发生错误, ' + err.message);
140
+ output('发生错误, ' + err.message);
138
141
  }
139
142
  }
140
- log(isErrorEnd ? '被下班~ 👻' : '快乐的~下班下班 👋');
143
+ output(isErrorEnd ? '被下班~ 👻' : '快乐的~下班下班 👋');
141
144
  return isErrorEnd;
142
145
  }
143
146
  //# sourceMappingURL=testAgent.js.map
@@ -50,6 +50,16 @@ exports.batchModifyLines = batchModifyLines;
50
50
  exports.deleteFolder = deleteFolder;
51
51
  const fs = __importStar(require("fs/promises"));
52
52
  const path_1 = __importDefault(require("path"));
53
+ const diff_1 = require("diff");
54
+ const cli_color_1 = __importDefault(require("cli-color"));
55
+ // 颜色配置
56
+ const colors = {
57
+ added: cli_color_1.default.green, // 新增内容 - 绿色
58
+ removed: cli_color_1.default.red, // 删除内容 - 红色
59
+ unchanged: cli_color_1.default.white, // 未变更内容 - 白色
60
+ header: cli_color_1.default.cyan.bold, // 标题 - 青色加粗
61
+ timestamp: cli_color_1.default.yellow // 时间戳 - 黄色
62
+ };
53
63
  /**
54
64
  * 解析操作字符串为内部操作对象
55
65
  * @param operations 操作字符串,格式:操作类型:行号范围:内容(仅增/改需要),多操作用逗号分隔
@@ -286,7 +296,20 @@ async function writeFile(filePath, content, encoding = 'utf8', overwrite = true)
286
296
  catch {
287
297
  await fs.mkdir(dir, { recursive: true });
288
298
  }
289
- await fs.writeFile(filePath, content.replace(/\r\n/g, '\n'), encoding);
299
+ const data = content.replace(/\r\n/g, '\n');
300
+ const old = process.env.NODE_ENV === 'test' ? await fs.readFile(filePath, encoding) : '';
301
+ await fs.writeFile(filePath, data, encoding);
302
+ if (process.env.NODE_ENV === 'test') {
303
+ // 比较文件差异
304
+ let logContent = '';
305
+ const diff = (0, diff_1.diffLines)(old, data);
306
+ diff.forEach((part) => {
307
+ const prefix = part.added ? '+' : part.removed ? '-' : ' ';
308
+ const colorFn = part.added ? colors.added : part.removed ? colors.removed : colors.unchanged;
309
+ logContent += colorFn(`${prefix} ${part.value}`);
310
+ });
311
+ console.log(logContent);
312
+ }
290
313
  }
291
314
  catch (error) {
292
315
  throw new Error(`写入文件失败: ${error.message}`);
package/dist/view.js CHANGED
@@ -128,8 +128,9 @@ function generateTableData(coverage) {
128
128
  }
129
129
  // 格式化百分比并应用颜色
130
130
  function formatPercentage(pct) {
131
- if (pct === 'Unknown')
131
+ if (pct === 'Unknown') {
132
132
  return cli_color_1.default.italic('Unknown');
133
+ }
133
134
  let formatted = pct.toFixed(2) + '%';
134
135
  // 根据覆盖率设置颜色
135
136
  if (pct < 50) {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "ai-worktool",
3
3
  "displayName": "吃豆豆:单测智能体",
4
- "version": "1.0.65",
4
+ "version": "1.0.66",
5
5
  "description": "单元测试智能体,帮你开发单元测试用例代码直到100%单测覆盖通过。",
6
6
  "author": "jianguoke.cn",
7
7
  "license": "MIT",
@@ -9,6 +9,11 @@
9
9
  "bin": {
10
10
  "testAgent": "dist/cli.js"
11
11
  },
12
+ "keywords": [
13
+ "单元测试智能体",
14
+ "AI",
15
+ "CLI"
16
+ ],
12
17
  "scripts": {
13
18
  "build": "tsc",
14
19
  "watch": "tsc -w",
@@ -23,11 +28,11 @@
23
28
  "createup": "node ./uposs.js create-local-folder",
24
29
  "changelog": "conventional-changelog -p angular -i CHANGELOG.md -s -r 0",
25
30
  "puball": "yarn ver && yarn exepack && yarn vspack && yarn pubvs && yarn pubovsx && yarn puboss && yarn pubnpm",
26
- "exepack": "yarn createup && cross-env PKG_CACHE_PATH=./binaries pkg -o packages/aicoder-1.0.65 . && yarn upicon",
31
+ "exepack": "yarn createup && cross-env PKG_CACHE_PATH=./binaries pkg -o packages/aicoder-1.0.66 . && yarn upicon",
27
32
  "pubvs": "yarn remove-deps && yarn changelog && vsce publish --yarn --baseContentUrl https://aicoder.jianguoke.cn/assets && yarn restore-deps",
28
33
  "pubovsx": "yarn remove-deps && ovsx publish -p 47621ff6-be56-4814-865e-d2a8e8a76f86 --yarn --baseContentUrl https://aicoder.jianguoke.cn/assets && yarn restore-deps",
29
34
  "patch": "yarn remove-deps && vsce publish patch --yarn && yarn restore-deps",
30
- "vspack": "yarn createup && yarn remove-deps && vsce package -o packages/aicoder-1.0.65.vsix --yarn --baseContentUrl https://aicoder.jianguoke.cn/assets && yarn restore-deps",
35
+ "vspack": "yarn createup && yarn remove-deps && vsce package -o packages/aicoder-1.0.66.vsix --yarn --baseContentUrl https://aicoder.jianguoke.cn/assets && yarn restore-deps",
31
36
  "puboss": "node ./uposs.js upload",
32
37
  "pubnpm": "npm publish --registry=https://registry.npmjs.org",
33
38
  "prepare": "husky"
@@ -255,6 +260,7 @@
255
260
  }
256
261
  },
257
262
  "dependencies": {
263
+ "diff": "^8.0.2",
258
264
  "fetch-sse": "^1.1.2",
259
265
  "jsonwebtoken": "^9.0.2",
260
266
  "simple-git": "^3.28.0",
package/dist/loging.js DELETED
@@ -1,110 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.LogLevel = void 0;
4
- exports.showLogs = showLogs;
5
- exports.setSpy = setSpy;
6
- exports.addLog = addLog;
7
- exports.updateLog = updateLog;
8
- exports.applyAspectToModule = applyAspectToModule;
9
- exports.spyConsole = spyConsole;
10
- const logs = [];
11
- const output = console.log;
12
- /**
13
- * 日志级别枚举
14
- */
15
- var LogLevel;
16
- (function (LogLevel) {
17
- LogLevel["DEBUG"] = "debug";
18
- LogLevel["INFO"] = "info";
19
- LogLevel["WARN"] = "warn";
20
- LogLevel["ERROR"] = "error";
21
- })(LogLevel || (exports.LogLevel = LogLevel = {}));
22
- /**
23
- * 默认配置
24
- */
25
- const defaultConfig = {
26
- level: LogLevel.INFO,
27
- logArgs: true,
28
- logResult: true,
29
- logExecutionTime: true,
30
- logger: (txt) => addLog(txt)
31
- };
32
- /**
33
- * 合并配置
34
- */
35
- function mergeConfig(customConfig) {
36
- return { ...defaultConfig, ...customConfig };
37
- }
38
- function showLogs() {
39
- console.log(logs.join('\n'));
40
- logs.length = 0;
41
- }
42
- let logSpy = undefined;
43
- function setSpy(fn) {
44
- logSpy = fn;
45
- }
46
- function addLog(...logs) {
47
- logs.push(...logs);
48
- if (logs.length > 20) {
49
- logs.splice(0, logs.length - 20);
50
- }
51
- for (const log of logs) {
52
- logSpy?.(log, 'add');
53
- }
54
- }
55
- function updateLog(log) {
56
- logs[logs.length - 1] = log;
57
- logSpy?.(log, 'update');
58
- }
59
- /**
60
- * 为模块中的所有导出函数应用切面 - 用于普通函数模块
61
- */
62
- function applyAspectToModule(moduleExports, config) {
63
- const mergedConfig = mergeConfig(config);
64
- for (const key in moduleExports) {
65
- if (typeof moduleExports[key] === 'function') {
66
- const originalFunction = moduleExports[key];
67
- moduleExports[key] = async function (...args) {
68
- const startTime = Date.now();
69
- const functionName = key;
70
- // 记录函数调用
71
- if (mergedConfig.logArgs) {
72
- mergedConfig.logger?.(`${functionName}, 参数: ${JSON.stringify(args)}`);
73
- }
74
- else {
75
- mergedConfig.logger?.(`${functionName}`);
76
- }
77
- // 执行原函数
78
- try {
79
- const result = await originalFunction.apply(this, args);
80
- // 处理同步返回
81
- const endTime = Date.now();
82
- const executionTime = endTime - startTime;
83
- if (mergedConfig.logResult) {
84
- mergedConfig.logger?.(`${functionName} 返回: ${JSON.stringify(result)} 执行时间: ${executionTime}ms`);
85
- }
86
- return result;
87
- }
88
- catch (error) {
89
- // 处理异常
90
- const endTime = Date.now();
91
- const executionTime = endTime - startTime;
92
- mergedConfig.logger?.(`${functionName} 抛出异常: ${error.message} 执行时间: ${executionTime}ms`);
93
- throw error;
94
- }
95
- };
96
- }
97
- }
98
- return moduleExports;
99
- }
100
- function spyConsole(logCount = 1, format = 'compact' // 紧凑还是宽松
101
- ) {
102
- console.log = async (...txts) => {
103
- addLog(...txts.map((txt) => (format === 'compact' && typeof txt === 'string' ? txt.replace(/\n/g, '\\n') : txt)));
104
- if (logs.length > logCount) {
105
- logs.shift();
106
- }
107
- logs.forEach((txts) => output(...txts));
108
- };
109
- }
110
- //# sourceMappingURL=loging.js.map
package/dist/statusBar.js DELETED
@@ -1,121 +0,0 @@
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.getStatusBarItem = getStatusBarItem;
37
- exports.createStatusBarItem = createStatusBarItem;
38
- exports.showLoginStatus = showLoginStatus;
39
- exports.showProgress = showProgress;
40
- exports.showLogedStatus = showLogedStatus;
41
- const vscode = __importStar(require("vscode"));
42
- const user_1 = require("./user");
43
- let statusBarItem;
44
- function getStatusBarItem() {
45
- return statusBarItem;
46
- ;
47
- }
48
- function createStatusBarItem(context) {
49
- if (!statusBarItem) {
50
- statusBarItem = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Right);
51
- context.subscriptions.push(statusBarItem);
52
- }
53
- return statusBarItem;
54
- }
55
- function showLoginStatus() {
56
- // 显示登录中状态
57
- statusBarItem.text = '$(sync~spin) 点击取消登录...';
58
- statusBarItem.command = 'ai-worktool.cancelLoginCommand';
59
- statusBarItem.show();
60
- }
61
- let timer;
62
- function showProgress(tasks) {
63
- if (!tasks) {
64
- showUserInfo();
65
- return;
66
- }
67
- if (timer) {
68
- clearTimeout(timer);
69
- }
70
- // 更新悬停面板内容
71
- function updateTaskProgress() {
72
- let progress = '';
73
- progress = `$(sync~spin) ${tasks
74
- .map((task) => {
75
- return (tasks?.length === 1 ? task.name + ' ' : '') + Math.round((task.progress / task.total) * 100) + '%';
76
- })
77
- .join(' | ')}`;
78
- statusBarItem.text = progress;
79
- statusBarItem.tooltip = `${tasks
80
- .map((task) => task.name + ' ' + Math.round((task.progress / task.total) * 100) + '%')
81
- .join('\n')}`;
82
- }
83
- updateTaskProgress();
84
- statusBarItem.show();
85
- // 检查所有任务是否完成
86
- if (tasks.every((t) => t.status === 'completed')) {
87
- statusBarItem.text = '$(check) 所有任务完成';
88
- // 5秒后隐藏状态栏项
89
- timer = setTimeout(() => {
90
- showUserInfo();
91
- }, 5000);
92
- }
93
- else {
94
- timer = setTimeout(() => {
95
- showUserInfo();
96
- }, 30000);
97
- }
98
- }
99
- async function showUserInfo() {
100
- const userInfo = await (0, user_1.getUserData)();
101
- if (!userInfo) {
102
- statusBarItem.hide();
103
- return;
104
- }
105
- statusBarItem.command = 'ai-worktool.usageCommand';
106
- statusBarItem.tooltip = '吃豆豆:查看使用量';
107
- statusBarItem.text = '$(check) ' + userInfo.name;
108
- statusBarItem.show();
109
- }
110
- function showLogedStatus() {
111
- if (statusBarItem.command === 'ai-worktool.cancelLoginCommand') {
112
- statusBarItem.text = '$(check) 登录成功';
113
- setTimeout(() => {
114
- showUserInfo();
115
- }, 3000);
116
- }
117
- else {
118
- showUserInfo();
119
- }
120
- }
121
- //# sourceMappingURL=statusBar.js.map