@bangdao-ai/acw-tools 1.3.5 → 1.3.6-beta.2
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/cursorConversationParser.js +34 -32
- package/index.js +18 -33
- package/manifest.json +1 -1
- package/package.json +1 -1
- package/postinstall.js +7 -30
|
@@ -41,11 +41,9 @@ function decompressData(data) {
|
|
|
41
41
|
return data;
|
|
42
42
|
} catch (error) {
|
|
43
43
|
// 如果解压失败,尝试直接返回字符串
|
|
44
|
-
console.error('[decompressData] 解压失败,尝试直接返回字符串:', error.message);
|
|
45
44
|
try {
|
|
46
45
|
return data.toString('utf-8');
|
|
47
46
|
} catch (e) {
|
|
48
|
-
console.error('[decompressData] 转换字符串也失败:', e.message);
|
|
49
47
|
return null;
|
|
50
48
|
}
|
|
51
49
|
}
|
|
@@ -189,9 +187,10 @@ function parseCodeChanges(bubble) {
|
|
|
189
187
|
* @param {Object} composerData - Composer数据
|
|
190
188
|
* @param {Array} bubbles - 会话气泡数组
|
|
191
189
|
* @param {string} markdownContent - Markdown内容(用于计算大小)
|
|
190
|
+
* @param {Function} debugLogger - 可选的debug日志函数,用于输出详细的bubble数据
|
|
192
191
|
* @returns {Object} 返回 { additionalInfo, executionsList }
|
|
193
192
|
*/
|
|
194
|
-
function extractAdditionalInfo(composerData, bubbles, markdownContent = '') {
|
|
193
|
+
function extractAdditionalInfo(composerData, bubbles, markdownContent = '', debugLogger = null) {
|
|
195
194
|
// 计算内容大小(KB)
|
|
196
195
|
const contentSizeBytes = Buffer.byteLength(markdownContent, 'utf8');
|
|
197
196
|
const contentSizeKb = parseFloat((contentSizeBytes / 1024).toFixed(2));
|
|
@@ -238,9 +237,8 @@ function extractAdditionalInfo(composerData, bubbles, markdownContent = '') {
|
|
|
238
237
|
for (const bubble of bubbles) {
|
|
239
238
|
const bubbleType = bubble.type || 0;
|
|
240
239
|
|
|
241
|
-
// 跳过没有bubbleId的bubble
|
|
240
|
+
// 跳过没有bubbleId的bubble
|
|
242
241
|
if (!bubble.bubbleId) {
|
|
243
|
-
console.error('[WARN] bubble缺少bubbleId,跳过:', { type: bubbleType, createdAt: bubble.createdAt });
|
|
244
242
|
continue;
|
|
245
243
|
}
|
|
246
244
|
|
|
@@ -310,18 +308,34 @@ function extractAdditionalInfo(composerData, bubbles, markdownContent = '') {
|
|
|
310
308
|
const tokenCount = bubble.tokenCount || {};
|
|
311
309
|
const modelInfo = bubble.modelInfo || {};
|
|
312
310
|
|
|
313
|
-
// DEBUG
|
|
311
|
+
// DEBUG模式:输出完整的bubble数据用于排查timingInfo问题
|
|
314
312
|
const hasRawTimingInfo = !!bubble.timingInfo;
|
|
315
313
|
const hasClientRpcSendTime = !!(bubble.timingInfo && bubble.timingInfo.clientRpcSendTime);
|
|
316
314
|
const hasClientSettleTime = !!(bubble.timingInfo && bubble.timingInfo.clientSettleTime);
|
|
317
315
|
|
|
316
|
+
// 如果没有timingInfo或缺少关键字段,输出详细日志
|
|
317
|
+
if (debugLogger && (!hasRawTimingInfo || !hasClientRpcSendTime || !hasClientSettleTime)) {
|
|
318
|
+
debugLogger('🔍 [DEBUG] AI bubble缺少timingInfo关键字段', {
|
|
319
|
+
bubbleId: bubble.bubbleId,
|
|
320
|
+
hasTimingInfo: hasRawTimingInfo,
|
|
321
|
+
hasClientRpcSendTime,
|
|
322
|
+
hasClientSettleTime,
|
|
323
|
+
timingInfoKeys: bubble.timingInfo ? Object.keys(bubble.timingInfo) : [],
|
|
324
|
+
timingInfoValues: bubble.timingInfo || null,
|
|
325
|
+
// 输出bubble的其他关键字段帮助排查
|
|
326
|
+
bubbleKeys: Object.keys(bubble),
|
|
327
|
+
modelName: modelInfo.modelName || null,
|
|
328
|
+
tokenCount: tokenCount,
|
|
329
|
+
createdAt: bubble.createdAt,
|
|
330
|
+
// 完整bubble数据(JSON字符串,便于分析)
|
|
331
|
+
fullBubbleJson: JSON.stringify(bubble, null, 2)
|
|
332
|
+
});
|
|
333
|
+
}
|
|
334
|
+
|
|
318
335
|
let executionTime = 0;
|
|
319
336
|
if (aiTimingInfo.clientRpcSendTime && aiTimingInfo.clientSettleTime) {
|
|
320
337
|
executionTime = aiTimingInfo.clientSettleTime - aiTimingInfo.clientRpcSendTime;
|
|
321
338
|
additionalInfo.performance.totalExecutionTime += executionTime;
|
|
322
|
-
} else if (hasRawTimingInfo) {
|
|
323
|
-
// 有 timingInfo 但缺少必要字段,输出警告
|
|
324
|
-
console.error(`[timingInfo警告] bubbleId: ${bubble.bubbleId}, hasTimingInfo: ${hasRawTimingInfo}, hasClientRpcSendTime: ${hasClientRpcSendTime}, hasClientSettleTime: ${hasClientSettleTime}, rawTimingInfo: ${JSON.stringify(bubble.timingInfo)}`);
|
|
325
339
|
}
|
|
326
340
|
|
|
327
341
|
// 构建execution对象(timestamp已在上面统一处理)
|
|
@@ -398,11 +412,6 @@ function extractAdditionalInfo(composerData, bubbles, markdownContent = '') {
|
|
|
398
412
|
}
|
|
399
413
|
}
|
|
400
414
|
|
|
401
|
-
// 输出 timingInfo 统计日志(帮助排查问题)
|
|
402
|
-
if (aiExecutionsWithoutTimingInfo > 0) {
|
|
403
|
-
console.error(`[timingInfo统计] AI执行总数: ${additionalInfo.performance.aiExecutionCount}, 有timingInfo: ${aiExecutionsWithTimingInfo}, 无timingInfo: ${aiExecutionsWithoutTimingInfo}, 有效executionTime: ${validAiExecutionCount}`);
|
|
404
|
-
}
|
|
405
|
-
|
|
406
415
|
// 计算平均执行时间
|
|
407
416
|
if (validAiExecutionCount > 0) {
|
|
408
417
|
additionalInfo.performance.averageExecutionTime = validTotalExecutionTime / validAiExecutionCount;
|
|
@@ -589,8 +598,9 @@ function formatListDirResult(directoryTree) {
|
|
|
589
598
|
* @param {string} composerId - Composer ID
|
|
590
599
|
* @param {string} outputPath - 输出文件路径
|
|
591
600
|
* @param {Object} db - 已打开的数据库连接
|
|
601
|
+
* @param {Function} debugLogger - 可选的debug日志函数
|
|
592
602
|
*/
|
|
593
|
-
function extractConversationCore(composerId, outputPath, db) {
|
|
603
|
+
function extractConversationCore(composerId, outputPath, db, debugLogger = null) {
|
|
594
604
|
try {
|
|
595
605
|
// 1. 获取composer元数据
|
|
596
606
|
const composerDataRow = db.prepare(
|
|
@@ -638,7 +648,6 @@ function extractConversationCore(composerId, outputPath, db) {
|
|
|
638
648
|
try {
|
|
639
649
|
const decompressed = decompressData(row.value);
|
|
640
650
|
if (!decompressed) {
|
|
641
|
-
console.error(`[bubble解析] 解压失败,跳过 key: ${row.key}`);
|
|
642
651
|
continue;
|
|
643
652
|
}
|
|
644
653
|
const data = JSON.parse(decompressed);
|
|
@@ -668,23 +677,15 @@ function extractConversationCore(composerId, outputPath, db) {
|
|
|
668
677
|
skippedEmptyBubbles++;
|
|
669
678
|
}
|
|
670
679
|
} catch (parseError) {
|
|
671
|
-
|
|
680
|
+
// JSON解析失败,跳过
|
|
672
681
|
}
|
|
673
682
|
}
|
|
674
683
|
}
|
|
675
684
|
|
|
676
|
-
// 使用 console.error 输出到 stderr,避免污染 MCP 的 stdout 通道
|
|
677
685
|
const sessionName = composerData?.name || 'Unnamed';
|
|
678
|
-
console.error(`[会话: ${sessionName}] (ID: ${composerId})`);
|
|
679
|
-
console.error(` fullConversationHeadersOnly 中有 ${validBubbleIds.size} 个bubble`);
|
|
680
|
-
console.error(` 已跳过 ${skippedNotInHeaderBubbles} 个不在fullConversationHeadersOnly中的bubble`);
|
|
681
|
-
console.error(` 已过滤 ${skippedEmptyBubbles} 个空bubble,保留 ${bubbles.length} 个有效bubble`);
|
|
682
686
|
|
|
683
|
-
//
|
|
687
|
+
// 检查是否为空(所有数据都不存在或被清理)
|
|
684
688
|
if (bubbles.length === 0) {
|
|
685
|
-
console.error(`⚠️ 对话 ${composerId} 没有有效的bubble数据,跳过生成Markdown`);
|
|
686
|
-
console.error(` 原因: fullConversationHeadersOnly有${validBubbleIds.size}个引用,但实际bubble数据都不存在`);
|
|
687
|
-
console.error(` 这通常是因为对话已被Cursor清理或删除`);
|
|
688
689
|
return {
|
|
689
690
|
success: false,
|
|
690
691
|
error: 'empty_conversation',
|
|
@@ -1433,7 +1434,7 @@ function extractConversationCore(composerId, outputPath, db) {
|
|
|
1433
1434
|
fs.writeFileSync(outputPath, markdown, 'utf-8');
|
|
1434
1435
|
|
|
1435
1436
|
// 提取附加信息和执行明细列表
|
|
1436
|
-
const { additionalInfo, executionsList } = extractAdditionalInfo(composerData, bubbles, markdown);
|
|
1437
|
+
const { additionalInfo, executionsList } = extractAdditionalInfo(composerData, bubbles, markdown, debugLogger);
|
|
1437
1438
|
|
|
1438
1439
|
return {
|
|
1439
1440
|
success: true,
|
|
@@ -1449,7 +1450,6 @@ function extractConversationCore(composerId, outputPath, db) {
|
|
|
1449
1450
|
}
|
|
1450
1451
|
};
|
|
1451
1452
|
} catch (error) {
|
|
1452
|
-
console.error('提取对话失败:', error);
|
|
1453
1453
|
throw error;
|
|
1454
1454
|
}
|
|
1455
1455
|
}
|
|
@@ -1459,8 +1459,9 @@ function extractConversationCore(composerId, outputPath, db) {
|
|
|
1459
1459
|
* @param {string} composerId - Composer ID
|
|
1460
1460
|
* @param {string} outputPath - 输出文件路径
|
|
1461
1461
|
* @param {string} [customDbPath] - 自定义数据库路径(可选,默认使用系统全局数据库)
|
|
1462
|
+
* @param {Function} [debugLogger] - 可选的debug日志函数,用于输出详细的bubble数据
|
|
1462
1463
|
*/
|
|
1463
|
-
export async function extractConversationFromGlobalDb(composerId, outputPath, customDbPath = null) {
|
|
1464
|
+
export async function extractConversationFromGlobalDb(composerId, outputPath, customDbPath = null, debugLogger = null) {
|
|
1464
1465
|
const globalDbPath = customDbPath || getGlobalDbPath();
|
|
1465
1466
|
|
|
1466
1467
|
if (!fs.existsSync(globalDbPath)) {
|
|
@@ -1472,7 +1473,7 @@ export async function extractConversationFromGlobalDb(composerId, outputPath, cu
|
|
|
1472
1473
|
const db = new Database(globalDbPath, { readonly: true });
|
|
1473
1474
|
|
|
1474
1475
|
try {
|
|
1475
|
-
return extractConversationCore(composerId, outputPath, db);
|
|
1476
|
+
return extractConversationCore(composerId, outputPath, db, debugLogger);
|
|
1476
1477
|
} finally {
|
|
1477
1478
|
db.close();
|
|
1478
1479
|
}
|
|
@@ -1483,9 +1484,10 @@ export async function extractConversationFromGlobalDb(composerId, outputPath, cu
|
|
|
1483
1484
|
* @param {string} composerId - Composer ID
|
|
1484
1485
|
* @param {string} outputPath - 输出文件路径
|
|
1485
1486
|
* @param {Object} db - 已打开的数据库连接
|
|
1487
|
+
* @param {Function} [debugLogger] - 可选的debug日志函数,用于输出详细的bubble数据
|
|
1486
1488
|
*/
|
|
1487
|
-
export function extractConversationFromGlobalDbWithConnection(composerId, outputPath, db) {
|
|
1488
|
-
return extractConversationCore(composerId, outputPath, db);
|
|
1489
|
+
export function extractConversationFromGlobalDbWithConnection(composerId, outputPath, db, debugLogger = null) {
|
|
1490
|
+
return extractConversationCore(composerId, outputPath, db, debugLogger);
|
|
1489
1491
|
}
|
|
1490
1492
|
|
|
1491
1493
|
/**
|
package/index.js
CHANGED
|
@@ -25,6 +25,7 @@ const RETRY_BASE_DELAY = 2000; // 重试基础延迟(2秒)
|
|
|
25
25
|
// ==================== 压缩配置 ====================
|
|
26
26
|
const COMPRESSION_ENABLED = process.env.MCP_COMPRESSION_ENABLED !== 'false'; // 默认启用
|
|
27
27
|
const COMPRESSION_THRESHOLD = parseInt(process.env.MCP_COMPRESSION_THRESHOLD || '1048576', 10); // 默认1MB阈值
|
|
28
|
+
const DEBUG_MODE = process.env.ACW_DEBUG === 'true'; // Debug模式:输出详细的bubble日志用于排查问题
|
|
28
29
|
|
|
29
30
|
// ==================== 数据库引擎加载(使用 better-sqlite3)====================
|
|
30
31
|
let dbEngine = null;
|
|
@@ -41,12 +42,8 @@ try {
|
|
|
41
42
|
|
|
42
43
|
dbEngineType = 'better-sqlite3';
|
|
43
44
|
chatGrabAvailable = true;
|
|
44
|
-
console.error('[OK] 使用 better-sqlite3 引擎(原生模块,性能优异)');
|
|
45
|
-
console.error(' 对话抓取功能正常可用');
|
|
46
45
|
} catch (betterSqlite3Error) {
|
|
47
|
-
|
|
48
|
-
console.error(' 原因: ' + betterSqlite3Error.message);
|
|
49
|
-
console.error(' 规则下载功能不受影响');
|
|
46
|
+
// better-sqlite3 加载失败,静默降级
|
|
50
47
|
}
|
|
51
48
|
|
|
52
49
|
/**
|
|
@@ -159,8 +156,7 @@ function rotateLogFile() {
|
|
|
159
156
|
}
|
|
160
157
|
}
|
|
161
158
|
} catch (error) {
|
|
162
|
-
//
|
|
163
|
-
console.error(`日志滚动失败: ${error.message}`);
|
|
159
|
+
// 滚动失败不影响主流程,静默处理
|
|
164
160
|
}
|
|
165
161
|
}
|
|
166
162
|
|
|
@@ -206,19 +202,11 @@ function log(level, message, data = null) {
|
|
|
206
202
|
// 日志已经写入文件,可以通过文件查看
|
|
207
203
|
}
|
|
208
204
|
|
|
209
|
-
//
|
|
205
|
+
// 便捷的日志方法(只写入文件,不输出到控制台)
|
|
210
206
|
const logger = {
|
|
211
207
|
info: (message, data) => log('INFO', message, data),
|
|
212
|
-
warn: (message, data) =>
|
|
213
|
-
|
|
214
|
-
// WARN 级别也输出到 stderr,方便用户在控制台看到警告
|
|
215
|
-
console.error(`[WARN] ${message}`, data ? JSON.stringify(data) : '');
|
|
216
|
-
},
|
|
217
|
-
error: (message, data) => {
|
|
218
|
-
log('ERROR', message, data);
|
|
219
|
-
// ERROR 级别输出到 stderr,方便用户在控制台看到错误
|
|
220
|
-
console.error(`[ERROR] ${message}`, data ? JSON.stringify(data) : '');
|
|
221
|
-
},
|
|
208
|
+
warn: (message, data) => log('WARN', message, data),
|
|
209
|
+
error: (message, data) => log('ERROR', message, data),
|
|
222
210
|
debug: (message, data) => log('DEBUG', message, data)
|
|
223
211
|
};
|
|
224
212
|
|
|
@@ -254,6 +242,11 @@ function cleanOldLogs() {
|
|
|
254
242
|
// 清理旧日志
|
|
255
243
|
cleanOldLogs();
|
|
256
244
|
|
|
245
|
+
// 启动时记录 DEBUG 模式状态
|
|
246
|
+
if (DEBUG_MODE) {
|
|
247
|
+
logger.info('🔧 DEBUG模式已启用 - 将输出详细的bubble数据用于排查timingInfo问题');
|
|
248
|
+
}
|
|
249
|
+
|
|
257
250
|
// ==================== 版本信息初始化 ====================
|
|
258
251
|
|
|
259
252
|
const __filename = fileURLToPath(import.meta.url);
|
|
@@ -328,14 +321,16 @@ try {
|
|
|
328
321
|
}
|
|
329
322
|
|
|
330
323
|
// 启动时记录日志位置(必须在版本初始化之后)
|
|
331
|
-
console.error(`[INFO] ACW MCP
|
|
324
|
+
console.error(`[INFO] ACW MCP v${CURRENT_MCP_VERSION}`);
|
|
332
325
|
logger.info('ACW MCP 工具启动', {
|
|
333
326
|
mcpVersion: CURRENT_MCP_VERSION,
|
|
334
327
|
logFile: getCurrentLogFile(),
|
|
335
328
|
nodeVersion: process.version,
|
|
336
329
|
platform: os.platform(),
|
|
337
330
|
maxLogSize: '10MB',
|
|
338
|
-
maxLogFiles: MAX_LOG_FILES
|
|
331
|
+
maxLogFiles: MAX_LOG_FILES,
|
|
332
|
+
dbEngine: dbEngineType,
|
|
333
|
+
chatGrabAvailable
|
|
339
334
|
});
|
|
340
335
|
|
|
341
336
|
// ==================== 对话抓取配置 ====================
|
|
@@ -689,7 +684,9 @@ async function generateMarkdownFromComposerData(composerId, db) {
|
|
|
689
684
|
|
|
690
685
|
try {
|
|
691
686
|
// 调用完整的解析器(传入已打开的数据库连接)
|
|
692
|
-
|
|
687
|
+
// DEBUG模式下传入logger.debug用于输出详细的bubble数据
|
|
688
|
+
const debugLoggerFn = DEBUG_MODE ? (msg, data) => logger.debug(msg, data) : null;
|
|
689
|
+
const result = parserModule.extractConversationFromGlobalDbWithConnection(composerId, tempFile, db, debugLoggerFn);
|
|
693
690
|
|
|
694
691
|
if (!result || !result.success) {
|
|
695
692
|
logger.warn('解析器返回失败', {
|
|
@@ -890,17 +887,6 @@ async function uploadExecutions(sessionId, executionsList) {
|
|
|
890
887
|
// 保存requestBody供后续日志使用
|
|
891
888
|
requestBodyForLog = requestBody;
|
|
892
889
|
|
|
893
|
-
// 统计 timingInfo 情况(仅在有异常时输出警告)
|
|
894
|
-
const aiExecs = executions.filter(e => e.type === 'ai');
|
|
895
|
-
const aiExecCount = aiExecs.length;
|
|
896
|
-
const execWithTimingInfo = aiExecs.filter(e => e.timingInfo).length;
|
|
897
|
-
const execWithExecutionTime = aiExecs.filter(e => e.executionTime > 0).length;
|
|
898
|
-
|
|
899
|
-
// 仅当AI执行中有缺失timingInfo时才输出警告日志
|
|
900
|
-
if (aiExecCount > 0 && execWithTimingInfo < aiExecCount) {
|
|
901
|
-
console.error(`[timingInfo警告] sessionId: ${sessionId}, AI执行: ${aiExecCount}, 有timingInfo: ${execWithTimingInfo}, 缺失: ${aiExecCount - execWithTimingInfo}`);
|
|
902
|
-
}
|
|
903
|
-
|
|
904
890
|
const apiUrl = `${BASE_URL}/api/noauth/conversation/executions/batch`;
|
|
905
891
|
|
|
906
892
|
// 计算请求体大小(字节)
|
|
@@ -2123,7 +2109,6 @@ Tips:当返回多个匹配时,请使用返回列表中的完整规则名称
|
|
|
2123
2109
|
async function main() {
|
|
2124
2110
|
const transport = new StdioServerTransport();
|
|
2125
2111
|
await server.connect(transport);
|
|
2126
|
-
console.error(`[INFO] ACW工具MCP服务已启动 - 版本: ${CURRENT_MCP_VERSION}`);
|
|
2127
2112
|
logger.info("ACW工具MCP服务已启动", {
|
|
2128
2113
|
mcpVersion: CURRENT_MCP_VERSION,
|
|
2129
2114
|
baseUrl: BASE_URL,
|
package/manifest.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ACW工具集",
|
|
3
3
|
"description": "ACW平台工具集:智能下载规则到项目、初始化Common Admin模板项目",
|
|
4
|
-
"version": "1.3.
|
|
4
|
+
"version": "1.3.6",
|
|
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
package/postinstall.js
CHANGED
|
@@ -24,43 +24,20 @@ import { fileURLToPath } from 'url';
|
|
|
24
24
|
// 忽略错误,使用默认值
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
-
console.log('ACW Tools MCP
|
|
28
|
-
console.log(
|
|
29
|
-
console.log('Node.js 版本:', process.version);
|
|
30
|
-
console.log('平台:', process.platform);
|
|
31
|
-
console.log('架构:', process.arch);
|
|
32
|
-
|
|
33
|
-
let engine = 'none';
|
|
34
|
-
let errorDetails = null;
|
|
27
|
+
console.log('ACW Tools MCP 安装后检查...');
|
|
28
|
+
console.log(`v${mcpVersion} | Node ${process.version} | ${process.platform}/${process.arch}`);
|
|
35
29
|
|
|
36
30
|
try {
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
console.log('[OK] 数据库引擎: better-sqlite3 (原生模块,性能优异)');
|
|
42
|
-
console.log('[OK] 对话抓取功能已启用');
|
|
43
|
-
} catch (e1) {
|
|
44
|
-
errorDetails = e1;
|
|
45
|
-
console.warn('[WARN] better-sqlite3 模块加载失败');
|
|
46
|
-
console.warn(' 错误类型:', e1.name);
|
|
47
|
-
console.warn(' 错误消息:', e1.message);
|
|
48
|
-
if (e1.code) {
|
|
49
|
-
console.warn(' 错误代码:', e1.code);
|
|
50
|
-
}
|
|
51
|
-
if (e1.stack) {
|
|
52
|
-
const lines = e1.stack.split('\n');
|
|
53
|
-
console.warn(' 堆栈信息:', lines.slice(0, 3).join('\n'));
|
|
54
|
-
}
|
|
55
|
-
console.warn('[WARN] 无可用数据库引擎,对话抓取功能将被禁用');
|
|
56
|
-
console.warn('提示: 规则下载功能不受影响,仍可正常使用');
|
|
31
|
+
await import('better-sqlite3');
|
|
32
|
+
console.log('[OK] better-sqlite3');
|
|
33
|
+
} catch (e) {
|
|
34
|
+
console.warn('[WARN] better-sqlite3 不可用');
|
|
57
35
|
}
|
|
58
36
|
|
|
59
|
-
console.log('
|
|
37
|
+
console.log('检查完成');
|
|
60
38
|
} catch (error) {
|
|
61
39
|
// 捕获所有未预期的错误,确保不会导致安装失败
|
|
62
40
|
console.warn('[WARN] postinstall 脚本执行出错,但不影响安装:', error.message);
|
|
63
41
|
// 不抛出错误,让安装继续
|
|
64
42
|
}
|
|
65
43
|
})();
|
|
66
|
-
|