@bangdao-ai/acw-tools 1.3.6 → 1.3.8

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.
@@ -8,6 +8,42 @@ import path from 'path';
8
8
  import os from 'os';
9
9
  import zlib from 'zlib';
10
10
 
11
+ // ==================== DEBUG 模式配置 ====================
12
+ // 通过环境变量 ACW_DEBUG=true 启用详细日志
13
+ const DEBUG_MODE = process.env.ACW_DEBUG === 'true';
14
+
15
+ // DEBUG 日志目录(与主日志目录相同)
16
+ const DEBUG_LOG_DIR = path.join(os.homedir(), '.cursor', '.chat_grab', 'logs');
17
+
18
+ // 确保日志目录存在
19
+ if (DEBUG_MODE && !fs.existsSync(DEBUG_LOG_DIR)) {
20
+ fs.mkdirSync(DEBUG_LOG_DIR, { recursive: true });
21
+ }
22
+
23
+ /**
24
+ * DEBUG 日志函数
25
+ * 仅在 DEBUG_MODE 启用时输出详细日志到文件
26
+ * 日志格式设计:方便贴给AI分析问题
27
+ */
28
+ function debugLog(message, data = null) {
29
+ if (!DEBUG_MODE) return;
30
+
31
+ const now = new Date();
32
+ const timestamp = now.toISOString().replace('T', ' ').replace('Z', '');
33
+ const logFile = path.join(DEBUG_LOG_DIR, `acw-mcp-debug-${now.toISOString().split('T')[0]}.log`);
34
+
35
+ let logLine = `[${timestamp}] ${message}`;
36
+ if (data !== null) {
37
+ if (typeof data === 'object') {
38
+ logLine += '\n' + JSON.stringify(data, null, 2);
39
+ } else {
40
+ logLine += ` ${data}`;
41
+ }
42
+ }
43
+
44
+ fs.appendFileSync(logFile, logLine + '\n', 'utf8');
45
+ }
46
+
11
47
  /**
12
48
  * 获取Cursor全局数据库路径
13
49
  */
@@ -202,6 +238,18 @@ function extractAdditionalInfo(composerData, bubbles, markdownContent = '') {
202
238
  duration = Math.max(0, duration);
203
239
  }
204
240
 
