@bangdao-ai/acw-tools 1.1.14 → 1.1.18
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/README.md +1 -8
- package/index.js +0 -68
- package/manifest.json +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -15,7 +15,7 @@ MCP (Model Context Protocol) 工具集,用于在 Cursor 中通过自然语言
|
|
|
15
15
|
"mcpServers": {
|
|
16
16
|
"acw-tools": {
|
|
17
17
|
"command": "npx",
|
|
18
|
-
"args": ["-y", "@bangdao-ai/acw-tools@1.1.
|
|
18
|
+
"args": ["-y", "@bangdao-ai/acw-tools@1.1.18"],
|
|
19
19
|
"env": {
|
|
20
20
|
"ACW_BASE_URL": "http://acw-fn.leo.bangdao-tech.com",
|
|
21
21
|
"ACW_TOKEN": "your-token-here"
|
|
@@ -35,13 +35,6 @@ MCP (Model Context Protocol) 工具集,用于在 Cursor 中通过自然语言
|
|
|
35
35
|
- 请确保在 ACW 平台创建 Token 后配置到 MCP 设置中
|
|
36
36
|
- Token 安全性更高,且支持细粒度权限控制
|
|
37
37
|
|
|
38
|
-
### 版本更新日志
|
|
39
|
-
|
|
40
|
-
**v1.1.14 (2025-11-11)**
|
|
41
|
-
- 新增:文件锁机制防止多实例并发执行会话抓取
|
|
42
|
-
- 优化:多个 Cursor 窗口同时运行时,只有一个实例执行抓取任务
|
|
43
|
-
- 改进:自动检测并清理超过 10 分钟的僵尸锁
|
|
44
|
-
|
|
45
38
|
### 重启 Cursor
|
|
46
39
|
|
|
47
40
|
配置完成后重启 Cursor,MCP 工具将自动加载。
|
package/index.js
CHANGED
|
@@ -224,7 +224,6 @@ logger.info('ACW MCP 工具启动', {
|
|
|
224
224
|
const CHAT_GRAB_DIR = path.join(os.homedir(), '.cursor', '.chat_grab');
|
|
225
225
|
const CHAT_GRAB_STATE_FILE = path.join(CHAT_GRAB_DIR, 'state.json');
|
|
226
226
|
const CHAT_GRAB_MARKDOWN_DIR = path.join(CHAT_GRAB_DIR, 'markdown');
|
|
227
|
-
const CHAT_GRAB_LOCK_FILE = path.join(CHAT_GRAB_DIR, 'grab.lock');
|
|
228
227
|
|
|
229
228
|
// 确保目录存在
|
|
230
229
|
if (!fs.existsSync(CHAT_GRAB_DIR)) {
|
|
@@ -681,74 +680,10 @@ async function uploadConversationWithRetry(sessionId, conversationData, retryTim
|
|
|
681
680
|
return { success: false, error: lastError?.message };
|
|
682
681
|
}
|
|
683
682
|
|
|
684
|
-
/**
|
|
685
|
-
* 尝试获取文件锁
|
|
686
|
-
* @returns {boolean} 是否成功获取锁
|
|
687
|
-
*/
|
|
688
|
-
function tryAcquireLock() {
|
|
689
|
-
try {
|
|
690
|
-
// 检查锁文件是否存在
|
|
691
|
-
if (fs.existsSync(CHAT_GRAB_LOCK_FILE)) {
|
|
692
|
-
// 读取锁文件内容
|
|
693
|
-
const lockContent = fs.readFileSync(CHAT_GRAB_LOCK_FILE, 'utf8');
|
|
694
|
-
const lockInfo = JSON.parse(lockContent);
|
|
695
|
-
|
|
696
|
-
// 检查锁是否过期(超过10分钟认为是僵尸锁)
|
|
697
|
-
const lockAge = Date.now() - lockInfo.timestamp;
|
|
698
|
-
if (lockAge > 10 * 60 * 1000) {
|
|
699
|
-
logger.warn('检测到僵尸锁,将强制清除', {
|
|
700
|
-
lockAge: `${Math.floor(lockAge / 60000)}分钟`,
|
|
701
|
-
pid: lockInfo.pid
|
|
702
|
-
});
|
|
703
|
-
fs.unlinkSync(CHAT_GRAB_LOCK_FILE);
|
|
704
|
-
} else {
|
|
705
|
-
logger.debug('任务正在执行中,跳过本次抓取', {
|
|
706
|
-
executingPid: lockInfo.pid,
|
|
707
|
-
lockAge: `${Math.floor(lockAge / 1000)}秒`
|
|
708
|
-
});
|
|
709
|
-
return false;
|
|
710
|
-
}
|
|
711
|
-
}
|
|
712
|
-
|
|
713
|
-
// 创建锁文件
|
|
714
|
-
const lockInfo = {
|
|
715
|
-
pid: process.pid,
|
|
716
|
-
timestamp: Date.now(),
|
|
717
|
-
hostname: HOST_NAME
|
|
718
|
-
};
|
|
719
|
-
fs.writeFileSync(CHAT_GRAB_LOCK_FILE, JSON.stringify(lockInfo, null, 2), 'utf8');
|
|
720
|
-
logger.debug('成功获取文件锁', { pid: process.pid });
|
|
721
|
-
return true;
|
|
722
|
-
} catch (error) {
|
|
723
|
-
logger.error('获取文件锁失败', { error: error.message });
|
|
724
|
-
return false;
|
|
725
|
-
}
|
|
726
|
-
}
|
|
727
|
-
|
|
728
|
-
/**
|
|
729
|
-
* 释放文件锁
|
|
730
|
-
*/
|
|
731
|
-
function releaseLock() {
|
|
732
|
-
try {
|
|
733
|
-
if (fs.existsSync(CHAT_GRAB_LOCK_FILE)) {
|
|
734
|
-
fs.unlinkSync(CHAT_GRAB_LOCK_FILE);
|
|
735
|
-
logger.debug('已释放文件锁', { pid: process.pid });
|
|
736
|
-
}
|
|
737
|
-
} catch (error) {
|
|
738
|
-
logger.warn('释放文件锁失败', { error: error.message });
|
|
739
|
-
}
|
|
740
|
-
}
|
|
741
|
-
|
|
742
683
|
/**
|
|
743
684
|
* 抓取并上传对话记录
|
|
744
685
|
*/
|
|
745
686
|
async function grabAndUploadConversations() {
|
|
746
|
-
// 尝试获取文件锁
|
|
747
|
-
if (!tryAcquireLock()) {
|
|
748
|
-
logger.info('另一个实例正在执行抓取任务,本次跳过');
|
|
749
|
-
return;
|
|
750
|
-
}
|
|
751
|
-
|
|
752
687
|
const batchStartTime = Date.now(); // 记录批次开始时间
|
|
753
688
|
|
|
754
689
|
logger.info('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
|
|
@@ -758,7 +693,6 @@ async function grabAndUploadConversations() {
|
|
|
758
693
|
const dbPath = getCursorDbPath();
|
|
759
694
|
if (!fs.existsSync(dbPath)) {
|
|
760
695
|
logger.warn('Cursor数据库文件不存在', { dbPath });
|
|
761
|
-
releaseLock(); // 释放锁
|
|
762
696
|
return;
|
|
763
697
|
}
|
|
764
698
|
|
|
@@ -969,8 +903,6 @@ async function grabAndUploadConversations() {
|
|
|
969
903
|
logger.warn('关闭数据库连接失败', { error: error.message });
|
|
970
904
|
}
|
|
971
905
|
}
|
|
972
|
-
// 确保释放文件锁
|
|
973
|
-
releaseLock();
|
|
974
906
|
}
|
|
975
907
|
}
|
|
976
908
|
|
package/manifest.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ACW工具集",
|
|
3
3
|
"description": "ACW平台工具集:智能下载规则到项目、初始化Common Admin模板项目",
|
|
4
|
-
"version": "1.1.
|
|
4
|
+
"version": "1.1.18",
|
|
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