241
+ // DEBUG 模式:记录解析开始
242
+ if (DEBUG_MODE) {
243
+ debugLog(`\n========== [开始解析会话] ==========`);
244
+ debugLog(`composerId: ${composerData?.composerId}`);
245
+ debugLog(`会话名称: ${composerData?.name || '无'}`);
246
+ debugLog(`bubble总数: ${bubbles.length}`);
247
+ // 统计有 timingInfo 的 bubble 数量
248
+ const bubblesWithTimingInfo = bubbles.filter(b => b.type === 2 && b.timingInfo);
249
+ debugLog(`其中AI bubble有timingInfo的数量: ${bubblesWithTimingInfo.length}`);
250
+ debugLog(`====================================`);
251
+ }
252
+
205
253
  const additionalInfo = {
206
254
  // 会话元数据
207
255
  metadata: {
@@ -307,11 +355,41 @@ function extractAdditionalInfo(composerData, bubbles, markdownContent = '') {
307
355
  const tokenCount = bubble.tokenCount || {};
308
356
  const modelInfo = bubble.modelInfo || {};
309
357
 
310
- // DEBUG: 输出原始 bubble.timingInfo 情况(仅在有问题时输出)
311
- const hasRawTimingInfo = !!bubble.timingInfo;
358
+ // DEBUG: 只记录有 timingInfo 的 bubble(这才是关键数据)
359
+ const hasTimingInfo = !!bubble.timingInfo;
312
360
  const hasClientRpcSendTime = !!(bubble.timingInfo && bubble.timingInfo.clientRpcSendTime);
313
361
  const hasClientSettleTime = !!(bubble.timingInfo && bubble.timingInfo.clientSettleTime);
314
362
 
363
+ // DEBUG 模式:只打印有 timingInfo 的 bubble,并输出完整 value
364
+ if (DEBUG_MODE && hasTimingInfo) {
365
+ debugLog(`━━━ [有timingInfo的Bubble] ━━━`);
366
+ debugLog(`bubbleId: ${bubble.bubbleId}`);
367
+ debugLog(`timingInfo原始值:`, bubble.timingInfo);
368
+ debugLog(`解析过程:`, {
369
+ step1_hasTimingInfo: hasTimingInfo,
370
+ step2_hasClientRpcSendTime: hasClientRpcSendTime,
371
+ step3_hasClientSettleTime: hasClientSettleTime,
372
+ step4_clientRpcSendTime: aiTimingInfo.clientRpcSendTime,
373
+ step5_clientSettleTime: aiTimingInfo.clientSettleTime,
374
+ step6_计算executionTime: hasClientRpcSendTime && hasClientSettleTime
375
+ ? `${aiTimingInfo.clientSettleTime} - ${aiTimingInfo.clientRpcSendTime} = ${aiTimingInfo.clientSettleTime - aiTimingInfo.clientRpcSendTime}ms`
376
+ : '缺少必要字段,无法计算'
377
+ });
378
+ // 输出完整 bubble(排除超长文本)
379
+ debugLog(`bubble完整数据:`, {
380
+ bubbleId: bubble.bubbleId,
381
+ type: bubble.type,
382
+ createdAt: bubble.createdAt,
383
+ timingInfo: bubble.timingInfo,
384
+ tokenCount: bubble.tokenCount,
385
+ modelInfo: bubble.modelInfo,
386
+ toolFormerData: bubble.toolFormerData ? { name: bubble.toolFormerData.name } : null,
387
+ // 其他字段(排除大文本)
388
+ otherKeys: Object.keys(bubble).filter(k => !['text', 'richText', 'timingInfo', 'tokenCount', 'modelInfo', 'toolFormerData', 'bubbleId', 'type', 'createdAt'].includes(k))
389
+ });
390
+ debugLog(`━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━`);
391
+ }
392
+
315
393
  let executionTime = 0;
316
394
  if (aiTimingInfo.clientRpcSendTime && aiTimingInfo.clientSettleTime) {
317
395
  executionTime = aiTimingInfo.clientSettleTime - aiTimingInfo.clientRpcSendTime;
@@ -404,6 +482,36 @@ function extractAdditionalInfo(composerData, bubbles, markdownContent = '') {
404
482
  additionalInfo.performance.minExecutionTime = 0;
405
483
  }
406
484
 
485
+ // DEBUG 模式:输出 timingInfo 解析结果汇总
486
+ if (DEBUG_MODE) {
487
+ debugLog(`\n========== [会话解析完成] ==========`);
488
+ debugLog(`composerId: ${composerData?.composerId}`);
489
+ debugLog(`会话名称: ${composerData?.name || '无'}`);
490
+ debugLog(`解析结果汇总:`, {
491
+ 总AI_bubble数: additionalInfo.performance.aiExecutionCount,
492
+ 有timingInfo的数量: aiExecutionsWithTimingInfo,
493
+ 无timingInfo的数量: aiExecutionsWithoutTimingInfo,
494
+ 有效执行时间的数量: validAiExecutionCount,
495
+ 总执行时间ms: additionalInfo.performance.totalExecutionTime,
496
+ 平均执行时间ms: Math.round(additionalInfo.performance.averageExecutionTime)
497
+ });
498
+ // 列出所有解析出的 execution(带 timingInfo 的)
499
+ const executionsWithTiming = additionalInfo.performance.executions
500
+ .filter(e => e.type === 'ai' && e.timingInfo);
501
+ if (executionsWithTiming.length > 0) {
502
+ debugLog(`有timingInfo的execution列表 (共${executionsWithTiming.length}个):`,
503
+ executionsWithTiming.map(e => ({
504
+ bubbleId: e.bubbleId,
505
+ executionTime: e.executionTime,
506
+ timingInfo: e.timingInfo
507
+ }))
508
+ );
509
+ } else {
510
+ debugLog(`⚠️ 警告: 该会话没有任何带timingInfo的AI bubble!`);
511
+ }
512
+ debugLog(`====================================\n`);
513
+ }
514
+
407
515
  // 分离executions数组
408
516
  const executionsList = additionalInfo.performance.executions;
409
517
 
package/manifest.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "ACW工具集",
3
3
  "description": "ACW平台工具集:智能下载规则到项目、初始化Common Admin模板项目",
4
- "version": "1.3.6",
4
+ "version": "1.3.8",
5
5
  "author": "邦道科技 - 产品技术中心",
6
6
  "homepage": "https://www.npmjs.com/package/@bangdao-ai/acw-tools",
7
7
  "repository": "https://www.npmjs.com/package/@bangdao-ai/acw-tools?activeTab=readme",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bangdao-ai/acw-tools",
3
- "version": "1.3.6",
3
+ "version": "1.3.8",
4
4
  "type": "module",
5
5
  "description": "MCP (Model Context Protocol) tools for ACW - download rules and initialize Common Admin projects",
6
6
  "main": "index.js",